$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78685 - trunk/boost/geometry/algorithms
From: barend.gehrels_at_[hidden]
Date: 2012-05-27 11:12:41
Author: barendgehrels
Date: 2012-05-27 11:12:40 EDT (Sun, 27 May 2012)
New Revision: 78685
URL: http://svn.boost.org/trac/boost/changeset/78685
Log:
[geometry] fixed disjoint for multi-polygon/multi-polygon where (not-first) rings were inside each other
Text files modified: 
   trunk/boost/geometry/algorithms/disjoint.hpp |    49 ++++++++++++++++++++++++++++++--------- 
   1 files changed, 37 insertions(+), 12 deletions(-)
Modified: trunk/boost/geometry/algorithms/disjoint.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/disjoint.hpp	(original)
+++ trunk/boost/geometry/algorithms/disjoint.hpp	2012-05-27 11:12:40 EDT (Sun, 27 May 2012)
@@ -27,6 +27,7 @@
 #include <boost/geometry/core/reverse_dispatch.hpp>
 
 #include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/for_each_range.hpp>
 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
 #include <boost/geometry/algorithms/within.hpp>
@@ -116,11 +117,45 @@
     }
 };
 
+template<typename Geometry>
+struct check_each_ring_for_within
+{
+    bool has_within;
+    Geometry const& m_geometry;
+
+    inline check_each_ring_for_within(Geometry const& g)
+        : has_within(false)
+        , m_geometry(g)
+    {}
+
+    template <typename Range>
+    inline void apply(Range const& range)
+    {
+        typename geometry::point_type<Range>::type p;
+        geometry::point_on_border(p, range);
+        if (geometry::within(p, m_geometry))
+        {
+            has_within = true;
+        }
+    }
+};
+
 
 
 template <typename Geometry1, typename Geometry2>
 struct general_areal
 {
+
+    template <typename FirstGeometry, typename SecondGeometry>
+    static inline bool containing(FirstGeometry const& geometry1,
+                    SecondGeometry const& geometry2)
+    {
+        check_each_ring_for_within<FirstGeometry> checker(geometry1);
+        geometry::detail::for_each_range(geometry2, checker);
+        return checker.has_within;
+    }
+
+
     static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
     {
         if (! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2))
@@ -128,20 +163,10 @@
             return false;
         }
 
-        typedef typename geometry::point_type<Geometry1>::type point_type;
-
         // If there is no intersection of segments, they might located
         // inside each other
-        point_type p1;
-        geometry::point_on_border(p1, geometry1);
-        if (geometry::within(p1, geometry2))
-        {
-            return false;
-        }
-
-        typename geometry::point_type<Geometry1>::type p2;
-        geometry::point_on_border(p2, geometry2);
-        if (geometry::within(p2, geometry1))
+        if (containing(geometry1, geometry2)
+            || containing(geometry2, geometry1))
         {
             return false;
         }