Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83996 - in trunk: boost/geometry/extensions/algorithms/buffer boost/geometry/extensions/strategies libs/geometry/test_extensions/algorithms/buffer
From: barend.gehrels_at_[hidden]
Date: 2013-04-21 06:43:26


Author: barendgehrels
Date: 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
New Revision: 83996
URL: http://svn.boost.org/trac/boost/changeset/83996

Log:
[geometry] Added (draft) versions of point_buffer, multi_point_buffer, end-caps, rounded endcap

Added:
   trunk/boost/geometry/extensions/strategies/buffer_end_flat.hpp (contents, props changed)
   trunk/boost/geometry/extensions/strategies/buffer_end_round.hpp (contents, props changed)
   trunk/boost/geometry/extensions/strategies/buffer_end_skip.hpp (contents, props changed)
   trunk/libs/geometry/test_extensions/algorithms/buffer/multi_point_buffer.cpp (contents, props changed)
   trunk/libs/geometry/test_extensions/algorithms/buffer/point_buffer.cpp (contents, props changed)
Text files modified:
   trunk/boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp | 173 +++++++++++++++++++++++++-----
   trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp | 118 ++++++++++++++------
   trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection_with_mapper.hpp | 21 ++-
   trunk/boost/geometry/extensions/algorithms/buffer/multi_buffer_inserter.hpp | 38 +++++-
   trunk/boost/geometry/extensions/algorithms/buffer/side_on_convex_range.hpp | 5
   trunk/boost/geometry/extensions/strategies/buffer_side.hpp | 6 +
   trunk/libs/geometry/test_extensions/algorithms/buffer/linestring_buffer.cpp | 155 ++++++++++++++------------
   trunk/libs/geometry/test_extensions/algorithms/buffer/multi_linestring_buffer.cpp | 25 +++
   trunk/libs/geometry/test_extensions/algorithms/buffer/multi_polygon_buffer.cpp | 204 ++++++++++++++++++-----------------
   trunk/libs/geometry/test_extensions/algorithms/buffer/polygon_buffer.cpp | 224 ++++++++++++++++++++--------------------
   trunk/libs/geometry/test_extensions/algorithms/buffer/test_buffer.hpp | 132 +++++++++++++++++++---
   11 files changed, 709 insertions(+), 392 deletions(-)

Modified: trunk/boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp (original)
+++ trunk/boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -23,6 +23,7 @@
 #include <boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp>
 #include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
 
+
 #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
 # include <boost/geometry/extensions/algorithms/buffer/buffered_piece_collection_with_mapper.hpp>
 #endif
@@ -88,13 +89,16 @@
         typename Collection,
         typename Iterator,
         typename DistanceStrategy,
- typename JoinStrategy
+ typename JoinStrategy,
+ typename EndStrategy
>
     static inline void iterate(Collection& collection,
                 Iterator begin, Iterator end,
                 buffer_side_selector side,
                 DistanceStrategy const& distance,
- JoinStrategy const& join_strategy, bool close = false)
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy,
+ bool close = false)
     {
         output_point_type previous_p1, previous_p2;
         output_point_type first_p1, first_p2;
@@ -103,9 +107,9 @@
 
         Iterator it = begin;
 
- // We want to memorize the last vector too.
+ // We want to memorize the last segment too.
         typedef BOOST_TYPEOF(*it) point_type;
- point_type last_ip1, last_ip2;
+ point_type penultimate_point, ultimate_point; // last two points from begin/end
 
 
         for (Iterator prev = it++; it != end; ++it)
@@ -113,8 +117,8 @@
             if (! detail::equals::equals_point_point(*prev, *it))
             {
                 output_point_type p1, p2;
- last_ip1 = *prev;
- last_ip2 = *it;
+ penultimate_point = *prev;
+ ultimate_point = *it;
                 generate_side(*prev, *it, side, distance, p1, p2);
 
                 std::vector<output_point_type> range_out;
@@ -150,6 +154,8 @@
             }
         }
 
+ // TODO: take care of degenerate segments
+
         // Might be replaced by specialization
         if(boost::is_same<Tag, ring_tag>::value)
         {
@@ -173,25 +179,105 @@
         }
         else if (boost::is_same<Tag, linestring_tag>::value)
         {
- // Assume flat-end-strategy for now
+
+ // Generate perpendicular points to the reverse side,
+ // these points are necessary for all end-cap strategies
             // TODO fix this (approach) for one-side buffer (1.5 - -1.0)
             output_point_type rp1, rp2;
- generate_side(last_ip2, last_ip1,
+ generate_side(ultimate_point, penultimate_point,
                     side == buffer_side_left
                     ? buffer_side_right
                     : buffer_side_left,
- distance, rp2, rp1);
+ distance, rp2, rp1);
 
- // For flat end:
             std::vector<output_point_type> range_out;
- range_out.push_back(previous_p2);
- if (close)
+
+ end_strategy.apply(penultimate_point, previous_p2, ultimate_point, rp2, side, distance, range_out);
+ collection.add_endcap(end_strategy, range_out, ultimate_point);
+ }
+ }
+};
+
+
+
+template
+<
+ typename Point,
+ typename RingOutput
+>
+struct buffer_point
+{
+ 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;
+
+ typedef typename geometry::select_most_precise
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type<Point>::type,
+ typename geometry::coordinate_type<output_point_type>::type
+ >::type,
+ double
+ >::type promoted_type;
+
+
+ template <typename RangeOut>
+ static inline void generate_points(Point const& point,
+ promoted_type const& buffer_distance,
+ RangeOut& range_out)
+ {
+
+ promoted_type two = 2.0;
+ promoted_type two_pi = two * geometry::math::pi<promoted_type>();
+ int point_buffer_count = 88; // 88 gives now fixed problem (collinear opposite / robustness. TODO: make this value flexible
+
+ promoted_type diff = two_pi / promoted_type(point_buffer_count);
+ promoted_type a = 0;
+
+ output_point_type first;
+ for (int i = 0; i < point_buffer_count; i++, a -= diff)
+ {
+ output_point_type p;
+ set<0>(p, get<0>(point) + buffer_distance * cos(a));
+ set<1>(p, get<1>(point) + buffer_distance * sin(a));
+ range_out.push_back(p);
+ if (i == 0)
             {
- range_out.push_back(rp2);
+ first = p;
             }
- collection.add_piece(buffered_flat_end, range_out);
         }
+
+ // Close it:
+ range_out.push_back(first);
     }
+
+
+ template
+ <
+ typename Collection,
+ typename DistanceStrategy,
+ typename JoinStrategy,
+ typename EndStrategy
+ >
+ static inline void generate_circle(Point const& point,
+ Collection& collection,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy)
+ {
+ std::vector<output_point_type> range_out;
+ //RingOutput range_out;
+
+ generate_points(point,
+ distance.apply(point, point, buffer_side_left),
+ range_out);
+
+ collection.add_piece(buffered_circle, range_out, false);
+
+ //std::cout << std::setprecision(20);
+ //std::cout << geometry::wkt(range_out) << std::endl;
+ }
 };
 
 }} // namespace detail::buffer
@@ -212,6 +298,27 @@
 {};
 
 
+
+template
+<
+ typename Point,
+ typename RingOutput
+>
+struct buffer_inserter<point_tag, Point, RingOutput>
+ : public detail::buffer::buffer_point<Point, RingOutput>
+{
+ template<typename Collection, typename DistanceStrategy, typename JoinStrategy, typename EndStrategy>
+ static inline void apply(Point const& point, Collection& collection,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy)
+ {
+ collection.start_new_ring();
+ generate_circle(point, collection, distance, join_strategy, end_strategy);
+ }
+};
+
+
 template
 <
     typename RingInput,
@@ -232,18 +339,19 @@
 
     template
     <
- typename Collection, typename DistanceStrategy, typename JoinStrategy
+ typename Collection, typename DistanceStrategy, typename JoinStrategy, typename EndStrategy
>
     static inline void apply(RingInput const& ring,
             Collection& collection,
             DistanceStrategy const& distance,
- JoinStrategy const& join_strategy)
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy)
     {
                 if (boost::size(ring) > 3)
                 {
                         base::iterate(collection, boost::begin(ring), boost::end(ring),
                                         buffer_side_left,
- distance, join_strategy);
+ distance, join_strategy, end_strategy);
                 }
     }
 };
@@ -267,21 +375,22 @@
             linestring_tag
> base;
 
- template<typename Collection, typename DistanceStrategy, typename JoinStrategy>
+ template<typename Collection, typename DistanceStrategy, typename JoinStrategy, typename EndStrategy>
     static inline void apply(Linestring const& linestring, Collection& collection,
             DistanceStrategy const& distance,
- JoinStrategy const& join_strategy)
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy)
     {
                 if (boost::size(linestring) > 1)
                 {
                         collection.start_new_ring();
                         base::iterate(collection, boost::begin(linestring), boost::end(linestring),
                                         buffer_side_left,
- distance, join_strategy);
+ distance, join_strategy, end_strategy);
                 
                         base::iterate(collection, boost::rbegin(linestring), boost::rend(linestring),
                                         buffer_side_right,
- distance, join_strategy, true);
+ distance, join_strategy, end_strategy, true);
                 }
 
     }
@@ -296,10 +405,11 @@
 struct buffer_inserter<polygon_tag, PolygonInput, PolygonOutput>
 {
 
- template <typename Collection, typename DistanceStrategy, typename JoinStrategy>
+ template <typename Collection, typename DistanceStrategy, typename JoinStrategy, typename EndStrategy>
     static inline void apply(PolygonInput const& polygon, Collection& collection,
             DistanceStrategy const& distance,
- JoinStrategy const& join_strategy)
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy)
     {
 
         typedef typename ring_type<PolygonInput>::type input_ring_type;
@@ -310,7 +420,7 @@
         {
             collection.start_new_ring();
             policy::apply(exterior_ring(polygon), collection,
- distance, join_strategy);
+ distance, join_strategy, end_strategy);
         }
 
         typename interior_return_type<PolygonInput const>::type rings
@@ -318,7 +428,7 @@
         for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
         {
             collection.start_new_ring();
- policy::apply(*it, collection, distance, join_strategy);
+ policy::apply(*it, collection, distance, join_strategy, end_strategy);
         }
 
     }
@@ -335,13 +445,16 @@
     typename GeometryInput,
     typename OutputIterator,
     typename DistanceStrategy,
- typename JoinStrategy
+ typename JoinStrategy,
+ typename EndStrategy
 #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
+ DistanceStrategy const& distance_strategy,
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy
 #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
             , Mapper& mapper
 #endif
@@ -361,9 +474,11 @@
             typename tag<GeometryInput>::type,
             GeometryInput,
             GeometryOutput
- >::apply(geometry_input, collection, distance_strategy, join_strategy);
+ >::apply(geometry_input, collection, distance_strategy, join_strategy, end_strategy);
 
- collection.get_turns(geometry_input, distance_strategy.factor());
+ //std::cout << "BEGIN GET TURNS" << std::endl;
+ collection.get_turns(geometry_input, distance_strategy);
+ //std::cout << "END GET TURNS" << std::endl;
 
 #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
     //collection.map_offsetted(mapper);

Modified: trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp (original)
+++ trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -55,11 +55,6 @@
 namespace detail { namespace buffer
 {
 
-enum piece_type
-{
- buffered_segment, buffered_join, buffered_flat_end
-};
-
 enum segment_relation_code
 {
     segment_relation_on_left,
@@ -69,9 +64,10 @@
 };
 
 
-// In the end this will go (if we have a multi-point within/covered_by geometry)
-// which is optimized for multi-points and skips linestrings
-template <typename tag>
+// Checks if an intersection point is inside a geometry
+// In some cases a trivial check might be done, e.g. using symmetric distance:
+// the point must be further than the distance from the geometry
+template <typename Tag>
 struct check_original
 {
 };
@@ -79,8 +75,8 @@
 template <>
 struct check_original<polygon_tag>
 {
- template <typename Point, typename Geometry>
- static inline int apply(Point const& point, Geometry const& geometry)
+ template <typename Point, typename Geometry, typename DistanceStrategy>
+ static inline int apply(Point const& point, Geometry const& geometry, DistanceStrategy const& distance_strategy)
     {
         return geometry::covered_by(point, geometry) ? 1 : -1;
     }
@@ -89,8 +85,18 @@
 template <>
 struct check_original<linestring_tag>
 {
- template <typename Point, typename Geometry>
- static inline int apply(Point const& point, Geometry const& geometry)
+ template <typename Point, typename Geometry, typename DistanceStrategy>
+ static inline int apply(Point const& point, Geometry const& geometry, DistanceStrategy const& distance_strategy)
+ {
+ return 0;
+ }
+};
+
+template <>
+struct check_original<point_tag>
+{
+ template <typename Point, typename Geometry, typename DistanceStrategy>
+ static inline int apply(Point const& point, Geometry const& geometry, DistanceStrategy const& distance_strategy)
     {
         return 0;
     }
@@ -416,13 +422,6 @@
             }
         }
 
- int side_helper = side_on_convex_range<side_strategy>(turn.point, pc.helper_segments);
- if (side_helper == 1)
- {
- // Left or outside
- return;
- }
-
         segment_identifier seg_id = pc.first_seg_id;
         if (seg_id.segment_index < 0)
         {
@@ -435,6 +434,29 @@
 
         buffered_ring<Ring> const& ring = offsetted_rings[seg_id.multi_index];
 
+ if (pc.type == buffered_circle)
+ {
+ // The piece is a full (pseudo) circle. There are no helper segments. We only check if it is the turn is inside the generated circle,
+ // or on the border.
+ int const side_wrt_circle = side_on_convex_range< /*relaxed_side<point_type> */ side_strategy >(turn.point,
+ boost::begin(ring) + seg_id.segment_index,
+ boost::begin(ring) + pc.last_segment_index,
+ seg_id, on_segment_seg_id);
+ switch (side_wrt_circle)
+ {
+ case 0 : turn.count_on_offsetted++; break;
+ case -1 : turn.count_within++; break;
+ }
+ return;
+ }
+
+ int side_helper = side_on_convex_range<side_strategy>(turn.point, pc.helper_segments);
+ if (side_helper == 1)
+ {
+ // Left or outside
+ return;
+ }
+
         int const side_offsetted = side_on_convex_range< /*relaxed_side<point_type> */ side_strategy >(turn.point,
                         boost::begin(ring) + seg_id.segment_index,
                         boost::begin(ring) + pc.last_segment_index,
@@ -985,10 +1007,10 @@
         }
     }
 
- template <typename Geometry>
- inline void check_remaining_points(Geometry const& input_geometry, int factor)
+ template <typename Geometry, typename DistanceStrategy>
+ inline void check_remaining_points(Geometry const& input_geometry, DistanceStrategy const& distance_strategy)
     {
- // TODO: this should be done as a collection-of-points, for performance
+ int const factor = distance_strategy.factor();
         for (typename boost::range_iterator<turn_vector_type>::type it =
             boost::begin(m_turns); it != boost::end(m_turns); ++it)
         {
@@ -997,7 +1019,7 @@
                 int code = check_original
                         <
                             typename geometry::tag<Geometry>::type
- >::apply(it->point, input_geometry);
+ >::apply(it->point, input_geometry, distance_strategy);
                 if (code * factor == 1)
                 {
                     it->location = inside_original;
@@ -1053,8 +1075,9 @@
 
     }
 
- template <typename Geometry>
- inline void get_turns(Geometry const& input_geometry, int factor)
+
+ template <typename Geometry, typename DistanceStrategy>
+ inline void get_turns(Geometry const& input_geometry, DistanceStrategy const& distance_strategy)
     {
         // Now: quadratic
         // TODO use partition
@@ -1101,10 +1124,7 @@
         classify_turns();
         classify_inside();
 
- if (boost::is_same<typename tag_cast<typename tag<Geometry>::type, areal_tag>::type, areal_tag>())
- {
- check_remaining_points(input_geometry, factor);
- }
+ check_remaining_points(input_geometry, distance_strategy);
     }
 
     inline void start_new_ring()
@@ -1130,7 +1150,9 @@
         return offsetted_rings.back().size();
     }
 
- inline piece& add_piece(piece_type type, bool decrease_by_one)
+ //-------------------------------------------------------------------------
+
+ inline piece& add_piece(piece_type type, bool decrease_segment_index_by_one)
     {
         piece pc;
         pc.type = type;
@@ -1138,7 +1160,7 @@
         pc.first_seg_id = current_segment_id;
 
         std::size_t const n = boost::size(offsetted_rings.back());
- pc.first_seg_id.segment_index = decrease_by_one ? n - 1 : n;
+ pc.first_seg_id.segment_index = decrease_segment_index_by_one ? n - 1 : n;
 
         m_pieces.push_back(pc);
         return m_pieces.back();
@@ -1147,15 +1169,19 @@
     inline void add_piece(piece_type type, point_type const& p1, point_type const& p2,
             point_type const& b1, point_type const& b2)
     {
+ // If the last type was a join, the segment_id of next segment should be decreased by one.
         bool const last_type_join = ! m_pieces.empty()
                 && m_pieces.back().first_seg_id.multi_index == current_segment_id.multi_index
- && m_pieces.back().type == buffered_join;
+ && (
+ m_pieces.back().type == buffered_join
+ || m_pieces.back().type == buffered_round_end
+ );
 
         piece& pc = add_piece(type, last_type_join);
 
- // If it follows the same piece-type point both should be added.
+ // If it follows a non-join (so basically the same piece-type) point b1 should be added.
         // There should be two intersections later and it should be discarded.
- // But for need it to calculate intersections
+ // But for now we need it to calculate intersections
         if (! last_type_join)
         {
             add_point(b1);
@@ -1169,9 +1195,9 @@
     }
 
     template <typename Range>
- inline piece& add_piece(piece_type type, Range const& range)
+ inline piece& add_piece(piece_type type, Range const& range, bool decrease_segment_index_by_one)
     {
- piece& pc = add_piece(type, true);
+ piece& pc = add_piece(type, decrease_segment_index_by_one);
 
         bool first = true;
         int last = offsetted_rings.back().size() + 1;
@@ -1201,7 +1227,7 @@
     template <typename Range>
     inline void add_piece(piece_type type, point_type const& p, Range const& range)
     {
- piece& pc = add_piece(type, range);
+ piece& pc = add_piece(type, range, true);
 
         if (boost::size(range) > 0)
         {
@@ -1211,6 +1237,24 @@
         }
     }
 
+ template <typename EndcapStrategy, typename Range>
+ inline void add_endcap(EndcapStrategy const& strategy, Range const& range, point_type const& end_point)
+ {
+ piece_type pt = strategy.get_piece_type();
+ if (pt == buffered_flat_end)
+ {
+ // It is flat, should just be added, without helper segments
+ add_piece(pt, range, true);
+ }
+ else
+ {
+ // Normal case, it has an "inside", helper segments should be added
+ add_piece(pt, end_point, range);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+
     inline void enrich()
     {
         typedef typename strategy::side::services::default_strategy

Modified: trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection_with_mapper.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection_with_mapper.hpp (original)
+++ trunk/boost/geometry/extensions/algorithms/buffer/buffered_piece_collection_with_mapper.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -160,14 +160,17 @@
 
                         segment_identifier seg_id = it->first_seg_id;
 
- buffered_ring<Ring> const& ring = offsetted_rings[seg_id.multi_index];
+ if (seg_id.segment_index >= 0)
+ {
+ buffered_ring<Ring> const& ring = offsetted_rings[seg_id.multi_index];
 
- std::copy(boost::begin(ring) + seg_id.segment_index,
- boost::begin(ring) + it->last_segment_index,
- std::back_inserter(corner));
- std::copy(boost::begin(it->helper_segments),
- boost::end(it->helper_segments),
- std::back_inserter(corner));
+ std::copy(boost::begin(ring) + seg_id.segment_index,
+ boost::begin(ring) + it->last_segment_index,
+ std::back_inserter(corner));
+ std::copy(boost::begin(it->helper_segments),
+ boost::end(it->helper_segments),
+ std::back_inserter(corner));
+ }
 
                         {
                                 // Corners of onesided buffers are empty.
@@ -181,7 +184,7 @@
                                 geometry::unique(corner);
                         }
 
- if (pieces)
+ if (pieces && ! corner.empty())
             {
                 if (it->type == buffered_segment)
                 {
@@ -200,7 +203,7 @@
                 }
             }
 
- if (indices)
+ if (indices && ! corner.empty())
             {
 
                 // Put starting piece_index / segment_index in centroid

Modified: trunk/boost/geometry/extensions/algorithms/buffer/multi_buffer_inserter.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/multi_buffer_inserter.hpp (original)
+++ trunk/boost/geometry/extensions/algorithms/buffer/multi_buffer_inserter.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -13,6 +13,7 @@
 #include <boost/typeof/typeof.hpp>
 
 #include <boost/geometry/multi/core/point_type.hpp>
+#include <boost/geometry/multi/algorithms/distance.hpp>
 
 #include <boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp>
 
@@ -27,8 +28,8 @@
 template <>
 struct check_original<multi_polygon_tag>
 {
- template <typename Point, typename Geometry>
- static inline int apply(Point const& point, Geometry const& geometry)
+ template <typename Point, typename Geometry, typename DistanceStrategy>
+ static inline int apply(Point const& point, Geometry const& geometry, DistanceStrategy const& distance_strategy)
     {
         return geometry::covered_by(point, geometry) ? 1 : -1;
     }
@@ -37,13 +38,25 @@
 template <>
 struct check_original<multi_linestring_tag>
 {
- template <typename Point, typename Geometry>
- static inline int apply(Point const& point, Geometry const& geometry)
+ template <typename Point, typename Geometry, typename DistanceStrategy>
+ static inline int apply(Point const& point, Geometry const& geometry, DistanceStrategy const& distance_strategy)
     {
         return 0;
     }
 };
 
+template <>
+struct check_original<multi_point_tag>
+{
+ template <typename Point, typename Geometry, typename DistanceStrategy>
+ static inline int apply(Point const& point, Geometry const& geometry, DistanceStrategy const& distance_strategy)
+ {
+ return 0;
+ //auto dist = boost::geometry::distance(point, geometry);
+ //auto d2 = distance_strategy.apply(point, point, buffer_side_left) * 0.99; // TODO: depends on chord length
+ //return (dist < d2) ? 1 : -1;
+ }
+};
 
 template
 <
@@ -54,12 +67,13 @@
 {
     template
     <
- typename Collection, typename DistanceStrategy, typename JoinStrategy
+ typename Collection, typename DistanceStrategy, typename JoinStrategy, typename EndStrategy
>
     static inline void apply(Multi const& multi,
             Collection& collection,
             DistanceStrategy const& distance,
- JoinStrategy const& join_strategy)
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy)
     {
         typedef typename geometry::ring_type<PolygonOutput>::type output_ring_type;
         typedef dispatch::buffer_inserter
@@ -77,7 +91,7 @@
             it != boost::end(multi);
             ++it)
         {
- policy::apply(*it, collection, distance, join_strategy);
+ policy::apply(*it, collection, distance, join_strategy, end_strategy);
         }
     }
 };
@@ -111,6 +125,16 @@
 {};
 
 
+template
+<
+ typename Multi,
+ typename PolygonOutput
+>
+struct buffer_inserter<multi_point_tag, Multi, PolygonOutput>
+ : public detail::buffer::multi_buffer_inserter<Multi, PolygonOutput>
+{};
+
+
 } // namespace dispatch
 #endif // DOXYGEN_NO_DISPATCH
 

Modified: trunk/boost/geometry/extensions/algorithms/buffer/side_on_convex_range.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algorithms/buffer/side_on_convex_range.hpp (original)
+++ trunk/boost/geometry/extensions/algorithms/buffer/side_on_convex_range.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -55,6 +55,11 @@
 template <typename SideStrategy, typename Point, typename Range>
 inline int side_on_convex_range(Point const& subject, Range const& range)
 {
+ if (boost::empty(range))
+ {
+ return 1;
+ }
+
     bool has_collinear = false;
 
     typedef typename boost::range_iterator

Added: trunk/boost/geometry/extensions/strategies/buffer_end_flat.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/strategies/buffer_end_flat.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -0,0 +1,97 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 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_EXTENSIONS_STRATEGIES_BUFFER_END_FLAT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_END_FLAT_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace buffer
+{
+
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+class end_flat
+{
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
+ typedef typename coordinate_type<PointOut>::type coordinate_type;
+
+ typedef typename geometry::select_most_precise
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type<PointIn>::type,
+ typename geometry::coordinate_type<PointOut>::type
+ >::type,
+ double
+ >::type promoted_type;
+
+
+public :
+
+ template <typename RangeOut, typename DistanceStrategy>
+ inline void apply(PointIn const& penultimate_point,
+ PointIn const& perp_left_point,
+ PointIn const& ultimate_point,
+ PointIn const& perp_right_point,
+ buffer_side_selector side,
+ DistanceStrategy const& distance,
+ RangeOut& range_out) const
+ {
+ promoted_type const dist_left = distance.apply(penultimate_point, ultimate_point, buffer_side_left);
+ promoted_type const dist_right = distance.apply(penultimate_point, ultimate_point, buffer_side_right);
+
+ bool reversed = (side == buffer_side_left && dist_right < 0 && -dist_right > dist_left)
+ || (side == buffer_side_right && dist_left < 0 && -dist_left > dist_right)
+ ;
+ if (reversed)
+ {
+ range_out.push_back(perp_right_point);
+ range_out.push_back(perp_left_point);
+ }
+ else
+ {
+ range_out.push_back(perp_left_point);
+ range_out.push_back(perp_right_point);
+ }
+ // Don't add the ultimate_point (endpoint of the linestring).
+ // The buffer might be generated completely at one side.
+ // In other cases it does no harm but is further useless
+ }
+
+ static inline piece_type get_piece_type()
+ {
+ return buffered_flat_end;
+ }
+};
+
+
+}} // namespace strategy::buffer
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_END_FLAT_HPP

Added: trunk/boost/geometry/extensions/strategies/buffer_end_round.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/strategies/buffer_end_round.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -0,0 +1,141 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 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_EXTENSIONS_STRATEGIES_BUFFER_END_ROUND_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_END_ROUND_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace buffer
+{
+
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+class end_round
+{
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
+ typedef typename coordinate_type<PointOut>::type coordinate_type;
+
+ typedef typename geometry::select_most_precise
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type<PointIn>::type,
+ typename geometry::coordinate_type<PointOut>::type
+ >::type,
+ double
+ >::type promoted_type;
+
+ int m_steps_per_circle;
+
+ template <typename RangeOut>
+ inline void generate_points(PointIn const& point,
+ promoted_type alpha,
+ promoted_type const& buffer_distance,
+ RangeOut& range_out) const
+ {
+ promoted_type const two = 2.0;
+ promoted_type const two_pi = two * geometry::math::pi<promoted_type>();
+
+ int point_buffer_count = m_steps_per_circle;
+
+ promoted_type const diff = two_pi / promoted_type(point_buffer_count);
+
+ // For half circle:
+ point_buffer_count /= 2;
+ point_buffer_count++;
+
+ for (int i = 0; i < point_buffer_count; i++, alpha -= diff)
+ {
+ typename boost::range_value<RangeOut>::type p;
+ set<0>(p, get<0>(point) + buffer_distance * cos(alpha));
+ set<1>(p, get<1>(point) + buffer_distance * sin(alpha));
+ range_out.push_back(p);
+ }
+ }
+
+ // COPIED FROM OCCUPATION_INFO
+ template <typename T, typename P1, typename P2>
+ static inline T calculate_angle(P1 const& from_point, P2 const& to_point)
+ {
+ typedef P1 vector_type;
+ vector_type v = from_point;
+ geometry::subtract_point(v, to_point);
+ return atan2(geometry::get<1>(v), geometry::get<0>(v));
+ }
+
+public :
+ inline end_round(int steps_per_circle = 100)
+ : m_steps_per_circle(steps_per_circle)
+ {}
+
+ template <typename RangeOut, typename DistanceStrategy>
+ inline void apply(PointIn const& penultimate_point,
+ PointIn const& perp_left_point,
+ PointIn const& ultimate_point,
+ PointIn const& perp_right_point,
+ buffer_side_selector side,
+ DistanceStrategy const& distance,
+ RangeOut& range_out) const
+ {
+ promoted_type alpha = calculate_angle<promoted_type>(perp_left_point, ultimate_point);
+
+ promoted_type const dist_left = distance.apply(penultimate_point, ultimate_point, buffer_side_left);
+ promoted_type const dist_right = distance.apply(penultimate_point, ultimate_point, buffer_side_right);
+ if (geometry::math::equals(dist_left, dist_right))
+ {
+ generate_points(ultimate_point, alpha, dist_left, range_out);
+ }
+ else
+ {
+ promoted_type const two = 2.0;
+ promoted_type dist_half_diff = (dist_left - dist_right) / two;
+
+ if (side == buffer_side_right)
+ {
+ dist_half_diff = -dist_half_diff;
+ }
+
+ PointIn shifted_point;
+ set<0>(shifted_point, get<0>(ultimate_point) + dist_half_diff * cos(alpha));
+ set<1>(shifted_point, get<1>(ultimate_point) + dist_half_diff * sin(alpha));
+ generate_points(shifted_point, alpha, (dist_left + dist_right) / two, range_out);
+ }
+ }
+
+ static inline piece_type get_piece_type()
+ {
+ return buffered_round_end;
+ }
+};
+
+
+}} // namespace strategy::buffer
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_END_ROUND_HPP

Added: trunk/boost/geometry/extensions/strategies/buffer_end_skip.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/strategies/buffer_end_skip.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -0,0 +1,64 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 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_EXTENSIONS_STRATEGIES_BUFFER_END_SKIP_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_END_SKIP_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace buffer
+{
+
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+class end_skip
+{
+public :
+
+ template <typename RangeOut, typename DistanceStrategy>
+ inline void apply(PointIn const& ,
+ PointIn const& ,
+ PointIn const& ,
+ PointIn const& ,
+ buffer_side_selector ,
+ DistanceStrategy const& ,
+ RangeOut& ) const
+ {
+ }
+
+ static inline piece_type get_piece_type()
+ {
+ return buffered_flat_end;
+ }
+};
+
+
+}} // namespace strategy::buffer
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_END_SKIP_HPP

Modified: trunk/boost/geometry/extensions/strategies/buffer_side.hpp
==============================================================================
--- trunk/boost/geometry/extensions/strategies/buffer_side.hpp (original)
+++ trunk/boost/geometry/extensions/strategies/buffer_side.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -24,6 +24,12 @@
 // or probably there will be more enum's or constants for the buffer
 enum buffer_side_selector { buffer_side_left, buffer_side_right };
 
+// Piece type, temporary here, might be reloaced TODO decid this
+enum piece_type
+{
+ buffered_segment, buffered_join, buffered_round_end, buffered_flat_end, buffered_circle
+};
+
 
 
 }} // namespace boost::geometry

Modified: trunk/libs/geometry/test_extensions/algorithms/buffer/linestring_buffer.cpp
==============================================================================
--- trunk/libs/geometry/test_extensions/algorithms/buffer/linestring_buffer.cpp (original)
+++ trunk/libs/geometry/test_extensions/algorithms/buffer/linestring_buffer.cpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -7,9 +7,9 @@
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-//#define BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+#define BOOST_GEOMETRY_DEBUG_WITH_MAPPER
 //#define BOOST_GEOMETRY_DEBUG_ASSEMBLE
-//#define BOOST_GEOMETRY_DEBUG_IDENTIFIER
+#define BOOST_GEOMETRY_DEBUG_IDENTIFIER
 
 #include <geometry_test_common.hpp>
 
@@ -48,7 +48,8 @@
     namespace buf = bg::strategy::buffer;
     typedef bg::model::linestring<P> linestring;
     typedef bg::model::polygon<P> polygon;
- double const aimes_width = 0.000018;
+ //double const aimes_width = 0.000018;
+ double const aimes_width = 0.000072;
 
         static std::string const aimes1 = "LINESTRING(-3.031075 52.22385,-3.030809 52.223579,-3.030424 52.223207,-3.030212 52.222931,-3.030013 52.222764,-3.029721 52.222584,-3.029469 52.222443,-3.029218 52.222319,-3.028886 52.222187,-3.028859 52.222176,-3.028815 52.222158,-3.028563 52.222016,-3.028462 52.221945,-3.028407 52.221881,-3.028351 52.22179,-3.028301 52.221718,-3.028203 52.221601,-3.028151 52.221552,-3.027982 52.221422,-3.027871 52.221353,-3.027755 52.221293,-3.027573 52.22121,-3.027493 52.221179,-3.027463 52.221165,-3.027147 52.221065,-3.027045 52.221039,-3.026812 52.220989,-3.026691 52.220968,-3.026602 52.220957,-3.026111 52.220898,-3.025715 52.220861,-3.025332 52.220842,-3.025011 52.220845,-3.024587 52.220849,-3.024339 52.220869,-3.024213 52.220881,-3.024103 52.220905,-3.023904 52.220966,-3.023687 52.221027,-3.023575 52.221054,-3.023409 52.221077,-3.023317 52.221072,-3.023259 52.221049,-3.023028 52.220905,-3.022859 52.220819,-3.022799 52.220774,-3.022739 52.220688)";
         static std::string const aimes2 = "LINESTRING(-3.056646 52.20421,-3.055298 52.204143,-3.054991 52.204119,-3.053966 52.204125,-3.053793 52.204126)";
@@ -71,26 +72,27 @@
         static std::string const aimes19 = "LINESTRING(-3.001027 52.270697,-3.001233 52.270714,-3.00157 52.270711,-3.001614 52.270715,-3.001658 52.270719,-3.001746 52.270736,-3.002 52.270828)";
         static std::string const aimes20 = "LINESTRING(-3.002514 52.270973,-3.002616 52.270954,-3.00282 52.270916,-3.002878 52.27088,-3.002978 52.270771,-3.003022 52.270752,-3.003066 52.270743,-3.003124 52.270734)";
 
- test_one<linestring, buf::join_miter, polygon>("aimes1", aimes1, 'm', 3.41515232094025e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes2", aimes2, 'm', 1.02802331980456e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes3", aimes3, 'm', 3.56112451527224e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes4", aimes4, 'm', 4.25305444196056e-008, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes5", aimes5, 'm', 3.69520876120077e-008, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes6", aimes6, 'm', 3.12580681338659e-008, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes7", aimes7, 'm', 2.64535032101776e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes8", aimes8, 'm', 1.26452604831684e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes9", aimes9, 'm', 5.62396706982327e-008, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes10", aimes10, 'm', 7.03945403301987e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes11", aimes11, 'm', 2.05895901217446e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes12", aimes12, 'm', 1.01571146160495e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes13", aimes13, 'm', 2.42559636376427e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes14", aimes14, 'm', 3.41515232094025e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes15", aimes15, 'm', 9.08697614931953e-008, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes16", aimes16, 'm', 6.0466163631645e-008, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes17", aimes17, 'm', 4.04659118657946e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes18", aimes18, 'm', 4.80904560618001e-007, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes19", aimes19, 'm', 3.57066625156222e-008, aimes_width, aimes_width);
- test_one<linestring, buf::join_miter, polygon>("aimes20", aimes20, 'm', 2.44433664420285e-008, aimes_width, aimes_width);
+ //test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes1", aimes1, 3.41515232094025e-007, aimes_width, aimes_width);
+ //test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes2", aimes2, 1.02802331980456e-007, aimes_width, aimes_width);
+ //test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes3", aimes3, 3.56112451527224e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes4", aimes4, 4.25305444196056e-008, aimes_width, aimes_width);
+ return;
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes5", aimes5, 3.69520876120077e-008, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes6", aimes6, 3.12580681338659e-008, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes7", aimes7, 2.64535032101776e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes8", aimes8, 1.26452604831684e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes9", aimes9, 5.62396706982327e-008, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes10", aimes10, 7.03945403301987e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes11", aimes11, 2.05895901217446e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes12", aimes12, 1.01571146160495e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes13", aimes13, 2.42559636376427e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes14", aimes14, 3.41515232094025e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes15", aimes15, 9.08697614931953e-008, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes16", aimes16, 6.0466163631645e-008, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes17", aimes17, 4.04659118657946e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes18", aimes18, 4.80904560618001e-007, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes19", aimes19, 3.57066625156222e-008, aimes_width, aimes_width);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("aimes20", aimes20, 2.44433664420285e-008, aimes_width, aimes_width);
 
 /* PostGIS:
 with viewy as
@@ -150,60 +152,69 @@
     typedef bg::model::linestring<P> linestring;
     typedef bg::model::polygon<P> polygon;
 
- test_one<linestring, buf::join_round, polygon>("simplex", simplex, 'r', 19.209, 1.5, 1.5);
- test_one<linestring, buf::join_miter, polygon>("simplex", simplex, 'm', 19.209, 1.5, 1.5);
-
- test_one<linestring, buf::join_miter, polygon>("simplex_asym_neg", simplex, 'm', 3.202, +1.5, -1.0);
- test_one<linestring, buf::join_miter, polygon>("simplex_asym_pos", simplex, 'm', 3.202, -1.0, +1.5);
-
- // Generates a reverse polygon, which will be empty TODO decide about this
- // test_one<linestring, buf::join_miter, polygon>("simplex_asym_pos", simplex, 'm', 0, -1.5, +1.0);
-
- //test_one<linestring, buf::join_round, polygon>("straight", straight, 'r', 19.2093727122985, 1.5, 1.5);
- //test_one<linestring, buf::join_miter, polygon>("straight", straight, 'm', 19.2093727122985, 1.5, 1.5);
-
- test_one<linestring, buf::join_round, polygon>("one_bend", one_bend, 'r', 28.488, 1.5, 1.5);
- test_one<linestring, buf::join_miter, polygon>("one_bend", one_bend, 'm', 28.696, 1.5, 1.5);
- test_one<linestring, buf::join_round_by_divide, polygon>("one_bend", one_bend, 'd', 28.488, 1.5, 1.5);
-
- test_one<linestring, buf::join_round, polygon>("two_bends", two_bends, 'r', 39.235, 1.5, 1.5);
- test_one<linestring, buf::join_round_by_divide, polygon>("two_bends", two_bends, 'd', 39.235, 1.5, 1.5);
- test_one<linestring, buf::join_miter, polygon>("two_bends", two_bends, 'm', 39.513, 1.5, 1.5);
- test_one<linestring, buf::join_round, polygon>("two_bends_left", two_bends, 'r', 20.028, 1.5, 0.0);
- test_one<linestring, buf::join_miter, polygon>("two_bends_left", two_bends, 'm', 20.225, 1.5, 0.0);
- test_one<linestring, buf::join_round, polygon>("two_bends_right", two_bends, 'r', 19.211, 0.0, 1.5);
- test_one<linestring, buf::join_miter, polygon>("two_bends_right", two_bends, 'm', 19.288, 0.0, 1.5);
+ // Simplex (join-type is not relevant)
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("simplex", simplex, 19.209, 1.5, 1.5);
+ test_one<linestring, buf::join_miter, buf::end_round, polygon>("simplex", simplex, 26.2733, 1.5, 1.5);
+
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("simplex_asym_neg", simplex, 3.202, +1.5, -1.0);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("simplex_asym_pos", simplex, 3.202, -1.0, +1.5);
+ // Do not work yet:
+ //test_one<linestring, buf::join_miter, buf::end_round, polygon>("simplex_asym_neg", simplex, 3.202, +1.5, -1.0);
+ //test_one<linestring, buf::join_miter, buf::end_round, polygon>("simplex_asym_pos", simplex, 3.202, -1.0, +1.5);
+
+ // Generates a reverse polygon, with a negative area, which will be made empty TODO decide about this
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("simplex_asym_neg_rev", simplex, 0, +1.0, -1.5);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("simplex_asym_pos_rev", simplex, 0, -1.5, +1.0);
+
+ //test_one<linestring, buf::join_round, buf::end_flat, polygon>("straight", straight, 19.2093727122985, 1.5, 1.5);
+ //test_one<linestring, buf::join_miter, buf::end_flat, polygon>("straight", straight, 19.2093727122985, 1.5, 1.5);
+
+ // One bend/two bends (tests join-type)
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("one_bend", one_bend, 28.488, 1.5, 1.5);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("one_bend", one_bend, 28.696, 1.5, 1.5);
+ test_one<linestring, buf::join_round_by_divide, buf::end_flat, polygon>("one_bend", one_bend, 28.488, 1.5, 1.5);
+
+ test_one<linestring, buf::join_round, buf::end_round, polygon>("one_bend", one_bend, 35.5603, 1.5, 1.5);
+ test_one<linestring, buf::join_miter, buf::end_round, polygon>("one_bend", one_bend, 35.7601, 1.5, 1.5);
+
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("two_bends", two_bends, 39.235, 1.5, 1.5);
+ test_one<linestring, buf::join_round_by_divide, buf::end_flat, polygon>("two_bends", two_bends, 39.235, 1.5, 1.5);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("two_bends", two_bends, 39.513, 1.5, 1.5);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("two_bends_left", two_bends, 20.028, 1.5, 0.0);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("two_bends_left", two_bends, 20.225, 1.5, 0.0);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("two_bends_right", two_bends, 19.211, 0.0, 1.5);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("two_bends_right", two_bends, 19.288, 0.0, 1.5);
 
 
         // Next (and all similar cases) which a offsetted-one-sided buffer has to be fixed. TODO
- //test_one<linestring, buf::join_miter, polygon>("two_bends_neg", two_bends, 'm', 99, +1.5, -1.0);
- //test_one<linestring, buf::join_miter, polygon>("two_bends_pos", two_bends, 'm', 99, -1.5, +1.0);
- //test_one<linestring, buf::join_round, polygon>("two_bends_neg", two_bends, 'r', 99, +1.5, -1.0);
- //test_one<linestring, buf::join_round, polygon>("two_bends_pos", two_bends, 'r', 99, -1.5, +1.0);
+ //test_one<linestring, buf::join_miter, buf::end_flat, polygon>("two_bends_neg", two_bends, 99, +1.5, -1.0);
+ //test_one<linestring, buf::join_miter, buf::end_flat, polygon>("two_bends_pos", two_bends, 99, -1.5, +1.0);
+ //test_one<linestring, buf::join_round, buf::end_flat, polygon>("two_bends_neg", two_bends, 99, +1.5, -1.0);
+ //test_one<linestring, buf::join_round, buf::end_flat, polygon>("two_bends_pos", two_bends, 99, -1.5, +1.0);
 
- test_one<linestring, buf::join_round, polygon>("overlapping150", overlapping, 'r', 65.646, 1.5, 1.5);
- test_one<linestring, buf::join_miter, polygon>("overlapping150", overlapping, 'm', 68.140, 1.5, 1.5);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("overlapping150", overlapping, 65.6786, 1.5, 1.5);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("overlapping150", overlapping, 68.140, 1.5, 1.5);
         // Different cases with intersection points on flat and (left/right from line itself)
- test_one<linestring, buf::join_round, polygon>("overlapping_asym_150_010", overlapping, 'r', 48.308, 1.5, 0.25);
- test_one<linestring, buf::join_miter, polygon>("overlapping_asym_150_010", overlapping, 'm', 50.770, 1.5, 0.25);
- test_one<linestring, buf::join_round, polygon>("overlapping_asym_150_075", overlapping, 'r', 58.506, 1.5, 0.75);
- test_one<linestring, buf::join_miter, polygon>("overlapping_asym_150_075", overlapping, 'm', 60.985, 1.5, 0.75);
- test_one<linestring, buf::join_round, polygon>("overlapping_asym_150_100", overlapping, 'r', 62.514, 1.5, 1.0);
- test_one<linestring, buf::join_miter, polygon>("overlapping_asym_150_100", overlapping, 'm', 64.984, 1.5, 1.0);
-
- test_one<linestring, buf::join_round, polygon>("for_collinear", for_collinear, 'r', 68.561, 2.0, 2.0);
- test_one<linestring, buf::join_miter, polygon>("for_collinear", for_collinear, 'm', 72, 2.0, 2.0);
- test_one<linestring, buf::join_round, polygon>("for_collinear2", for_collinear2, 'r', 74.387, 2.0, 2.0);
- test_one<linestring, buf::join_miter, polygon>("for_collinear2", for_collinear2, 'm', 78.0, 2.0, 2.0);
-
- //test_one<linestring, buf::join_round, polygon>("curve", curve, 'r', 99, 5.0, 3.0);
- //test_one<linestring, buf::join_miter, polygon>("curve", curve, 'm', 99, 5.0, 3.0);
-
- test_one<linestring, buf::join_round, polygon>("chained2", chained2, 'r', 11.3137, 2.5, 1.5);
- test_one<linestring, buf::join_round, polygon>("chained3", chained3, 'r', 16.9706, 2.5, 1.5);
- test_one<linestring, buf::join_round, polygon>("chained4", chained4, 'r', 22.6274, 2.5, 1.5);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("overlapping_asym_150_010", overlapping, 48.308, 1.5, 0.25);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("overlapping_asym_150_010", overlapping, 50.770, 1.5, 0.25);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("overlapping_asym_150_075", overlapping, 58.506, 1.5, 0.75);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("overlapping_asym_150_075", overlapping, 60.985, 1.5, 0.75);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("overlapping_asym_150_100", overlapping, 62.514, 1.5, 1.0);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("overlapping_asym_150_100", overlapping, 64.984, 1.5, 1.0);
+
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("for_collinear", for_collinear, 68.561, 2.0, 2.0);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("for_collinear", for_collinear, 72, 2.0, 2.0);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("for_collinear2", for_collinear2, 74.387, 2.0, 2.0);
+ test_one<linestring, buf::join_miter, buf::end_flat, polygon>("for_collinear2", for_collinear2, 78.0, 2.0, 2.0);
+
+ //test_one<linestring, buf::join_round, buf::end_flat, polygon>("curve", curve, 99, 5.0, 3.0);
+ //test_one<linestring, buf::join_miter, buf::end_flat, polygon>("curve", curve, 99, 5.0, 3.0);
+
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("chained2", chained2, 11.3137, 2.5, 1.5);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("chained3", chained3, 16.9706, 2.5, 1.5);
+ test_one<linestring, buf::join_round, buf::end_flat, polygon>("chained4", chained4, 22.6274, 2.5, 1.5);
 
- //test_one<linestring, buf::join_round, polygon>("reallife1", reallife1, 'r', 99, 16.5, 6.5);
+ //test_one<linestring, buf::join_round, buf::end_flat, polygon>("reallife1", reallife1, 99, 16.5, 6.5);
 }
 
 
@@ -218,7 +229,7 @@
     test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
     //test_all<bg::model::point<tt, 2, bg::cs::cartesian> >();
 
- // test_aimes<bg::model::point<double, 2, bg::cs::cartesian> >();
+ //test_aimes<bg::model::point<double, 2, bg::cs::cartesian> >();
 
     return 0;
 }

Modified: trunk/libs/geometry/test_extensions/algorithms/buffer/multi_linestring_buffer.cpp
==============================================================================
--- trunk/libs/geometry/test_extensions/algorithms/buffer/multi_linestring_buffer.cpp (original)
+++ trunk/libs/geometry/test_extensions/algorithms/buffer/multi_linestring_buffer.cpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -22,6 +22,7 @@
 
 static std::string const simplex = "MULTILINESTRING((0 0,4 5),(5 4,10 0))";
 static std::string const two_bends = "MULTILINESTRING((0 0,4 5,7 4,10 6),(1 5,5 9,8 6))";
+static std::string const turn_inside = "MULTILINESTRING((0 0,4 5,7 4,10 6),(1 5,5 9,8 6),(0 4,-2 6))";
 
 
 template <typename P>
@@ -32,11 +33,25 @@
     typedef bg::model::multi_linestring<linestring> multi_linestring_type;
     typedef bg::model::polygon<P> polygon;
 
- test_one<multi_linestring_type, buf::join_round, polygon>("simplex", simplex, 'r', 38.2623, 1.5, 1.5);
- test_one<multi_linestring_type, buf::join_round, polygon>("two_bends", two_bends, 'r', 64.6217, 1.5, 1.5);
- test_one<multi_linestring_type, buf::join_round_by_divide, polygon>("two_bends", two_bends, 'd', 64.6217, 1.5, 1.5);
- test_one<multi_linestring_type, buf::join_miter, polygon>("two_bends", two_bends, 'm', 65.1834, 1.5, 1.5);
- test_one<multi_linestring_type, buf::join_round, polygon>("two_bends_asym", two_bends, 'm', 52.3793, 1.5, 0.75);
+ // Round joins / round ends
+ test_one<multi_linestring_type, buf::join_round, buf::end_round, polygon>("simplex", simplex, 49.0217, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_round, buf::end_round, polygon>("two_bends", two_bends, 74.73, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_round, buf::end_round, polygon>("turn_inside", turn_inside, 86.3313, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_round, buf::end_round, polygon>("two_bends_asym", two_bends, 58.3395, 1.5, 0.75);
+
+ // Round joins / flat ends:
+ test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("simplex", simplex, 38.2623, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("two_bends", two_bends, 64.6217, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("turn_inside", turn_inside, 99, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("two_bends_asym", two_bends, 52.3793, 1.5, 0.75);
+
+ // This one is far from done:
+ // test_one<multi_linestring_type, buf::join_round, polygon>("turn_inside_asym_neg", turn_inside, 99, +1.5, -1.0);
+
+ // Miter / divide joins, various ends
+ test_one<multi_linestring_type, buf::join_round_by_divide, buf::end_flat, polygon>("two_bends", two_bends, 64.6217, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_miter, buf::end_flat, polygon>("two_bends", two_bends, 65.1834, 1.5, 1.5);
+ test_one<multi_linestring_type, buf::join_miter, buf::end_round, polygon>("two_bends", two_bends, 75.2917, 1.5, 1.5);
 }
 
 

Added: trunk/libs/geometry/test_extensions/algorithms/buffer/multi_point_buffer.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/test_extensions/algorithms/buffer/multi_point_buffer.cpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -0,0 +1,211 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-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)
+
+//#define BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+//#define BOOST_GEOMETRY_DEBUG_ASSEMBLE
+//#define BOOST_GEOMETRY_DEBUG_IDENTIFIER
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/buffer.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/box.hpp>
+
+#include <test_buffer.hpp>
+
+#include <boost/geometry/multi/multi.hpp> // TODO: more specific
+#include <boost/geometry/multi/geometries/multi_geometries.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/multi_buffer_inserter.hpp>
+
+
+static std::string const simplex = "MULTIPOINT((5 5),(7 7))";
+static std::string const three = "MULTIPOINT((5 8),(9 8),(7 11))";
+
+// Generates error (extra polygon on top of rest) at distance 14.0:
+static std::string const multipoint_a = "MULTIPOINT((39 44),(38 37),(41 29),(15 33),(58 39))";
+
+// Just one with holes at distance ~ 15
+static std::string const multipoint_b = "MULTIPOINT((5 56),(98 67),(20 7),(58 60),(10 4),(75 68),(61 68),(75 62),(92 26),(74 6),(67 54),(20 43),(63 30),(45 7))";
+
+
+template <typename P>
+void test_all()
+{
+ //std::cout << typeid(bg::coordinate_type<P>::type).name() << std::endl;
+
+ namespace buf = bg::strategy::buffer;
+ typedef bg::model::polygon<P> polygon;
+ typedef bg::model::multi_point<P> multi_point_type;
+
+ double const pi = boost::geometry::math::pi<double>();
+
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("simplex1", simplex, 2.0 * pi, 1.0, 1.0);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("simplex2", simplex, 22.8372, 2.0, 2.0);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("simplex3", simplex, 44.5692, 3.0, 3.0);
+
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("three1", three, 3.0 * pi, 1.0, 1.0);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("three2", three, 36.7592, 2.0, 2.0);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("three19", three, 33.6914, 1.9, 1.9);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("three21", three, 39.6394, 2.1, 2.1);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("three3", three, 65.533, 3.0, 3.0);
+
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("multipoint_a", multipoint_a, 2049.98, 14.0, 14.0);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("multipoint_b", multipoint_b, 7109.88, 15.0, 15.0);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("multipoint_b1", multipoint_b, 6911.89, 14.7, 14.7);
+ test_one<multi_point_type, buf::join_miter, buf::end_round, polygon>("multipoint_b2", multipoint_b, 7174.79, 15.1, 15.1);
+}
+
+template
+<
+ typename GeometryOut,
+ template<typename, typename> class JoinStrategy,
+ template<typename, typename> class EndStrategy,
+ typename Geometry
+>
+double test_growth(Geometry const& geometry, int n, int d, double distance)
+{
+ namespace bg = boost::geometry;
+
+ typedef typename bg::coordinate_type<Geometry>::type coordinate_type;
+ typedef typename bg::point_type<Geometry>::type point_type;
+
+ typedef typename bg::ring_type<GeometryOut>::type ring_type;
+
+ typedef typename bg::tag<Geometry>::type tag;
+
+ // extern int point_buffer_count;
+ std::ostringstream complete;
+ complete
+ << "point" << "_"
+ << "growth" << "_"
+ << string_from_type<coordinate_type>::name()
+ << "_" << "r"
+ << "_" << n
+ << "_" << d
+ // << "_" << point_buffer_count
+ ;
+
+ //std::cout << complete.str() << std::endl;
+
+ std::ostringstream filename;
+ filename << "buffer_" << complete.str() << ".svg";
+
+ std::ofstream svg(filename.str().c_str());
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ bg::svg_mapper<point_type> mapper(svg, 500, 500);
+
+ {
+ bg::model::box<point_type> box;
+ bg::envelope(geometry, box);
+
+ bg::buffer(box, box, distance * 1.01);
+ mapper.add(box);
+ }
+#endif
+
+ JoinStrategy
+ <
+ point_type,
+ typename bg::point_type<GeometryOut>::type
+ > join_strategy;
+ EndStrategy
+ <
+ point_type,
+ typename bg::point_type<GeometryOut>::type
+ > end_strategy;
+
+ typedef bg::strategy::buffer::distance_symmetric<coordinate_type> distance_strategy_type;
+ distance_strategy_type distance_strategy(distance);
+
+ std::vector<GeometryOut> buffered;
+
+ bg::buffer_inserter<GeometryOut>(geometry, std::back_inserter(buffered),
+ distance_strategy,
+ join_strategy,
+ end_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , mapper
+#endif
+ );
+
+ typename bg::default_area_result<GeometryOut>::type area = 0;
+ BOOST_FOREACH(GeometryOut const& polygon, buffered)
+ {
+ area += bg::area(polygon);
+ }
+
+ // Map input geometry in green
+ mapper.map(geometry, "opacity:0.5;fill:rgb(0,128,0);stroke:rgb(0,128,0);stroke-width:10");
+
+ BOOST_FOREACH(GeometryOut const& polygon, buffered)
+ {
+ mapper.map(polygon, "opacity:0.4;fill:rgb(255,255,128);stroke:rgb(0,0,0);stroke-width:3");
+ }
+
+ return area;
+}
+
+template <typename P>
+void test_growth(int n, int distance_count)
+{
+ srand(int(time(NULL)));
+ //std::cout << typeid(bg::coordinate_type<P>::type).name() << std::endl;
+ boost::timer t;
+
+ namespace buf = bg::strategy::buffer;
+ typedef bg::model::polygon<P> polygon;
+ typedef bg::model::multi_point<P> multi_point_type;
+
+ multi_point_type multi_point;
+ for (int i = 0; i < n; i++)
+ {
+ P point(rand() % 100, rand() % 100);
+ multi_point.push_back(point);
+ }
+
+ std::cout << bg::wkt(multi_point) << std::endl;
+
+ double previous_area = 0;
+ double epsilon = 0.1;
+ double distance = 15.0;
+ for (int d = 0; d < distance_count; d++, distance += epsilon)
+ {
+ double area = test_growth<polygon, buf::join_miter, buf::end_round>(multi_point, n, d, distance);
+ if (area < previous_area)
+ {
+ std::cout << "Error: " << area << " < " << previous_area << std::endl
+ << " n=" << n << " distance=" << distance
+ << bg::wkt(multi_point) << std::endl;
+ }
+ previous_area = area;
+ }
+ std::cout << "n=" << n << " time=" << t.elapsed() << std::endl;
+}
+
+int test_main(int, char* [])
+{
+ //std::cout << std::setprecision(6);
+ //test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+#ifdef NDEBUG
+ // only in release mode
+ for (int i = 5; i <= 50; i++)
+ {
+ test_growth<bg::model::point<double, 2, bg::cs::cartesian> >(i, 20);
+ }
+#endif
+
+ return 0;
+}

Modified: trunk/libs/geometry/test_extensions/algorithms/buffer/multi_polygon_buffer.cpp
==============================================================================
--- trunk/libs/geometry/test_extensions/algorithms/buffer/multi_polygon_buffer.cpp (original)
+++ trunk/libs/geometry/test_extensions/algorithms/buffer/multi_polygon_buffer.cpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -240,110 +240,116 @@
     typedef bg::model::polygon<P> polygon_type;
     typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
 
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("triangles424", triangles, 'm', 417.910, 4.24);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("triangles425", triangles, 'm', 418.918, 4.25);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("triangles426", triangles, 'm', 419.927, 4.26);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("zonethru_10", zonethru, 'm', 96.0000, 1.0);
-
- test_one<multi_polygon_type, buf::join_round, polygon_type>("multi_simplex_05", simplex, 'r', 23.7030, 0.5);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("multi_simplex_05", simplex, 'm', 24.5965, 0.5);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("multi_simplex_10", simplex, 'r', 34.2532, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("multi_simplex_10", simplex, 'm', 38.1379, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("multi_simplex_20", simplex, 'r', 59.9159, 2.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("multi_simplex_20", simplex, 'm', 77.7060, 2.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("multi_simplex_50", simplex, 'r', 174.46, 5.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("multi_simplex_50", simplex, 'm', 298.797, 5.0);
- test_one<multi_polygon_type, buf::join_round_by_divide, polygon_type>("multi_simplex_50", simplex, 'd', 174.46, 5.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("triangles424", triangles, 417.910, 4.24);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("triangles425", triangles, 418.918, 4.25);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("triangles426", triangles, 419.927, 4.26);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("zonethru_10", zonethru, 96.0000, 1.0);
+
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("multi_simplex_05", simplex, 23.7030, 0.5);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("multi_simplex_05", simplex, 24.5965, 0.5);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("multi_simplex_10", simplex, 34.2532, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("multi_simplex_10", simplex, 38.1379, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("multi_simplex_20", simplex, 59.9159, 2.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("multi_simplex_20", simplex, 77.7060, 2.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("multi_simplex_50", simplex, 174.46, 5.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("multi_simplex_50", simplex, 298.797, 5.0);
+
+ // This one does not work:
+ // test_one<multi_polygon_type, buf::join_round_by_divide, buf::end_skip, polygon_type>("multi_simplex_50", simplex, 'd', 174.46, 5.0);
     
- test_one<multi_polygon_type, buf::join_round, polygon_type>("zonethru_05", zonethru, 'r', 67.4627, 0.5);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("zonethru_05", zonethru, 'm', 68.0000, 0.5);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("zonethru_10", zonethru, 'r', 93.8508, 1.0, -999, 1);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("zonethru_10", zonethru, 'm', 96.0000, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("zonethru_15", zonethru, 'r', 114.584, 1.5);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("zonethru_15", zonethru, 'm', 117.000, 1.5);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("wrapped_05", wrapped, 'r', 104.570, 0.5);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("wrapped_05", wrapped, 'm', 105.000, 0.5);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("wrapped_10", wrapped, 'r', 142.281, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("wrapped_10", wrapped, 'm', 144.000, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("wrapped_15", wrapped, 'r', 167.066, 1.5);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("wrapped_15", wrapped, 'm', 169.000, 1.5);
-
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_a", rt_a, 'r', 34.5381, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_a", rt_a, 'm', 36, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_b", rt_b, 'r', 31.4186, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_b", rt_b, 'm', 34, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_c", rt_c, 'r', 14.7093, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_c", rt_c, 'm', 16, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_d", rt_d, 'r', 18.8726, 0.3);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_d", rt_d, 'm', 19.8823, 0.3);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_e", rt_e, 'r', 14.1866, 0.3);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_e", rt_e, 'm', 15.1198, 0.3);
- // This does not add anything: test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_f", rt_f, 'r', 4.28937, 0.3);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_f", rt_f, 'm', 4.60853, 0.3);
-
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_g1", rt_g1, 'r', 24.719, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_g1", rt_g1, 'm', 30.3137, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_g2", rt_g2, 'm', 18.5711, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_g3", rt_g3, 'm', 16.5711, 1.0);
-
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_h", rt_h, 'r', 47.6012, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_h", rt_h, 'm', 61.7058, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_i", rt_i, 'r', 10.7528, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_i", rt_i, 'm', 13.6569, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_j", rt_j, 'r', 28.7309, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_j", rt_j, 'm', 35.1421, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_k", rt_k, 'r', 42.0092, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_k", rt_k, 'm', 48.0563, 1.0);
- // This does not add anything: test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_l", rt_l, 'r', 14.1074, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_l", rt_l, 'm', 19.3995, 1.0);
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_m1", rt_m1, 'r', 14.1074, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_m1", rt_m1, 'm', 19.4853, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_m2", rt_m2, 'm', 21.4853, 1.0);
-
- // This does not add anything: test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_n", rt_n, 'r', 14.1074, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_n", rt_n, 'm', 18.4853, 1.0);
-
- test_one<multi_polygon_type, buf::join_round, polygon_type>("rt_o1", rt_o1, 'r', 17.536, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_o1", rt_o1, 'm', 20.9142, 1.0);
-
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_o2", rt_o2, 'm', 25.7426, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_o3", rt_o3, 'm', 28.8247, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_o4", rt_o4, 'm', 34.6532, 1.0);
-
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p1", rt_p1, 'm', 24.8211, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p2", rt_p2, 'm', 21.4853, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p3", rt_p3, 'm', 22.3995, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p4", rt_p4, 'm', 33.0563, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p5", rt_p5, 'm', 17, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p6", rt_p6, 'm', 18.4853, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p7", rt_p7, 'm', 26.2279, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p8", rt_p8, 'm', 29.0563, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p9", rt_p9, 'm', 26.1421, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p10", rt_p10, 'm', 23.3995, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p11", rt_p11, 'm', 28.7426, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p12", rt_p12, 'm', 22.5711, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p13", rt_p13, 'm', 19.9142, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p14", rt_p14, 'm', 20.8284, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p15", rt_p15, 'm', 23.6569, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p16", rt_p16, 'm', 23.4853, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p17", rt_p17, 'm', 25.3137, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p18", rt_p18, 'm', 23.3137, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p19", rt_p19, 'm', 25.5637, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p20", rt_p20, 'm', 25.4853, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p21", rt_p21, 'm', 17.1716, 1.0);
- // test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_p22", rt_p22, 'm', 99, 1.0); TODO fix this one
-
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_q1", rt_q1, 'm', 27, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_q2", rt_q2, 'm', 26.4853, 1.0);
-
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_r", rt_r, 'm', 21.0761, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_s1", rt_s1, 'm', 20.4853, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_s2", rt_s2, 'm', 24.6495, 1.0);
- test_one<multi_polygon_type, buf::join_miter, polygon_type>("rt_t", rt_t, 'm', 15.6569, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("zonethru_05", zonethru, 67.4627, 0.5);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("zonethru_05", zonethru, 68.0000, 0.5);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("zonethru_10", zonethru, 93.8508, 1.0, -999, 1);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("zonethru_10", zonethru, 96.0000, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("zonethru_15", zonethru, 114.584, 1.5);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("zonethru_15", zonethru, 117.000, 1.5);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("wrapped_05", wrapped, 104.570, 0.5);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("wrapped_05", wrapped, 105.000, 0.5);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("wrapped_10", wrapped, 142.281, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("wrapped_10", wrapped, 144.000, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("wrapped_15", wrapped, 167.066, 1.5);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("wrapped_15", wrapped, 169.000, 1.5);
+
+ // TODO: there is still an undetected hole inside rt_a
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_a", rt_a, 34.5381, 1.0);
+
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_a", rt_a, 36, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_b", rt_b, 31.4186, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_b", rt_b, 34, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_c", rt_c, 14.7093, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_c", rt_c, 16, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_d", rt_d, 18.8726, 0.3);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_d", rt_d, 19.8823, 0.3);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_e", rt_e, 14.1866, 0.3);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_e", rt_e, 15.1198, 0.3);
+ // This does not add anything: test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_f", rt_f, 4.28937, 0.3);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_f", rt_f, 4.60853, 0.3);
+
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_g1", rt_g1, 24.719, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_g1", rt_g1, 30.3137, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_g2", rt_g2, 18.5711, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_g3", rt_g3, 16.5711, 1.0);
+
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_h", rt_h, 47.6012, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_h", rt_h, 61.7058, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_i", rt_i, 10.7528, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_i", rt_i, 13.6569, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_j", rt_j, 28.7309, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_j", rt_j, 35.1421, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_k", rt_k, 42.0092, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_k", rt_k, 48.0563, 1.0);
+ // This does not add anything: test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_l", rt_l, 14.1074, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_l", rt_l, 19.3995, 1.0);
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_m1", rt_m1, 14.1074, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_m1", rt_m1, 19.4853, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_m2", rt_m2, 21.4853, 1.0);
+
+ // This does not add anything: test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_n", rt_n, 14.1074, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_n", rt_n, 18.4853, 1.0);
+
+ test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_o1", rt_o1, 17.536, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o1", rt_o1, 20.9142, 1.0);
+
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o2", rt_o2, 25.7426, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o3", rt_o3, 28.8247, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o4", rt_o4, 34.6532, 1.0);
+
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p1", rt_p1, 24.8211, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p2", rt_p2, 21.4853, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p3", rt_p3, 22.3995, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p4", rt_p4, 33.0563, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p5", rt_p5, 17, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p6", rt_p6, 18.4853, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p7", rt_p7, 26.2279, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p8", rt_p8, 29.0563, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p9", rt_p9, 26.1421, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p10", rt_p10, 23.3995, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p11", rt_p11, 28.7426, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p12", rt_p12, 22.5711, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p13", rt_p13, 19.9142, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p14", rt_p14, 20.8284, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p15", rt_p15, 23.6569, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p16", rt_p16, 23.4853, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p17", rt_p17, 25.3137, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p18", rt_p18, 23.3137, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p19", rt_p19, 25.5637, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p20", rt_p20, 25.4853, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p21", rt_p21, 17.1716, 1.0);
+ // test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p22", rt_p22, 99, 1.0); TODO fix this one
+
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_q1", rt_q1, 27, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_q2", rt_q2, 26.4853, 1.0);
+
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_r", rt_r, 21.0761, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_s1", rt_s1, 20.4853, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_s2", rt_s2, 24.6495, 1.0);
+ test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_t", rt_t, 15.6569, 1.0);
 
 
 }
 
+int point_buffer_count;
+
 int test_main(int, char* [])
 {
     test_all<bg::model::point<double, 2, bg::cs::cartesian> >();

Added: trunk/libs/geometry/test_extensions/algorithms/buffer/point_buffer.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/test_extensions/algorithms/buffer/point_buffer.cpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -0,0 +1,49 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-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)
+
+//#define BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+//#define BOOST_GEOMETRY_DEBUG_ASSEMBLE
+//#define BOOST_GEOMETRY_DEBUG_IDENTIFIER
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/buffer.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/box.hpp>
+
+#include <test_buffer.hpp>
+
+
+static std::string const simplex = "POINT(5 5)";
+
+template <typename P>
+void test_all()
+{
+ namespace buf = bg::strategy::buffer;
+ typedef bg::model::polygon<P> polygon;
+
+ double const pi = boost::geometry::math::pi<double>();
+
+ test_one<P, buf::join_miter, buf::end_round, polygon>("simplex1", simplex, pi, 1.0, 1.0);
+ test_one<P, buf::join_miter, buf::end_round, polygon>("simplex2", simplex, pi * 4.0, 2.0, 2.0);
+ test_one<P, buf::join_miter, buf::end_round, polygon>("simplex3", simplex, pi * 9.0, 3.0, 3.0);
+}
+
+
+int test_main(int, char* [])
+{
+ //std::cout << std::setprecision(6);
+ //test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
+ return 0;
+}

Modified: trunk/libs/geometry/test_extensions/algorithms/buffer/polygon_buffer.cpp
==============================================================================
--- trunk/libs/geometry/test_extensions/algorithms/buffer/polygon_buffer.cpp (original)
+++ trunk/libs/geometry/test_extensions/algorithms/buffer/polygon_buffer.cpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -72,109 +72,109 @@
 
     typedef bg::model::polygon<P> polygon_type;
 
- test_one<polygon_type, buf::join_round, polygon_type>("simplex", simplex, 'r', 47.9408, 1.5);
- test_one<polygon_type, buf::join_miter, polygon_type>("simplex", simplex, 'm', 52.8733, 1.5);
- test_one<polygon_type, buf::join_round, polygon_type>("concave_simplex", concave_simplex, 'r', 14.5616, 0.5);
- test_one<polygon_type, buf::join_miter, polygon_type>("concave_simplex", concave_simplex, 'm', 16.3861, 0.5);
- test_one<polygon_type, buf::join_round, polygon_type>("chained_box", chained_box, 'r', 83.1403, 1.0);
- test_one<polygon_type, buf::join_miter, polygon_type>("chained_box", chained_box, 'm', 84, 1.0);
- test_one<polygon_type, buf::join_round, polygon_type>("L", letter_L, 'r', 13.7314, 0.5);
- test_one<polygon_type, buf::join_miter, polygon_type>("L", letter_L, 'm', 14.0, 0.5);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("chained_box", chained_box, 'm', 84, 1.0);
- test_one<polygon_type, buf::join_round, polygon_type>("chained_box", chained_box, 'r', 83.1403, 1.0);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("indentation4", indentation, 'm', 25.7741, 0.4);
- test_one<polygon_type, buf::join_round, polygon_type>("indentation4", indentation, 'r', 25.5695, 0.4);
- test_one<polygon_type, buf::join_miter, polygon_type>("indentation5", indentation, 'm', 28.2426, 0.5);
- test_one<polygon_type, buf::join_round, polygon_type>("indentation5", indentation, 'r', 27.9953, 0.5);
- test_one<polygon_type, buf::join_miter, polygon_type>("indentation6", indentation, 'm', 30.6712, 0.6);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("simplex", simplex, 47.9408, 1.5);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("simplex", simplex, 52.8733, 1.5);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("concave_simplex", concave_simplex, 14.5616, 0.5);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("concave_simplex", concave_simplex, 16.3861, 0.5);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("chained_box", chained_box, 83.1403, 1.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("chained_box", chained_box, 84, 1.0);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("L", letter_L, 13.7314, 0.5);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("L", letter_L, 14.0, 0.5);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("chained_box", chained_box, 84, 1.0);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("chained_box", chained_box, 83.1403, 1.0);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation4", indentation, 25.7741, 0.4);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation4", indentation, 25.5695, 0.4);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation5", indentation, 28.2426, 0.5);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation5", indentation, 27.9953, 0.5);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation6", indentation, 30.6712, 0.6);
 
     // SQL Server gives 30.34479159164
- test_one<polygon_type, buf::join_round, polygon_type>("indentation6", indentation, 'r', 30.3445, 0.6);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation6", indentation, 30.3445, 0.6);
 
- test_one<polygon_type, buf::join_miter, polygon_type>("indentation7", indentation, 'm', 33.0958, 0.7);
- test_one<polygon_type, buf::join_round, polygon_type>("indentation7", indentation, 'r', 32.6533, 0.7);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation7", indentation, 33.0958, 0.7);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation7", indentation, 32.6533, 0.7);
 
- test_one<polygon_type, buf::join_miter, polygon_type>("indentation8", indentation, 'm', 35.5943, 0.8);
- test_one<polygon_type, buf::join_round, polygon_type>("indentation8", indentation, 'r', 35.0164, 0.8);
- test_one<polygon_type, buf::join_miter, polygon_type>("indentation12", indentation, 'm', 46.3541, 1.2);
- test_one<polygon_type, buf::join_round, polygon_type>("indentation12", indentation, 'r', 45.0537, 1.2);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation8", indentation, 35.5943, 0.8);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation8", indentation, 35.0164, 0.8);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation12", indentation, 46.3541, 1.2);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation12", indentation, 45.0537, 1.2);
 
         // TODO: fix, the buffered pieces are currently counterclockwise, that should be reversed
- //test_one<polygon_type, buf::join_miter, polygon_type>("indentation4_neg", indentation, 'm', 6.99098413022335, -0.4);
- //test_one<polygon_type, buf::join_round, polygon_type>("indentation4_neg", indentation, 'r', 7.25523322189147, -0.4);
- //test_one<polygon_type, buf::join_miter, polygon_type>("indentation8_neg", indentation, 'm', 1.36941992048731, -0.8);
- //test_one<polygon_type, buf::join_round, polygon_type>("indentation8_neg", indentation, 'r', 1.37375487490664, -0.8);
- //test_one<polygon_type, buf::join_miter, polygon_type>("indentation12_neg", indentation, 'm', 0, -1.2);
- //test_one<polygon_type, buf::join_round, polygon_type>("indentation12_neg", indentation, 'r', 0, -1.2);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("donut_simplex6", donut_simplex, 'm', 53.648, 0.6);
- test_one<polygon_type, buf::join_round, polygon_type>("donut_simplex6", donut_simplex, 'r', 52.820, 0.6);
- test_one<polygon_type, buf::join_miter, polygon_type>("donut_simplex8", donut_simplex, 'm', 61.132, 0.8);
- test_one<polygon_type, buf::join_round, polygon_type>("donut_simplex8", donut_simplex, 'r', 59.6713, 0.8);
- test_one<polygon_type, buf::join_miter, polygon_type>("donut_simplex10", donut_simplex, 'm', 68.670, 1.0);
- test_one<polygon_type, buf::join_round, polygon_type>("donut_simplex10", donut_simplex, 'r', 66.387, 1.0);
- test_one<polygon_type, buf::join_miter, polygon_type>("donut_simplex12", donut_simplex, 'm', 76.605, 1.2);
- test_one<polygon_type, buf::join_round, polygon_type>("donut_simplex12", donut_simplex, 'r', 73.3179, 1.2);
- test_one<polygon_type, buf::join_miter, polygon_type>("donut_simplex14", donut_simplex, 'm', 84.974, 1.4);
- test_one<polygon_type, buf::join_round, polygon_type>("donut_simplex14", donut_simplex, 'r', 80.500, 1.4);
- test_one<polygon_type, buf::join_miter, polygon_type>("donut_simplex16", donut_simplex, 'm', 93.777, 1.6);
- test_one<polygon_type, buf::join_round, polygon_type>("donut_simplex16", donut_simplex, 'r', 87.933, 1.6);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("arrow4", arrow, 'm', 28.265, 0.4);
- test_one<polygon_type, buf::join_round, polygon_type>("arrow4", arrow, 'r', 27.039, 0.4);
- test_one<polygon_type, buf::join_miter, polygon_type>("arrow5", arrow, 'm', 31.500, 0.5);
- test_one<polygon_type, buf::join_round, polygon_type>("arrow5", arrow, 'r', 29.621, 0.5);
- test_one<polygon_type, buf::join_miter, polygon_type>("arrow6", arrow, 'm', 34.903, 0.6);
- test_one<polygon_type, buf::join_round, polygon_type>("arrow6", arrow, 'r', 32.268, 0.6);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("tipped_aitch3", tipped_aitch, 'm', 55.36, 0.3);
- test_one<polygon_type, buf::join_miter, polygon_type>("tipped_aitch9", tipped_aitch, 'm', 77.44, 0.9);
- test_one<polygon_type, buf::join_miter, polygon_type>("tipped_aitch13", tipped_aitch, 'm', 92.16, 1.3);
+ //test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation4_neg", indentation, 6.99098413022335, -0.4);
+ //test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation4_neg", indentation, 7.25523322189147, -0.4);
+ //test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation8_neg", indentation, 1.36941992048731, -0.8);
+ //test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation8_neg", indentation, 1.37375487490664, -0.8);
+ //test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("indentation12_neg", indentation, 0, -1.2);
+ //test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("indentation12_neg", indentation, 0, -1.2);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("donut_simplex6", donut_simplex, 53.648, 0.6);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("donut_simplex6", donut_simplex, 52.820, 0.6);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("donut_simplex8", donut_simplex, 61.132, 0.8);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("donut_simplex8", donut_simplex, 59.6713, 0.8);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("donut_simplex10", donut_simplex, 68.670, 1.0);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("donut_simplex10", donut_simplex, 66.387, 1.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("donut_simplex12", donut_simplex, 76.605, 1.2);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("donut_simplex12", donut_simplex, 73.3179, 1.2);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("donut_simplex14", donut_simplex, 84.974, 1.4);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("donut_simplex14", donut_simplex, 80.500, 1.4);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("donut_simplex16", donut_simplex, 93.777, 1.6);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("donut_simplex16", donut_simplex, 87.933, 1.6);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("arrow4", arrow, 28.265, 0.4);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("arrow4", arrow, 27.039, 0.4);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("arrow5", arrow, 31.500, 0.5);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("arrow5", arrow, 29.621, 0.5);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("arrow6", arrow, 34.903, 0.6);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("arrow6", arrow, 32.268, 0.6);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("tipped_aitch3", tipped_aitch, 55.36, 0.3);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("tipped_aitch9", tipped_aitch, 77.44, 0.9);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("tipped_aitch13", tipped_aitch, 92.16, 1.3);
 
     // SQL Server: 55.205415532967 76.6468846383224 90.642916957136
- test_one<polygon_type, buf::join_round, polygon_type>("tipped_aitch3", tipped_aitch, 'r', 55.2053, 0.3);
- test_one<polygon_type, buf::join_round, polygon_type>("tipped_aitch9", tipped_aitch, 'r', 76.6457, 0.9);
- test_one<polygon_type, buf::join_round, polygon_type>("tipped_aitch13", tipped_aitch, 'r', 90.641, 1.3);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("snake4", snake, 'm', 64.44, 0.4);
- test_one<polygon_type, buf::join_miter, polygon_type>("snake5", snake, 'm', 72, 0.5);
- test_one<polygon_type, buf::join_miter, polygon_type>("snake6", snake, 'm', 75.44, 0.6);
- test_one<polygon_type, buf::join_miter, polygon_type>("snake16", snake, 'm', 114.24, 1.6);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("funnelgate2", funnelgate, 'm', 120.982, 2);
- test_one<polygon_type, buf::join_miter, polygon_type>("funnelgate3", funnelgate, 'm', 13*13, 3);
- test_one<polygon_type, buf::join_miter, polygon_type>("funnelgate4", funnelgate, 'm', 15*15, 4);
- test_one<polygon_type, buf::join_miter, polygon_type>("gammagate1", gammagate, 'm', 88, 1);
- test_one<polygon_type, buf::join_miter, polygon_type>("fork_a1", fork_a, 'm', 88, 1);
- test_one<polygon_type, buf::join_miter, polygon_type>("fork_b1", fork_b, 'm', 154, 1);
- test_one<polygon_type, buf::join_miter, polygon_type>("fork_c1", fork_c, 'm', 152, 1);
- test_one<polygon_type, buf::join_miter, polygon_type>("triangle", triangle, 'm', 14.6569, 1.0);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("gammagate2", gammagate, 'm', 130, 2);
-
- test_one<polygon_type, buf::join_miter, polygon_type>("flower1", flower, 'm', 67.614, 0.1);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower20", flower, 'm', 74.894, 0.20);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower25", flower, 'm', 78.226, 0.25);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower30", flower, 'm', 81.492494146177947, 0.30);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower35", flower, 'm', 84.694183819917185, 0.35);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower40", flower, 'm', 87.8306529577, 0.40);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower45", flower, 'm', 90.901901559536029, 0.45);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower50", flower, 'm', 93.907929625415662, 0.50);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower55", flower, 'm', 96.848737155342079, 0.55);
- test_one<polygon_type, buf::join_miter, polygon_type>("flower60", flower, 'm', 99.724324149315279, 0.60);
-
- test_one<polygon_type, buf::join_round, polygon_type>("flower10", flower, 'r', 67.486, 0.10);
- test_one<polygon_type, buf::join_round, polygon_type>("flower20", flower, 'r', 74.702, 0.20);
- test_one<polygon_type, buf::join_round, polygon_type>("flower25", flower, 'r', 78.071, 0.25);
- test_one<polygon_type, buf::join_round, polygon_type>("flower30", flower, 'r', 81.352, 0.30);
- test_one<polygon_type, buf::join_round, polygon_type>("flower35", flower, 'r', 84.547, 0.35);
- test_one<polygon_type, buf::join_round, polygon_type>("flower40", flower, 'r', 87.665, 0.40);
- test_one<polygon_type, buf::join_round, polygon_type>("flower45", flower, 'r', 90.709, 0.45);
- test_one<polygon_type, buf::join_round, polygon_type>("flower50", flower, 'r', 93.680, 0.50);
- test_one<polygon_type, buf::join_round, polygon_type>("flower55", flower, 'r', 96.580, 0.55);
- test_one<polygon_type, buf::join_round, polygon_type>("flower60", flower, 'r', 99.408, 0.60);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("tipped_aitch3", tipped_aitch, 55.2053, 0.3);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("tipped_aitch9", tipped_aitch, 76.6457, 0.9);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("tipped_aitch13", tipped_aitch, 90.641, 1.3);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snake4", snake, 64.44, 0.4);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snake5", snake, 72, 0.5);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snake6", snake, 75.44, 0.6);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snake16", snake, 114.24, 1.6);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("funnelgate2", funnelgate, 120.982, 2);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("funnelgate3", funnelgate, 13*13, 3);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("funnelgate4", funnelgate, 15*15, 4);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("gammagate1", gammagate, 88, 1);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("fork_a1", fork_a, 88, 1);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("fork_b1", fork_b, 154, 1);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("fork_c1", fork_c, 152, 1);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("triangle", triangle, 14.6569, 1.0);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("gammagate2", gammagate, 130, 2);
+
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower1", flower, 67.614, 0.1);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower20", flower, 74.894, 0.20);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower25", flower, 78.226, 0.25);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower30", flower, 81.492494146177947, 0.30);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower35", flower, 84.694183819917185, 0.35);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower40", flower, 87.8306529577, 0.40);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower45", flower, 90.901901559536029, 0.45);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower50", flower, 93.907929625415662, 0.50);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower55", flower, 96.848737155342079, 0.55);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("flower60", flower, 99.724324149315279, 0.60);
+
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower10", flower, 67.486, 0.10);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower20", flower, 74.702, 0.20);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower25", flower, 78.071, 0.25);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower30", flower, 81.352, 0.30);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower35", flower, 84.547, 0.35);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower40", flower, 87.665, 0.40);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower45", flower, 90.709, 0.45);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower50", flower, 93.680, 0.50);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower55", flower, 96.580, 0.55);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("flower60", flower, 99.408, 0.60);
 
     // Saw
     {
@@ -197,8 +197,8 @@
         {
             std::ostringstream out;
             out << "saw_" << i;
- test_one<polygon_type, buf::join_round, polygon_type>(out.str(), saw, 'r', expected_round[i - 1], double(i) / 2.0);
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(), saw, 'm', expected_miter[i - 1], double(i) / 2.0);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>(out.str(), saw, expected_round[i - 1], double(i) / 2.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(), saw, expected_miter[i - 1], double(i) / 2.0);
         }
     }
 
@@ -226,12 +226,12 @@
         {
             std::ostringstream out;
             out << "bowl_" << i;
- test_one<polygon_type, buf::join_round, polygon_type>(out.str(), bowl, 'r', expected_round[i - 1], double(i) / 2.0);
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(), bowl, 'm', expected_miter[i - 1], double(i) / 2.0);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>(out.str(), bowl, expected_round[i - 1], double(i) / 2.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(), bowl, expected_miter[i - 1], double(i) / 2.0);
         }
     }
- test_one<polygon_type, buf::join_round, polygon_type>("county1", county1, 'r', 0.00114092, 0.01);
- test_one<polygon_type, buf::join_miter, polygon_type>("county1", county1, 'm', 0.00132859, 0.01);
+ test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("county1", county1, 0.00114092, 0.01);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("county1", county1, 0.00132859, 0.01);
 
     return;
 
@@ -241,12 +241,12 @@
         {
             std::ostringstream out;
             out << "snake_" << i;
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(), snake, double(i) / 10.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(), snake, double(i) / 10.0);
         }
         {
             std::ostringstream out;
             out << "snake_" << i << "_neg";
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(), snake, double(-i) / 10.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(), snake, double(-i) / 10.0);
         }
     }
     */
@@ -256,23 +256,23 @@
     {
         std::ostringstream out;
         out << "church_" << i;
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(), church, 'm', double(i) / 10.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(), church, double(i) / 10.0);
     }
     for (int i = 4; i < 30; i++)
     {
         std::ostringstream out;
         out << "flower_" << i;
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(), flower, 'm', double(i) / 10.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(), flower, double(i) / 10.0);
     }
     static std::string const snl_8961 =
         "POLYGON((161081 472784,161061 472769,161007 472740,160996 472746,160998 472777,160999 472782,161005 472888,161012 472889,161019 472891,161032 472895,161038 472883,161081 472784),(161026 472811,161022 472814,161019 472810,161023 472807,161026 472811))";
- test_one<polygon_type, buf::join_miter, polygon_type>("snl_8961_10", snl_8961, 'm', 10.0);
- test_one<polygon_type, buf::join_miter, polygon_type>("snl_8961_100", snl_8961, 'm', 100.0);
- test_one<polygon_type, buf::join_miter, polygon_type>("snl_8961_500", snl_8961, 'm', 500.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snl_8961_10", snl_8961, 10.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snl_8961_100", snl_8961, 100.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snl_8961_500", snl_8961, 500.0);
 
     static std::string const snl_25120 =
         "POLYGON((225343.489 585110.376,225319.123 585165.731,225323.497 585167.287,225323.134 585167.157,225313.975 585169.208,225321.828 585172,225332.677 585175.83,225367.032 585186.977,225401.64 585196.671,225422.799 585201.029,225429.784 585202.454,225418.859 585195.112,225423.803 585196.13,225425.389 585196.454,225397.027 585165.48,225363.802 585130.372,225354.086 585120.261,225343.489 585110.376))";
- test_one<polygon_type, buf::join_miter, polygon_type>("snl_25120", snl_25120, 'm', 1.25);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("snl_25120", snl_25120, 1.25);
     return;
 
 
@@ -282,17 +282,17 @@
         out << "snl_7309_" << i;
         static std::string const snl_7309 =
             "POLYGON((116042.2 464335.07,116045.9 464325.15,116051.33 464311.53,116056.35 464294.59,116066.41 464264.16,116066.44 464264.09,116060.35 464280.93,116028.89 464268.43,116028.89 464268.44,116024.74 464280.7,116018.91 464296.71,116012.3 464319.59,116004.76 464345.13,115988.36 464389.71,115975.39 464426.35,115965.07 464455.99,115964.81 464458.9,115966.39 464461.02,115976.45 464466.84,115984.12 464470.41,115988.22 464471.33,115991.8 464470.8,115995.9 464467.76,115997.48 464462.73,115999.73 464455.72,116002.11 464448.98,116006.08 464438.53,116010.18 464429.79,116021.96 464392.75,116034 464357.7,116042.2 464335.07))";
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(), snl_7309, 'm', i * 10.0);
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(), snl_7309, i * 10.0);
     }
 
     //return;
- test_one<polygon_type, buf::join_miter, polygon_type>("toolkit1", "POLYGON((173356.986490154 605912.122380707,173358.457939143 605902.891897507,173358.458257372 605902.889901239,173214.162964795 605901.13020255,173214.162746654 605901.132200038,173213.665 605905.69,173212.712441616 605913.799985923,173356.986490154 605912.122380707))",
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("toolkit1", "POLYGON((173356.986490154 605912.122380707,173358.457939143 605902.891897507,173358.458257372 605902.889901239,173214.162964795 605901.13020255,173214.162746654 605901.132200038,173213.665 605905.69,173212.712441616 605913.799985923,173356.986490154 605912.122380707))",
             'm', 10.0);
     for (int i = 1; i < 20; i++)
     {
         std::ostringstream out;
         out << "toolkit2_" << i;
- test_one<polygon_type, buf::join_miter, polygon_type>(out.str(),
+ test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>(out.str(),
             "POLYGON((120528.56 462115.62,120533.4 462072.1,120533.4 462072.01,120533.39 462071.93,120533.36 462071.86,120533.33 462071.78,120533.28 462071.72,120533.22 462071.66,120533.15 462071.61,120533.08 462071.58,120533 462071.55,120532.92 462071.54,120467.68 462068.66,120468.55 462059.04,120517.39 462062.87,120517.47 462062.87,120517.55 462062.86,120517.62 462062.83,120517.69 462062.79,120517.76 462062.74,120517.81 462062.68,120517.86 462062.62,120517.89 462062.55,120517.92 462062.47,120530.49 461998.63,120530.5 461998.55,120530.49 461998.47,120530.47 461998.39,120530.44 461998.31,120530.4 461998.24,120530.35 461998.18,120530.28 461998.13,120530.21 461998.09,120530.13 461998.06,120482.19 461984.63,120485 461963.14,120528.2 461950.66,120528.28 461950.63,120528.35 461950.59,120528.42 461950.53,120528.47 461950.47,120528.51 461950.4,120528.54 461950.32,120528.56 461950.24,120528.56 461950.15,120528.55 461950.07,120528.53 461949.99,120528.49 461949.92,120528.44 461949.85,120497.49 461915.03,120497.43 461
914.98,120497.37 461914.93,120497.3 461914.9,120497.23 461914.88,120497.15 461914.86,120424.61 461910.03,120424.53 461910.03,120424.45 461910.05,120424.37 461910.07,120424.3 461910.11,120424.24 461910.16,120424.18 461910.22,120424.14 461910.29,120424.11 461910.37,120424.09 461910.45,120424.08 461910.53,120424.08 461967.59,120424.08 461967.67,120424.1 461967.75,120424.14 461967.82,120424.18 461967.89,120424.23 461967.95,120424.3 461968,120424.37 461968.04,120424.44 461968.07,120424.52 461968.09,120473.31 461973.83,120469.63 461993.16,120399.48 461986.43,120399.4 461986.43,120399.32 461986.44,120399.25 461986.47,120399.17 461986.5,120399.11 461986.55,120399.05 461986.61,120399.01 461986.67,120398.97 461986.74,120398.95 461986.82,120398.93 461986.9,120394.1 462057.5,120394.1 462057.58,120394.11 462057.66,120394.14 462057.74,120394.18 462057.81,120394.23 462057.87,120394.29 462057.93,120394.35 462057.97,120394.43 462058,120394.5 462058.03,120394.58 462058.03,120458.74 462059.95,120455.16 462072.48,120396.57 4620
67.68,120396.49 462067.68,120396.4 462067.69,120396.32 462067.72,120396.25 462067.76,120396.18 462067.82,120396.13 462067.88,120396.08 462067.96,120396.05 462068.04,120396.03 462068.12,120392.17 462103.9,120392.16 462103.99,120392.18 462104.07,120392.2 462104.15,120392.24 462104.22,120392.29 462104.29,120392.35 462104.35,120392.42 462104.4,120392.5 462104.43,120392.58 462104.45,120392.66 462104.46,120393.63 462104.46,120393.63 462103.46,120393.22 462103.46,120396.98 462068.71,120455.49 462073.51,120455.57 462073.51,120455.66 462073.49,120455.74 462073.46,120455.81 462073.42,120455.88 462073.37,120455.93 462073.3,120455.98 462073.23,120456.01 462073.15,120459.88 462059.61,120459.89 462059.52,120459.9 462059.44,120459.88 462059.36,120459.86 462059.28,120459.82 462059.21,120459.77 462059.14,120459.72 462059.08,120459.65 462059.04,120459.57 462059,120459.49 462058.98,120459.41 462058.97,120395.13 462057.05,120399.9 461987.48,120469.99 461994.2,120470.07 461994.2,120470.15 461994.19,120470.23 461994.16,120470.3 4
61994.13,120470.37 461994.08,120470.42 461994.02,120470.47 461993.95,120470.5 461993.88,120470.53 461993.8,120474.4 461973.48,120474.4 461973.4,120474.4 461973.32,120474.38 461973.24,120474.35 461973.16,120474.31 461973.09,120474.25 461973.03,120474.19 461972.98,120474.12 461972.94,120474.04 461972.91,120473.96 461972.9,120425.08 461967.14,120425.08 461911.06,120496.88 461915.85,120527.16 461949.92,120484.4 461962.27,120484.33 461962.3,120484.25 461962.35,120484.19 461962.4,120484.14 461962.46,120484.09 461962.53,120484.06 461962.61,120484.05 461962.69,120481.14 461984.93,120481.14 461985.01,120481.15 461985.09,120481.17 461985.17,120481.2 461985.24,120481.25 461985.31,120481.3 461985.36,120481.36 461985.41,120481.43 461985.45,120481.51 461985.48,120529.42 461998.9,120517.02 462061.84,120468.14 462058,120468.05 462058,120467.97 462058.02,120467.89 462058.05,120467.81 462058.09,120467.75 462058.15,120467.69 462058.22,120467.65 462058.29,120467.62 462058.37,120467.6 462058.46,120466.64 462069.1,120466.63 46206
9.18,120466.65 462069.26,120466.67 462069.33,120466.71 462069.4,120466.76 462069.47,120466.81 462069.53,120466.88 462069.57,120466.95 462069.61,120467.03 462069.63,120467.11 462069.64,120532.34 462072.52,120527.62 462115.03,120391.73 462106.36,120391.66 462107.36,120528.03 462116.06,120528.12 462116.06,120528.2 462116.04,120528.28 462116.02,120528.35 462115.97,120528.42 462115.92,120528.47 462115.85,120528.51 462115.78,120528.54 462115.7,120528.56 462115.62))",
                 'm', double(i)
                 );

Modified: trunk/libs/geometry/test_extensions/algorithms/buffer/test_buffer.hpp
==============================================================================
--- trunk/libs/geometry/test_extensions/algorithms/buffer/test_buffer.hpp (original)
+++ trunk/libs/geometry/test_extensions/algorithms/buffer/test_buffer.hpp 2013-04-21 06:43:22 EDT (Sun, 21 Apr 2013)
@@ -38,6 +38,11 @@
 #include <boost/geometry/extensions/algorithms/buffer/buffer_inserter.hpp>
 
 #include <boost/geometry/extensions/strategies/buffer.hpp>
+#include <boost/geometry/extensions/strategies/buffer_end_round.hpp>
+#include <boost/geometry/extensions/strategies/buffer_end_flat.hpp>
+#include <boost/geometry/extensions/strategies/buffer_end_skip.hpp>
+
+
 
 #include <boost/geometry/io/wkt/wkt.hpp>
 
@@ -70,16 +75,62 @@
     }
 }
 
+//-----------------------------------------------------------------------------
+template <template<typename, typename> class JoinStrategy>
+struct JoinTestProperties { };
+
+template<> struct JoinTestProperties<boost::geometry::strategy::buffer::join_round>
+{
+ static std::string name() { return "round"; }
+ static double tolerance() { return 0.1; }
+};
+
+template<> struct JoinTestProperties<boost::geometry::strategy::buffer::join_miter>
+{
+ static std::string name() { return "miter"; }
+ static double tolerance() { return 0.001; }
+};
+
+template<> struct JoinTestProperties<boost::geometry::strategy::buffer::join_round_by_divide>
+{
+ static std::string name() { return "divide"; }
+ static double tolerance() { return 0.1; }
+};
+
+
+//-----------------------------------------------------------------------------
+template <template<typename, typename> class EndStrategy>
+struct EndTestProperties { };
+
+template<> struct EndTestProperties<boost::geometry::strategy::buffer::end_round>
+{
+ static std::string name() { return "round"; }
+ static double tolerance() { return 0.1; }
+};
+
+template<> struct EndTestProperties<boost::geometry::strategy::buffer::end_flat>
+{
+ static std::string name() { return "flat"; }
+ static double tolerance() { return 0.001; }
+};
+
+template<> struct EndTestProperties<boost::geometry::strategy::buffer::end_skip>
+{
+ static std::string name() { return ""; }
+ static double tolerance() { return 0.001; }
+};
+
 template
 <
     typename GeometryOut,
     template<typename, typename> class JoinStrategy,
+ template<typename, typename> class EndStrategy,
     typename Geometry
>
 void test_buffer(std::string const& caseid, Geometry const& geometry,
- char join,
             bool check, double expected_area,
- double distance_left, double distance_right, int expected_self_tangencies)
+ double distance_left, double distance_right,
+ int expected_self_tangencies)
 {
     namespace bg = boost::geometry;
 
@@ -100,12 +151,26 @@
                 : ""
                 ;
 
+ typedef typename bg::point_type<GeometryOut>::type output_point_type;
+
+ std::string join_name = JoinTestProperties<JoinStrategy>::name();
+ std::string end_name = EndTestProperties<EndStrategy>::name();
+
+ if (boost::is_same<tag, bg::point_tag>::value
+ || boost::is_same<tag, bg::multi_point_tag>::value)
+ {
+ join_name.clear();
+ }
+
     std::ostringstream complete;
     complete
         << type << "_"
         << caseid << "_"
         << string_from_type<coordinate_type>::name()
- << "_" << join;
+ << "_" << join_name
+ << (end_name.empty() ? "" : "_") << end_name
+ // << "_" << point_buffer_count
+ ;
 
     //std::cout << complete.str() << std::endl;
 
@@ -129,31 +194,52 @@
             distance_right = distance_left;
         }
 
- bg::buffer(box, box, d * (join == 'm' ? 2.0 : 1.1));
+ bg::buffer(box, box, d * (join_name == "miter" ? 2.0 : 1.1));
         mapper.add(box);
     }
 
- typedef JoinStrategy
+
+//#ifdef BOOST_GEOMETRY_BUFFER_FLAT_END
+// bg::strategy::buffer::end_flat<point_type, output_point_type> end_strategy;
+//#else
+// bg::strategy::buffer::end_round<point_type, output_point_type> end_strategy;
+//#endif
+//
+ JoinStrategy
         <
             point_type,
- typename bg::point_type<GeometryOut>::type
- > join_strategy_type;
+ output_point_type
+ > join_strategy;
 
- join_strategy_type join_strategy;
+ EndStrategy
+ <
+ point_type,
+ output_point_type
+ > end_strategy;
 
- typedef bg::strategy::buffer::distance_asymmetric<coordinate_type> distance_strategy_type;
- distance_strategy_type distance_strategy(distance_left, distance_right);
+ bg::strategy::buffer::distance_asymmetric
+ <
+ coordinate_type
+ >
+ distance_strategy(distance_left, distance_right);
 
     std::vector<GeometryOut> buffered;
 
     bg::buffer_inserter<GeometryOut>(geometry, std::back_inserter(buffered),
                         distance_strategy,
- join_strategy
+ join_strategy,
+ end_strategy
 #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
                         , mapper
 #endif
                                 );
 
+ //// Remove duplicate point (this step should go automatically in the end)
+ //BOOST_FOREACH(GeometryOut& polygon, buffered)
+ //{
+ // bg::unique(polygon);
+ //}
+
     typename bg::default_area_result<GeometryOut>::type area = 0;
     BOOST_FOREACH(GeometryOut const& polygon, buffered)
     {
@@ -171,17 +257,17 @@
 
     if (expected_area > -0.1)
     {
- typename bg::default_area_result<GeometryOut>::type tolerance = 0.01;
- if (join == 'r')
- {
- tolerance = 0.1;
- }
+ double tol = JoinTestProperties<JoinStrategy>::tolerance()
+ + EndTestProperties<EndStrategy>::tolerance();
 
                 if (expected_area < 1.0e-5)
                 {
- tolerance = 1.0e-10;
+ tol /= 1.0e6;
                 }
 
+ typename bg::default_area_result<GeometryOut>::type tolerance = tol;
+
+
         BOOST_CHECK_MESSAGE
             (
                 bg::math::abs(area - expected_area) < tolerance,
@@ -230,11 +316,13 @@
 <
     typename Geometry,
     template<typename, typename> class JoinStrategy,
+ template<typename, typename> class EndStrategy,
     typename GeometryOut
>
 void test_one(std::string const& caseid, std::string const& wkt,
- char join, double expected_area,
- double distance_left, double distance_right = -999, int expected_self_tangencies = 0)
+ double expected_area,
+ double distance_left, double distance_right = -999,
+ int expected_self_tangencies = 0)
 {
     namespace bg = boost::geometry;
     Geometry g;
@@ -250,13 +338,13 @@
         << ", '" << caseid << "' as caseid"
         << ", ST_Area(ST_Buffer(ST_GeomFromText('" << wkt << "'), "
         << distance_left
- << ", 'endcap=flat join=" << (join == 'm' ? "miter" : "round") << "'))"
+ << ", 'endcap=" << end_name << " join=" << join_name << "'))"
         << ", " << expected_area
         << std::endl;
 #endif
 
- test_buffer<GeometryOut, JoinStrategy>
- (caseid, g, join, false, expected_area,
+ test_buffer<GeometryOut, JoinStrategy, EndStrategy>
+ (caseid, g, false, expected_area,
             distance_left, distance_right, expected_self_tangencies);
 }
 


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