Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77061 - in trunk/boost/geometry/extensions: algorithms/buffer strategies
From: barend.gehrels_at_[hidden]
Date: 2012-02-18 05:07:22


Author: barendgehrels
Date: 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
New Revision: 77061
URL: http://svn.boost.org/trac/boost/changeset/77061

Log:
Boost.Geometry Substantial progress on buffer
Added:
   trunk/boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp (contents, props changed)
   trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp (contents, props changed)
   trunk/boost/geometry/extensions/algorithms/buffer/buffered_ring.hpp (contents, props changed)
Removed:
   trunk/boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp
   trunk/boost/geometry/extensions/algorithms/buffer/polygon_buffer.hpp
   trunk/boost/geometry/extensions/algorithms/buffer/range_buffer.hpp
   trunk/boost/geometry/extensions/algorithms/buffer/sectionalizing_buffer.hpp
   trunk/boost/geometry/extensions/algorithms/buffer/segmenting_buffer.hpp
   trunk/boost/geometry/extensions/algorithms/buffer/splitting_buffer.hpp
   trunk/boost/geometry/extensions/algorithms/buffer/traversing_buffer.hpp
Text files modified:
   trunk/boost/geometry/extensions/algorithms/buffer/buffer_appender.hpp | 46 ------------
   trunk/boost/geometry/extensions/strategies/buffer.hpp | 143 ++++++---------------------------------
   2 files changed, 24 insertions(+), 165 deletions(-)

Modified: trunk/boost/geometry/extensions/algorithms/buffer/buffer_appender.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/buffer_appender.hpp (original)
+++ trunk/boost/geometry/extensions/algorithms/buffer/buffer_appender.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
@@ -29,29 +29,15 @@
 // Appends points to an output range (always a ring).
 // On the way, special points can be marked, and marked points
 // forming a hooklet, loop, curve, curl, or how you call it are checked on intersections.
-template
- <
- typename Range
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
- >
+template<typename Range>
 class buffer_appender
 {
 public :
     typedef Range range_type;
     typedef typename geometry::point_type<Range>::type point_type;
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- Mapper const& m_mapper;
- inline buffer_appender(Range& r, Mapper const& mapper)
- : m_range(r)
- , m_mapper(mapper)
-#else
     inline buffer_appender(Range& r)
         : m_range(r)
-#endif
-
     {}
 
     inline void append(point_type const& point)
@@ -83,9 +69,6 @@
     inline void append_begin_hooklet(point_type const& point)
     {
         DEBUG("begin hooklet");
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(0,0,192);", 3);
-#endif
 
         check(point);
 
@@ -99,9 +82,6 @@
     inline void append_end_hooklet(point_type const& point)
     {
         DEBUG("end hooklet");
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(0,0,255);", 4);
-#endif
 
         do_append(point);
     }
@@ -177,12 +157,6 @@
             }
         }
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- if (! m_pieces.empty() && m_pieces.back().end > m_pieces.back().begin)
- {
- const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(0,255,0);", 4);
- }
-#endif
     }
 
     inline bool calculate_ip(point_type const& point, piece const& the_piece)
@@ -193,14 +167,6 @@
             return false;
         }
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(255,0,0);", 4);
- for (int i = the_piece.begin; i <= the_piece.end && i < n; i++)
- {
- //const_cast<Mapper&>(m_mapper).map(m_range[i], "fill:rgb(0,255,255);", 3);
- }
-#endif
-
         segment_type segment1(m_previous_point, point);
 
         // Walk backwards through list (chance is higher to have IP at the end)
@@ -215,11 +181,6 @@
                 if (get_valid_split(is.intersections[0], i + 1, split_off))
                 {
                     add_ip(is.intersections[0], i + 1, the_piece, split_off);
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- const_cast<Mapper&>(m_mapper).map(is.intersections[0], "fill:rgb(255,0,255);", 4);
- const_cast<Mapper&>(m_mapper).map(split_off, "fill:none;stroke:rgb(255,0,0);stroke-width:2");
-#endif
                 }
 
                 return true;
@@ -253,11 +214,6 @@
 
                         add_ip(is.intersections[0], the_piece.begin + 1, the_piece, split_off);
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- const_cast<Mapper&>(m_mapper).map(is.intersections[0], "fill:rgb(255,255,0);", 4);
- const_cast<Mapper&>(m_mapper).map(m_range[the_piece.begin], "fill:rgb(255,192,0);", 4);
- const_cast<Mapper&>(m_mapper).map(split_off, "fill:none;stroke:rgb(255,192,0);stroke-width:2");
-#endif
                         return true;
                     }
 

Added: trunk/boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
@@ -0,0 +1,324 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_BUFFER_INSERTER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_INSERTER_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template
+<
+ typename RingOutput,
+ typename Tag
+>
+struct buffer_range
+{
+ typedef typename point_type<RingOutput>::type output_point_type;
+ typedef typename coordinate_type<RingOutput>::type coordinate_type;
+ typedef model::referring_segment<output_point_type const> segment_type;
+
+ template
+ <
+ typename Collection,
+ typename Iterator,
+ typename DistanceStrategy,
+ typename JoinStrategy
+ >
+ static inline void iterate(Collection& collection,
+ Iterator begin, Iterator end,
+ buffer_side_selector side,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join_strategy
+ )
+ {
+ output_point_type previous_p1, previous_p2;
+ output_point_type first_p1, first_p2;
+
+ bool first = true;
+
+ Iterator it = begin;
+ for (Iterator prev = it++; it != end; ++it)
+ {
+ if (! detail::equals::equals_point_point(*prev, *it))
+ {
+ // Generate a block along (left or right of) the segment
+
+ // Simulate a vector d (dx,dy)
+ coordinate_type dx = get<0>(*it) - get<0>(*prev);
+ coordinate_type dy = get<1>(*it) - get<1>(*prev);
+
+ // For normalization [0,1] (=dot product d.d, sqrt)
+ coordinate_type length = sqrt(dx * dx + dy * dy);
+
+ // Because coordinates are not equal, length should not be zero
+ BOOST_ASSERT((! geometry::math::equals(length, 0)));
+
+ // Generate the normalized perpendicular p, to the left (ccw)
+ coordinate_type px = -dy / length;
+ coordinate_type py = dx / length;
+
+ output_point_type p1, p2;
+
+ coordinate_type d = distance.apply(*prev, *it, side);
+
+ set<0>(p2, get<0>(*it) + px * d);
+ set<1>(p2, get<1>(*it) + py * d);
+
+ set<0>(p1, get<0>(*prev) + px * d);
+ set<1>(p1, get<1>(*prev) + py * d);
+
+ std::vector<output_point_type> range_out;
+ if (! first)
+ {
+ output_point_type p;
+ segment_type s1(p1, p2);
+ segment_type s2(previous_p1, previous_p2);
+
+ if (line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p))
+ {
+ join_strategy.apply(p, *prev, previous_p2, p1,
+ distance.apply(*prev, *it, side),
+ range_out);
+ }
+ }
+ else
+ {
+ first = false;
+ first_p1 = p1;
+ first_p2 = p2;
+ }
+ if (! range_out.empty())
+ {
+ collection.add_piece(*prev, range_out);
+ range_out.clear();
+ }
+ collection.add_piece(*prev, *it, p1, p2);
+
+ previous_p1 = p1;
+ previous_p2 = p2;
+ prev = it;
+ }
+ }
+
+ // Might be replaced by specialization
+ if(boost::is_same<Tag, ring_tag>::value)
+ {
+ // Generate closing corner
+ output_point_type p;
+ segment_type s1(previous_p1, previous_p2);
+ segment_type s2(first_p1, first_p2);
+ line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p);
+
+ std::vector<output_point_type> range_out;
+ join_strategy.apply(p, *begin, previous_p2, first_p1,
+ distance.apply(*(end - 1), *begin, side),
+ range_out);
+ if (! range_out.empty())
+ {
+ collection.add_piece(*begin, range_out);
+ }
+
+ // Buffer is closed automatically by last closing corner (NOT FOR OPEN POLYGONS - TODO)
+ }
+ }
+};
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag,
+ typename RingInput,
+ typename RingOutput
+>
+struct buffer_inserter
+{};
+
+
+template
+<
+ typename RingInput,
+ typename RingOutput
+>
+struct buffer_inserter<ring_tag, RingInput, RingOutput>
+ : public detail::buffer::buffer_range
+ <
+ RingOutput,
+ ring_tag
+ >
+{
+
+ template
+ <
+ typename Collection, typename DistanceStrategy, typename JoinStrategy
+ >
+ static inline void apply(RingInput const& ring,
+ Collection& collection,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join_strategy)
+ {
+ iterate(collection, boost::begin(ring), boost::end(ring),
+ buffer_side_left,
+ distance, join_strategy);
+ }
+};
+
+
+template
+<
+ typename Linestring,
+ typename Polygon
+>
+struct buffer_inserter<linestring_tag, Linestring, Polygon>
+ : public detail::buffer::buffer_range
+ <
+ typename ring_type<Polygon>::type,
+ linestring_tag
+ >
+{
+
+ template<typename Collection, typename DistanceStrategy, typename JoinStrategy>
+ static inline void apply(Linestring const& linestring, Collection& collection,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join_strategy)
+ {
+ collection.add_input();
+ iterate(collection, boost::begin(linestring), boost::end(linestring),
+ buffer_side_left,
+ distance, join_strategy);
+
+ iterate(collection, boost::rbegin(linestring), boost::rend(linestring),
+ buffer_side_right,
+ distance, join_strategy);
+
+ }
+};
+
+
+template
+<
+ typename PolygonInput,
+ typename PolygonOutput
+>
+struct buffer_inserter<polygon_tag, PolygonInput, PolygonOutput>
+{
+
+ template <typename Collection, typename DistanceStrategy, typename JoinStrategy>
+ static inline void apply(PolygonInput const& polygon, Collection& collection,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join_strategy)
+ {
+
+ typedef typename ring_type<PolygonInput>::type input_ring_type;
+ typedef typename ring_type<PolygonOutput>::type output_ring_type;
+
+ typedef buffer_inserter<ring_tag, input_ring_type, output_ring_type> policy;
+
+ {
+ collection.add_input();
+
+ policy::apply(exterior_ring(polygon), collection,
+ distance, join_strategy);
+ }
+
+ typename interior_return_type<PolygonInput const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ output_ring_type ring;
+
+ collection.add_input();
+
+ policy::apply(*it, collection, distance, join_strategy);
+ }
+
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template
+<
+ typename GeometryOutput,
+ typename GeometryInput,
+ typename OutputIterator,
+ typename DistanceStrategy,
+ typename JoinStrategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+>
+inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator out,
+ DistanceStrategy const& distance_strategy, JoinStrategy const& join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+#endif
+ )
+{
+ detail::buffer::buffered_piece_collection<typename geometry::ring_type<GeometryOutput>::type> collection;
+
+ dispatch::buffer_inserter
+ <
+ typename tag<GeometryInput>::type,
+ GeometryInput,
+ GeometryOutput
+ >::apply(geometry_input, collection, distance_strategy, join_strategy);
+
+ collection.get_turns(geometry_input);
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ collection.map_offsetted(mapper);
+#endif
+
+ collection.discard_points();
+ collection.enrich();
+ collection.traverse();
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ //collection.map<geometry::polygon_tag>(mapper);
+ collection.map_turns(mapper);
+ collection.map_traverse(mapper);
+#endif
+
+ collection.assign<GeometryOutput>(out);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_INSERTER_HPP

Added: trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
@@ -0,0 +1,657 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2012 Barend Gehrels, 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_BUFFER_BUFFERED_PIECE_COLLECTION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_PIECE_COLLECTION_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
+
+#include <boost/geometry/extensions/algorithms/buffer/buffered_ring.hpp>
+
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+class backtrack_for_buffer
+{
+public :
+ typedef detail::overlay::backtrack_state state_type;
+
+ template <typename Operation, typename Rings, typename Turns, typename Geometry>
+ static inline void apply(std::size_t size_at_start,
+ Rings& rings, typename boost::range_value<Rings>::type& ring,
+ Turns& turns, Operation& operation,
+ std::string const& reason,
+ Geometry const& ,
+ Geometry const& ,
+ state_type& state
+ )
+ {
+std::cout << "WARNING " << reason << std::endl;
+
+ // TODO this is a copy of dissolve, check this for buffer
+ state.m_good = false;
+
+ // Make bad output clean
+ rings.resize(size_at_start);
+ ring.clear();
+
+ // Reject this as a starting point
+ operation.visited.set_rejected();
+
+ // And clear all visit info
+ clear_visit_info(turns);
+ }
+};
+
+enum intersection_location_type
+{
+ location_ok, inside_buffer, inside_original
+};
+
+
+// Shoould follow traversal-turn-concept (enrichment, visit structure)
+// and adds index in piece vector to find it back
+template <typename Point>
+struct buffer_turn_operation : public detail::overlay::traversal_turn_operation<Point>
+{
+ int piece_index;
+
+ inline buffer_turn_operation()
+ : piece_index(-1)
+ {}
+};
+
+// Add an "intersection_location_type" which gets true for all intersection points lying inside the buffer or original polygon
+template <typename Point>
+struct buffer_turn_info : public detail::overlay::turn_info<Point, buffer_turn_operation<Point> >
+{
+ intersection_location_type location;
+
+ inline buffer_turn_info()
+ : location(location_ok)
+ {}
+};
+
+
+template <typename Ring>
+struct buffered_piece_collection
+{
+ typedef typename geometry::point_type<Ring>::type Point;
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<Point>::type>::type side;
+
+ enum piece_type
+ {
+ buffered_segment, buffered_join
+ };
+
+ template <typename Turn>
+ struct redundant_turn
+ {
+ inline bool operator()(Turn const& turn) const
+ {
+ return turn.location != location_ok;
+ }
+ };
+
+ struct piece
+ {
+ piece_type type;
+ int index;
+ segment_identifier seg_id;
+
+ // -----------------------------------------------------------------
+ // type=buffered_segment:
+
+ // This buffered_segment (2 points of the original)
+ Point p1, p2;
+
+ // The buffered buffered_segment (offsetted with certain distance to left/right)
+ Point b1, b2;
+
+ // -----------------------------------------------------------------
+ // type=buffered_join
+ Point p;
+
+ // Corner next to this buffered_segment (so connected to p2 and b2).
+ // In case p2 is a concave point, corner is empty
+ Ring corner; // TODO redundant
+
+ // Filled for both:
+ typedef geometry::model::linestring<Point> buffered_vector_type;
+
+ buffered_vector_type offseted_segment;
+ };
+
+ typedef std::vector<piece> piece_vector;
+ piece_vector all_pieces;
+ buffered_ring_collection<buffered_ring<Ring> > offsetted_rings;
+ buffered_ring_collection<Ring> traversed_rings;
+ segment_identifier current_segment_id;
+
+ typedef std::vector<buffer_turn_info<Point> > turn_vector_type;
+ typedef detail::overlay::get_turn_info
+ <
+ Point, Point, buffer_turn_info<Point>,
+ detail::overlay::calculate_distance_policy
+ > turn_policy;
+ turn_vector_type turn_vector;
+
+
+
+ inline buffered_piece_collection()
+ {}
+
+
+ inline bool within_piece(buffer_turn_info<Point> const& turn, piece const& pc) const
+ {
+ bool const collinear =
+ turn.operations[0].operation == detail::overlay::operation_continue
+ && turn.operations[0].operation == detail::overlay::operation_continue;
+
+ // For now: use within, using built-up corner (which will be redundant later)
+
+ // Because pieces are always concave we only have to verify if it is left of all segments.
+ // As soon as it is right of one, we can quit. This is faster than the normal within,
+ // and we don't have to build up the polygon.
+ if (collinear)
+ {
+ // ONLY for the outer-boundary: return within
+ return geometry::within(turn.point, pc.corner);
+ }
+
+ return geometry::covered_by(turn.point, pc.corner);
+ }
+
+ // Checks if an intersection point is within one of all pieces
+ // (but skip the pieces of which this intersection point is the result
+ inline bool is_wrong(buffer_turn_info<Point> const& turn, piece const& piece1, piece const& piece2) const
+ {
+ // We might do this using partition.
+ typename std::vector<piece>::const_iterator it;
+ for (it = boost::begin(all_pieces);
+ it != boost::end(all_pieces);
+ ++it)
+ {
+ if (it->index != piece1.index && it->index != piece2.index)
+ {
+ if (within_piece(turn, *it))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+
+ }
+
+ inline bool is_neighbor(piece const& piece1, piece const& piece2) const
+ {
+ if (std::abs(piece1.index - piece2.index) == 1)
+ {
+ return true;
+ }
+
+ int const b = boost::size(all_pieces) - 1; // back
+ return (piece1.index == 0 && piece2.index == b)
+ || (piece1.index == b && piece2.index == 0)
+ ;
+ }
+
+ inline bool skip_neighbor(piece const& piece1, piece const& piece2) const
+ {
+ return piece1.type != piece2.type && is_neighbor(piece1, piece2);
+ }
+
+ template <typename Iterator>
+ inline Point next_point(piece const& piece, Iterator it) const
+ {
+ // Next point in current offseted:
+ Iterator next = it;
+ ++next;
+ if (next != boost::end(piece.offseted_segment))
+ {
+ return *next;
+ }
+
+ // TODO: check if there is a second point (there should be one)
+ // Second point from next piece:
+ int next_index = piece.index + 1;
+ if (next_index >= boost::size(all_pieces))
+ {
+ next_index = 0;
+ }
+ return piece.offseted_segment[1];
+ }
+
+ inline void calculate_turns(piece const& piece1, piece const& piece2)
+ {
+ buffer_turn_info<Point> the_model;
+ the_model.operations[0].piece_index = piece1.index;
+ the_model.operations[0].seg_id = piece1.seg_id;
+
+ // TODO use partition
+ typedef typename boost::range_iterator<typename piece::buffered_vector_type const>::type iterator;
+ iterator it1 = boost::begin(piece1.offseted_segment);
+ for (iterator prev1 = it1++;
+ it1 != boost::end(piece1.offseted_segment);
+ prev1 = it1++, the_model.operations[0].seg_id.segment_index++)
+ {
+ the_model.operations[1].piece_index = piece2.index;
+ the_model.operations[1].seg_id = piece2.seg_id;
+
+ iterator it2 = boost::begin(piece2.offseted_segment);
+ for (iterator prev2 = it2++;
+ it2 != boost::end(piece2.offseted_segment);
+ prev2 = it2++, the_model.operations[1].seg_id.segment_index++)
+ {
+ // Revert (this is used more often - should be common function TODO)
+ the_model.operations[0].other_id = the_model.operations[1].seg_id;
+ the_model.operations[1].other_id = the_model.operations[0].seg_id;
+
+
+ turn_vector_type turns; // TEMPORARY in the end we can add directly to turn_vector
+ turn_policy::apply(*prev1, *it1, next_point(piece1, it1),
+ *prev2, *it2, next_point(piece2, it2),
+ the_model, std::back_inserter(turns));
+
+ // Add buffered_segment identifier info
+ for (typename boost::range_iterator<turn_vector_type>::type it =
+ boost::begin(turns); it != boost::end(turns); ++it)
+ {
+ // TODO: much later in partition.
+ if (is_wrong(*it, piece1, piece2))
+ {
+ it->location = inside_buffer;
+ }
+ turn_vector.push_back(*it);
+ }
+ }
+ }
+ }
+
+ template <typename Geometry>
+ inline void check_remaining_points(Geometry const& input_geometry)
+ {
+ // TODO: this should be done as a collection-of-points, for performance
+ for (typename boost::range_iterator<turn_vector_type>::type it =
+ boost::begin(turn_vector); it != boost::end(turn_vector); ++it)
+ {
+ if (it->location == location_ok)
+ {
+ if (geometry::covered_by(it->point, input_geometry))
+ {
+ it->location = inside_original;
+ }
+ }
+ }
+ }
+
+
+ template <typename Geometry>
+ inline void get_turns(Geometry const& input_geometry)
+ {
+ for(typename piece_vector::const_iterator it1 = boost::begin(all_pieces);
+ it1 != boost::end(all_pieces);
+ ++it1)
+ {
+ for(typename piece_vector::const_iterator it2 = it1 + 1;
+ it2 != boost::end(all_pieces);
+ ++it2)
+ {
+ if (! skip_neighbor(*it1, *it2))
+ {
+ calculate_turns(*it1, *it2);
+ }
+ }
+ }
+ if (boost::is_same<typename tag_cast<typename tag<Geometry>::type, areal_tag>::type, areal_tag>())
+ {
+ check_remaining_points(input_geometry);
+ }
+
+ calculate_discarded();
+ }
+
+ inline void add_input()
+ {
+ int const n = offsetted_rings.size();
+ current_segment_id.source_index = 0;
+ current_segment_id.multi_index = n;
+ current_segment_id.ring_index = -1;
+ current_segment_id.segment_index = 0;
+
+ offsetted_rings.resize(n + 1);
+ }
+
+ inline void add_point(Point const& p)
+ {
+ BOOST_ASSERT
+ (
+ boost::size(offsetted_rings) > 0
+ );
+
+ current_segment_id.segment_index++;
+ offsetted_rings.back().push_back(p);
+ }
+
+
+ inline piece& add_piece(piece_type type, bool decrease_by_one)
+ {
+ piece pc;
+ pc.type = type;
+ pc.index = boost::size(all_pieces);
+ pc.seg_id = current_segment_id;
+
+ std::size_t const n = boost::size(offsetted_rings.back());
+
+ pc.seg_id.segment_index = decrease_by_one ? n - 1 : n;
+
+ all_pieces.push_back(pc);
+ return all_pieces.back();
+ }
+
+
+ inline void add_piece(Point const& p1, Point const& p2,
+ Point const& b1, Point const& b2)
+ {
+ bool const last_type_join = ! all_pieces.empty()
+ && all_pieces.back().type != buffered_segment;
+
+ piece& pc = add_piece(buffered_segment, last_type_join);
+
+ pc.p1 = p1;
+ pc.p2 = p2;
+ pc.b1 = b1;
+ pc.b2 = b2;
+
+ // If it follows the same piece-type point both should be added.
+ // There should be two intersections later and it should be discarded.
+ // But for need it to calculate intersections
+ if (! last_type_join)
+ {
+ add_point(b1);
+ }
+ add_point(b2);
+
+ // TEMPORARY
+ pc.corner.push_back(p1);
+ pc.corner.push_back(b1);
+ pc.corner.push_back(b2);
+ pc.corner.push_back(p2);
+ pc.corner.push_back(p1);
+ // END TEMPORARY
+
+ pc.offseted_segment.push_back(b1);
+ pc.offseted_segment.push_back(b2);
+ }
+
+ template <typename Corner>
+ inline void add_piece(Point const& p, Corner const& corner)
+ {
+ piece& pc = add_piece(buffered_join, true);
+
+ pc.p = p;
+
+ pc.corner.push_back(p);// TEMPORARY
+ bool first = true;
+ for (typename Corner::const_iterator it = boost::begin(corner);
+ it != boost::end(corner);
+ ++it)
+ {
+ bool add = true;
+ if (first)
+ {
+ // Only for very first one, add first. In all other cases it is shared with previous.
+ add = offsetted_rings.back().empty();
+ first = false;
+ }
+ if (add)
+ {
+ add_point(*it);
+ }
+ pc.corner.push_back(*it); // TEMPORARY
+ pc.offseted_segment.push_back(*it); // REDUNDANT
+ }
+ pc.corner.push_back(p);// TEMPORARY
+ }
+
+ inline void enrich()
+ {
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Ring>::type
+ >::type side_strategy_type;
+
+ enrich_intersection_points<false, false>(turn_vector,
+ detail::overlay::operation_union,
+ offsetted_rings, offsetted_rings,
+ side_strategy_type());
+ }
+
+ // Discards all rings which do have not-OK intersection points only.
+ // Those can never be traversed and should not be part of the output.
+ inline void calculate_discarded()
+ {
+ for (typename boost::range_iterator<turn_vector_type const>::type it =
+ boost::begin(turn_vector); it != boost::end(turn_vector); ++it)
+ {
+ if (it->location != location_ok)
+ {
+ offsetted_rings[it->operations[0].seg_id.multi_index].has_discarded_intersections = true;
+ offsetted_rings[it->operations[1].seg_id.multi_index].has_discarded_intersections = true;
+ }
+ else
+ {
+ offsetted_rings[it->operations[0].seg_id.multi_index].has_accepted_intersections = true;
+ offsetted_rings[it->operations[1].seg_id.multi_index].has_accepted_intersections = true;
+ }
+ }
+ }
+
+ inline void discard_points()
+ {
+ // Erase all points being inside
+ turn_vector.erase(
+ std::remove_if(boost::begin(turn_vector), boost::end(turn_vector), redundant_turn<buffer_turn_info<Point> >()),
+ boost::end(turn_vector));
+
+ }
+
+ inline void traverse()
+ {
+ typedef detail::overlay::traverse
+ <
+ false, false,
+ buffered_ring_collection<buffered_ring<Ring > >, buffered_ring_collection<buffered_ring<Ring > >,
+ backtrack_for_buffer
+ > traverser;
+
+ traversed_rings.clear();
+ traverser::apply(offsetted_rings, offsetted_rings,
+ detail::overlay::operation_union,
+ turn_vector, traversed_rings);
+ }
+
+ template <typename GeometryOutput, typename OutputIterator>
+ inline OutputIterator assign(OutputIterator out)
+ {
+ typedef detail::overlay::ring_properties<Point> properties;
+
+ std::map<ring_identifier, properties> selected;
+
+ // Select all rings which do not have any self-intersection (other ones should be traversed)
+ int index = 0;
+ for(typename buffered_ring_collection<buffered_ring<Ring> >::const_iterator it = boost::begin(offsetted_rings);
+ it != boost::end(offsetted_rings);
+ ++it, ++index)
+ {
+ if (! it->has_intersections())
+ {
+ ring_identifier id(0, index, -1);
+ selected[id] = properties(*it, true);
+ }
+ }
+
+ // Select all created rings
+ index = 0;
+ for (typename boost::range_iterator<buffered_ring_collection<Ring> const>::type
+ it = boost::begin(traversed_rings);
+ it != boost::end(traversed_rings);
+ ++it, ++index)
+ {
+ ring_identifier id(2, index, -1);
+ selected[id] = properties(*it, true);
+ }
+
+ detail::overlay::assign_parents(offsetted_rings, traversed_rings, selected);
+ return detail::overlay::add_rings<GeometryOutput>(selected, offsetted_rings, traversed_rings, out);
+ }
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+
+ template <typename Mapper>
+ inline void map_turns(Mapper& mapper)
+ {
+ int index = 0;
+ for (typename boost::range_iterator<turn_vector_type>::type it =
+ boost::begin(turn_vector); it != boost::end(turn_vector); ++it)
+ {
+ std::string fill = "fill:rgb(0,255,0);";
+ switch(it->location)
+ {
+ case inside_buffer : fill = "fill:rgb(255,0,0);"; break;
+ case inside_original : fill = "fill:rgb(0,0,255);"; break;
+ }
+ mapper.map(it->point, fill, 6);
+ std::ostringstream out;
+ //out << it->operations[0].piece_index << "/" << it->operations[1].piece_index;
+ out << " " << all_pieces[it->operations[0].piece_index].seg_id.segment_index
+ << "+" << all_pieces[it->operations[1].piece_index].seg_id.segment_index;
+ //out << " " << all_pieces[it->operations[0].piece_index].index_in_all_points
+ // << "," << all_pieces[it->operations[1].piece_index].index_in_all_points;
+ //out << " " << it->operations[0].seg_id.segment_index
+ // << "|" << it->operations[1].seg_id.segment_index;
+ out << ":" << operation_char(it->operations[0].operation);
+ mapper.text(it->point, out.str(), "fill:rgb(0,0,0);font-family='Arial';", 5, 5);
+ }
+ }
+
+ template <typename Tag, typename Mapper>
+ inline void map(Mapper& mapper)
+ {
+ for(typename piece_vector::const_iterator it = boost::begin(all_pieces);
+ it != boost::end(all_pieces);
+ ++it)
+ {
+ if (it->type == buffered_segment)
+ {
+ geometry::model::ring<Point> ring;
+ ring.push_back(it->p1);
+ ring.push_back(it->b1);
+ ring.push_back(it->b2);
+ ring.push_back(it->p2);
+ ring.push_back(it->p1);
+
+ if(boost::is_same<Tag, ring_tag>::value || boost::is_same<Tag, polygon_tag>::value)
+ {
+ mapper.map(ring, "opacity:0.3;fill:rgb(255,128,0);stroke:rgb(0,0,0);stroke-width:1");
+ }
+ else if(boost::is_same<Tag, linestring_tag>::value)
+ {
+ mapper.map(ring, "opacity:0.3;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:1");
+ }
+ }
+ else
+ {
+ mapper.map(it->corner, "opacity:0.3;fill:rgb(255,0,0);stroke:rgb(0,0,0);stroke-width:1");
+ }
+
+
+ // Put starting segment_index in centroid
+ Point centroid;
+ geometry::centroid(it->corner, centroid);
+ std::ostringstream out;
+ out << it->seg_id.segment_index;
+ mapper.text(centroid, out.str(), "fill:rgb(255,0,0);font-family='Arial';", 5, 5);
+
+ }
+
+ int index = 0;
+ for (typename boost::range_iterator<std::vector<Point> >::type it =
+ boost::begin(offsetted_rings.front()); it != boost::end(offsetted_rings.front()); ++it)
+ {
+ mapper.map(*it, "fill:rgb(0,0,0);", 2);
+ std::ostringstream out;
+ out << index++;
+ mapper.text(*it, out.str(), "fill:rgb(0,0,255);font-family='Arial';", -5, -5);
+ }
+
+ }
+
+ template <typename Mapper>
+ inline void map_traverse(Mapper& mapper)
+ {
+ for(typename buffered_ring_collection<Ring>::const_iterator it = boost::begin(traversed_rings);
+ it != boost::end(traversed_rings);
+ ++it)
+ {
+ mapper.map(*it, "opacity:0.4;fill:none;stroke:rgb(0,255,0);stroke-width:8");
+ }
+ }
+
+ template <typename Mapper>
+ inline void map_offsetted(Mapper& mapper)
+ {
+ for(typename buffered_ring_collection<buffered_ring<Ring> >::const_iterator it = boost::begin(offsetted_rings);
+ it != boost::end(offsetted_rings);
+ ++it)
+ {
+ if (it->discarded())
+ {
+ mapper.map(*it, "opacity:0.4;fill:none;stroke:rgb(255,0,0);stroke-width:8");
+ }
+ else
+ {
+ mapper.map(*it, "opacity:0.4;fill:none;stroke:rgb(0,0,255);stroke-width:8");
+ }
+ }
+ }
+#endif
+};
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_PIECE_COLLECTION_HPP

Added: trunk/boost/geometry/extensions/algorithms/buffer/buffered_ring.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/algorithms/buffer/buffered_ring.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
@@ -0,0 +1,260 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2012 Barend Gehrels, 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_BUFFER_BUFFERED_RING
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
+
+#include <boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp>
+#include <boost/geometry/multi/algorithms/within.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+struct buffered_ring_collection_tag : polygonal_tag, multi_tag
+{};
+
+
+template <typename Ring>
+struct buffered_ring : public Ring
+{
+ bool has_discarded_intersections;
+ bool has_accepted_intersections;
+ inline buffered_ring()
+ : has_accepted_intersections(false)
+ , has_discarded_intersections(false)
+ {}
+
+ inline bool discarded() const
+ {
+ return has_discarded_intersections && ! has_accepted_intersections;
+ }
+ inline bool has_intersections() const
+ {
+ return has_discarded_intersections || has_accepted_intersections;
+ }
+};
+
+// This is a collection now special for overlay (needs vector of rings)
+template <typename Ring>
+struct buffered_ring_collection : public std::vector<Ring>
+{
+};
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+// Register the types
+namespace traits
+{
+
+
+template <typename Ring>
+struct tag<detail::buffer::buffered_ring<Ring> >
+{
+ typedef ring_tag type;
+};
+
+
+template <typename Ring>
+struct point_order<detail::buffer::buffered_ring<Ring> >
+{
+ static const order_selector value = geometry::point_order<Ring>::value;
+};
+
+
+template <typename Ring>
+struct closure<detail::buffer::buffered_ring<Ring> >
+{
+ static const closure_selector value = geometry::closure<Ring>::value;
+};
+
+
+template <typename Ring>
+struct point_type<detail::buffer::buffered_ring_collection<Ring> >
+{
+ typedef typename geometry::point_type<Ring>::type type;
+};
+
+template <typename Ring>
+struct tag<detail::buffer::buffered_ring_collection<Ring> >
+{
+ typedef detail::buffer::buffered_ring_collection_tag type;
+};
+
+
+} // namespace traits
+
+namespace core_dispatch
+{
+
+template <typename Ring>
+struct ring_type
+<
+ detail::buffer::buffered_ring_collection_tag,
+ detail::buffer::buffered_ring_collection<Ring>
+>
+{
+ typedef Ring type;
+};
+
+}
+
+namespace dispatch
+{
+
+template
+<
+ typename MultiRing,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename PointOut
+>
+struct copy_segment_point
+ <
+ detail::buffer::buffered_ring_collection_tag,
+ MultiRing,
+ Reverse,
+ SegmentIdentifier,
+ PointOut
+ >
+ : detail::copy_segments::copy_segment_point_multi
+ <
+ MultiRing,
+ SegmentIdentifier,
+ PointOut,
+ detail::copy_segments::copy_segment_point_range
+ <
+ typename boost::range_value<MultiRing>::type,
+ Reverse,
+ SegmentIdentifier,
+ PointOut
+ >
+ >
+{};
+
+
+template
+<
+ typename MultiRing,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments
+ <
+ detail::buffer::buffered_ring_collection_tag,
+ MultiRing,
+ Reverse,
+ SegmentIdentifier,
+ RangeOut
+ >
+ : detail::copy_segments::copy_segments_multi
+ <
+ MultiRing,
+ SegmentIdentifier,
+ RangeOut,
+ detail::copy_segments::copy_segments_ring
+ <
+ typename boost::range_value<MultiRing>::type,
+ Reverse,
+ SegmentIdentifier,
+ RangeOut
+ >
+ >
+{};
+
+
+
+template <typename Point, typename MultiGeometry>
+struct within
+<
+ Point,
+ MultiGeometry,
+ point_tag,
+ detail::buffer::buffered_ring_collection_tag
+>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point,
+ MultiGeometry const& multi, Strategy const& strategy)
+ {
+ return detail::within::geometry_multi_within_code
+ <
+ Point,
+ MultiGeometry,
+ Strategy,
+ detail::within::point_in_ring
+ <
+ Point,
+ typename boost::range_value<MultiGeometry>::type,
+ //iterate_forward,
+ //closed,
+ order_as_direction
+ <
+ geometry::point_order<MultiGeometry>::value
+ >::value,
+ geometry::closure<MultiGeometry>::value,
+ Strategy
+ >
+ >::apply(point, multi, strategy) == 1;
+ }
+};
+
+
+} // namespace dispatch
+
+namespace detail { namespace overlay
+{
+
+template<>
+struct get_ring<detail::buffer::buffered_ring_collection_tag>
+{
+ template<typename MultiGeometry>
+ static inline typename ring_type<MultiGeometry>::type const& apply(
+ ring_identifier const& id,
+ MultiGeometry const& multi_ring)
+ {
+ BOOST_ASSERT
+ (
+ id.multi_index >= 0
+ && id.multi_index < boost::size(multi_ring)
+ );
+ return get_ring<ring_tag>::apply(id, multi_ring[id.multi_index]);
+ }
+};
+
+}}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING

Deleted: trunk/boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
+++ (empty file)
@@ -1,100 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_LINESTRING_BUFFER_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINESTRING_BUFFER_HPP
-
-#include <cstddef>
-
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/range.hpp>
-
-#include <boost/geometry/extensions/strategies/buffer_side.hpp>
-
-#include <boost/geometry/extensions/algorithms/buffer/buffer_appender.hpp>
-#include <boost/geometry/extensions/algorithms/buffer/range_buffer.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-template
-<
- typename Linestring,
- typename Polygon,
- typename DistanceStrategy,
- typename JoinStrategy
->
-struct linestring_buffer
- : public range_buffer
- <
- typename ring_type<Polygon>::type,
- DistanceStrategy,
- JoinStrategy,
- linestring_tag
- >
-{
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- template<typename Mapper>
-#endif
- static inline void apply(Linestring const& linestring, Polygon& buffered,
- DistanceStrategy const& distance,
- JoinStrategy const& join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
-#endif
- )
- {
- buffer_appender
- <
- typename geometry::ring_type<Polygon>::type
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper
-#endif
- > appender
- (
- geometry::exterior_ring(buffered)
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
-
- iterate(appender, boost::begin(linestring), boost::end(linestring),
- buffer_side_left,
- distance, join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
-
- iterate(appender, boost::rbegin(linestring), boost::rend(linestring),
- buffer_side_right,
- distance, join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
-
- }
-};
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINESTRING_BUFFER_HPP

Deleted: trunk/boost/geometry/extensions/algorithms/buffer/polygon_buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/polygon_buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
+++ (empty file)
@@ -1,159 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_POLYGON_BUFFER_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_POLYGON_BUFFER_HPP
-
-#include <cstddef>
-
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/range.hpp>
-#include <boost/typeof/typeof.hpp>
-
-#include <boost/geometry/core/exterior_ring.hpp>
-#include <boost/geometry/core/interior_rings.hpp>
-
-#include <boost/geometry/extensions/strategies/buffer_side.hpp>
-#include <boost/geometry/extensions/algorithms/buffer/buffer_appender.hpp>
-#include <boost/geometry/extensions/algorithms/buffer/range_buffer.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-
-template
-<
- typename RingInput,
- typename RingOutput,
- typename DistanceStrategy,
- typename JoinStrategy
->
-struct ring_buffer
- : public range_buffer
- <
- RingOutput,
- DistanceStrategy,
- JoinStrategy,
- ring_tag
- >
-{
-
- template
- <
- typename BufferAppender
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
- >
- static inline void apply(RingInput const& ring,
- BufferAppender& appender,
- DistanceStrategy const& distance,
- JoinStrategy const& join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
-#endif
- )
- {
- iterate(appender, boost::begin(ring), boost::end(ring),
- buffer_side_left,
- distance, join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
- }
-};
-
-
-
-template
-<
- typename PolygonInput,
- typename PolygonOutput,
- typename DistanceStrategy,
- typename JoinStrategy
->
-struct polygon_buffer
-{
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- template <typename Mapper>
-#endif
- static inline void apply(PolygonInput const& polygon, PolygonOutput& buffered,
- DistanceStrategy const& distance,
- JoinStrategy const& join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
-#endif
- )
- {
- geometry::clear(buffered);
-
- typedef typename ring_type<PolygonInput>::type input_ring_type;
- typedef typename ring_type<PolygonOutput>::type output_ring_type;
-
- typedef buffer_appender
- <
- output_ring_type
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper
-#endif
- > appender_type;
-
- typedef ring_buffer<input_ring_type, output_ring_type, DistanceStrategy, JoinStrategy> policy;
-
- {
- appender_type appender(geometry::exterior_ring(buffered)
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
- policy::apply(exterior_ring(polygon), appender,
- distance, join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
- }
-
- typename interior_return_type<PolygonInput const>::type rings
- = interior_rings(polygon);
- for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
- {
- output_ring_type ring;
-
- appender_type appender(ring
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
-
- policy::apply(*it, appender, distance, join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
- interior_rings(buffered).push_back(ring);
- }
- }
-};
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_POLYGON_BUFFER_HPP

Deleted: trunk/boost/geometry/extensions/algorithms/buffer/range_buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/range_buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
+++ (empty file)
@@ -1,199 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_RANGE_BUFFER_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_RANGE_BUFFER_HPP
-
-#include <cstddef>
-
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/coordinate_type.hpp>
-#include <boost/geometry/core/point_type.hpp>
-
-#include <boost/geometry/extensions/strategies/buffer_side.hpp>
-
-#include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
-
-#include <boost/geometry/geometries/segment.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-template
-<
- typename RingOutput,
- typename DistanceStrategy,
- typename JoinStrategy,
- typename Tag
->
-struct range_buffer
-{
- typedef typename point_type<RingOutput>::type output_point_type;
- typedef typename coordinate_type<RingOutput>::type coordinate_type;
- typedef model::referring_segment<output_point_type const> segment_type;
-
- template
- <
- typename BufferAppender,
- typename Iterator
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
- >
- static inline void iterate(BufferAppender& appender,
- Iterator begin, Iterator end,
- buffer_side_selector side,
- DistanceStrategy const& distance,
- JoinStrategy const& join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
-#endif
- )
- {
- output_point_type previous_p1, previous_p2;
- output_point_type first_p1, first_p2;
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- int index = 0;
-#endif
-
- bool first = true;
-
- Iterator it = begin;
- for (Iterator prev = it++; it != end; ++it)
- {
- if (! detail::equals::equals_point_point(*prev, *it))
- {
- // Generate a block along (left or right of) the segment
-
- // Simulate a vector d (dx,dy)
- coordinate_type dx = get<0>(*it) - get<0>(*prev);
- coordinate_type dy = get<1>(*it) - get<1>(*prev);
-
- // For normalization [0,1] (=dot product d.d, sqrt)
- coordinate_type length = sqrt(dx * dx + dy * dy);
-
- // Because coordinates are not equal, length should not be zero
- BOOST_ASSERT((! geometry::math::equals(length, 0)));
-
- // Generate the normalized perpendicular p, to the left (ccw)
- coordinate_type px = -dy / length;
- coordinate_type py = dx / length;
-
- output_point_type p1, p2;
-
- coordinate_type d = distance.apply(*prev, *it, side);
-
- set<0>(p2, get<0>(*it) + px * d);
- set<1>(p2, get<1>(*it) + py * d);
-
- set<0>(p1, get<0>(*prev) + px * d);
- set<1>(p1, get<1>(*prev) + py * d);
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- {
- RingOutput block;
- block.push_back(*prev);
- block.push_back(*it);
- block.push_back(p2);
- block.push_back(p1);
- block.push_back(*prev);
-
- if(boost::is_same<Tag, ring_tag>::value)
- {
- mapper.map(block, "opacity:0.4;fill:rgb(255,128,0);stroke:rgb(0,0,0);stroke-width:1");
- }
- else if(boost::is_same<Tag, linestring_tag>::value)
- {
- mapper.map(block, "opacity:0.4;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:1");
- }
- }
-#endif
-
- if (! first)
- {
- output_point_type p;
- segment_type s1(p1, p2);
- segment_type s2(previous_p1, previous_p2);
- if (line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p))
- {
- join_strategy.apply(p, *prev, previous_p2, p1,
- distance.apply(*prev, *it, side),
- appender);
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- {
- //mapper.map(p, "fill:rgb(0,0,0);", 3);
-
- //std::ostringstream out;
- //out << index++;
- //mapper.text(p, out.str(), "fill:rgb(0,0,0);font-family='Arial';", 5, 5);
- }
-#endif
- }
- }
- else
- {
- first = false;
- first_p1 = p1;
- first_p2 = p2;
-
- appender.append(p1);
- }
-
- previous_p1 = p1;
- previous_p2 = p2;
- prev = it;
- }
- }
-
- // Might be replaced by specialization
- if(boost::is_same<Tag, linestring_tag>::value)
- {
- appender.append(previous_p2);
- }
- else if(boost::is_same<Tag, ring_tag>::value)
- {
- // Generate closing corner
- output_point_type p;
- segment_type s1(previous_p1, previous_p2);
- segment_type s2(first_p1, first_p2);
- line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p);
-
- join_strategy.apply(p, *begin, previous_p2, first_p1,
- distance.apply(*(end - 1), *begin, side),
- appender);
-
- // Buffer is closed automatically by last closing corner (NOT FOR OPEN POLYGONS - TODO)
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- {
- //mapper.map(p, "fill:rgb(0,0,0);", 3);
- //std::ostringstream out;
- //out << index++;
- //mapper.text(p, out.str(), "fill:rgb(0,0,0);font-family='Arial';", 5, 5);
- }
-#endif
- }
- }
-};
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_RANGE_BUFFER_HPP

Deleted: trunk/boost/geometry/extensions/algorithms/buffer/sectionalizing_buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/sectionalizing_buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
+++ (empty file)
@@ -1,167 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_SECTIONALIZING_BUFFER_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SECTIONALIZING_BUFFER_HPP
-
-#include <cstddef>
-
-#include <boost/foreach.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <boost/geometry/core/point_type.hpp>
-
-#include <boost/geometry/extensions/strategies/buffer_side.hpp>
-#include <boost/geometry/extensions/algorithms/detail/buffer/intersecting_inserter.hpp>
-#include <boost/geometry/extensions/algorithms/detail/buffer/linestring_buffer.hpp>
-#include <boost/geometry/extensions/algorithms/detail/buffer/line_line_intersection.hpp>
-
-#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
-#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
-
-#include <boost/geometry/extensions/algorithms/dissolve.hpp>
-
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-
-
-template
-<
- typename GeometryOut, typename Geometry,
- typename DistanceStrategy,
- typename JoinStrategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
->
-void sectionalizing_buffer(Geometry const& geometry,
- std::vector<GeometryOut>& buffered,
- DistanceStrategy const& distance_strategy,
- JoinStrategy const& join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
-#endif
- )
-{
- typedef typename point_type<Geometry>::type point_type;
- typedef geometry::box<point_type> box_type;
- typedef geometry::sections<box_type, 2> sections_type;
- typedef typename geometry::ring_type<GeometryOut>::type ring_type;
-
- // TEMPORARY
- typedef intersecting_inserter
- <
- std::vector<GeometryOut>
- > inserter_type;
-
-
- sections_type sections;
- geometry::sectionalize(geometry, sections);
-
-
-
- // Buffer all sections separately, and put them in a temporary vector
- std::vector<GeometryOut> buffered_sections;
- BOOST_FOREACH(typename sections_type::value_type const& section, sections)
- {
- if (! section.duplicate)
- {
- typedef typename boost::range_iterator
- <
- typename geometry::detail::range_type<Geometry>::type const
- >::type iterator_type;
-
-
- inserter_type inserter(buffered_sections);
-
- iterator_type begin, end;
- typedef std::pair<iterator_type, iterator_type> section_range;
-
-TODO: UPDATE: get _ section IS OBSOLETE NOW AND DISCARDED.
-TAKE range_by_section AND ADD section.begin_index/section.end_index
-
- geometry::get _ section(geometry, section, begin, end); // get_section is DISCARDED
- geometry::detail::buffer::linestring_buffer
- <
- section_range, ring_type, DistanceStrategy, JoinStrategy
- >::apply(std::make_pair(begin, end), inserter,
- distance_strategy,
- join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , mapper
-#endif
- );
- }
- }
-
- // IF there are bowl-like shapes, there can still be self-intersections
- std::vector<GeometryOut> dissolved;
- BOOST_FOREACH(GeometryOut const& p, buffered_sections)
- {
- geometry::dissolve(p, dissolved);
- }
-
- /*BOOST_FOREACH(GeometryOut const& p, buffered_sections)
- {
- if (geometry::intersects(p))
- {
- //std::cout << ".";
- }
- }*/
-
- // TEMP
- //buffered.swap(dissolved);
- //return;
- // END TEMP
-
-
- BOOST_FOREACH(GeometryOut const& p, dissolved)
- {
- if (buffered.empty())
- {
- buffered.push_back(p);
- //geometry::union_inserter<GeometryOut>(geometry, p, std::back_inserter(buffered));
- }
- else if (boost::size(buffered) == 1)
- {
- std::vector<GeometryOut> unioned;
- geometry::union_inserter<GeometryOut>(buffered.front(), p, std::back_inserter(unioned));
- buffered.swap(unioned);
- }
- else
- {
- std::cerr << " D " << buffered.size();
- /*std::vector<GeometryOut> dissolved;
- dissolved.push_back(p);
- geometry::dissolver(buffered, dissolved);
- dissolved.swap(buffered);*/
- }
- }
-
- // Output
-}
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SECTIONALIZING_BUFFER_HPP

Deleted: trunk/boost/geometry/extensions/algorithms/buffer/segmenting_buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/segmenting_buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
+++ (empty file)
@@ -1,350 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_SEGMENTING_BUFFER_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SEGMENTING_BUFFER_HPP
-
-
-#include <cstddef>
-#include <vector>
-
-#include <boost/foreach.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/ring_type.hpp>
-
-#include <boost/geometry/extensions/strategies/buffer_side.hpp>
-#include <boost/geometry/extensions/strategies/buffer_join_round.hpp>
-#include <boost/geometry/util/math.hpp>
-
-#include <boost/geometry/algorithms/detail/disjoint.hpp>
-
-
-#include <boost/geometry/extensions/algorithms/dissolve.hpp>
-
-
-// TEMPORARY do not use yet.
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-
-template <typename Point, typename PointOut, typename DistanceType>
-inline bool calculate_parallels(Point const& point1, Point const& point2,
- PointOut& p1, PointOut& p2, DistanceType const& distance)
-{
- typedef typename coordinate_type<Point>::type coordinate_type;
-
- // Simulate a vector d (dx,dy)
- coordinate_type dx = get<0>(point2) - get<0>(point1);
- coordinate_type dy = get<1>(point2) - get<1>(point1);
-
- // For normalization [0,1] (=dot product d.d, sqrt)
- // TODO: promote to non-integer
- coordinate_type length = sqrt(dx * dx + dy * dy);
-
- // Because coordinates are not equal, should been checked before, length should not be zero
- if(geometry::math::equals(length, 0))
- {
- return false;
- }
-
- // Generate the normalized perpendicular p, to the left (ccw)
- coordinate_type px = -dy / length;
- coordinate_type py = dx / length;
-
- set<0>(p1, get<0>(point1) + px * distance);
- set<1>(p1, get<1>(point1) + py * distance);
-
- set<0>(p2, get<0>(point2) + px * distance);
- set<1>(p2, get<1>(point2) + py * distance);
- return true;
-}
-
-
-
-template
-<
- typename GeometryOut, typename Range,
- typename DistanceStrategy,
- typename JoinStrategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
->
-struct per_segment_buffer
-{
- typedef typename point_type<Range>::type input_point_type;
- typedef typename point_type<GeometryOut>::type point_type;
- typedef typename coordinate_type<point_type>::type coordinate_type;
- typedef coordinate_type distance_type; // TODO promote to FP
- typedef model::segment<point_type const> segment_type;
- typedef typename geometry::ring_type<GeometryOut>::type ring_type;
- typedef typename strategy::side::services::default_strategy<typename cs_tag<point_type>::type>::type side;
-
- typedef typename boost::range_iterator<Range const>::type iterator_type;
-
-
- static inline void calculate_tail(input_point_type const& tail, input_point_type const& head,
- point_type& tail_left, point_type& tail_right,
- distance_type& distance_left,
- distance_type& distance_right,
- distance_type& buffered_length)
- {
- coordinate_type ext_x = get<0>(head) - get<0>(tail);
- coordinate_type ext_y = get<1>(head) - get<1>(tail);
- distance_type segment_length = sqrt(ext_x * ext_x + ext_y * ext_y);
-
- if (buffered_length < geometry::math::abs(distance_left))
- {
- distance_left = buffered_length * distance_left < 0 ? -1.0 : 1.0;
- }
- if (buffered_length < geometry::math::abs(distance_right))
- {
- distance_right = buffered_length * distance_right < 0 ? -1.0 : 1.0;
- }
-
- distance_type prop_left = geometry::math::abs(distance_left) / segment_length;
- distance_type prop_right = geometry::math::abs(distance_right) / segment_length;
-
- set<0>(tail_left, get<0>(tail) - ext_x * prop_left);
- set<1>(tail_left, get<1>(tail) - ext_y * prop_left);
- set<0>(tail_right, get<0>(tail) - ext_x * prop_right);
- set<1>(tail_right, get<1>(tail) - ext_y * prop_right);
-
- buffered_length += segment_length;
- }
-
-
- static inline void calculate_head(input_point_type const& tail, input_point_type const& head,
- point_type& head_left, point_type& head_right,
- distance_type& distance_left,
- distance_type& distance_right,
- distance_type const& rest_length)
- {
- coordinate_type ext_x = get<0>(head) - get<0>(tail);
- coordinate_type ext_y = get<1>(head) - get<1>(tail);
- distance_type segment_length = sqrt(ext_x * ext_x + ext_y * ext_y);
-
- if (rest_length < distance_left)
- {
- distance_left = rest_length;
- }
- if (rest_length < distance_right)
- {
- distance_right = rest_length;
- }
-
- distance_type prop_left = distance_left / segment_length;
- distance_type prop_right = distance_right / segment_length;
-
- set<0>(head_left, get<0>(head) + ext_x * prop_left);
- set<1>(head_left, get<1>(head) + ext_y * prop_left);
- set<0>(head_right, get<0>(head) + ext_x * prop_right);
- set<1>(head_right, get<1>(head) + ext_y * prop_right);
- }
-
- static inline void apply(Range const& range,
- std::vector<GeometryOut>& buffered,
- DistanceStrategy const& distance_strategy,
- JoinStrategy const& join_strategy
- #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
- #endif
- )
- {
- // Buffer all segments separately, and put them in a temporary vector
- std::vector<GeometryOut> buffered_pieces;
-
- bool first = true;
-
- strategy::buffer::join_round2<point_type> new_join;
- //strategy::buffer::join_none<point_type> new_join;
-
- distance_type range_length = geometry::length(range);
- distance_type buffered_length = coordinate_type();
-
- iterator_type it = boost::begin(range);
- //iterator_type it_c = boost::end(range);
- for (iterator_type previous = it++;
- it != boost::end(range);
- ++it)
- {
- bool const last = it + 1 == boost::end(range);
-
- distance_type distance_left = distance_strategy.apply(
- *previous, *it, buffer_side_left);
- distance_type distance_right = distance_strategy.apply(
- *previous, *it, buffer_side_right);
-
- point_type left_ab_p1, left_ab_p2, right_ab_p1, right_ab_p2;
-
- if (detail::disjoint::disjoint_point_point(*previous, *it)
- && calculate_parallels(*previous, *it, left_ab_p1, left_ab_p2,
- distance_left)
- && calculate_parallels(*previous, *it, right_ab_p1, right_ab_p2,
- -distance_right)
- )
- {
- {
- point_type tail_left, tail_right, head_left, head_right;
-
- // For flat buffers, generate corners only if outside range of buffer_distance
- distance_type distance_tail_left = distance_left;
- distance_type distance_tail_right = distance_right;
- distance_type distance_head_left = distance_left;
- distance_type distance_head_right = distance_right;
-
- calculate_tail(*previous, *it,
- tail_left, tail_right,
- distance_tail_left, distance_tail_right,
- buffered_length);
-
- distance_type const rest_length = range_length - buffered_length;
-
- calculate_head(*previous, *it,
- head_left, head_right,
- distance_head_left, distance_head_right,
- rest_length);
-
- // Add non-axis aligned rectangle
- buffered_pieces.resize(buffered_pieces.size() + 1);
- ring_type& ring = exterior_ring(buffered_pieces.back());
- ring.push_back(left_ab_p1);
- ring.push_back(left_ab_p2);
-
- if (! last)
- {
- new_join.apply(*it, left_ab_p2, left_ab_p2, head_left,
- distance_left, distance_head_left,
- std::back_inserter(ring));
-
- ring.push_back(head_left);
- ring.push_back(head_right);
-
- new_join.apply(*it, right_ab_p2, head_right, right_ab_p2,
- distance_right, distance_head_right,
- std::back_inserter(ring));
- }
-
- ring.push_back(right_ab_p2);
- ring.push_back(right_ab_p1);
-
- if (! first)
- {
- new_join.apply(*previous, right_ab_p1, right_ab_p1, tail_right,
- distance_right, distance_tail_right,
- std::back_inserter(ring));
-
- ring.push_back(tail_right);
- ring.push_back(tail_left);
-
- new_join.apply(*previous, left_ab_p1, tail_left, left_ab_p1,
- distance_left, distance_tail_left,
- std::back_inserter(ring));
- }
-
- ring.push_back(left_ab_p1);
- }
-
- previous = it;
-
- first = false;
- }
- }
-
- // TEMP, uncomment to see what was actually generated
- //buffered.swap(buffered_pieces);
- //return;
- // END TEMP
-
-
-
- BOOST_FOREACH(GeometryOut const& p, buffered_pieces)
- {
- if (buffered.empty())
- {
- buffered.push_back(p);
- }
- else if (boost::size(buffered) == 1)
- {
- std::vector<GeometryOut> unioned;
- geometry::union_inserter<GeometryOut>(buffered.front(), p, std::back_inserter(unioned));
- buffered.swap(unioned);
- }
- else
- {
- std::cerr << " D " << buffered.size();
- /*std::vector<GeometryOut> dissolved;
- dissolved.push_back(p);
- geometry::dissolver(buffered, dissolved);
- dissolved.swap(buffered);*/
- }
- }
-
- /***
- std::vector<GeometryOut> dissolved;
- BOOST_FOREACH(GeometryOut const& p, buffered)
- {
- geometry::dissolve(p, dissolved);
- }
- dissolved.swap(buffered);
- ***/
-
- // Output
- }
-};
-
-
-
-template
-<
- typename GeometryOut, typename Geometry,
- typename DistanceStrategy,
- typename JoinStrategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
->
-inline void segmenting_buffer(Geometry const& geometry,
- std::vector<GeometryOut>& buffered,
- DistanceStrategy const& distance_strategy,
- JoinStrategy const& join_strategy
- #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
- #endif
- )
-{
- per_segment_buffer
- <
- GeometryOut, Geometry,
- DistanceStrategy, JoinStrategy
- >::apply(geometry, buffered, distance_strategy, join_strategy);
-}
-
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SEGMENTING_BUFFER_HPP

Deleted: trunk/boost/geometry/extensions/algorithms/buffer/splitting_buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/splitting_buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
+++ (empty file)
@@ -1,116 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_SPLITTING_BUFFER_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SPLITTING_BUFFER_HPP
-
-#include <cstddef>
-
-#include <boost/foreach.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <boost/geometry/core/point_type.hpp>
-
-#include <boost/geometry/extensions/strategies/buffer_side.hpp>
-#include <boost/geometry/extensions/algorithms/detail/buffer/intersecting_inserter.hpp>
-#include <boost/geometry/extensions/algorithms/detail/buffer/linestring_buffer.hpp>
-#include <boost/geometry/extensions/algorithms/detail/buffer/line_line_intersection.hpp>
-
-
-#include <boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp>
-#include <boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp>
-
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-
-template
-<
- typename GeometryOut, typename Geometry,
- typename DistanceStrategy,
- typename JoinStrategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
->
-inline void splitting_buffer(Geometry const& geometry,
- std::vector<GeometryOut>& buffered,
- DistanceStrategy const& distance_strategy,
- JoinStrategy const& join_strategy
-
- , int option
- )
-{
- typedef typename ring_type<GeometryOut>::type ring_type;
- typedef detail::buffer::intersecting_inserter
- <
- std::vector<GeometryOut>
- > inserter_type;
-
-
- inserter_type inserter(buffered);
-
- detail::buffer::linestring_buffer
- <
- Geometry, GeometryOut, DistanceStrategy, JoinStrategy
- >::apply(geometry, inserter, distance_strategy, join_strategy);
-
- if (option == 0)
- {
- return;
- }
-
- std::vector<ring_type> rings;
- BOOST_FOREACH(GeometryOut const& polygon, buffered)
- {
-//std::cout << geometry::wkt(polygon) << " ; POLYGON" << std::endl;
- geometry::split_rings(polygon, rings);
- }
-
- if (option == 1)
- {
- buffered.resize(rings.size());
- int i = 0;
- BOOST_FOREACH(ring_type const& ring, rings)
- {
- exterior_ring(buffered[i++]) = ring;
- }
- return;
- }
-
- std::vector<GeometryOut> buffered_and_unioned;
- geometry::dissolver(rings, buffered_and_unioned);
-
- std::vector<GeometryOut> buffered_and_assembled;
- detail::overlay::assemble<GeometryOut>(buffered_and_unioned,
- std::map<ring_identifier, int>(),
- buffered_and_unioned[0], buffered_and_unioned[0], 1, true, true,
- std::back_inserter(buffered_and_assembled));
-
- buffered = buffered_and_assembled;
-}
-
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SPLITTING_BUFFER_HPP

Deleted: trunk/boost/geometry/extensions/algorithms/buffer/traversing_buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/traversing_buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
+++ (empty file)
@@ -1,89 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, 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_BUFFER_TRAVERSING_BUFFER_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TRAVERSING_BUFFER_HPP
-
-#include <cstddef>
-
-#include <boost/foreach.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <boost/geometry/core/point_type.hpp>
-
-#include <boost/geometry/extensions/strategies/buffer_side.hpp>
-#include <boost/geometry/extensions/algorithms/buffer/intersecting_inserter.hpp>
-#include <boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp>
-#include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
-
-
-#include <boost/geometry/extensions/algorithms/dissolve.hpp>
-
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-
-template
-<
- typename GeometryOut, typename Geometry,
- typename DistanceStrategy,
- typename JoinStrategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , typename Mapper
-#endif
->
-inline void traversing_buffer(Geometry const& geometry,
- std::vector<GeometryOut>& buffered,
- DistanceStrategy const& distance_strategy,
- JoinStrategy const& join_strategy
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- , Mapper& mapper
-#endif
- )
-{
- typedef typename ring_type<GeometryOut>::type ring_type;
- typedef detail::buffer::intersecting_inserter
- <
- std::vector<GeometryOut>
- > inserter_type;
-
-
- inserter_type inserter(buffered);
-
- detail::buffer::linestring_buffer
- <
- Geometry, GeometryOut, DistanceStrategy, JoinStrategy
- >::apply(geometry, inserter, distance_strategy, join_strategy);
-
- std::vector<GeometryOut> buffered_and_assembled;
- detail::overlay::assemble<GeometryOut>(buffered,
- std::map<ring_identifier, int>(),
- buffered[0], buffered[0], 1, true, true,
- std::back_inserter(buffered_and_assembled));
-
- buffered = buffered_and_assembled;
-}
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TRAVERSING_BUFFER_HPP

Modified: trunk/boost/geometry/extensions/strategies/buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/strategies/buffer.hpp (original)
+++ trunk/boost/geometry/extensions/strategies/buffer.hpp 2012-02-18 05:07:18 EST (Sat, 18 Feb 2012)
@@ -59,65 +59,25 @@
 */
 
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
-template
-<
- typename PointIn, typename Mapper
->
-struct join_mapper
-{
- Mapper const& m_mapper;
- join_mapper(Mapper const& mapper)
- : m_mapper(mapper)
- {}
-
- template <typename BufferAppender>
- inline void map(PointIn const& ip, PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2) const
- {
- typename BufferAppender::range_type corner;
- corner.push_back(vertex);
- corner.push_back(perp1);
- corner.push_back(ip);
- corner.push_back(perp2);
- corner.push_back(vertex);
-
- const_cast<Mapper&>(m_mapper).map(corner,
- "opacity:0.4;fill:rgb(255,0,0);stroke:rgb(0,0,0);stroke-width:1");
- }
-};
-#endif
 
 // TODO: merge join_miter with join_round, lot of duplicate code
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
-// Forget this, it will go
-template<typename PointIn, typename PointOut, bool AddHooklets, typename Mapper>
-struct join_miter : public join_mapper<PointIn, Mapper>
-{
- join_miter(Mapper const& mapper) : join_mapper(mapper) {}
-#else
-
-
 template
 <
     typename PointIn,
- typename PointOut,
- bool AddHooklets = true
+ typename PointOut
>
 struct join_miter
 {
-
-#endif
     typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
     typedef typename coordinate_type<PointIn>::type coordinate_type;
 
 
- template <typename BufferAppender>
+ template <typename RangeOut>
     inline void apply(PointIn const& ip, PointIn const& vertex,
                 PointIn const& perp1, PointIn const& perp2,
                 coordinate_type const& buffer_distance,
- BufferAppender& appender) const
+ RangeOut& range_out) const
     {
         coordinate_type zero = 0;
         int signum = buffer_distance > zero ? 1
@@ -126,15 +86,6 @@
 
         if (side::apply(perp1, ip, perp2) == signum)
         {
- if (AddHooklets)
- {
- appender.append_begin_hooklet(perp1);
- appender.append_end_hooklet(perp2);
- }
- else
- {
- appender.append(ip);
- }
         }
         else
         {
@@ -165,26 +116,15 @@
 #endif
             }
 
- appender.append_begin_join(p);
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- map<BufferAppender>(ip, vertex, perp1, perp2);
-#endif
+ range_out.push_back(perp1);
+ range_out.push_back(p);
+ range_out.push_back(perp2);
         }
 
     }
 };
 
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
-// Forget this, it will go
-template<typename PointIn, typename PointOut, typename Mapper>
-struct join_bevel : public join_mapper<PointIn, Mapper>
-{
- join_bevel(Mapper const& mapper) : join_mapper(mapper) {}
-#else
-
-
 template
 <
     typename PointIn,
@@ -192,62 +132,39 @@
>
 struct join_bevel
 {
-#endif
-
-
     typedef typename coordinate_type<PointIn>::type coordinate_type;
 
- template <typename BufferAppender>
+ template <typename RangeOut>
     inline void apply(PointIn const& ip, PointIn const& vertex,
                 PointIn const& perp1, PointIn const& perp2,
                 coordinate_type const& buffer_distance,
- BufferAppender& appender) const
+ RangeOut& range_out) const
     {
- appender.append(perp1);
- appender.append(perp2);
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- map<BufferAppender>(ip, vertex, perp1, perp2);
-#endif
     }
 };
 
 
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
-// Forget this, it will go
-template<typename PointIn, typename PointOut, bool AddHooklets, typename Mapper>
-struct join_round : public join_mapper<PointIn, Mapper>
-{
- join_round(Mapper const& mapper, int max_level = 4)
- : join_mapper(mapper)
- , m_max_level(max_level)
- {}
-#else
-
-
 template
 <
     typename PointIn,
- typename PointOut,
- bool AddHooklets = true
+ typename PointOut
>
 struct join_round
 {
- inline join_round(int max_level = 4)
+ inline join_round(int max_level = 6)
         : m_max_level(max_level)
     {}
-#endif
 
     typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
     typedef typename coordinate_type<PointOut>::type coordinate_type;
     int m_max_level;
 
 
- template <typename BufferAppender>
+ template <typename RangeOut>
     inline void mid_points(PointIn const& vertex,
                 PointIn const& p1, PointIn const& p2,
                 coordinate_type const& buffer_distance,
- BufferAppender& appender,
+ RangeOut& range_out,
                 int level = 1) const
     {
         // Generate 'vectors'
@@ -272,22 +189,22 @@
 
         if (level < m_max_level)
         {
- mid_points(vertex, p1, mid_point, buffer_distance, appender, level + 1);
+ mid_points(vertex, p1, mid_point, buffer_distance, range_out, level + 1);
         }
- appender.append(mid_point);
+ range_out.push_back(mid_point);
         if (level < m_max_level)
         {
- mid_points(vertex, mid_point, p2, buffer_distance, appender, level + 1);
+ mid_points(vertex, mid_point, p2, buffer_distance, range_out, level + 1);
         }
 
     }
 
 
- template <typename BufferAppender>
+ template <typename RangeOut>
     inline void apply(PointIn const& ip, PointIn const& vertex,
                 PointIn const& perp1, PointIn const& perp2,
                 coordinate_type const& buffer_distance,
- BufferAppender& appender) const
+ RangeOut& range_out) const
     {
         coordinate_type zero = 0;
         int signum = buffer_distance > zero ? 1
@@ -296,16 +213,6 @@
 
         if (side::apply(perp1, ip, perp2) == signum)
         {
- // If it is concave (corner to left), add helperline
- if (AddHooklets)
- {
- appender.append_begin_hooklet(perp1);
- appender.append_end_hooklet(perp2);
- }
- else
- {
- appender.append(ip);
- }
         }
         else
         {
@@ -323,25 +230,21 @@
             set<0>(bp, get<0>(vertex) + vix * prop);
             set<1>(bp, get<1>(vertex) + viy * prop);
 
- appender.append_begin_join(perp1);
+ range_out.push_back(perp1);
             if (m_max_level <= 1)
             {
                 if (m_max_level == 1)
                 {
- appender.append(bp);
+ range_out.push_back(bp);
                 }
             }
             else
             {
- mid_points(vertex, perp1, bp, bd, appender);
- appender.append(bp);
- mid_points(vertex, bp, perp2, bd, appender);
+ mid_points(vertex, perp1, bp, bd, range_out);
+ range_out.push_back(bp);
+ mid_points(vertex, bp, perp2, bd, range_out);
             }
- appender.append_end_join(perp2);
-
-#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
- map<BufferAppender>(bp, vertex, perp1, perp2);
-#endif
+ range_out.push_back(perp2);
         }
     }
 };


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