Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r76975 - trunk/boost/geometry/algorithms/detail/overlay
From: barend.gehrels_at_[hidden]
Date: 2012-02-11 09:24:43


Author: barendgehrels
Date: 2012-02-11 09:24:42 EST (Sat, 11 Feb 2012)
New Revision: 76975
URL: http://svn.boost.org/trac/boost/changeset/76975

Log:
Boost.Geometry line/poly overlay (new for 1.49), bugfix (take point-in-between instead of first point)
Text files modified:
   trunk/boost/geometry/algorithms/detail/overlay/follow.hpp | 52 ++++++++++++++++++++++++++++++---------
   trunk/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp | 13 +++++++++
   2 files changed, 52 insertions(+), 13 deletions(-)

Modified: trunk/boost/geometry/algorithms/detail/overlay/follow.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/follow.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/follow.hpp 2012-02-11 09:24:42 EST (Sat, 11 Feb 2012)
@@ -14,11 +14,12 @@
 #include <boost/range.hpp>
 #include <boost/mpl/assert.hpp>
 
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
 #include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
 #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
 
-#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/algorithms/covered_by.hpp>
 
 
 namespace boost { namespace geometry
@@ -50,6 +51,29 @@
     typename LineString,
     typename Polygon
>
+static inline bool last_covered_by(Turn const& turn, Operation const& op,
+ LineString const& linestring, Polygon const& polygon)
+{
+ // Check any point between the this one and the first IP
+ typedef typename geometry::point_type<LineString>::type point_type;
+ point_type point_in_between;
+ detail::point_on_border::midpoint_helper
+ <
+ point_type,
+ 0, dimension<point_type>::value
+ >::apply(point_in_between, linestring[op.seg_id.segment_index], turn.point);
+
+ return geometry::covered_by(point_in_between, polygon);
+}
+
+
+template
+<
+ typename Turn,
+ typename Operation,
+ typename LineString,
+ typename Polygon
+>
 static inline bool is_leaving(Turn const& turn, Operation const& op,
                 bool entered, bool first,
                 LineString const& linestring, Polygon const& polygon)
@@ -58,7 +82,7 @@
     {
         return entered
             || turn.method == method_crosses
- || (first && geometry::within(linestring[0], polygon))
+ || (first && last_covered_by(turn, op, linestring, polygon))
             ;
     }
     return false;
@@ -79,27 +103,31 @@
     if (turn.method == method_crosses)
     {
         // The normal case, this is completely covered with entering/leaving
- // so stay out of this time consuming "within"
+ // so stay out of this time consuming "covered_by"
         return false;
     }
 
     if (is_entering(turn, op))
     {
- return entered || (first && geometry::within(linestring[0], polygon));
+ return entered || (first && last_covered_by(turn, op, linestring, polygon));
     }
 
     return false;
 }
 
-template <typename Turn>
-static inline bool was_entered(Turn const& turn, bool first)
+template
+<
+ typename Turn,
+ typename Operation,
+ typename Linestring,
+ typename Polygon
+>
+static inline bool was_entered(Turn const& turn, Operation const& op, bool first,
+ Linestring const& linestring, Polygon const& polygon)
 {
     if (first && (turn.method == method_collinear || turn.method == method_equal))
     {
- // If it is the very first point, and either equal or collinear, there is only one
- // IP generated (on purpose). So consider this as having entered.
- // Maybe it will leave immediately after that (u/i) but that is checked later.
- return true;
+ return last_covered_by(turn, op, linestring, polygon);
     }
     return false;
 }
@@ -169,7 +197,7 @@
     template <typename Point, typename Geometry>
     static inline bool included(Point const& point, Geometry const& geometry)
     {
- return geometry::within(point, geometry);
+ return geometry::covered_by(point, geometry);
     }
 
 };
@@ -299,7 +327,7 @@
         {
             turn_operation_iterator_type iit = boost::begin(it->operations);
 
- if (following::was_entered(*it, first))
+ if (following::was_entered(*it, *iit, first, linestring, polygon))
             {
                 debug_traverse(*it, *iit, "-> Was entered");
                 entered = true;

Modified: trunk/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp 2012-02-11 09:24:42 EST (Sat, 11 Feb 2012)
@@ -22,6 +22,7 @@
 #include <boost/geometry/core/reverse_dispatch.hpp>
 #include <boost/geometry/geometries/concepts/check.hpp>
 #include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
 #include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
 #include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
@@ -171,7 +172,17 @@
             // No intersection points, it is either completely
             // inside (interior + borders)
             // or completely outside
- if (follower::included(*boost::begin(linestring), areal))
+
+ // Use border point (on a segment) to check this
+ // (because turn points might skip some cases)
+ point_type border_point;
+ if (! geometry::point_on_border(border_point, linestring, true))
+ {
+ return out;
+ }
+
+
+ if (follower::included(border_point, areal))
             {
                 LineStringOut copy;
                 geometry::convert(linestring, copy);


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk