mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 05:24:02 +00:00
fix: example of wxwidgets
This commit is contained in:
parent
4d49535192
commit
e131a02175
34
example/with_external_libs/CMakeLists.txt
Normal file
34
example/with_external_libs/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Boost.Geometry
|
||||||
|
# Example CMakeLists.txt building the Boost.Geometry with wxWidget example
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021-2021 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
|
|
||||||
|
# Use, modification and distribution is subject to the Boost Software License,
|
||||||
|
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
# http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
project(with_external_libs)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
|
# Set BOOST_ROOT in your environment (this is cmake default)
|
||||||
|
find_package(Boost)
|
||||||
|
|
||||||
|
# Set WX_ROOT, similarly, also in your environment
|
||||||
|
set(WX_ROOT $ENV{WX_ROOT})
|
||||||
|
message(STATUS "Using wxWidgets from this folder: " $ENV{WX_ROOT})
|
||||||
|
|
||||||
|
# WX Widgets
|
||||||
|
link_directories(${WX_ROOT}/lib)
|
||||||
|
add_executable(wx x04_wxwidgets_world_mapper.cpp)
|
||||||
|
target_include_directories(wx PRIVATE ${Boost_INCLUDE_DIRS})
|
||||||
|
target_include_directories(wx PRIVATE ${WX_ROOT}/include)
|
||||||
|
target_include_directories(wx PRIVATE ${WX_ROOT}/include/wx-3.1)
|
||||||
|
|
||||||
|
# WX configuration (get the values using wx-config --cxxflags and wx-config --libs)
|
||||||
|
target_compile_definitions(wx PRIVATE WXUSINGDLL __WXGTK2__ __WXGTK__)
|
||||||
|
target_link_libraries(wx PRIVATE wx_gtk2u_html-3.1 wx_gtk2u_core-3.1 wx_baseu_net-3.1 wx_baseu-3.1)
|
||||||
|
|
@ -1,115 +1,62 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
// Boost.Geometry
|
||||||
//
|
//
|
||||||
// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2010-2021 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// wxWidgets World Mapper example
|
// wxWidgets World Mapper example
|
||||||
|
//
|
||||||
|
// It will show a basic wxWidgets window, displaying world countries,
|
||||||
|
// highlighting the country under the mouse, and indicating position
|
||||||
|
// of the mouse in latitude/longitude and in pixels.
|
||||||
|
|
||||||
|
// To compile this program:
|
||||||
|
// Install wxWidgets (if not done before)
|
||||||
|
// export BOOST_ROOT=.....
|
||||||
|
// export WX_ROOT=.... (for example /home/myname/mylib/wxWidgets/Linux/x86_64)
|
||||||
|
// mkdir build
|
||||||
|
// cd build
|
||||||
|
// cmake .. -G Ninja
|
||||||
|
// ninja
|
||||||
|
// If necessary, CMakeLists.txt should be adapted, the options for wx
|
||||||
|
// are provided by "wx-config --cxxflags" and "... --libs"
|
||||||
|
// and might need a change in CMakeLists.txt
|
||||||
|
|
||||||
// #define EXAMPLE_WX_USE_GRAPHICS_CONTEXT 1
|
//#define EXAMPLE_WX_USE_GRAPHICS_CONTEXT 1
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/scoped_array.hpp>
|
|
||||||
|
|
||||||
#include <boost/geometry/geometry.hpp>
|
#include <boost/geometry/geometry.hpp>
|
||||||
#include <boost/geometry/geometries/geometries.hpp>
|
#include <boost/geometry/geometries/geometries.hpp>
|
||||||
#include <boost/geometry/geometries/point_xy.hpp>
|
#include <boost/geometry/geometries/point_xy.hpp>
|
||||||
#include <boost/geometry/geometries/multi_geometries.hpp>
|
#include <boost/geometry/geometries/multi_polygon.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/geometries/register/point.hpp>
|
#include <boost/geometry/geometries/register/point.hpp>
|
||||||
#include <boost/geometry/geometries/register/ring.hpp>
|
#include <boost/geometry/geometries/register/ring.hpp>
|
||||||
#include <boost/geometry/extensions/algorithms/selected.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
// wxWidgets, if these headers are NOT found, adapt include path (and lib path)
|
|
||||||
|
|
||||||
#include "wx/wx.h"
|
#include "wx/wx.h"
|
||||||
#include "wx/math.h"
|
#include "wx/math.h"
|
||||||
#include "wx/stockitem.h"
|
#include "wx/stockitem.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef EXAMPLE_WX_USE_GRAPHICS_CONTEXT
|
#ifdef EXAMPLE_WX_USE_GRAPHICS_CONTEXT
|
||||||
#include "wx/graphics.h"
|
#include "wx/graphics.h"
|
||||||
#include "wx/dcgraph.h"
|
#include "wx/dcgraph.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef boost::geometry::model::d2::point_xy<double> point_2d;
|
|
||||||
typedef boost::geometry::model::multi_polygon
|
using point_2d = boost::geometry::model::d2::point_xy<double>;
|
||||||
|
using country_type = boost::geometry::model::multi_polygon
|
||||||
<
|
<
|
||||||
boost::geometry::model::polygon<point_2d>
|
boost::geometry::model::polygon<point_2d>
|
||||||
> country_type;
|
>;
|
||||||
|
|
||||||
// Adapt wxWidgets points to Boost.Geometry points such that they can be used
|
// Adapt wxWidgets points to Boost.Geometry points such that they can be used
|
||||||
// in e.g. transformations (see below)
|
// in e.g. transformations (see below)
|
||||||
BOOST_GEOMETRY_REGISTER_POINT_2D(wxPoint, int, cs::cartesian, x, y)
|
BOOST_GEOMETRY_REGISTER_POINT_2D(wxPoint, int, cs::cartesian, x, y)
|
||||||
BOOST_GEOMETRY_REGISTER_POINT_2D(wxRealPoint, double, cs::cartesian, x, y)
|
BOOST_GEOMETRY_REGISTER_POINT_2D(wxRealPoint, double, cs::cartesian, x, y)
|
||||||
|
|
||||||
|
|
||||||
// wxWidgets draws using wxPoint*, so we HAVE to use that.
|
|
||||||
// Therefore have to make a wxPoint* array
|
|
||||||
// 1) compatible with Boost.Geometry
|
|
||||||
// 2) compatible with Boost.Range (required by Boost.Geometry)
|
|
||||||
// 3) compatible with std::back_inserter (required by Boost.Geometry)
|
|
||||||
|
|
||||||
// For compatible 2):
|
|
||||||
typedef std::pair<wxPoint*,wxPoint*> wxPointPointerPair;
|
|
||||||
|
|
||||||
// For compatible 1):
|
|
||||||
BOOST_GEOMETRY_REGISTER_RING(wxPointPointerPair);
|
|
||||||
|
|
||||||
|
|
||||||
// For compatible 3):
|
|
||||||
// Specialize back_insert_iterator for the wxPointPointerPair
|
|
||||||
// (has to be done within "namespace std")
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class back_insert_iterator<wxPointPointerPair>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::output_iterator_tag iterator_category;
|
|
||||||
typedef void value_type;
|
|
||||||
typedef void difference_type;
|
|
||||||
typedef void pointer;
|
|
||||||
typedef void reference;
|
|
||||||
|
|
||||||
typedef wxPointPointerPair container_type;
|
|
||||||
|
|
||||||
explicit back_insert_iterator(wxPointPointerPair& x)
|
|
||||||
: current(boost::begin(x))
|
|
||||||
, end(boost::end(x))
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline back_insert_iterator<wxPointPointerPair>&
|
|
||||||
operator=(wxPoint const& value)
|
|
||||||
{
|
|
||||||
// Check if not passed beyond
|
|
||||||
if (current != end)
|
|
||||||
{
|
|
||||||
*current++ = value;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Boiler-plate
|
|
||||||
inline back_insert_iterator<wxPointPointerPair>& operator*() { return *this; }
|
|
||||||
inline back_insert_iterator<wxPointPointerPair>& operator++() { return *this; }
|
|
||||||
inline back_insert_iterator<wxPointPointerPair>& operator++(int) { return *this; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
boost::range_iterator<wxPointPointerPair>::type current, end;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Read an ASCII file containing WKT's
|
// Read an ASCII file containing WKT's
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -161,26 +108,29 @@ private:
|
|||||||
void OnPaint(wxPaintEvent& );
|
void OnPaint(wxPaintEvent& );
|
||||||
void OnMouseMove(wxMouseEvent&);
|
void OnMouseMove(wxMouseEvent&);
|
||||||
|
|
||||||
typedef boost::geometry::strategy::transform::map_transformer
|
using map_transformer_type = boost::geometry::strategy::transform::map_transformer
|
||||||
<
|
<
|
||||||
double, 2, 2,
|
double, 2, 2,
|
||||||
true, true
|
true, true
|
||||||
> map_transformer_type;
|
>;
|
||||||
|
|
||||||
typedef boost::geometry::strategy::transform::inverse_transformer
|
using inverse_transformer_type = boost::geometry::strategy::transform::inverse_transformer
|
||||||
<
|
<
|
||||||
double, 2, 2
|
double, 2, 2
|
||||||
> inverse_transformer_type;
|
>;
|
||||||
|
|
||||||
boost::shared_ptr<map_transformer_type> m_map_transformer;
|
std::shared_ptr<map_transformer_type> m_map_transformer;
|
||||||
boost::shared_ptr<inverse_transformer_type> m_inverse_transformer;
|
std::shared_ptr<inverse_transformer_type> m_inverse_transformer;
|
||||||
|
|
||||||
boost::geometry::model::box<point_2d> m_box;
|
boost::geometry::model::box<point_2d> m_box;
|
||||||
std::vector<country_type> m_countries;
|
std::vector<country_type> m_countries;
|
||||||
int m_focus;
|
int m_focus = -1;
|
||||||
|
|
||||||
wxBrush m_orange;
|
wxBrush m_orange = wxBrush(wxColour(255, 128, 0), wxBRUSHSTYLE_SOLID);
|
||||||
wxFrame* m_owner;
|
wxBrush m_blue = wxBrush(wxColour(0, 128, 255), wxBRUSHSTYLE_SOLID);
|
||||||
|
wxBrush m_green = wxBrush(wxColour(0, 255, 0), wxBRUSHSTYLE_SOLID);
|
||||||
|
|
||||||
|
wxFrame* m_owner = nullptr;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
@ -244,19 +194,14 @@ void HelloWorldFrame::OnCloseWindow(wxCloseEvent& )
|
|||||||
HelloWorldCanvas::HelloWorldCanvas(wxFrame *frame)
|
HelloWorldCanvas::HelloWorldCanvas(wxFrame *frame)
|
||||||
: wxWindow(frame, wxID_ANY)
|
: wxWindow(frame, wxID_ANY)
|
||||||
, m_owner(frame)
|
, m_owner(frame)
|
||||||
, m_focus(-1)
|
|
||||||
{
|
{
|
||||||
boost::geometry::assign_inverse(m_box);
|
boost::geometry::assign_inverse(m_box);
|
||||||
read_wkt("../data/world.wkt", m_countries, m_box);
|
read_wkt("../data/world.wkt", m_countries, m_box);
|
||||||
m_orange = wxBrush(wxColour(255, 128, 0), wxSOLID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
||||||
{
|
{
|
||||||
namespace bg = boost::geometry;
|
|
||||||
|
|
||||||
if (m_inverse_transformer)
|
if (m_inverse_transformer)
|
||||||
{
|
{
|
||||||
// Boiler-plate wxWidgets code
|
// Boiler-plate wxWidgets code
|
||||||
@ -264,19 +209,21 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
|||||||
PrepareDC(dc);
|
PrepareDC(dc);
|
||||||
m_owner->PrepareDC(dc);
|
m_owner->PrepareDC(dc);
|
||||||
|
|
||||||
// Transform the point to Lon/Lat
|
// Transform the point opn the screen back to Lon/Lat
|
||||||
point_2d point;
|
point_2d point;
|
||||||
bg::transform(event.GetPosition(), point, *m_inverse_transformer);
|
boost::geometry::transform(event.GetPosition(), point,
|
||||||
|
*m_inverse_transformer);
|
||||||
|
|
||||||
// Determine selected object
|
// Determine selected object
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int previous_focus = m_focus;
|
int previous_focus = m_focus;
|
||||||
m_focus = -1;
|
m_focus = -1;
|
||||||
BOOST_FOREACH(country_type const& country, m_countries)
|
for (country_type const& country : m_countries)
|
||||||
{
|
{
|
||||||
if (bg::selected(country, point, 0))
|
if (boost::geometry::within(point, country))
|
||||||
{
|
{
|
||||||
m_focus = i;
|
m_focus = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -287,7 +234,7 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
|||||||
// Undraw old focus
|
// Undraw old focus
|
||||||
if (previous_focus >= 0)
|
if (previous_focus >= 0)
|
||||||
{
|
{
|
||||||
dc.SetBrush(*wxWHITE_BRUSH);
|
dc.SetBrush(m_green);
|
||||||
DrawCountry(dc, m_countries[previous_focus]);
|
DrawCountry(dc, m_countries[previous_focus]);
|
||||||
}
|
}
|
||||||
// Draw new focus
|
// Draw new focus
|
||||||
@ -309,6 +256,11 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
|||||||
|
|
||||||
void HelloWorldCanvas::OnPaint(wxPaintEvent& )
|
void HelloWorldCanvas::OnPaint(wxPaintEvent& )
|
||||||
{
|
{
|
||||||
|
if (m_countries.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(EXAMPLE_WX_USE_GRAPHICS_CONTEXT)
|
#if defined(EXAMPLE_WX_USE_GRAPHICS_CONTEXT)
|
||||||
wxPaintDC pdc(this);
|
wxPaintDC pdc(this);
|
||||||
wxGCDC gdc(pdc);
|
wxGCDC gdc(pdc);
|
||||||
@ -340,11 +292,12 @@ void HelloWorldCanvas::DrawCountries(wxDC& dc)
|
|||||||
{
|
{
|
||||||
namespace bg = boost::geometry;
|
namespace bg = boost::geometry;
|
||||||
|
|
||||||
dc.SetBackground(*wxLIGHT_GREY_BRUSH);
|
dc.SetBackground(m_blue);
|
||||||
dc.Clear();
|
dc.Clear();
|
||||||
|
|
||||||
BOOST_FOREACH(country_type const& country, m_countries)
|
for (country_type const& country : m_countries)
|
||||||
{
|
{
|
||||||
|
dc.SetBrush(m_green);
|
||||||
DrawCountry(dc, country);
|
DrawCountry(dc, country);
|
||||||
}
|
}
|
||||||
if (m_focus != -1)
|
if (m_focus != -1)
|
||||||
@ -357,27 +310,23 @@ void HelloWorldCanvas::DrawCountries(wxDC& dc)
|
|||||||
|
|
||||||
void HelloWorldCanvas::DrawCountry(wxDC& dc, country_type const& country)
|
void HelloWorldCanvas::DrawCountry(wxDC& dc, country_type const& country)
|
||||||
{
|
{
|
||||||
namespace bg = boost::geometry;
|
for (auto const& poly : country)
|
||||||
|
|
||||||
BOOST_FOREACH(bg::model::polygon<point_2d> const& poly, country)
|
|
||||||
{
|
{
|
||||||
// Use only exterior ring, holes are (for the moment) ignored. This would need
|
// Use only exterior ring, holes are (for the moment) ignored.
|
||||||
// a holey-polygon compatible wx object
|
// This would need a holey-polygon compatible wx object
|
||||||
|
|
||||||
std::size_t n = boost::size(bg::exterior_ring(poly));
|
// Define a Boost.Geometry ring of wxPoints
|
||||||
|
// Behind the scenes that is a vector, and a vector has .data(),
|
||||||
boost::scoped_array<wxPoint> points(new wxPoint[n]);
|
// can be used for the *wxPoint pointer needed for wxWidget DrawPolygon
|
||||||
|
boost::geometry::model::ring<wxPoint> ring;
|
||||||
wxPointPointerPair pair = std::make_pair(points.get(), points.get() + n);
|
boost::geometry::transform(boost::geometry::exterior_ring(poly), ring,
|
||||||
bg::transform(bg::exterior_ring(poly), pair, *m_map_transformer);
|
*m_map_transformer);
|
||||||
|
dc.DrawPolygon(ring.size(), ring.data());
|
||||||
dc.DrawPolygon(n, points.get());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(HelloWorldFrame, wxFrame)
|
BEGIN_EVENT_TABLE(HelloWorldFrame, wxFrame)
|
||||||
EVT_CLOSE(HelloWorldFrame::OnCloseWindow)
|
EVT_CLOSE(HelloWorldFrame::OnCloseWindow)
|
||||||
EVT_MENU(wxID_EXIT, HelloWorldFrame::OnExit)
|
EVT_MENU(wxID_EXIT, HelloWorldFrame::OnExit)
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
||||||
//
|
|
||||||
// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
|
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
|
||||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
wxWidgets World Mapper example
|
|
||||||
|
|
||||||
It will show a basic wxWidgets window, displaying world countries, highlighting the country under
|
|
||||||
the mouse, and indicating position of the mouse in latitude/longitude and in pixels.
|
|
||||||
|
|
||||||
|
|
||||||
To compile this program:
|
|
||||||
|
|
||||||
Install wxWidgets (if not done before)
|
|
||||||
|
|
||||||
Using Linux/gcc
|
|
||||||
- check if installation is OK, http://wiki.wxwidgets.org/Installing_and_configuring_under_Ubuntu
|
|
||||||
- compile using e.g. gcc -o x04_wxwidgets -I../../../.. x04_wxwidgets_world_mapper.cpp `wx-config --cxxflags` `wx-config --libs`
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user