|
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