From 8e9dfdf3e626d994976d541413fac5fcafff484f Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Mon, 24 May 2010 17:03:41 +0000 Subject: [PATCH] Moved order/closure outside dispatches, not necessary there / more overhead Implemented order/closure in within [SVN r62175] --- include/boost/geometry/algorithms/area.hpp | 41 ++++++------ .../boost/geometry/algorithms/centroid.hpp | 41 ++++++------ include/boost/geometry/algorithms/within.hpp | 63 +++++++++++++++---- .../boost/geometry/multi/algorithms/area.hpp | 5 +- .../geometry/multi/algorithms/centroid.hpp | 7 +-- .../geometry/multi/algorithms/within.hpp | 2 + test/algorithms/test_within.hpp | 54 ++++++++++------ test/algorithms/within.cpp | 2 +- 8 files changed, 140 insertions(+), 75 deletions(-) diff --git a/include/boost/geometry/algorithms/area.hpp b/include/boost/geometry/algorithms/area.hpp index fc833e69d..bca72e401 100644 --- a/include/boost/geometry/algorithms/area.hpp +++ b/include/boost/geometry/algorithms/area.hpp @@ -116,7 +116,6 @@ struct ring_area return type(); } - typedef reversible_view rview_type; typedef closeable_view < @@ -158,8 +157,6 @@ template < typename Tag, typename Geometry, - order_selector Order, - closure_selector Closure, typename Strategy > struct area @@ -171,26 +168,38 @@ struct area > {}; -template -struct area +template +< + typename Geometry, + typename Strategy +> +struct area : detail::area::box_area {}; -template -struct area +template +< + typename Ring, + typename Strategy +> +struct area : detail::area::ring_area < - Geometry, - order_as_direction::value, - Closure, //closure_as_bool::value, + Ring, + order_as_direction::value>::value, + geometry::closure::value, Strategy > {}; -template -struct area +template +< + typename Polygon, + typename Strategy +> +struct area : detail::calculate_polygon_sum < typename Strategy::return_type, @@ -199,8 +208,8 @@ struct area detail::area::ring_area < typename ring_type::type, - order_as_direction::value, - Closure, //closure_as_bool::value, + order_as_direction::value>::value, + geometry::closure::value, Strategy > > @@ -234,8 +243,6 @@ inline typename area_result::type area(Geometry const& geometry) < typename tag::type, Geometry, - geometry::point_order::value, - geometry::closure::value, strategy_type >::apply(geometry, strategy_type()); } @@ -259,8 +266,6 @@ inline typename Strategy::return_type area( < typename tag::type, Geometry, - geometry::point_order::value, - geometry::closure::value, Strategy >::apply(geometry, strategy); } diff --git a/include/boost/geometry/algorithms/centroid.hpp b/include/boost/geometry/algorithms/centroid.hpp index d9fb5ea8b..d0c74e88c 100644 --- a/include/boost/geometry/algorithms/centroid.hpp +++ b/include/boost/geometry/algorithms/centroid.hpp @@ -276,16 +276,18 @@ struct centroid_linestring \note Because outer ring is clockwise, inners are counter clockwise, triangle approach is OK and works for polygons with rings. */ -template +template struct centroid_polygon_state { + typedef typename ring_type::type ring_type; + static inline void apply(Polygon const& poly, Strategy const& strategy, typename Strategy::state_type& state) { typedef centroid_ring_state < - typename ring_type::type, - Closure, + ring_type, + geometry::closure::value, Strategy > per_ring; @@ -303,7 +305,7 @@ struct centroid_polygon_state } }; -template +template struct centroid_polygon { static inline void apply(Polygon const& poly, Point& centroid, @@ -315,7 +317,6 @@ struct centroid_polygon centroid_polygon_state < Polygon, - Closure, Strategy >::apply(poly, strategy, state); Strategy::result(state, centroid); @@ -337,7 +338,6 @@ template typename Tag, typename Geometry, typename Point, - closure_selector Closure, typename Strategy > struct centroid {}; @@ -346,10 +346,9 @@ template < typename Geometry, typename Point, - closure_selector Closure, typename Strategy > -struct centroid +struct centroid : detail::centroid::centroid_point {}; @@ -357,26 +356,31 @@ template < typename Box, typename Point, - closure_selector Closure, typename Strategy > -struct centroid +struct centroid : detail::centroid::centroid_box {}; -template -struct centroid - : detail::centroid::centroid_ring +template +struct centroid + : detail::centroid::centroid_ring + < + Ring, + Point, + geometry::closure::value, + Strategy + > {}; -template -struct centroid +template +struct centroid : detail::centroid::centroid_linestring {}; -template -struct centroid - : detail::centroid::centroid_polygon +template +struct centroid + : detail::centroid::centroid_polygon {}; } // namespace dispatch @@ -407,7 +411,6 @@ inline void centroid(Geometry const& geometry, Point& c, typename tag::type, Geometry, Point, - geometry::closure::value, Strategy >::apply(geometry, c, strategy); } diff --git a/include/boost/geometry/algorithms/within.hpp b/include/boost/geometry/algorithms/within.hpp index e13a83a4d..ec5b4a6d6 100644 --- a/include/boost/geometry/algorithms/within.hpp +++ b/include/boost/geometry/algorithms/within.hpp @@ -51,14 +51,18 @@ The within algorithm is used as following: #include #include +#include +#include #include #include -#include - +#include +#include #include - #include #include +#include +#include +#include namespace boost { namespace geometry @@ -168,7 +172,14 @@ struct box_in_box }; -template +template +< + typename Point, + typename Ring, + iterate_direction Direction, + closure_selector Closure, + typename Strategy +> struct point_in_ring { BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy) ); @@ -181,14 +192,23 @@ struct point_in_ring return false; } - typedef typename boost::range_iterator::type iterator_type; + typedef reversible_view rev_view_type; + typedef closeable_view + < + rev_view_type const, + Closure == open // close it if it is open + > cl_view_type; + typedef typename boost::range_iterator::type iterator_type; + rev_view_type rev_view(ring); + cl_view_type view(rev_view); typename Strategy::state_type state; + iterator_type it = boost::begin(view); + iterator_type end = boost::end(view); - iterator_type it = boost::begin(ring); for (iterator_type previous = it++; - it != boost::end(ring); - previous = it++) + it != end; + ++previous, ++it) { if (! strategy.apply(point, *previous, *it, state)) { @@ -200,7 +220,14 @@ struct point_in_ring }; // Polygon: in exterior ring, and if so, not within interior ring(s) -template +template +< + typename Point, + typename Polygon, + iterate_direction Direction, + closure_selector Closure, + typename Strategy +> struct point_in_polygon { BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy) ); @@ -213,6 +240,8 @@ struct point_in_polygon < Point, typename ring_type::type, + Direction, + Closure, Strategy > per_ring; @@ -286,13 +315,25 @@ struct within template struct within : detail::within::point_in_ring - + < + Point, + Ring, + order_as_direction::value>::value, + geometry::closure::value, + Strategy + > {}; template struct within : detail::within::point_in_polygon - + < + Point, + Polygon, + order_as_direction::value>::value, + geometry::closure::value, + Strategy + > {}; } // namespace dispatch diff --git a/include/boost/geometry/multi/algorithms/area.hpp b/include/boost/geometry/multi/algorithms/area.hpp index 0112208d4..28d98f0dc 100644 --- a/include/boost/geometry/multi/algorithms/area.hpp +++ b/include/boost/geometry/multi/algorithms/area.hpp @@ -24,8 +24,8 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { -template -struct area +template +struct area : detail::multi_sum < typename Strategy::return_type, @@ -35,7 +35,6 @@ struct area < polygon_tag, typename boost::range_value::type, - Order, Closure, Strategy > > diff --git a/include/boost/geometry/multi/algorithms/centroid.hpp b/include/boost/geometry/multi/algorithms/centroid.hpp index a2ec1dd61..a1797df77 100644 --- a/include/boost/geometry/multi/algorithms/centroid.hpp +++ b/include/boost/geometry/multi/algorithms/centroid.hpp @@ -103,10 +103,9 @@ template < typename MultiPolygon, typename Point, - closure_selector Closure, typename Strategy > -struct centroid +struct centroid : detail::centroid::centroid_multi < MultiPolygon, @@ -115,7 +114,6 @@ struct centroid detail::centroid::centroid_polygon_state < typename boost::range_value::type, - Closure, Strategy > > @@ -126,10 +124,9 @@ template < typename MultiPoint, typename Point, - closure_selector Closure, typename Strategy > -struct centroid +struct centroid : detail::centroid::centroid_multi < MultiPoint, diff --git a/include/boost/geometry/multi/algorithms/within.hpp b/include/boost/geometry/multi/algorithms/within.hpp index da74def93..438ba337a 100644 --- a/include/boost/geometry/multi/algorithms/within.hpp +++ b/include/boost/geometry/multi/algorithms/within.hpp @@ -71,6 +71,8 @@ struct within < Point, typename boost::range_value::type, + order_as_direction::value>::value, + geometry::closure::value, Strategy > > diff --git a/test/algorithms/test_within.hpp b/test/algorithms/test_within.hpp index 0c24d35b2..cfbd0a87a 100644 --- a/test/algorithms/test_within.hpp +++ b/test/algorithms/test_within.hpp @@ -24,13 +24,14 @@ template void test_geometry(std::string const& wkt1, std::string const& wkt2, bool expected) { + namespace bg = boost::geometry; Geometry1 geometry1; Geometry2 geometry2; - boost::geometry::read_wkt(wkt1, geometry1); - boost::geometry::read_wkt(wkt2, geometry2); + bg::read_wkt(wkt1, geometry1); + bg::read_wkt(wkt2, geometry2); - bool detected = boost::geometry::within(geometry1, geometry2); + bool detected = bg::within(geometry1, geometry2); BOOST_CHECK_MESSAGE(detected == expected, "within: " << wkt1 @@ -40,53 +41,68 @@ void test_geometry(std::string const& wkt1, } -template +template void test_ordered_ring(std::string const& wkt_point, std::string const& wkt_geometry, bool expected, bool on_border) { - typedef boost::geometry::linear_ring ring_type; + namespace bg = boost::geometry; + typedef bg::linear_ring ring_type; ring_type ring; Point point; - boost::geometry::read_wkt(wkt_geometry, ring); - if (! CW) + bg::read_wkt(wkt_geometry, ring); + if (! Clockwise) { std::reverse(boost::begin(ring), boost::end(ring)); } - boost::geometry::read_wkt(wkt_point, point); + if (! Closed) + { + ring.resize(ring.size() - 1); + } - bool detected = boost::geometry::within(point, ring); + bg::read_wkt(wkt_point, point); + + bool detected = bg::within(point, ring); BOOST_CHECK_MESSAGE(detected == expected, "within: " << wkt_point << " in " << wkt_geometry << " -> Expected: " << expected - << " detected: " << detected); + << " detected: " << detected + << " clockwise: " << int(Clockwise) + << " closed: " << int(Closed) + ); // other strategy (note that this one cannot detect OnBorder // (without modifications) - boost::geometry::strategy::within::franklin franklin; - detected = boost::geometry::within(point, ring, franklin); + bg::strategy::within::franklin franklin; + detected = bg::within(point, ring, franklin); if (! on_border) { BOOST_CHECK_MESSAGE(detected == expected, "within: " << wkt_point << " in " << wkt_geometry << " -> Expected: " << expected - << " detected: " << detected); + << " detected: " << detected + << " clockwise: " << int(Clockwise) + << " closed: " << int(Closed) + ); } - boost::geometry::strategy::within::crossings_multiply cm; - detected = boost::geometry::within(point, ring, cm); + bg::strategy::within::crossings_multiply cm; + detected = bg::within(point, ring, cm); if (! on_border) { BOOST_CHECK_MESSAGE(detected == expected, "within: " << wkt_point << " in " << wkt_geometry << " -> Expected: " << expected - << " detected: " << detected); + << " detected: " << detected + << " clockwise: " << int(Clockwise) + << " closed: " << int(Closed) + ); } } @@ -95,8 +111,10 @@ void test_ring(std::string const& wkt_point, std::string const& wkt_geometry, bool expected, bool on_border) { - test_ordered_ring(wkt_point, wkt_geometry, expected, on_border); - test_ordered_ring(wkt_point, wkt_geometry, expected, on_border); + test_ordered_ring(wkt_point, wkt_geometry, expected, on_border); + test_ordered_ring(wkt_point, wkt_geometry, expected, on_border); + test_ordered_ring(wkt_point, wkt_geometry, expected, on_border); + test_ordered_ring(wkt_point, wkt_geometry, expected, on_border); test_geometry >(wkt_point, wkt_geometry, expected); } diff --git a/test/algorithms/within.cpp b/test/algorithms/within.cpp index 08d4ab2b7..d3dfca501 100644 --- a/test/algorithms/within.cpp +++ b/test/algorithms/within.cpp @@ -77,5 +77,5 @@ int test_main( int , char* [] ) test_all >(); #endif - return 0; + return 0; }