From cea8dd1b0dbf81eb08d98fdddbcc9b42b13e0190 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Sun, 11 May 2014 23:21:22 +0300 Subject: [PATCH] [distance] polish code; make clear when the result of comparable or regular strategy is used; --- .../detail/distance/multi_to_multi.hpp | 25 +++-- .../detail/distance/point_to_geometry.hpp | 99 ++++++++++++------- .../distance/polygon_to_segment_or_box.hpp | 27 +++-- .../distance/range_to_segment_or_box.hpp | 64 ++++++------ .../detail/distance/segment_to_box.hpp | 12 ++- .../detail/distance/segment_to_segment.hpp | 23 +++-- .../detail/distance/single_to_multi.hpp | 25 +++-- 7 files changed, 174 insertions(+), 101 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp index 0be5b8641..1e6e3c77f 100644 --- a/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp +++ b/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp @@ -50,24 +50,33 @@ namespace detail { namespace distance template -struct distance_multi_to_multi_generic +class distance_multi_to_multi_generic { +private: typedef typename strategy::distance::services::comparable_type < Strategy >::type comparable_strategy; typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; + < + comparable_strategy, + typename point_type::type, + typename point_type::type + >::type comparable_return_type; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; static inline return_type apply(Multi1 const& multi1, Multi2 const& multi2, Strategy const& strategy) { - return_type min_cdist = return_type(); + comparable_return_type min_cdist = comparable_return_type(); bool first = true; comparable_strategy cstrategy = @@ -80,7 +89,7 @@ struct distance_multi_to_multi_generic it != boost::end(multi1); ++it, first = false) { - return_type cdist = + comparable_return_type cdist = dispatch::splitted_dispatch::distance_single_to_multi < typename range_value::type, diff --git a/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp b/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp index bac63e830..4d6a598ad 100644 --- a/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp @@ -56,14 +56,11 @@ namespace detail { namespace distance { -// To avoid spurious namespaces here: -using strategy::distance::services::return_type; - - template struct point_to_point { - static inline typename return_type::type + static inline + typename strategy::distance::services::return_type::type apply(P1 const& p1, P2 const& p2, Strategy const& strategy) { boost::ignore_unused_variable_warning(strategy); @@ -79,18 +76,25 @@ template closure_selector Closure, typename Strategy > -struct point_to_range +class point_to_range { - typedef typename return_type - < - Strategy, Point, typename point_type::type - >::type return_type; - +private: typedef typename strategy::distance::services::comparable_type < Strategy >::type comparable_strategy; + typedef typename strategy::distance::services::return_type + < + comparable_strategy, Point, typename point_type::type + >::type comparable_return_type; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, Point, typename point_type::type + >::type return_type; + static inline return_type apply(Point const& point, Range const& range, Strategy const& strategy) { @@ -100,7 +104,7 @@ struct point_to_range Strategy >::apply(strategy); - return_type const zero = return_type(0); + comparable_return_type const zero = comparable_return_type(0); if (boost::size(range) == 0) { @@ -126,26 +130,29 @@ struct point_to_range } // start with first segment distance - return_type d = c_strategy.apply(point, *prev, *it); + comparable_return_type cd = c_strategy.apply(point, *prev, *it); // check if other segments are closer for (++prev, ++it; it != boost::end(view); ++prev, ++it) { - return_type const ds = c_strategy.apply(point, *prev, *it); - if (geometry::math::equals(ds, zero)) + comparable_return_type cds = c_strategy.apply(point, *prev, *it); + if (geometry::math::equals(cds, zero)) { - return ds; + return strategy::distance::services::comparable_to_regular + < + comparable_strategy, Strategy, Point, Range + >::apply(zero); } - else if (ds < d) + else if (cds < cd) { - d = ds; + cd = cds; } } return strategy::distance::services::comparable_to_regular < comparable_strategy, Strategy, Point, Range - >::apply(d); + >::apply(cd); } }; @@ -161,7 +168,7 @@ struct point_to_ring { typedef std::pair < - typename return_type + typename strategy::distance::services::return_type < Strategy, Point, typename point_type::type >::type, @@ -195,19 +202,31 @@ template closure_selector Closure, typename Strategy > -struct point_to_polygon +class point_to_polygon { - typedef typename return_type - < - Strategy, Point, typename point_type::type - >::type return_type; - typedef std::pair distance_containment; - +private: typedef typename strategy::distance::services::comparable_type < Strategy >::type comparable_strategy; + typedef typename strategy::distance::services::return_type + < + comparable_strategy, Point, typename point_type::type + >::type comparable_return_type; + + typedef std::pair + < + comparable_return_type, bool + > comparable_distance_containment; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, Point, typename point_type::type + >::type return_type; + typedef std::pair distance_containment; + static inline distance_containment apply(Point const& point, Polygon const& polygon, Strategy const& strategy) @@ -227,9 +246,8 @@ struct point_to_polygon comparable_strategy > per_ring; - distance_containment dc = per_ring::apply(point, - exterior_ring(polygon), - c_strategy); + comparable_distance_containment dc = + per_ring::apply(point, exterior_ring(polygon), c_strategy); typename interior_return_type::type rings = interior_rings(polygon); @@ -239,7 +257,8 @@ struct point_to_polygon >::type it = boost::begin(rings); it != boost::end(rings); ++it) { - distance_containment dcr = per_ring::apply(point, *it, c_strategy); + comparable_distance_containment dcr = + per_ring::apply(point, *it, c_strategy); if (dcr.first < dc.first) { dc.first = dcr.first; @@ -305,11 +324,14 @@ struct distance false > { - typedef typename return_type::type>::type return_type; + typedef typename strategy::distance::services::return_type + < + Strategy, Point, typename point_type::type + >::type return_type; static inline return_type apply(Point const& point, - Ring const& ring, - Strategy const& strategy) + Ring const& ring, + Strategy const& strategy) { std::pair dc = detail::distance::point_to_ring @@ -332,11 +354,14 @@ struct distance strategy_tag_distance_point_segment, false > { - typedef typename return_type::type>::type return_type; + typedef typename strategy::distance::services::return_type + < + Strategy, Point, typename point_type::type + >::type return_type; static inline return_type apply(Point const& point, - Polygon const& polygon, - Strategy const& strategy) + Polygon const& polygon, + Strategy const& strategy) { std::pair dc = detail::distance::point_to_polygon diff --git a/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp index 351e7278e..631cb25d3 100644 --- a/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp @@ -42,20 +42,29 @@ namespace detail { namespace distance template -struct polygon_to_segment_or_box +class polygon_to_segment_or_box { - typedef typename return_type +private: + typedef typename strategy::distance::services::comparable_type + < + Strategy + >::type comparable_strategy; + + typedef typename strategy::distance::services::return_type + < + comparable_strategy, + typename point_type::type, + typename point_type::type + >::type comparable_return_type; + +public: + typedef typename strategy::distance::services::return_type < Strategy, typename point_type::type, typename point_type::type >::type return_type; - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - static inline return_type apply(Polygon const& polygon, SegmentOrBox const& segment_or_box, Strategy const& strategy) @@ -79,7 +88,7 @@ struct polygon_to_segment_or_box >::apply(strategy); - return_type cd_min = range_to_segment_or_box + comparable_return_type cd_min = range_to_segment_or_box < e_ring, SegmentOrBox, comparable_strategy >::apply(ext_ring, segment_or_box, cstrategy, false); @@ -88,7 +97,7 @@ struct polygon_to_segment_or_box for (iterator_type it = boost::begin(int_rings); it != boost::end(int_rings); ++it) { - return_type cd = range_to_segment_or_box + comparable_return_type cd = range_to_segment_or_box < i_ring, SegmentOrBox, comparable_strategy >::apply(*it, segment_or_box, cstrategy, false); diff --git a/include/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp index b73c5a840..db2bcf68f 100644 --- a/include/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp @@ -57,18 +57,16 @@ private: typedef typename point_type::type segment_or_box_point; typedef typename point_type::type range_point; -public: - typedef typename strategy::distance::services::return_type - < - Strategy, range_point, segment_or_box_point - >::type return_type; - -private: typedef typename strategy::distance::services::comparable_type < Strategy >::type comparable_strategy; + typedef typename strategy::distance::services::return_type + < + comparable_strategy, range_point, segment_or_box_point + >::type comparable_return_type; + typedef typename strategy::distance::services::tag < comparable_strategy @@ -79,7 +77,7 @@ private: segment_or_box_point, Range, comparable_strategy, point_tag, typename tag::type, comparable_strategy_tag, false - > point_to_range; + > comparable_point_to_range; // compute distance of a point to a segment or a box template @@ -89,7 +87,7 @@ private: typename ComparableStrategy, typename Tag > - struct distance_point_to_segment_or_box + struct comparable_distance_point_to_segment_or_box {}; template @@ -98,14 +96,15 @@ private: typename SegmentPoints, typename ComparableStrategy > - struct distance_point_to_segment_or_box + struct comparable_distance_point_to_segment_or_box < Point, SegmentPoints, ComparableStrategy, segment_tag > { - static inline return_type apply(Point const& point, - SegmentPoints const& segment_points, - ComparableStrategy const& strategy) + static inline + comparable_return_type apply(Point const& point, + SegmentPoints const& segment_points, + ComparableStrategy const& strategy) { return strategy.apply(point, segment_points[0], segment_points[1]); } @@ -117,21 +116,22 @@ private: typename BoxPoints, typename ComparableStrategy > - struct distance_point_to_segment_or_box + struct comparable_distance_point_to_segment_or_box < Point, BoxPoints, ComparableStrategy, box_tag > { - static inline return_type apply(Point const& point, - BoxPoints const& box_points, - ComparableStrategy const& strategy) + static inline + comparable_return_type apply(Point const& point, + BoxPoints const& box_points, + ComparableStrategy const& strategy) { - return_type cd_min = + comparable_return_type cd_min = strategy.apply(point, box_points[0], box_points[3]); for (unsigned int i = 0; i < 2; ++i) { - return_type cd = + comparable_return_type cd = strategy.apply(point, box_points[i], box_points[i+1]); if ( cd < cd_min ) @@ -177,6 +177,11 @@ private: public: + typedef typename strategy::distance::services::return_type + < + Strategy, range_point, segment_or_box_point + >::type return_type; + static inline return_type apply(Range const& range, SegmentOrBox const& segment_or_box, Strategy const& strategy, bool check_intersection = true) @@ -208,11 +213,13 @@ public: // to the range typename std::vector::const_iterator it = segment_or_box_points.begin(); - return_type cd_min = point_to_range::apply(*it, range, cstrategy); + comparable_return_type cd_min = + comparable_point_to_range::apply(*it, range, cstrategy); for (++it; it != segment_or_box_points.end(); ++it) { - return_type cd = point_to_range::apply(*it, range, cstrategy); + comparable_return_type cd = + comparable_point_to_range::apply(*it, range, cstrategy); if ( cd < cd_min ) { cd_min = cd; @@ -224,13 +231,14 @@ public: typedef typename range_iterator::type iterator_type; for (iterator_type it = boost::begin(range); it != boost::end(range); ++it) { - return_type cd = distance_point_to_segment_or_box - < - typename point_type::type, - std::vector, - comparable_strategy, - typename tag::type - >::apply(*it, segment_or_box_points, cstrategy); + comparable_return_type cd = + comparable_distance_point_to_segment_or_box + < + typename point_type::type, + std::vector, + comparable_strategy, + typename tag::type + >::apply(*it, segment_or_box_points, cstrategy); if ( cd < cd_min ) { diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp index 7f7f6da6a..3efa7673a 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp @@ -407,6 +407,10 @@ private: PSStrategy >::type ps_comparable_strategy; + typedef typename strategy::distance::services::return_type + < + ps_comparable_strategy, segment_point, box_point + >::type comparable_return_type; public: typedef typename strategy::distance::services::return_type < @@ -468,11 +472,11 @@ public: PSStrategy >::apply(ps_strategy); - return_type d; + comparable_return_type cd; if ( geometry::less()(p[0], p[1]) ) { - d = segment_to_box_2D + cd = segment_to_box_2D < return_type, segment_point, @@ -486,7 +490,7 @@ public: } else { - d = segment_to_box_2D + cd = segment_to_box_2D < return_type, segment_point, @@ -502,7 +506,7 @@ public: return strategy::distance::services::comparable_to_regular < ps_comparable_strategy, PSStrategy, Segment, Box - >::apply( d ); + >::apply( cd ); } }; diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp index ab7d11f57..1ae22153c 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp @@ -37,8 +37,22 @@ namespace detail { namespace distance // compute segment-segment distance template -struct segment_to_segment +class segment_to_segment { +private: + typedef typename strategy::distance::services::comparable_type + < + Strategy + >::type comparable_strategy; + + typedef typename strategy::distance::services::return_type + < + comparable_strategy, + typename point_type::type, + typename point_type::type + >::type comparable_return_type; + +public: typedef typename strategy::distance::services::return_type < Strategy, @@ -46,11 +60,6 @@ struct segment_to_segment typename point_type::type >::type return_type; - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - static inline return_type apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& strategy) @@ -74,7 +83,7 @@ struct segment_to_segment Strategy >::apply(strategy); - return_type d[4]; + comparable_return_type d[4]; d[0] = cstrategy.apply(q[0], p[0], p[1]); d[1] = cstrategy.apply(q[1], p[0], p[1]); d[2] = cstrategy.apply(p[0], q[0], q[1]); diff --git a/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp index 6b43144ac..f0c18476d 100644 --- a/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp +++ b/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp @@ -67,25 +67,34 @@ namespace detail { namespace distance template -struct distance_single_to_multi_generic +class distance_single_to_multi_generic { +private: typedef typename strategy::distance::services::comparable_type < Strategy >::type comparable_strategy; typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; + < + comparable_strategy, + typename point_type::type, + typename point_type::type + >::type comparable_return_type; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; static inline return_type apply(Geometry const& geometry, MultiGeometry const& multi, Strategy const& strategy) { - return_type min_cdist = return_type(); + comparable_return_type min_cdist = comparable_return_type(); bool first = true; comparable_strategy cstrategy = @@ -98,7 +107,7 @@ struct distance_single_to_multi_generic it != boost::end(multi); ++it, first = false) { - return_type cdist = dispatch::distance + comparable_return_type cdist = dispatch::distance < Geometry, typename range_value::type,