$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r67487 - in sandbox/geometry/boost/geometry: algorithms algorithms/detail/overlay multi/algorithms
From: barend.gehrels_at_[hidden]
Date: 2010-12-29 08:57:14
Author: barendgehrels
Date: 2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
New Revision: 67487
URL: http://svn.boost.org/trac/boost/changeset/67487
Log:
Update for difference
Changed value (1,-1) to overlay_type now
Removed dissolve flag, now an overlay type
Added:
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/overlay_type.hpp   (contents, props changed)
Text files modified: 
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/assemble.hpp        |   129 ++++++++++++++++++++++----------------- 
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/convert_ring.hpp    |    18 ++++                                    
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_ring.hpp        |     2                                         
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/overlay.hpp         |    18 ++--                                    
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/ring_properties.hpp |    94 +++++++++++++++++++---------            
   sandbox/geometry/boost/geometry/algorithms/difference.hpp                     |     4                                         
   sandbox/geometry/boost/geometry/algorithms/dissolve.hpp                       |     2                                         
   sandbox/geometry/boost/geometry/algorithms/intersection.hpp                   |     1                                         
   sandbox/geometry/boost/geometry/algorithms/intersection_inserter.hpp          |    47 ++++++--------                          
   sandbox/geometry/boost/geometry/algorithms/sym_difference.hpp                 |     6                                         
   sandbox/geometry/boost/geometry/algorithms/union.hpp                          |     2                                         
   sandbox/geometry/boost/geometry/multi/algorithms/intersection.hpp             |     6 +                                       
   12 files changed, 195 insertions(+), 134 deletions(-)
Modified: sandbox/geometry/boost/geometry/algorithms/detail/overlay/assemble.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/overlay/assemble.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/assemble.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -23,6 +23,7 @@
 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
 #include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
 #include <boost/geometry/algorithms/detail/overlay/add_to_containment.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
 #include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
 //#include <boost/geometry/strategies/intersection_result.hpp>
@@ -174,7 +175,7 @@
     typedef void tag3; // For the ring-container
 
 
-    static inline void assign(item_type& larger, item_type& smaller, int direction, bool dissolve)
+    static inline void assign(item_type& larger, item_type& smaller, overlay_type direction)
     {
         typedef typename geometry::coordinate_type
             <
@@ -185,7 +186,7 @@
         {
             if (larger.signum == 1)
             {
-                smaller.push(larger, direction, dissolve);
+                smaller.push(larger, direction);
             }
             else if (larger.signum == -1)
             {
@@ -244,7 +245,7 @@
     static inline void enrich(Selection& selection, Map& map,
             Geometry1 const& geometry1, Geometry2 const& geometry2,
             RingCollection const& collection,
-            int direction, bool dissolve)
+            overlay_type direction)
     {
         typedef typename boost::range_iterator<Selection>::type iterator;
 
@@ -271,7 +272,7 @@
                                     collection)
                         )
                     {
-                        assign(item1, item2, direction, dissolve);
+                        assign(item1, item2, direction);
                     }
                 }
             }
@@ -283,7 +284,7 @@
     static inline void divide_and_conquer(Selection& selection, Map& map,
             Geometry1 const& geometry1, Geometry2 const& geometry2,
             RingCollection const& collection,
-            int direction, bool dissolve, Box const& box,
+            int direction, Box const& box,
             std::size_t iteration = 0, std::size_t previous_count = 0)
     {
         std::size_t n = boost::size(selection);
@@ -297,7 +298,7 @@
 
         if (iteration > 3)
         {
-            enrich(selection, map, geometry1, geometry2, collection, direction, dissolve);
+            enrich(selection, map, geometry1, geometry2, collection, direction);
             return;
         }
 
@@ -318,16 +319,16 @@
         select_by_box(upper_sel, selection, upper);
 
         divide_and_conquer<1 - Dimension>(lower_sel, map, geometry1, geometry2,
-                    collection, direction, dissolve, lower, iteration + 1, n);
+                    collection, direction, lower, iteration + 1, n);
         divide_and_conquer<1 - Dimension>(upper_sel, map, geometry1, geometry2,
-                    collection, direction, dissolve, upper, iteration + 1, n);
+                    collection, direction, upper, iteration + 1, n);
     }
     ***/
 
     static inline void enrich(Container& container,
             Geometry1 const& geometry1, Geometry2 const& geometry2,
             RingCollection const& collection,
-            int direction, bool dissolve)
+            overlay_type direction)
     {
         typedef typename boost::range_iterator<Container>::type iterator;
 
@@ -340,10 +341,6 @@
             item_type& item1 = *it1;
 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
 std::cout << item1.ring_id << " area: " << item1.area << std::endl;
-if (item1.area < 0)
-{
-    std::cout << "(negative ";
-}
 #endif
             iterator it2 = it1;
             for (it2++; it2 != boost::end(container); ++it2)
@@ -359,7 +356,7 @@
 std::cout << " -> contains " << item2.ring_id;
 #endif
                     n++;
-                    assign(item1, item2, direction, dissolve);
+                    assign(item1, item2, direction);
 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
 std::cout << std::endl;
 #endif
@@ -374,13 +371,13 @@
     static inline void apply(Container& container,
             Geometry1 const& geometry1, Geometry2 const& geometry2,
             RingCollection const& collection,
-            int direction, bool dissolve, Box const& )
+            overlay_type direction, Box const& )
     {
         if (boost::size(container) == 0)
         {
             return;
         }
-        enrich(container, geometry1, geometry2, collection, direction, dissolve);
+        enrich(container, geometry1, geometry2, collection, direction);
 
 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
         for (typename boost::range_iterator<Container const>::type
@@ -409,7 +406,7 @@
 
         std::map<std::pair<item_type*, item_type*>, bool> map;
         divide_and_conquer<1>(selection, map, geometry1, geometry2, collection,
-                    direction, dissolve, box);
+                    direction, box);
         ***/
     }
 };
@@ -427,7 +424,7 @@
 inline OutputIterator add_all_rings(Container& container,
             Geometry1 const& geometry1, Geometry2 const& geometry2,
             RingCollection const& collection,
-            int direction, bool dissolve,
+            overlay_type direction, 
             OutputIterator out)
 {
     typedef typename boost::range_iterator<Container>::type iterator;
@@ -446,65 +443,79 @@
         it != boost::end(container);
         ++it)
     {
-        if (it->positive())
-        {
-            if (result_filled)
-            {
-                *out++ = result;
-                previous_id.source_index = -1;
-                result_filled = false;
-            }
 
+        bool const include_as_interior = result_filled
+                && it->id(direction) == previous_id
+                && it->included(direction);
+
+        bool include_and_reverse = direction == overlay_difference
+                && ! include_as_interior
+                && it->negative()
+                && it->included(direction);
+
+        if (it->positive() || include_and_reverse)
+        {
             // If it is an outer ring, it is included if there are no parents
             // (union) or if there are parents (intersection)
-            if (it->included(direction, dissolve))
+            // or for difference it is an exterior ring but becomes an interior ring
+            if (it->included(direction))
             {
-                geometry::clear(result);
+                if (result_filled && ! include_as_interior)
+                {
+                    *out++ = result;
+                    previous_id.source_index = -1;
+                    result_filled = false;
+                    geometry::clear(result);
+                }
+
+                if (include_as_interior)
+                {
+                    include_and_reverse = true;
+                }
+
                 previous_id = it->ring_id;
                 result_filled = true;
                 if (it->ring_id.source_index == 0)
                 {
                     convert_ring<tag_out>::apply(result,
-                                get_ring<tag1>::apply(it->ring_id, geometry1));
+                                get_ring<tag1>::apply(it->ring_id, geometry1), 
+                                include_as_interior, include_and_reverse);
                 }
                 else if (it->ring_id.source_index == 1)
                 {
                     convert_ring<tag_out>::apply(result,
-                                get_ring<tag2>::apply(it->ring_id, geometry2));
+                                get_ring<tag2>::apply(it->ring_id, geometry2), 
+                                include_as_interior, include_and_reverse);
                 }
                 else if (it->ring_id.source_index == 2)
                 {
                     convert_ring<tag_out>::apply(result,
-                                get_ring<tag3>::apply(it->ring_id, collection));
+                                get_ring<tag3>::apply(it->ring_id, collection), 
+                                include_as_interior, include_and_reverse);
                 }
             }
         }
-        else
+        else if (include_as_interior)
         {
             // If it is an interior ring, it is included if
             // it's parent-id matches the id of the outputted exterior ring
-            if (result_filled
-                && it->id() == previous_id
-                && it->included(direction, dissolve))
+            if (it->ring_id.source_index == 0)
             {
-                if (it->ring_id.source_index == 0)
-                {
-                    convert_ring<tag_out>::apply(result,
-                                get_ring<tag1>::apply(it->ring_id,
-                                            geometry1), true);
-                }
-                else if (it->ring_id.source_index == 1)
-                {
-                    convert_ring<tag_out>::apply(result,
-                                get_ring<tag2>::apply(it->ring_id,
-                                            geometry2), true);
-                }
-                else if (it->ring_id.source_index == 2)
-                {
-                    convert_ring<tag_out>::apply(result,
-                                get_ring<tag3>::apply(it->ring_id,
-                                            collection), true);
-                }
+                convert_ring<tag_out>::apply(result,
+                            get_ring<tag1>::apply(it->ring_id,
+                                        geometry1), true, false);
+            }
+            else if (it->ring_id.source_index == 1)
+            {
+                convert_ring<tag_out>::apply(result,
+                            get_ring<tag2>::apply(it->ring_id,
+                                        geometry2), true, false);
+            }
+            else if (it->ring_id.source_index == 2)
+            {
+                convert_ring<tag_out>::apply(result,
+                            get_ring<tag3>::apply(it->ring_id,
+                                        collection), true, false);
             }
         }
     }
@@ -526,7 +537,7 @@
 inline OutputIterator assemble(Rings const& rings, Map const& map,
             Geometry1 const& geometry1,
             Geometry2 const& geometry2,
-            int direction, bool dissolve, bool splitted,
+            overlay_type direction, bool , bool splitted,
             OutputIterator out)
 {
         typedef typename geometry::tag<Geometry1>::type tag1;
@@ -546,6 +557,8 @@
             > ring_properties_container_type;
         ring_properties_container_type ring_properties_container;
 
+        bool const dissolve = direction == overlay_dissolve;
+
         if (! splitted)
         {
             add_to_containment
@@ -564,7 +577,7 @@
                     Geometry2
                 >::apply(ring_properties_container,
                             ring_identifier(1, -1,-1), geometry2,
-                            map, dissolve);
+                            map, false);
         }
 
         // Add all produced rings using source index 2
@@ -631,7 +644,7 @@
                     Rings,
                     model::box<point_type>
                 >::apply(ring_properties_container,
-                        geometry1, geometry2, rings, direction, dissolve, total);
+                        geometry1, geometry2, rings, direction, total);
 
     // Sort container on parent-id
 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
@@ -643,13 +656,13 @@
                     sort_on_id_or_parent_id
                         <
                             ring_properties<point_type>
-                        >());
+                        >(direction));
         }
 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
 std::cout << "assemble.add rings" << std::endl;
 #endif
         return add_all_rings<GeometryOut>(ring_properties_container,
-                    geometry1, geometry2, rings, direction, dissolve, out);
+                    geometry1, geometry2, rings, direction, out);
 }
 
 
Modified: sandbox/geometry/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/overlay/convert_ring.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/convert_ring.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -11,7 +11,7 @@
 
 #include <boost/mpl/assert.hpp>
 #include <boost/range.hpp>
-
+#include <boost/range/algorithm/reverse.hpp>
 
 #include <boost/geometry/core/tags.hpp>
 #include <boost/geometry/core/exterior_ring.hpp>
@@ -45,11 +45,15 @@
 {
     template<typename Destination, typename Source>
     static inline void apply(Destination& destination, Source const& source,
-                bool append = false)
+                bool append, bool reverse)
     {
         if (! append)
         {
             geometry::convert(source, destination);
+            if (reverse)
+            {
+                boost::reverse(destination);
+            }
         }
     }
 };
@@ -60,17 +64,25 @@
 {
     template<typename Destination, typename Source>
     static inline void apply(Destination& destination, Source const& source,
-                bool append = false)
+                bool append, bool reverse)
     {
         if (! append)
         {
             geometry::convert(source, exterior_ring(destination));
+            if (reverse)
+            {
+                boost::reverse(exterior_ring(destination));
+            }
         }
         else
         {
             interior_rings(destination).resize(
                         interior_rings(destination).size() + 1);
             geometry::convert(source, interior_rings(destination).back());
+            if (reverse)
+            {
+                boost::reverse(interior_rings(destination).back());
+            }
         }
     }
 };
Modified: sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_ring.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_ring.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_ring.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -71,7 +71,7 @@
 struct get_ring<polygon_tag>
 {
     template<typename Polygon>
-    static inline typename ring_type<Polygon>::type const& apply(
+    static inline typename ring_return_type<Polygon const>::type const apply(
                 ring_identifier const& id,
                 Polygon const& polygon)
     {
Modified: sandbox/geometry/boost/geometry/algorithms/detail/overlay/overlay.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/overlay/overlay.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/overlay.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -52,7 +52,7 @@
     typename Geometry1, typename Geometry2,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
-    int Direction, 
+    overlay_type Direction, 
     typename Strategy
 >
 struct overlay
@@ -80,10 +80,11 @@
 
         // If one input is empty, output the other one for a union.
         // For an intersection, the intersection is empty.
+        // TODO: for a difference, take one of them.
         if (geometry::num_points(geometry1) == 0
             || geometry::num_points(geometry2) == 0)
         {
-            if (Direction == 1)
+            if (Direction == overlay_union)
             {
                 std::map<ring_identifier, int> map;
                 ring_container_type rings;
@@ -110,9 +111,9 @@
 #endif
         typename Strategy::side_strategy_type side_strategy;
         geometry::enrich_intersection_points<Reverse1, Reverse2>(turn_points, 
-                Direction == -1
-                    ? boost::geometry::detail::overlay::operation_intersection
-                    : boost::geometry::detail::overlay::operation_union,
+                Direction == overlay_union
+                    ? boost::geometry::detail::overlay::operation_union
+                    : boost::geometry::detail::overlay::operation_intersection,
                     geometry1, geometry2,
                     side_strategy);
 
@@ -121,10 +122,9 @@
 #endif
         ring_container_type rings;
         geometry::traverse<Reverse1, Reverse2>(geometry1, geometry2,
-                Direction == -1
-                    ? boost::geometry::detail::overlay::operation_intersection
-                    : boost::geometry::detail::overlay::operation_union
-                    ,
+                Direction == overlay_union
+                    ? boost::geometry::detail::overlay::operation_union
+                    : boost::geometry::detail::overlay::operation_intersection,
                 turn_points, rings);
 
         // TEMP condition, reversal should be done in traverse by calling "push_front"
Added: sandbox/geometry/boost/geometry/algorithms/detail/overlay/overlay_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/overlay_type.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -0,0 +1,28 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 2007-2010, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
+
+
+
+namespace boost { namespace geometry
+{
+
+enum overlay_type
+{
+    overlay_union,
+    overlay_intersection,
+    overlay_difference,
+    overlay_dissolve
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
Modified: sandbox/geometry/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/overlay/ring_properties.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/ring_properties.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -11,6 +11,7 @@
 
 #include <boost/geometry/algorithms/area.hpp>
 #include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
 #include <boost/geometry/algorithms/detail/ring_identifier.hpp>
 #include <boost/geometry/util/math.hpp>
@@ -34,6 +35,7 @@
 
     bool intersects;
     bool produced;
+    bool diff_included;
 
     // "Stack"/counter of non-intersecting parent rings.
     // This denotes if it a negative ring should be included,
@@ -51,6 +53,7 @@
     inline ring_properties()
         : intersects(false)
         , produced(false)
+        , diff_included(false)
         , parent_count(0)
         , has_point(false)
     {
@@ -64,6 +67,7 @@
         , area(geometry::area(geometry))
         , intersects(i)
         , produced(p)
+        , diff_included(false)
         , parent_count(0)
         , box(geometry::make_envelope<box_type>(geometry))
     {
@@ -83,8 +87,16 @@
         return geometry::math::abs(area) > geometry::math::abs(other.area);
     }
 
-    inline ring_identifier const& id() const
+    inline ring_identifier const& id(overlay_type type) const
     {
+        if (type == overlay_difference
+            && positive()
+            && parent_ring_id.source_index == 0
+            && ring_id.source_index == 1)
+        {
+            return parent_ring_id;
+        }
+
         // Return the id of ifself, or of the parent
         return positive() || parent_ring_id.source_index < 0
             ? ring_id
@@ -93,17 +105,25 @@
 
 
     inline void push(ring_properties<Point> const& r,
-                int direction, bool dissolve)
+                overlay_type direction)
     {
-        if (//(r.produced || r.untouched()) &&
-            r.included(direction, dissolve))
+        if (r.included(direction))
         {
 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
 std::cout << " id.push " << r.ring_id;
 #endif
             parent_ring_id = r.ring_id;
         }
-        if (! r.produced || dissolve)
+        else if (direction == overlay_difference
+            && r.ring_id.source_index == this->ring_id.source_index
+            && r.ring_id.source_index == 1)
+        {
+#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
+std::cout << " diff.parent " << r.ring_id << " of " << this->ring_id;
+#endif
+            diff_included = true;
+        }
+        if (! r.produced || direction == overlay_dissolve)
         {
 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
 std::cout << " or.push " << r.ring_id;
@@ -126,27 +146,29 @@
     }
 
 
-    inline bool interior_included(int direction) const
+    inline bool interior_included(overlay_type direction) const
     {
         if (negative())
         {
             // Original inner rings are included if there
-            // are two untouched parents (union) or one (intersection);
-            // Produced are ones are included if there is a parent found
-            if (produced)
-            {
-                return parent_count > 0;
-            }
-            return
-                (direction == 1  && parent_count == 1)
-                || (direction == -1 && parent_count > 1);
+            // are two untouched parents (intersection) or one (union);
+            // Produced ones are included if there is a parent found (should be!)
+            return (produced && parent_count > 0)
+                || (direction == overlay_union && parent_count == 1)
+                || (direction == overlay_dissolve && parent_count == 1)
+                || (direction == overlay_intersection && parent_count > 1)
+                || (direction == overlay_difference
+                    && parent_count > 1
+                    && ring_id.source_index == 2 // produced
+                    )
+                ;
         }
         return false;
     }
 
-    inline bool included(int direction, bool dissolve) const
+    inline bool included(overlay_type direction) const
     {
-        if (produced && ! dissolve)
+        if (produced && direction != overlay_dissolve)
         {
             // Traversed rings are included in all operations,
             // because traversal was direction-dependant.
@@ -163,20 +185,25 @@
         if (positive())
         {
             // Outer rings are included if they don't have parents
-            // (union) or have parents (intersection)
-            if (produced)
-            {
-                return parent_count == 0;
-            }
-            return
-                (direction == 1  && parent_count == 0)
-                || (direction == -1 && parent_count > 0);
+            // (union,dissolve,difference if source=0) or have parents (intersection)
+            return (produced && parent_count == 0)
+                || (direction == overlay_union && parent_count == 0)
+                || (direction == overlay_dissolve && parent_count == 0)
+                || (direction == overlay_difference 
+                        && parent_count == 0 
+                        && ring_id.source_index == 0) 
+                || (direction == overlay_difference 
+                        && parent_count > 0
+                        && ring_id.source_index == 1) 
+                || (direction == overlay_intersection && parent_count > 0)
+                ;
         }
         else if (negative())
         {
             // Inner rings are included if the last encountered parent
             // matches the operation
-            return interior_included(direction);
+            return interior_included(direction)
+                || (direction == overlay_difference && diff_included);
         }
         return false;
     }
@@ -198,8 +225,10 @@
         std::cout << " parent: " << prop.parent_ring_id;
         if (prop.produced) std::cout << " produced";
         if (prop.intersects) std::cout << " intersects";
-        if (prop.included(1, false)) std::cout << " union";
-        if (prop.included(-1, false)) std::cout << " intersection";
+        if (prop.included(overlay_union)) std::cout << " @union";
+        if (prop.included(overlay_dissolve)) std::cout << " @dissolve";
+        if (prop.included(overlay_intersection)) std::cout << " @intersection";
+        if (prop.included(overlay_difference)) std::cout << " @difference";
         return os;
     }
 #endif
@@ -210,11 +239,16 @@
 template<typename Prop>
 struct sort_on_id_or_parent_id
 {
+    overlay_type m_type;
 public :
+    inline sort_on_id_or_parent_id(overlay_type type)
+        : m_type(type)
+    {}
+
     inline bool operator()(Prop const& left, Prop const& right) const
     {
-        ring_identifier const& left_id = left.id();
-        ring_identifier const& right_id = right.id();
+        ring_identifier const& left_id = left.id(m_type);
+        ring_identifier const& right_id = right.id(m_type);
 
         // If it is the same, sort on size descending
         return left_id == right_id
Modified: sandbox/geometry/boost/geometry/algorithms/difference.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/difference.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/difference.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -10,7 +10,7 @@
 
 #include <algorithm>
 
-#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/intersection_inserter.hpp>
 
 namespace boost { namespace geometry
 {
@@ -51,7 +51,7 @@
         > strategy;
 
 
-    detail::intersection::inserter<geometry_out, false, true, false>(
+    detail::intersection::inserter<geometry_out, false, true, false, overlay_difference>(
             geometry1, geometry2, 
             std::back_inserter(output_collection),
             strategy());
Modified: sandbox/geometry/boost/geometry/algorithms/dissolve.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/dissolve.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/dissolve.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -103,7 +103,7 @@
             std::map<ring_identifier, int> map;
             map_turns(map, turns);
             return detail::overlay::assemble<GeometryOut>(rings, map,
-                            geometry, geometry, 1, true, false, out);
+                            geometry, geometry, overlay_dissolve, true, false, out);
         }
         else
         {
Modified: sandbox/geometry/boost/geometry/algorithms/intersection.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/intersection.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/intersection.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -113,6 +113,7 @@
             detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, false>::value,
             false,
             output_iterator, OneOut,
+            overlay_intersection,
             Strategy
         >::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy);
 
Modified: sandbox/geometry/boost/geometry/algorithms/intersection_inserter.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/intersection_inserter.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/intersection_inserter.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -121,6 +121,7 @@
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator,
     typename GeometryOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -140,6 +141,7 @@
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator,
     typename GeometryOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -149,9 +151,10 @@
         Geometry1, Geometry2,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
+        OverlayType,
         Strategy
     > : detail::overlay::overlay
-        <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
+        <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
 {};
 
 
@@ -163,6 +166,7 @@
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator,
     typename GeometryOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -172,38 +176,19 @@
         Geometry, Box,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
+        OverlayType,
         Strategy
     > : detail::overlay::overlay
-        <Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
+        <Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
 {};
 
-/*// box/box
-template
-<
-    typename Box1, typename Box2,
-    bool Reverse1, bool Reverse2, bool ReverseOut,
-    typename OutputIterator,
-    typename BoxOut,
-    typename Strategy
->
-struct intersection_inserter
-    <
-        box_tag, box_tag, box_tag,
-        true, true, true,
-        Box1, Box2,
-        Reverse1, Reverse2, ReverseOut,
-        OutputIterator, BoxOut,
-        Strategy
-    > : detail::intersection::intersection_box_box
-        <Box1, Box2, OutputIterator, BoxOut, Strategy>
-{};
-*/
 
 template
 <
     typename Segment1, typename Segment2,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -213,7 +198,7 @@
         Segment1, Segment2,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
-        Strategy
+        OverlayType, Strategy
     > : detail::intersection::intersection_segment_segment_point
             <
                 Segment1, Segment2,
@@ -228,6 +213,7 @@
     typename Linestring1, typename Linestring2,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -237,7 +223,7 @@
         Linestring1, Linestring2,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
-        Strategy
+        OverlayType, Strategy
     > : detail::intersection::intersection_linestring_linestring_point
             <
                 Linestring1, Linestring2,
@@ -252,6 +238,7 @@
     typename Linestring, typename Box,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
+    overlay_type OverlayType, 
     typename Strategy
 >
 struct intersection_inserter
@@ -261,6 +248,7 @@
         Linestring, Box,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
+        OverlayType, 
         Strategy
     >
 {
@@ -279,6 +267,7 @@
     typename Segment, typename Box,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
+    overlay_type OverlayType, 
     typename Strategy
 >
 struct intersection_inserter
@@ -288,6 +277,7 @@
         Segment, Box,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
+        OverlayType, 
         Strategy
     >
 {
@@ -312,6 +302,7 @@
     typename Geometry1, typename Geometry2,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
+    overlay_type OverlayType, 
     typename Strategy
 >
 struct intersection_inserter_reversed
@@ -327,6 +318,7 @@
                 Geometry2, Geometry1,
                 Reverse2, Reverse1, ReverseOut,
                 OutputIterator, GeometryOut,
+                OverlayType, 
                 Strategy
             >::apply(g2, g1, out, strategy);
     }
@@ -347,6 +339,7 @@
 <
     typename GeometryOut,
     bool Reverse1, bool Reverse2, bool ReverseOut,
+    overlay_type OverlayType, 
     typename Geometry1, typename Geometry2,
     typename OutputIterator,
     typename Strategy
@@ -372,6 +365,7 @@
                 overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
                 ReverseOut,
                 OutputIterator, GeometryOut,
+                OverlayType,
                 Strategy
             >,
             geometry::dispatch::intersection_inserter
@@ -387,6 +381,7 @@
                 overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
                 ReverseOut,
                 OutputIterator, GeometryOut,
+                OverlayType,
                 Strategy
             >
         >::type::apply(geometry1, geometry2, out, strategy);
@@ -433,7 +428,7 @@
     concept::check<Geometry1 const>();
     concept::check<Geometry2 const>();
 
-    return detail::intersection::inserter<GeometryOut, false, false, true>(
+    return detail::intersection::inserter<GeometryOut, false, false, true, overlay_intersection>(
             geometry1, geometry2, out, strategy);
 }
 
Modified: sandbox/geometry/boost/geometry/algorithms/sym_difference.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/sym_difference.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/sym_difference.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -53,12 +53,12 @@
         > strategy;
 
 
-    detail::intersection::inserter<geometry_out, false, true, false>(
+    detail::intersection::inserter<geometry_out, false, true, false, overlay_difference>(
             geometry1, geometry2, 
             std::back_inserter(output_collection),
             strategy());
-    detail::intersection::inserter<geometry_out, true, false, false>(
-            geometry1, geometry2, 
+    detail::intersection::inserter<geometry_out, false, true, false, overlay_difference>(
+            geometry2, geometry1, 
             std::back_inserter(output_collection),
             strategy());
 }
Modified: sandbox/geometry/boost/geometry/algorithms/union.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/union.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/union.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -69,7 +69,7 @@
         OutputIterator, GeometryOut,
         Strategy
     > : detail::overlay::overlay
-        <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, 1, Strategy>
+        <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, overlay_union, Strategy>
 {};
 
 
Modified: sandbox/geometry/boost/geometry/multi/algorithms/intersection.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/multi/algorithms/intersection.hpp	(original)
+++ sandbox/geometry/boost/geometry/multi/algorithms/intersection.hpp	2010-12-29 08:57:06 EST (Wed, 29 Dec 2010)
@@ -147,6 +147,7 @@
     typename MultiLinestring1, typename MultiLinestring2,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -156,6 +157,7 @@
         MultiLinestring1, MultiLinestring2,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
+        OverlayType,
         Strategy
     > : detail::intersection::intersection_multi_linestring_multi_linestring_point
             <
@@ -171,6 +173,7 @@
     typename Linestring, typename MultiLinestring,
     typename OutputIterator, typename GeometryOut,
     bool Reverse1, bool Reverse2, bool ReverseOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -180,6 +183,7 @@
         Linestring, MultiLinestring,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
+        OverlayType,
         Strategy
     > : detail::intersection::intersection_linestring_multi_linestring_point
             <
@@ -195,6 +199,7 @@
     typename MultiLinestring, typename Box,
     bool Reverse1, bool Reverse2, bool ReverseOut,
     typename OutputIterator, typename GeometryOut,
+    overlay_type OverlayType,
     typename Strategy
 >
 struct intersection_inserter
@@ -204,6 +209,7 @@
         MultiLinestring, Box,
         Reverse1, Reverse2, ReverseOut,
         OutputIterator, GeometryOut,
+        OverlayType,
         Strategy
     > : detail::intersection::clip_multi_linestring
             <