diff --git a/example/with_external_libs/CMakeLists.txt b/example/with_external_libs/CMakeLists.txt new file mode 100644 index 000000000..1d60eb866 --- /dev/null +++ b/example/with_external_libs/CMakeLists.txt @@ -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) + diff --git a/example/with_external_libs/x04_wxwidgets_world_mapper.cpp b/example/with_external_libs/x04_wxwidgets_world_mapper.cpp index 49bf0878b..ac3f6322e 100644 --- a/example/with_external_libs/x04_wxwidgets_world_mapper.cpp +++ b/example/with_external_libs/x04_wxwidgets_world_mapper.cpp @@ -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, // 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) +// 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 #include -#include -#include -#include - #include #include #include -#include +#include #include #include -#include - - -// wxWidgets, if these headers are NOT found, adapt include path (and lib path) #include "wx/wx.h" #include "wx/math.h" #include "wx/stockitem.h" - #ifdef EXAMPLE_WX_USE_GRAPHICS_CONTEXT #include "wx/graphics.h" #include "wx/dcgraph.h" #endif -typedef boost::geometry::model::d2::point_xy point_2d; -typedef boost::geometry::model::multi_polygon + +using point_2d = boost::geometry::model::d2::point_xy; +using country_type = boost::geometry::model::multi_polygon < boost::geometry::model::polygon - > country_type; + >; // Adapt wxWidgets points to Boost.Geometry points such that they can be used // in e.g. transformations (see below) BOOST_GEOMETRY_REGISTER_POINT_2D(wxPoint, int, 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 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 -{ -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& - operator=(wxPoint const& value) - { - // Check if not passed beyond - if (current != end) - { - *current++ = value; - } - return *this; - } - - // Boiler-plate - inline back_insert_iterator& operator*() { return *this; } - inline back_insert_iterator& operator++() { return *this; } - inline back_insert_iterator& operator++(int) { return *this; } - -private: - boost::range_iterator::type current, end; -}; - -} // namespace std - - // ---------------------------------------------------------------------------- // Read an ASCII file containing WKT's // ---------------------------------------------------------------------------- @@ -161,26 +108,29 @@ private: void OnPaint(wxPaintEvent& ); void OnMouseMove(wxMouseEvent&); - typedef boost::geometry::strategy::transform::map_transformer + using map_transformer_type = boost::geometry::strategy::transform::map_transformer < double, 2, 2, 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 - > inverse_transformer_type; + >; - boost::shared_ptr m_map_transformer; - boost::shared_ptr m_inverse_transformer; + std::shared_ptr m_map_transformer; + std::shared_ptr m_inverse_transformer; boost::geometry::model::box m_box; std::vector m_countries; - int m_focus; + int m_focus = -1; - wxBrush m_orange; - wxFrame* m_owner; + wxBrush m_orange = wxBrush(wxColour(255, 128, 0), wxBRUSHSTYLE_SOLID); + 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() }; @@ -244,19 +194,14 @@ void HelloWorldFrame::OnCloseWindow(wxCloseEvent& ) HelloWorldCanvas::HelloWorldCanvas(wxFrame *frame) : wxWindow(frame, wxID_ANY) , m_owner(frame) - , m_focus(-1) { boost::geometry::assign_inverse(m_box); read_wkt("../data/world.wkt", m_countries, m_box); - m_orange = wxBrush(wxColour(255, 128, 0), wxSOLID); } - void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event) { - namespace bg = boost::geometry; - if (m_inverse_transformer) { // Boiler-plate wxWidgets code @@ -264,19 +209,21 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event) 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; - bg::transform(event.GetPosition(), point, *m_inverse_transformer); + boost::geometry::transform(event.GetPosition(), point, + *m_inverse_transformer); // Determine selected object int i = 0; int previous_focus = m_focus; 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; + break; } i++; } @@ -287,7 +234,7 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event) // Undraw old focus if (previous_focus >= 0) { - dc.SetBrush(*wxWHITE_BRUSH); + dc.SetBrush(m_green); DrawCountry(dc, m_countries[previous_focus]); } // Draw new focus @@ -309,6 +256,11 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event) void HelloWorldCanvas::OnPaint(wxPaintEvent& ) { + if (m_countries.empty()) + { + return; + } + #if defined(EXAMPLE_WX_USE_GRAPHICS_CONTEXT) wxPaintDC pdc(this); wxGCDC gdc(pdc); @@ -340,11 +292,12 @@ void HelloWorldCanvas::DrawCountries(wxDC& dc) { namespace bg = boost::geometry; - dc.SetBackground(*wxLIGHT_GREY_BRUSH); + dc.SetBackground(m_blue); dc.Clear(); - BOOST_FOREACH(country_type const& country, m_countries) + for (country_type const& country : m_countries) { + dc.SetBrush(m_green); DrawCountry(dc, country); } if (m_focus != -1) @@ -357,27 +310,23 @@ void HelloWorldCanvas::DrawCountries(wxDC& dc) void HelloWorldCanvas::DrawCountry(wxDC& dc, country_type const& country) { - namespace bg = boost::geometry; - - BOOST_FOREACH(bg::model::polygon const& poly, country) + for (auto const& poly : country) { - // Use only exterior ring, holes are (for the moment) ignored. This would need - // a holey-polygon compatible wx object + // Use only exterior ring, holes are (for the moment) ignored. + // This would need a holey-polygon compatible wx object - std::size_t n = boost::size(bg::exterior_ring(poly)); - - boost::scoped_array points(new wxPoint[n]); - - wxPointPointerPair pair = std::make_pair(points.get(), points.get() + n); - bg::transform(bg::exterior_ring(poly), pair, *m_map_transformer); - - dc.DrawPolygon(n, points.get()); + // Define a Boost.Geometry ring of wxPoints + // Behind the scenes that is a vector, and a vector has .data(), + // can be used for the *wxPoint pointer needed for wxWidget DrawPolygon + boost::geometry::model::ring ring; + boost::geometry::transform(boost::geometry::exterior_ring(poly), ring, + *m_map_transformer); + dc.DrawPolygon(ring.size(), ring.data()); } } // ---------------------------------------------------------------------------- - BEGIN_EVENT_TABLE(HelloWorldFrame, wxFrame) EVT_CLOSE(HelloWorldFrame::OnCloseWindow) EVT_MENU(wxID_EXIT, HelloWorldFrame::OnExit) diff --git a/example/with_external_libs/x04_wxwidgets_world_mapper_readme.txt b/example/with_external_libs/x04_wxwidgets_world_mapper_readme.txt deleted file mode 100644 index cba0c8eeb..000000000 --- a/example/with_external_libs/x04_wxwidgets_world_mapper_readme.txt +++ /dev/null @@ -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` -