diff --git a/doc/html/img/algorithms/buffer_linestring.png b/doc/html/img/algorithms/buffer_linestring.png
new file mode 100644
index 000000000..2e135613e
Binary files /dev/null and b/doc/html/img/algorithms/buffer_linestring.png differ
diff --git a/doc/html/img/algorithms/buffer_multi_point.png b/doc/html/img/algorithms/buffer_multi_point.png
new file mode 100644
index 000000000..2d21c6e3f
Binary files /dev/null and b/doc/html/img/algorithms/buffer_multi_point.png differ
diff --git a/doc/html/img/algorithms/buffer_multi_polygon.png b/doc/html/img/algorithms/buffer_multi_polygon.png
new file mode 100644
index 000000000..f6c94a140
Binary files /dev/null and b/doc/html/img/algorithms/buffer_multi_polygon.png differ
diff --git a/doc/html/img/strategies/buffer_circle.png b/doc/html/img/strategies/buffer_circle.png
new file mode 100644
index 000000000..c48369ea1
Binary files /dev/null and b/doc/html/img/strategies/buffer_circle.png differ
diff --git a/doc/html/img/strategies/buffer_square.png b/doc/html/img/strategies/buffer_square.png
new file mode 100644
index 000000000..d03500eec
Binary files /dev/null and b/doc/html/img/strategies/buffer_square.png differ
diff --git a/doc/html/index.html b/doc/html/index.html
index 9719e84fa..841fbf5b1 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -3,7 +3,7 @@
Chapter 1. Geometry
-
+
@@ -100,12 +100,12 @@
Boost.Geometry contains contributions by:
-
+
-
Akira Takahashi (adaption of Boost.Fusion)
@@ -124,10 +124,14 @@
-
Mats Taraldsvik (documentation: adapting a legacy model)
+-
+ Samuel Debionne (variant support for distance, assign, crosses, intersection,
+ ...)
+
-Last revised: May 07, 2014 at 10:12:25 GMT |
+Last revised: July 17, 2014 at 20:45:09 GMT |
|
diff --git a/doc/imports.qbk b/doc/imports.qbk
index 3463c511d..4314a783a 100644
--- a/doc/imports.qbk
+++ b/doc/imports.qbk
@@ -20,6 +20,7 @@
[import src/examples/algorithms/assign_3d_point.cpp]
[import src/examples/algorithms/assign_inverse.cpp]
[import src/examples/algorithms/assign_points.cpp]
+[import src/examples/algorithms/buffer_with_strategies.cpp]
[import src/examples/algorithms/clear.cpp]
[import src/examples/algorithms/centroid.cpp]
[import src/examples/algorithms/comparable_distance.cpp]
@@ -82,7 +83,10 @@
[import src/examples/geometries/adapted/c_array.cpp]
[import src/examples/geometries/adapted/boost_array.cpp]
[import src/examples/geometries/adapted/boost_fusion.cpp]
-[import src/examples/geometries/adapted/boost_polygon.cpp]
+[import src/examples/geometries/adapted/boost_polygon_box.cpp]
+[import src/examples/geometries/adapted/boost_polygon_point.cpp]
+[import src/examples/geometries/adapted/boost_polygon_polygon.cpp]
+[import src/examples/geometries/adapted/boost_polygon_ring.cpp]
[import src/examples/geometries/adapted/boost_tuple.cpp]
[import src/examples/geometries/adapted/boost_range/filtered.cpp]
@@ -110,5 +114,8 @@
[import src/examples/io/wkt.cpp]
[import src/examples/io/read_wkt.cpp]
+[import src/examples/strategies/buffer_circle.cpp]
+[import src/examples/strategies/buffer_square.cpp]
+
[import src/examples/views/box_view.cpp]
[import src/examples/views/segment_view.cpp]
diff --git a/doc/index/imports.qbk b/doc/index/imports.qbk
index 45a613f75..4502ee41c 100644
--- a/doc/index/imports.qbk
+++ b/doc/index/imports.qbk
@@ -14,5 +14,6 @@
[import src/examples/rtree/variants_map.cpp]
[import src/examples/rtree/value_shared_ptr.cpp]
[import src/examples/rtree/value_index.cpp]
+[import src/examples/rtree/iterative_query.cpp]
[import src/examples/rtree/interprocess.cpp]
[import src/examples/rtree/mapped_file.cpp]
diff --git a/doc/index/rtree/examples.qbk b/doc/index/rtree/examples.qbk
index 24d54d466..ba82e88f0 100644
--- a/doc/index/rtree/examples.qbk
+++ b/doc/index/rtree/examples.qbk
@@ -46,6 +46,12 @@
[include ../src/examples/rtree/value_index_results.qbk]
[endsect]
+[section Iterative query]
+[rtree_iterative_query]
+[h4 Expected results]
+[include ../src/examples/rtree/iterative_query.qbk]
+[endsect]
+
[section Index stored in shared memory using Boost.Interprocess]
[rtree_interprocess]
[h4 Expected results]
diff --git a/doc/index/src/examples/rtree/Jamfile.v2 b/doc/index/src/examples/rtree/Jamfile.v2
index f45b5cb30..3e03c6000 100644
--- a/doc/index/src/examples/rtree/Jamfile.v2
+++ b/doc/index/src/examples/rtree/Jamfile.v2
@@ -6,12 +6,13 @@
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
-exe quick_start : quick_start.cpp ;
-exe polygons_vector : polygons_vector.cpp ;
+exe iterative_query : iterative_query.cpp ;
exe polygons_shared_ptr : polygons_shared_ptr.cpp ;
-exe variants_map : variants_map.cpp ;
-exe value_shared_ptr : value_shared_ptr.cpp ;
+exe polygons_vector : polygons_vector.cpp ;
+exe quick_start : quick_start.cpp ;
exe value_index : value_index.cpp ;
+exe value_shared_ptr : value_shared_ptr.cpp ;
+exe variants_map : variants_map.cpp ;
exe interprocess : interprocess.cpp /boost/thread//boost_thread
:
diff --git a/doc/index/src/examples/rtree/iterative_query.cpp b/doc/index/src/examples/rtree/iterative_query.cpp
new file mode 100644
index 000000000..32ce87606
--- /dev/null
+++ b/doc/index/src/examples/rtree/iterative_query.cpp
@@ -0,0 +1,65 @@
+// Boost.Geometry Index
+//
+// Quickbook Examples
+//
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+//
+// 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)
+
+//[rtree_iterative_query
+
+#include
+#include
+#include
+
+#include
+
+// just for output
+#include
+
+namespace bg = boost::geometry;
+namespace bgi = boost::geometry::index;
+
+int main(void)
+{
+ typedef bg::model::point point;
+ typedef point value;
+ typedef bgi::rtree< value, bgi::linear<16> > rtree_t;
+
+ // create the rtree using default constructor
+ rtree_t rtree;
+
+ // create some values
+ for ( double f = 0 ; f < 10 ; f += 1 )
+ {
+ // insert new value
+ rtree.insert(point(f, f));
+ }
+
+ // query point
+ point pt(5.1, 5.1);
+
+ // iterate over nearest Values
+ for ( rtree_t::const_query_iterator
+ it = rtree.qbegin(bgi::nearest(pt, 100)) ;
+ it != rtree.qend() ;
+ ++it )
+ {
+ double d = bg::distance(pt, *it);
+
+ std::cout << bg::wkt(*it) << ", distance= " << d << std::endl;
+
+ // break if the distance is too big
+ if ( d > 2 )
+ {
+ std::cout << "break!" << std::endl;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+//]
diff --git a/doc/index/src/examples/rtree/iterative_query.qbk b/doc/index/src/examples/rtree/iterative_query.qbk
new file mode 100644
index 000000000..816f04c27
--- /dev/null
+++ b/doc/index/src/examples/rtree/iterative_query.qbk
@@ -0,0 +1,16 @@
+[/============================================================================
+ Boost.Geometry Index
+
+ Copyright (c) 2011-2014 Adam Wulkiewicz.
+
+ 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)
+=============================================================================/]
+
+ POINT(5 5), distance= 0.141421
+ POINT(6 6), distance= 1.27279
+ POINT(4 4), distance= 1.55563
+ POINT(7 7), distance= 2.68701
+ break!
+
diff --git a/doc/make_qbk.py b/doc/make_qbk.py
index 333cf3d5c..6cd47f83c 100755
--- a/doc/make_qbk.py
+++ b/doc/make_qbk.py
@@ -115,6 +115,7 @@ strategies = ["distance::pythagoras", "distance::pythagoras_box_box"
, "distance::cross_track", "distance::projected_point"
, "within::winding", "within::franklin", "within::crossings_multiply"
, "area::surveyor", "area::huiller"
+ , "buffer::buffer_circle", "buffer::buffer_square"
, "centroid::bashein_detmer", "centroid::average"
, "convex_hull::graham_andrew"
, "simplify::douglas_peucker"
diff --git a/doc/quickref.xml b/doc/quickref.xml
index e1d816729..c57426c4b 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -487,13 +487,12 @@
-->
-
+
-
-
+
Strategies
@@ -630,6 +629,37 @@
+
+
+
+
+
+
+
+
+ IO
+
+
+
+
+
+
+ WKT (Well-Known Text)
+
+ read_wkt
+ wkt
+
+
+
+ SVG (Scalable Vector Graphics)
+
+ svg
+ svg_mapper
+
+
+
+
+
diff --git a/doc/reference.qbk b/doc/reference.qbk
index 5ae619b58..020bffa18 100644
--- a/doc/reference.qbk
+++ b/doc/reference.qbk
@@ -4,7 +4,7 @@
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
- Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+ Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -230,6 +230,7 @@
[section:io IO (input/output)]
[section:wkt WKT (Well-Known Text)]
+[include reference/io/wkt_format.qbk]
[include generated/wkt.qbk]
[endsect]
[section:svg SVG (Scalable Vector Graphics)]
@@ -299,6 +300,8 @@
[include generated/distance_cross_track.qbk]
[include generated/area_surveyor.qbk]
[include generated/area_huiller.qbk]
+[include generated/buffer_buffer_circle.qbk]
+[include generated/buffer_buffer_square.qbk]
[include generated/centroid_average.qbk]
[include generated/centroid_bashein_detmer.qbk]
[include generated/convex_hull_graham_andrew.qbk]
diff --git a/doc/reference/algorithms/buffer_with_strategies.qbk b/doc/reference/algorithms/buffer_with_strategies.qbk
new file mode 100644
index 000000000..197ab3ace
--- /dev/null
+++ b/doc/reference/algorithms/buffer_with_strategies.qbk
@@ -0,0 +1,29 @@
+[/============================================================================
+ Boost.Geometry (aka GGL, Generic Geometry Library)
+
+ Copyright (c) 2014 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)
+=============================================================================/]
+
+[def __this_function__ buffer]
+
+[heading_conformance_ogc __this_function__..Buffer]
+
+[heading Examples]
+[buffer_with_strategies]
+
+[heading The linestring case]
+[$img/algorithms/buffer_linestring.png]
+
+[heading The multi_point case]
+[$img/algorithms/buffer_multi_point.png]
+
+[heading The multi_polygon case]
+[$img/algorithms/buffer_multi_polygon.png]
+
+[heading Available Strategies]
+* PointStrategy: [link geometry.reference.strategies.strategy_buffer_buffer_circle Circle (cartesian)]
+* PointStrategy: [link geometry.reference.strategies.strategy_buffer_buffer_square Square (cartesian)]
diff --git a/doc/reference/geometries/adapted/boost_polygon/point_data.qbk b/doc/reference/geometries/adapted/boost_polygon/point_data.qbk
index ff013ed17..edc3f1f19 100644
--- a/doc/reference/geometries/adapted/boost_polygon/point_data.qbk
+++ b/doc/reference/geometries/adapted/boost_polygon/point_data.qbk
@@ -1,9 +1,10 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
- Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
- Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
- Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+ Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+ Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+ Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+ Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,8 +30,8 @@ algorithms from both Boost.Polygon and Boost.Geometry can be called.
__not_in_boost_geometry_hpp__
[heading Example]
-[boost_polygon]
-[boost_polygon_output]
+[boost_polygon_point]
+[boost_polygon_point_output]
[endsect]
diff --git a/doc/reference/geometries/adapted/boost_polygon/polygon_data.qbk b/doc/reference/geometries/adapted/boost_polygon/polygon_data.qbk
index e37628cb2..23c419014 100644
--- a/doc/reference/geometries/adapted/boost_polygon/polygon_data.qbk
+++ b/doc/reference/geometries/adapted/boost_polygon/polygon_data.qbk
@@ -1,9 +1,10 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
- Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
- Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
- Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+ Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+ Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+ Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+ Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +18,7 @@ Boost.Polygon's polygon type (boost::polygon::polygon_data) is adapted to the Bo
[heading Description]
Boost.Polygon's points (as well as polygons) can be used by Boost.Geometry. The
-two libraries can therefore be used together. Using a boost::polygon::point_data<...>,
+two libraries can therefore be used together. Using a boost::polygon::polygon_data<...>,
algorithms from both Boost.Polygon and Boost.Geometry can be called.
[heading Model of]
@@ -29,8 +30,8 @@ algorithms from both Boost.Polygon and Boost.Geometry can be called.
__not_in_boost_geometry_hpp__
[heading Example]
-[boost_polygon]
-[boost_polygon_output]
+[boost_polygon_ring]
+[boost_polygon_ring_output]
[endsect]
diff --git a/doc/reference/geometries/adapted/boost_polygon/polygon_with_holes_data.qbk b/doc/reference/geometries/adapted/boost_polygon/polygon_with_holes_data.qbk
index 52655a6f2..f9080cf20 100644
--- a/doc/reference/geometries/adapted/boost_polygon/polygon_with_holes_data.qbk
+++ b/doc/reference/geometries/adapted/boost_polygon/polygon_with_holes_data.qbk
@@ -1,9 +1,10 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
- Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
- Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
- Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+ Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+ Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+ Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+ Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -18,7 +19,7 @@ is adapted to the Boost.Geometry Polygon Concept.
[heading Description]
Boost.Polygon's points (as well as polygons) can be used by Boost.Geometry. The
-two libraries can therefore be used together. Using a boost::polygon::point_data<...>,
+two libraries can therefore be used together. Using a boost::polygon::polygon_with_holes_data<...>,
algorithms from both Boost.Polygon and Boost.Geometry can be called.
[heading Model of]
@@ -30,8 +31,8 @@ algorithms from both Boost.Polygon and Boost.Geometry can be called.
__not_in_boost_geometry_hpp__
[heading Example]
-[boost_polygon]
-[boost_polygon_output]
+[boost_polygon_polygon]
+[boost_polygon_polygon_output]
[endsect]
diff --git a/doc/reference/geometries/adapted/boost_polygon/rectangle_data.qbk b/doc/reference/geometries/adapted/boost_polygon/rectangle_data.qbk
index 48b80416d..75b38e6b8 100644
--- a/doc/reference/geometries/adapted/boost_polygon/rectangle_data.qbk
+++ b/doc/reference/geometries/adapted/boost_polygon/rectangle_data.qbk
@@ -1,9 +1,10 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
- Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
- Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
- Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+ Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+ Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+ Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+ Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +18,7 @@ Boost.Polygon's rectangle type (boost::polygon::rectangle_data) is adapted to th
[heading Description]
Boost.Polygon's points (as well as polygons) can be used by Boost.Geometry. The
-two libraries can therefore be used together. Using a boost::polygon::point_data<...>,
+two libraries can therefore be used together. Using a boost::polygon::rectangle_data<...>,
algorithms from both Boost.Polygon and Boost.Geometry can be called.
[heading Model of]
@@ -29,8 +30,8 @@ algorithms from both Boost.Polygon and Boost.Geometry can be called.
__not_in_boost_geometry_hpp__
[heading Example]
-[boost_polygon]
-[boost_polygon_output]
+[boost_polygon_box]
+[boost_polygon_box_output]
[endsect]
diff --git a/doc/reference/io/read_wkt.qbk b/doc/reference/io/read_wkt.qbk
index d34e90647..8022d8474 100644
--- a/doc/reference/io/read_wkt.qbk
+++ b/doc/reference/io/read_wkt.qbk
@@ -2,23 +2,13 @@
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2014 Barend Gehrels, Amsterdam, the Netherlands.
+ Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
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)
=============================================================================/]
-[heading The WKT Format]
-WKT is a general markup format in ASCII.
-It is described in detail on [@http://en.wikipedia.org/wiki/Well-known_text Wikipedia]
-
-Boost Geometry supports the common formats (POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON). Because Boost.Geometry
-also supports Box and Segment geometries, which are not standard OGC geometries, there are some extensions:
-
-* a Box can be read from WKT by specifying either a polygon (with 4 points) or a specific BOX string (non OGC)
-* a Segment can be read from WKT by specifying either a linestring (with 2 points) or a specific SEGMENT string (non OGC)
-* a Ring can be read from WKT by specifying a polygon (with no holes)
-
[heading Conformance]
Other libraries refer to this functionality as [*ST_GeomFromText] or [*STGeomFromText].
That is not done here because Boost.Geometry support more text formats. The name GeomFromText
diff --git a/doc/reference/io/wkt_format.qbk b/doc/reference/io/wkt_format.qbk
new file mode 100644
index 000000000..3c99fe808
--- /dev/null
+++ b/doc/reference/io/wkt_format.qbk
@@ -0,0 +1,29 @@
+[/============================================================================
+ Boost.Geometry (aka GGL, Generic Geometry Library)
+
+ Copyright (c) 2009-2014 Barend Gehrels, Amsterdam, the Netherlands.
+ Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+ 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)
+=============================================================================/]
+
+WKT is a general markup format in ASCII.
+It is described in detail on [@http://en.wikipedia.org/wiki/Well-known_text Wikipedia]
+
+Boost Geometry supports the common formats (POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON).
+
+Because Boost.Geometry also supports Box and Segment geometries, which are not standard OGC geometries, there are some extensions:
+
+[heading Box]
+* can be read from WKT by specifying either a polygon (with 4 points) or a specific BOX string (non OGC)
+* streamed to WKT as a POLYGON
+
+[heading Segment]
+* can be read from WKT by specifying either a linestring (with 2 points) or a specific SEGMENT string (non OGC)
+* streamed to WKT as a LINESTRING
+
+[heading Ring]
+* can be read from WKT by specifying a polygon (with no holes)
+* streamed to WKT as POLYGON
diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk
index 03304dbea..7ae7a5ce7 100644
--- a/doc/release_notes.qbk
+++ b/doc/release_notes.qbk
@@ -38,12 +38,15 @@
[*Solved tickets]
-* [@https://svn.boost.org/trac/boost/ticket/9245 9245] Check for process errors in make_qbk.py
-* [@https://svn.boost.org/trac/boost/ticket/9081 9081] Booleans create self-intersecting polygons from non-self-intersecting polygons
* [@https://svn.boost.org/trac/boost/ticket/8310 8310] Wrong results with overlapping polygons (fixed using point_on_surface for disjoint)
-* [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike
+* [@https://svn.boost.org/trac/boost/ticket/9081 9081] Booleans create self-intersecting polygons from non-self-intersecting polygons
+* [@https://svn.boost.org/trac/boost/ticket/9245 9245] Check for process errors in make_qbk.py
* [@https://svn.boost.org/trac/boost/ticket/9563 9563] (Sym)difference not successful, fixed by rescaling to robust type
+* [@https://svn.boost.org/trac/boost/ticket/9628 9628] Wrong result of within() due to the winding strategy not working correctly for nearly-horizontal segments
+* [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike
+* [@https://svn.boost.org/trac/boost/ticket/9947 9947] Missing info about WKT in documentation
* [@https://svn.boost.org/trac/boost/ticket/10019 10019] Difference of Linestring and Box returns their intersection
+* [@https://svn.boost.org/trac/boost/ticket/10077 10077] Wrong types in concept checks in boost/geometry/arithmetic/arithmetic.hpp
[*Bugfixes]
@@ -82,7 +85,6 @@
* [@https://svn.boost.org/trac/boost/ticket/8825 8825] Patch adding member variable documentation to doxygen_xml2qbk
* [@https://svn.boost.org/trac/boost/ticket/8652 8652] Intersection fails for triangle-triangle intersection. Caused by spike, fixed
* [@https://svn.boost.org/trac/boost/ticket/9047 9047] Boost files that include themselves (strategies/intersection.hpp), fixed
-* [@https://svn.boost.org/trac/boost/ticket/10077 10077] Wrong types in concept checks in boost/geometry/arithmetic/arithmetic.hpp, fixed
[*Internal changes]
diff --git a/doc/src/docutils/tools/support_status/support_status.cpp b/doc/src/docutils/tools/support_status/support_status.cpp
index 2fbc46a14..4cf636d74 100644
--- a/doc/src/docutils/tools/support_status/support_status.cpp
+++ b/doc/src/docutils/tools/support_status/support_status.cpp
@@ -34,6 +34,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -121,6 +123,8 @@ DECLARE_BINARY_ALGORITHM(equals)
DECLARE_BINARY_ALGORITHM(expand)
DECLARE_UNARY_ALGORITHM(for_each_point)
DECLARE_UNARY_ALGORITHM(for_each_segment)
+DECLARE_UNARY_ALGORITHM(is_simple)
+DECLARE_UNARY_ALGORITHM(is_valid)
DECLARE_UNARY_ALGORITHM(length)
DECLARE_UNARY_ALGORITHM(num_geometries)
DECLARE_UNARY_ALGORITHM(num_interior_rings)
@@ -257,10 +261,12 @@ void support_status()
test_binary_algorithm("expand");
test_unary_algorithm("for_each_point");
test_unary_algorithm("for_each_segment");
+ test_unary_algorithm("is_simple");
+ test_unary_algorithm("is_valid");
test_unary_algorithm("length");
test_unary_algorithm("num_geometries");
test_unary_algorithm("num_interior_rings");
- test_unary_algorithm("num_points");
+ test_unary_algorithm("num_points");
test_binary_algorithm("overlaps");
test_unary_algorithm("perimeter");
test_unary_algorithm("reverse");
diff --git a/doc/src/examples/Jamfile.v2 b/doc/src/examples/Jamfile.v2
index 90c5337d2..fbc49fe39 100644
--- a/doc/src/examples/Jamfile.v2
+++ b/doc/src/examples/Jamfile.v2
@@ -19,4 +19,5 @@ build-project algorithms ;
build-project core ;
build-project geometries ;
build-project io ;
+build-project strategies ;
build-project views ;
diff --git a/doc/src/examples/algorithms/Jamfile.v2 b/doc/src/examples/algorithms/Jamfile.v2
index 6da320270..d8e25d9fb 100644
--- a/doc/src/examples/algorithms/Jamfile.v2
+++ b/doc/src/examples/algorithms/Jamfile.v2
@@ -27,6 +27,7 @@ exe assign_points : assign_points.cpp ;
# exe assign_point_from_index : assign_point_from_index.cpp ;
# exe assign_point_to_index : assign_point_to_index.cpp ;
+exe buffer_with_strategies : buffer_with_strategies.cpp ;
exe centroid : centroid.cpp ;
exe clear : clear.cpp ;
exe comparable_distance : comparable_distance.cpp ;
diff --git a/doc/src/examples/algorithms/buffer_with_strategies.cpp b/doc/src/examples/algorithms/buffer_with_strategies.cpp
new file mode 100644
index 000000000..db2264bfd
--- /dev/null
+++ b/doc/src/examples/algorithms/buffer_with_strategies.cpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// QuickBook Example
+
+// Copyright (c) 2013, 2014 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)
+
+//[buffer_with_strategies
+//` Shows how the buffer algorithm can be used to create a buffer of a linestring
+
+#include
+#include
+#include
+/*<-*/ #include "../examples_utils/create_svg_buffer.hpp" /*->*/
+
+int main()
+{
+ typedef double coordinate_type;
+ typedef boost::geometry::model::d2::point_xy point;
+ typedef boost::geometry::model::polygon polygon;
+
+ // Declare strategies
+ const double buffer_distance = 1.0;
+ const int points_per_circle = 36;
+ boost::geometry::strategy::buffer::distance_symmetric distance_strategy(buffer_distance);
+ boost::geometry::strategy::buffer::join_round join_strategy(points_per_circle);
+ boost::geometry::strategy::buffer::end_round end_strategy(points_per_circle);
+ boost::geometry::strategy::buffer::buffer_circle circle_strategy(points_per_circle);
+ boost::geometry::strategy::buffer::buffer_side side_strategy;
+
+ // Declare output
+ boost::geometry::model::multi_polygon result;
+
+ // Declare/fill a linestring
+ boost::geometry::model::linestring ls;
+ boost::geometry::read_wkt("LINESTRING(0 0,4 5,7 4,10 6)", ls);
+
+ // Create the buffer of a linestring
+ boost::geometry::buffer(ls, result,
+ distance_strategy, side_strategy,
+ join_strategy, end_strategy, circle_strategy);
+ /*<-*/ create_svg_buffer("buffer_linestring.svg", ls, result); /*->*/
+
+ // Declare/fill a multi point
+ boost::geometry::model::multi_point mp;
+ boost::geometry::read_wkt("MULTIPOINT((3 3),(4 4))", mp);
+
+ // Create the buffer of a multi point
+ boost::geometry::buffer(mp, result,
+ distance_strategy, side_strategy,
+ join_strategy, end_strategy, circle_strategy);
+ /*<-*/ create_svg_buffer("buffer_multi_point.svg", mp, result); /*->*/
+
+ // Declare/fill a multi_polygon
+ boost::geometry::model::multi_polygon mpol;
+ boost::geometry::read_wkt("MULTIPOLYGON(((0 1,2 5,5 3,0 1)),((1 1,5 2,5 0,1 1)))", mpol);
+
+ // Create the buffer of a multi polygon
+ boost::geometry::buffer(mpol, result,
+ distance_strategy, side_strategy,
+ join_strategy, end_strategy, circle_strategy);
+ /*<-*/ create_svg_buffer("buffer_multi_polygon.svg", mpol, result); /*->*/
+
+ return 0;
+}
+
+//]
+
diff --git a/doc/src/examples/examples_utils/create_svg_buffer.hpp b/doc/src/examples/examples_utils/create_svg_buffer.hpp
new file mode 100644
index 000000000..b69d281bb
--- /dev/null
+++ b/doc/src/examples/examples_utils/create_svg_buffer.hpp
@@ -0,0 +1,49 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014 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)
+
+// Code to create SVG for buffer examples
+
+#ifndef CREATE_SVG_BUFFER_HPP
+#define CREATE_SVG_BUFFER_HPP
+
+#include
+
+#if defined(HAVE_SVG)
+# include
+#endif
+
+template
+void create_svg_buffer(std::string const& filename, Geometry1 const& original, Geometry2 const& buffer)
+{
+#if defined(HAVE_SVG)
+ typedef typename boost::geometry::point_type::type point_type;
+ std::ofstream svg(filename.c_str());
+
+ boost::geometry::svg_mapper mapper(svg, 400, 400);
+ mapper.add(original);
+ mapper.add(buffer);
+
+ // Draw buffer at bottom
+ mapper.map(buffer, "fill-opacity:0.6;fill:rgb(255,255,64);stroke:rgb(255,128,0);stroke-width:5;stroke-dasharray:1,7;stroke-linecap:round");
+
+ // Draw original on top
+ mapper.map(original, "fill-opacity:0.6;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:3");
+
+#else
+ boost::ignore_unused_variable_warning(filename);
+ boost::ignore_unused_variable_warning(original);
+ boost::ignore_unused_variable_warning(buffer);
+#endif
+}
+
+// NOTE: convert manually from svg to png using Inkscape ctrl-shift-E
+// and copy png to html/img/...
+
+
+#endif // CREATE_SVG_BUFFER_HPP
+
diff --git a/doc/src/examples/geometries/adapted/Jamfile.v2 b/doc/src/examples/geometries/adapted/Jamfile.v2
index 2fd3aefaa..dd40a2494 100644
--- a/doc/src/examples/geometries/adapted/Jamfile.v2
+++ b/doc/src/examples/geometries/adapted/Jamfile.v2
@@ -16,7 +16,10 @@ project boost-geometry-doc-src-example-geometries-adapted
exe c_array : c_array.cpp ;
exe boost_array : boost_array.cpp ;
exe boost_fusion : boost_fusion.cpp ;
-exe boost_polygon : boost_polygon.cpp ;
+exe boost_polygon_box : boost_polygon_box.cpp ;
+exe boost_polygon_point : boost_polygon_point.cpp ;
+exe boost_polygon_polygon : boost_polygon_polygon.cpp ;
+exe boost_polygon_ring : boost_polygon_ring.cpp ;
exe boost_tuple : boost_tuple.cpp ;
build-project boost_range ;
diff --git a/doc/src/examples/geometries/adapted/boost_polygon_box.cpp b/doc/src/examples/geometries/adapted/boost_polygon_box.cpp
new file mode 100644
index 000000000..dd465513c
--- /dev/null
+++ b/doc/src/examples/geometries/adapted/boost_polygon_box.cpp
@@ -0,0 +1,42 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// QuickBook Example
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// 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)
+
+//[boost_polygon_box
+//`Shows how to use Boost.Polygon rectangle_data within Boost.Geometry
+
+#include
+#include
+#include
+
+int main()
+{
+ typedef boost::polygon::rectangle_data rect;
+
+ rect b = boost::polygon::construct(1, 2, 3, 4);
+
+ std::cout << "Area (using Boost.Geometry): "
+ << boost::geometry::area(b) << std::endl;
+ std::cout << "Area (using Boost.Polygon): "
+ << boost::polygon::area(b) << std::endl;
+
+ return 0;
+}
+
+//]
+
+//[boost_polygon_box_output
+/*`
+Output:
+[pre
+Area (using Boost.Geometry): 4
+Area (using Boost.Polygon): 4
+]
+*/
+//]
diff --git a/doc/src/examples/geometries/adapted/boost_polygon.cpp b/doc/src/examples/geometries/adapted/boost_polygon_point.cpp
similarity index 83%
rename from doc/src/examples/geometries/adapted/boost_polygon.cpp
rename to doc/src/examples/geometries/adapted/boost_polygon_point.cpp
index b56a13d45..0f71f3f79 100644
--- a/doc/src/examples/geometries/adapted/boost_polygon.cpp
+++ b/doc/src/examples/geometries/adapted/boost_polygon_point.cpp
@@ -2,13 +2,14 @@
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// 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)
-//[boost_polygon
-//`Shows how to use Boost.Polygon points within Boost.Geometry
+//[boost_polygon_point
+//`Shows how to use Boost.Polygon point_data within Boost.Geometry
#include
#include
@@ -27,7 +28,7 @@ int main()
//]
-//[boost_polygon_output
+//[boost_polygon_point_output
/*`
Output:
[pre
diff --git a/doc/src/examples/geometries/adapted/boost_polygon_polygon.cpp b/doc/src/examples/geometries/adapted/boost_polygon_polygon.cpp
new file mode 100644
index 000000000..5444d832f
--- /dev/null
+++ b/doc/src/examples/geometries/adapted/boost_polygon_polygon.cpp
@@ -0,0 +1,64 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// QuickBook Example
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// 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)
+
+//[boost_polygon_polygon
+//`Shows how to use Boost.Polygon polygon_with_holes_data within Boost.Geometry
+
+#include
+#include
+#include
+
+int main()
+{
+ typedef boost::polygon::polygon_with_holes_data polygon;
+ typedef boost::polygon::polygon_traits::point_type point;
+ typedef boost::polygon::polygon_with_holes_traits::hole_type hole;
+
+ point pts[5] = {
+ boost::polygon::construct(0, 0),
+ boost::polygon::construct(0, 10),
+ boost::polygon::construct(10, 10),
+ boost::polygon::construct(10, 0),
+ boost::polygon::construct(0, 0)
+ };
+ point hole_pts[5] = {
+ boost::polygon::construct(1, 1),
+ boost::polygon::construct(9, 1),
+ boost::polygon::construct(9, 9),
+ boost::polygon::construct(1, 9),
+ boost::polygon::construct(1, 1)
+ };
+
+ hole hls[1];
+ boost::polygon::set_points(hls[0], hole_pts, hole_pts+5);
+
+ polygon poly;
+ boost::polygon::set_points(poly, pts, pts+5);
+ boost::polygon::set_holes(poly, hls, hls+1);
+
+ std::cout << "Area (using Boost.Geometry): "
+ << boost::geometry::area(poly) << std::endl;
+ std::cout << "Area (using Boost.Polygon): "
+ << boost::polygon::area(poly) << std::endl;
+
+ return 0;
+}
+
+//]
+
+//[boost_polygon_polygon_output
+/*`
+Output:
+[pre
+Area (using Boost.Geometry): 36
+Area (using Boost.Polygon): 36
+]
+*/
+//]
diff --git a/doc/src/examples/geometries/adapted/boost_polygon_ring.cpp b/doc/src/examples/geometries/adapted/boost_polygon_ring.cpp
new file mode 100644
index 000000000..e0cfd6dcb
--- /dev/null
+++ b/doc/src/examples/geometries/adapted/boost_polygon_ring.cpp
@@ -0,0 +1,52 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// QuickBook Example
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// 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)
+
+//[boost_polygon_ring
+//`Shows how to use Boost.Polygon polygon_data within Boost.Geometry
+
+#include
+#include
+#include
+
+int main()
+{
+ typedef boost::polygon::polygon_data polygon;
+ typedef boost::polygon::polygon_traits::point_type point;
+
+ point pts[5] = {
+ boost::polygon::construct(0, 0),
+ boost::polygon::construct(0, 10),
+ boost::polygon::construct(10, 10),
+ boost::polygon::construct(10, 0),
+ boost::polygon::construct(0, 0)
+ };
+
+ polygon poly;
+ boost::polygon::set_points(poly, pts, pts+5);
+
+ std::cout << "Area (using Boost.Geometry): "
+ << boost::geometry::area(poly) << std::endl;
+ std::cout << "Area (using Boost.Polygon): "
+ << boost::polygon::area(poly) << std::endl;
+
+ return 0;
+}
+
+//]
+
+//[boost_polygon_ring_output
+/*`
+Output:
+[pre
+Area (using Boost.Geometry): 100
+Area (using Boost.Polygon): 100
+]
+*/
+//]
diff --git a/doc/src/examples/strategies/Jamfile.v2 b/doc/src/examples/strategies/Jamfile.v2
new file mode 100644
index 000000000..fe25d740b
--- /dev/null
+++ b/doc/src/examples/strategies/Jamfile.v2
@@ -0,0 +1,15 @@
+# Boost.Geometry (aka GGL, Generic Geometry Library)
+#
+# Copyright (c) 2007-2014 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)
+
+
+project boost-geometry-doc-example-strategies
+ : # requirements
+ ;
+
+exe buffer_circle : buffer_circle.cpp ;
+exe buffer_square : buffer_square.cpp ;
diff --git a/doc/src/examples/strategies/buffer_circle.cpp b/doc/src/examples/strategies/buffer_circle.cpp
new file mode 100644
index 000000000..237824a85
--- /dev/null
+++ b/doc/src/examples/strategies/buffer_circle.cpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// QuickBook Example
+
+// Copyright (c) 2014 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)
+
+//[buffer_circle
+//` Shows how the buffer_circle strategy can be used as a PointStrategy to create circular buffers around points
+
+#include
+#include
+#include
+/*<-*/ #include "../examples_utils/create_svg_buffer.hpp" /*->*/
+
+int main()
+{
+ typedef double coordinate_type;
+ typedef boost::geometry::model::d2::point_xy point;
+ typedef boost::geometry::model::polygon polygon;
+
+ // Declare the buffer_circle strategy
+ const int points_per_circle = 360;
+
+ boost::geometry::strategy::buffer::buffer_circle circle_strategy(points_per_circle);
+
+ // Declare other strategies
+ const double buffer_distance = 0.7;
+ boost::geometry::strategy::buffer::distance_symmetric distance_strategy(buffer_distance);
+ boost::geometry::strategy::buffer::join_round join_strategy(points_per_circle);
+ boost::geometry::strategy::buffer::end_round end_strategy(points_per_circle);
+ boost::geometry::strategy::buffer::buffer_side side_strategy;
+
+ // Declare output
+ boost::geometry::model::multi_polygon result;
+
+ // Declare/fill of a multi point
+ boost::geometry::model::multi_point mp;
+ boost::geometry::read_wkt("MULTIPOINT((3 3),(3 4),(4 4),(7 3))", mp);
+
+ // Create the buffer of a multi point
+ boost::geometry::buffer(mp, result,
+ distance_strategy, side_strategy,
+ join_strategy, end_strategy, circle_strategy);
+ /*<-*/ create_svg_buffer("buffer_circle.svg", mp, result); /*->*/
+
+ return 0;
+}
+
+//]
+
diff --git a/doc/src/examples/strategies/buffer_square.cpp b/doc/src/examples/strategies/buffer_square.cpp
new file mode 100644
index 000000000..ea38be9b5
--- /dev/null
+++ b/doc/src/examples/strategies/buffer_square.cpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// QuickBook Example
+
+// Copyright (c) 2014 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)
+
+//[buffer_square
+//` Shows how the buffer_square strategy can be used as a PointStrategy to create square buffers where the original point lies in the center
+
+
+#include
+#include
+#include
+/*<-*/ #include "../examples_utils/create_svg_buffer.hpp" /*->*/
+
+int main()
+{
+ typedef double coordinate_type;
+ typedef boost::geometry::model::d2::point_xy point;
+ typedef boost::geometry::model::polygon polygon;
+
+ // Declare the buffer_square strategy
+ boost::geometry::strategy::buffer::buffer_square square_strategy;
+
+ // Declare other strategies
+ const int points_per_circle = 36;
+ const double buffer_distance = 0.5;
+ boost::geometry::strategy::buffer::distance_symmetric distance_strategy(buffer_distance);
+ boost::geometry::strategy::buffer::join_round join_strategy(points_per_circle);
+ boost::geometry::strategy::buffer::end_round end_strategy(points_per_circle);
+ boost::geometry::strategy::buffer::buffer_side side_strategy;
+
+ // Declare output
+ boost::geometry::model::multi_polygon result;
+
+ // Declare/fill of a multi point
+ boost::geometry::model::multi_point mp;
+ boost::geometry::read_wkt("MULTIPOINT((3 3),(3 4),(4 4),(7 3))", mp);
+
+ // Create the buffer of a multi point
+ boost::geometry::buffer(mp, result,
+ distance_strategy, side_strategy,
+ join_strategy, end_strategy, square_strategy);
+ /*<-*/ create_svg_buffer("buffer_square.svg", mp, result); /*->*/
+
+ return 0;
+}
+
+//]
+
diff --git a/include/boost/geometry/algorithms/buffer.hpp b/include/boost/geometry/algorithms/buffer.hpp
index 13d48c0d5..ca2e39f20 100644
--- a/include/boost/geometry/algorithms/buffer.hpp
+++ b/include/boost/geometry/algorithms/buffer.hpp
@@ -28,6 +28,7 @@
#include
#include
+#include
namespace boost { namespace geometry
{
@@ -99,11 +100,6 @@ struct buffer
}
};
-// Many things to do. Point is easy, other geometries require self intersections
-// For point, note that it should output as a polygon (like the rest). Buffers
-// of a set of geometries are often lateron combined using a "dissolve" operation.
-// Two points close to each other get a combined kidney shaped buffer then.
-
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
@@ -174,7 +170,6 @@ struct buffer >
\param geometry_out \param_geometry
\param distance The distance to be used for the buffer
\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
-\note Currently only implemented for box, the trivial case, but still useful
\qbk{[include reference/algorithms/buffer.qbk]}
*/
@@ -198,7 +193,7 @@ inline void buffer(Input const& geometry_in, Output& geometry_out,
\param geometry \param_geometry
\param distance The distance to be used for the buffer
\param chord_length (optional) The length of the chord's in the generated arcs
- around points or bends
+ around points or bends (RESERVED, NOT YET USED)
\return \return_calc{buffer}
*/
template
@@ -214,6 +209,68 @@ Output return_buffer(Input const& geometry, Distance const& distance, Distance c
return geometry_out;
}
+/*!
+\brief \brief_calc{buffer}
+\ingroup buffer
+\details \details_calc{buffer, \det_buffer}.
+\tparam GeometryIn \tparam_geometry
+\tparam MultiPolygon \tparam_geometry
+\tparam DistanceStrategy A strategy defining distance behaviour (symmetric, asymetric)
+\tparam SideStrategy A strategy defining creation of buffer along sides
+\tparam JoinStrategy A strategy defining creation of buffer around convex joins (round, miter)
+\tparam EndStrategy A strategy defining creation of buffer at linestring ends (round, flat)
+\tparam PointStrategy A strategy defining creation of buffer around points
+\param geometry_in \param_geometry
+\param geometry_out output multi polygon (or std:: collection of polygons), contains buffer of input geometry
+\param distance_strategy The distance strategy to be used
+\param side_strategy The side strategy to be used
+\param join_strategy The join strategy to be used
+\param end_strategy The end strategy to be used
+\param point_strategy The point strategy to be used
+
+\qbk{distinguish,with strategies}
+\qbk{[include reference/algorithms/buffer_with_strategies.qbk]}
+ */
+template
+<
+ typename GeometryIn,
+ typename MultiPolygon,
+ typename DistanceStrategy,
+ typename SideStrategy,
+ typename JoinStrategy,
+ typename EndStrategy,
+ typename PointStrategy
+>
+inline void buffer(GeometryIn const& geometry_in,
+ MultiPolygon& geometry_out,
+ DistanceStrategy const& distance_strategy,
+ SideStrategy const& side_strategy,
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy)
+{
+ typedef typename boost::range_value::type polygon_type;
+ concept::check();
+ concept::check();
+
+ typedef typename point_type::type point_type;
+ typedef typename rescale_policy_type::type rescale_policy_type;
+
+ geometry_out.clear();
+
+ rescale_policy_type rescale_policy
+ = boost::geometry::get_rescale_policy(geometry_in);
+
+ detail::buffer::buffer_inserter(geometry_in, std::back_inserter(geometry_out),
+ distance_strategy,
+ side_strategy,
+ join_strategy,
+ end_strategy,
+ point_strategy,
+ rescale_policy);
+}
+
+
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
index d67f09888..1ed549bc0 100644
--- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
+++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
@@ -29,6 +29,10 @@
#include
+#if defined(BOOST_GEOMETRY_BUFFER_SIMPLIFY_WITH_AX)
+#include
+#endif
+
namespace boost { namespace geometry
{
@@ -51,10 +55,41 @@ inline void simplify_input(Range const& range,
// sensitive to small scale input features, however the result will
// look better.
// It also get rid of duplicate points
+#if ! defined(BOOST_GEOMETRY_BUFFER_SIMPLIFY_WITH_AX)
geometry::simplify(range, simplified, distance.simplify_distance());
- //simplified = range;
+#else
+
+ typedef typename boost::range_value::type point_type;
+ typedef strategy::distance::detail::projected_point_ax<> ax_type;
+ typedef typename strategy::distance::services::return_type
+ <
+ strategy::distance::detail::projected_point_ax<>,
+ point_type,
+ point_type
+ >::type return_type;
+
+ typedef strategy::distance::detail::projected_point_ax_less
+ <
+ return_type
+ > comparator_type;
+
+ typedef strategy::simplify::detail::douglas_peucker
+ <
+ point_type,
+ strategy::distance::detail::projected_point_ax<>,
+ comparator_type
+ > dp_ax;
+
+ return_type max_distance(distance.simplify_distance() * 2.0,
+ distance.simplify_distance());
+ comparator_type comparator(max_distance);
+ dp_ax strategy(comparator);
+
+ geometry::simplify(range, simplified, max_distance, strategy);
+#endif
}
+
template
struct buffer_range
{
@@ -72,7 +107,6 @@ struct buffer_range
>
static inline
void add_join(Collection& collection,
- int phase,
Point const& penultimate_input,
Point const& previous_input,
output_point_type const& prev_perp1,
@@ -110,7 +144,6 @@ struct buffer_range
previous_input, prev_perp2, perp1);
return;
case strategy::buffer::join_spike :
- //if (phase == 0) avoid duplicate joins at spikes? this still causes other issues
{
// For linestrings, only add spike at one side to avoid
// duplicates
@@ -124,7 +157,7 @@ struct buffer_range
}
// The corner is convex, we create a join
- // TODO - try to avoid a separate vector, add the piece directly
+ // TODO (future) - avoid a separate vector, add the piece directly
std::vector range_out;
join_strategy.apply(intersection_point,
previous_input, prev_perp2, perp1,
@@ -168,7 +201,6 @@ struct buffer_range
typename RobustPolicy
>
static inline void iterate(Collection& collection,
- int phase, // 0/1 for left/right of rings. For polygons: 0
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -235,7 +267,7 @@ struct buffer_range
if (! first)
{
- add_join(collection, phase,
+ add_join(collection,
penultimate_point,
*prev, last_p1, last_p2,
*it, generated_side.front(), generated_side.back(),
@@ -265,85 +297,6 @@ struct buffer_range
}
};
-
-
-template
-<
- typename Point,
- typename RingOutput
->
-struct buffer_point
-{
- typedef typename point_type::type output_point_type;
- typedef typename coordinate_type::type coordinate_type;
-
- typedef typename geometry::select_most_precise
- <
- typename geometry::select_most_precise
- <
- typename geometry::coordinate_type::type,
- typename geometry::coordinate_type::type
- >::type,
- double
- >::type promoted_type;
-
-
- template
- 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();
- 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)
- {
- first = p;
- }
- }
-
- // Close it:
- range_out.push_back(first);
- }
-
-
- template
- <
- typename Collection,
- typename DistanceStrategy,
- typename JoinStrategy,
- typename EndStrategy,
- typename RobustPolicy
- >
- static inline void generate_circle(Point const& point,
- Collection& collection,
- DistanceStrategy const& distance,
- JoinStrategy const& ,
- EndStrategy const& ,
- RobustPolicy const& )
- {
- std::vector range_out;
-
- generate_points(point,
- distance.apply(point, point, strategy::buffer::buffer_side_left),
- range_out);
-
- collection.add_piece(strategy::buffer::buffered_circle, range_out, false);
- }
-};
-
template
<
typename Multi,
@@ -359,14 +312,16 @@ struct buffer_multi
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
static inline void apply(Multi const& multi,
Collection& collection,
- DistanceStrategy const& distance,
+ DistanceStrategy const& distance_strategy,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy)
{
for (typename boost::range_iterator::type
@@ -374,7 +329,10 @@ struct buffer_multi
it != boost::end(multi);
++it)
{
- Policy::apply(*it, collection, distance, side_strategy, join_strategy, end_strategy, robust_policy);
+ Policy::apply(*it, collection,
+ distance_strategy, side_strategy,
+ join_strategy, end_strategy, point_strategy,
+ robust_policy);
}
}
};
@@ -411,7 +369,6 @@ template
typename RingOutput
>
struct buffer_inserter
- : public detail::buffer::buffer_point
{
template
<
@@ -420,18 +377,23 @@ struct buffer_inserter
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
static inline void apply(Point const& point, Collection& collection,
- DistanceStrategy const& distance,
+ DistanceStrategy const& distance_strategy,
SideStrategy const& ,
- JoinStrategy const& join_strategy,
- EndStrategy const& end_strategy,
- RobustPolicy const& robust_policy)
+ JoinStrategy const& ,
+ EndStrategy const& ,
+ PointStrategy const& point_strategy,
+ RobustPolicy const& )
{
+ typedef typename point_type::type output_point_type;
+
collection.start_new_ring();
- typedef detail::buffer::buffer_point base;
- base::generate_circle(point, collection, distance, join_strategy, end_strategy, robust_policy);
+ std::vector range_out;
+ point_strategy.apply(point, distance_strategy, range_out);
+ collection.add_piece(strategy::buffer::buffered_point, range_out, false);
collection.finish_ring();
}
};
@@ -469,13 +431,13 @@ struct buffer_inserter
typedef detail::buffer::buffer_range buffer_range;
- buffer_range::iterate(collection, 0, begin, end,
+ buffer_range::iterate(collection, begin, end,
side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
// Generate closing join
- buffer_range::add_join(collection, 0,
+ buffer_range::add_join(collection,
*(end - 2),
*(end - 1), last_p1, last_p2,
*(begin + 1), first_p1, first_p2,
@@ -484,7 +446,6 @@ struct buffer_inserter
robust_policy);
// Buffer is closed automatically by last closing corner
- // (OPEN IT FOR OPEN POLYGONS - TODO)
}
template
@@ -494,6 +455,7 @@ struct buffer_inserter
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
static inline void apply(RingInput const& ring,
@@ -502,6 +464,7 @@ struct buffer_inserter
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& ,
RobustPolicy const& robust_policy)
{
if (boost::size(ring) > 3)
@@ -564,7 +527,7 @@ struct buffer_inserter
typename EndStrategy,
typename RobustPolicy
>
- static inline void iterate(Collection& collection, int phase,
+ static inline void iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -589,7 +552,7 @@ struct buffer_inserter
output_point_type first_p2, last_p1, last_p2;
detail::buffer::buffer_range::iterate(collection,
- phase, begin, end, side,
+ begin, end, side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
@@ -605,6 +568,7 @@ struct buffer_inserter
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
static inline void apply(Linestring const& linestring, Collection& collection,
@@ -612,6 +576,7 @@ struct buffer_inserter
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& ,
RobustPolicy const& robust_policy)
{
if (boost::size(linestring) > 1)
@@ -621,17 +586,21 @@ struct buffer_inserter
collection.start_new_ring();
output_point_type first_p1;
- iterate(collection, 0, boost::begin(simplified), boost::end(simplified),
+ iterate(collection, boost::begin(simplified), boost::end(simplified),
strategy::buffer::buffer_side_left,
distance, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1);
- iterate(collection, 1, boost::rbegin(simplified), boost::rend(simplified),
+ iterate(collection, boost::rbegin(simplified), boost::rend(simplified),
strategy::buffer::buffer_side_right,
distance, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1);
collection.finish_ring();
}
+ else
+ {
+ // Use point_strategy to buffer degenerated linestring
+ }
}
};
@@ -658,6 +627,7 @@ private:
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
static inline
@@ -667,12 +637,15 @@ private:
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy)
{
for (Iterator it = begin; it != end; ++it)
{
collection.start_new_ring();
- policy::apply(*it, collection, distance, side_strategy, join_strategy, end_strategy, robust_policy);
+ policy::apply(*it, collection, distance, side_strategy,
+ join_strategy, end_strategy, point_strategy,
+ robust_policy);
collection.finish_ring();
}
}
@@ -685,6 +658,7 @@ private:
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
static inline
@@ -694,10 +668,13 @@ private:
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy)
{
iterate(boost::begin(interior_rings), boost::end(interior_rings),
- collection, distance, side_strategy, join_strategy, end_strategy, robust_policy);
+ collection, distance, side_strategy,
+ join_strategy, end_strategy, point_strategy,
+ robust_policy);
}
public:
@@ -708,6 +685,7 @@ public:
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
static inline void apply(PolygonInput const& polygon,
@@ -716,17 +694,22 @@ public:
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy)
{
{
collection.start_new_ring();
policy::apply(exterior_ring(polygon), collection,
- distance, side_strategy, join_strategy, end_strategy, robust_policy);
+ distance, side_strategy,
+ join_strategy, end_strategy, point_strategy,
+ robust_policy);
collection.finish_ring();
}
apply_interior_rings(interior_rings(polygon),
- collection, distance, side_strategy, join_strategy, end_strategy, robust_policy);
+ collection, distance, side_strategy,
+ join_strategy, end_strategy, point_strategy,
+ robust_policy);
}
};
@@ -757,6 +740,10 @@ struct buffer_inserter
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
template
<
typename GeometryOutput,
@@ -766,6 +753,7 @@ template
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy,
typename VisitPiecesPolicy
>
@@ -774,6 +762,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy,
VisitPiecesPolicy& visit_pieces_policy
)
@@ -795,7 +784,10 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
>::type,
GeometryInput,
GeometryOutput
- >::apply(geometry_input, collection, distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy);
+ >::apply(geometry_input, collection,
+ distance_strategy, side_strategy, join_strategy,
+ end_strategy, point_strategy,
+ robust_policy);
collection.get_turns(geometry_input, distance_strategy);
@@ -836,6 +828,7 @@ template
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
+ typename PointStrategy,
typename RobustPolicy
>
inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator out,
@@ -843,13 +836,18 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy)
{
detail::buffer::visit_pieces_default_policy visitor;
buffer_inserter(geometry_input, out,
- distance_strategy, side_strategy, join_strategy, end_strategy,
+ distance_strategy, side_strategy, join_strategy,
+ end_strategy, point_strategy,
robust_policy, visitor);
}
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace detail::buffer
}} // namespace boost::geometry
diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
index 828547040..216b17143 100644
--- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
+++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
@@ -23,6 +23,8 @@
#include
+#include
+
#include
#include
#include
@@ -571,7 +573,7 @@ struct buffered_piece_collection
inline void finish_ring()
{
BOOST_ASSERT(m_first_piece_index != -1);
- if (m_first_piece_index < boost::size(m_pieces))
+ if (m_first_piece_index < static_cast(boost::size(m_pieces)))
{
// If piece was added
// Reassign left-of-first and right-of-last
diff --git a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
index b82cb1e6d..3328b174d 100644
--- a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
+++ b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
@@ -11,6 +11,7 @@
#include
+#include
#include
#include
#include
diff --git a/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp
index 29ceb96be..0d541cc3a 100644
--- a/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp
+++ b/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp
@@ -104,10 +104,10 @@ public:
if (first || cdist < min_cdist)
{
min_cdist = cdist;
- }
- if ( geometry::math::equals(min_cdist, 0) )
- {
- break;
+ if ( geometry::math::equals(min_cdist, 0) )
+ {
+ break;
+ }
}
}
diff --git a/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp
index 9966381e5..59cf17230 100644
--- a/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp
+++ b/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp
@@ -111,10 +111,10 @@ public:
if (first || cdist < min_cdist)
{
min_cdist = cdist;
- }
- if ( geometry::math::equals(min_cdist, 0) )
- {
- break;
+ if ( geometry::math::equals(min_cdist, 0) )
+ {
+ break;
+ }
}
}
diff --git a/include/boost/geometry/extensions/algorithms/offset.hpp b/include/boost/geometry/extensions/algorithms/offset.hpp
index baf8f91ef..ec8943d2a 100644
--- a/include/boost/geometry/extensions/algorithms/offset.hpp
+++ b/include/boost/geometry/extensions/algorithms/offset.hpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
#include
@@ -39,43 +40,48 @@ template
typename RangeOut
>
struct offset_range
- : public geometry::detail::buffer::buffer_range
- <
- RangeOut,
- linestring_tag
- >
{
typedef geometry::detail::buffer::buffer_range
<
- RangeOut,
- linestring_tag
- > super;
+ Range
+ > per_range;
+
template
<
typename Collection,
typename DistanceStrategy,
+ typename SideStrategy,
typename JoinStrategy,
- typename EndStrategy
+ typename EndStrategy,
+ typename RobustPolicy
>
static inline void apply(Collection& collection, Range const& range,
DistanceStrategy const& distance_strategy,
+ SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
+ RobustPolicy const& robust_policy,
bool reverse)
{
collection.start_new_ring();
+ typedef typename point_type::type output_point_type;
+ output_point_type first_p1, first_p2, last_p1, last_p2;
+
if (reverse)
{
- super::iterate(collection, boost::rbegin(range), boost::rend(range),
- buffer_side_left,
- distance_strategy, join_strategy, end_strategy);
+ per_range::iterate(collection, 0, boost::rbegin(range), boost::rend(range),
+ strategy::buffer::buffer_side_left,
+ distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
+ first_p1, first_p2, last_p1, last_p2);
}
else
{
- super::iterate(collection, boost::begin(range), boost::end(range),
- buffer_side_left,
- distance_strategy, join_strategy, end_strategy);
+ per_range::iterate(collection, 0, boost::begin(range), boost::end(range),
+ strategy::buffer::buffer_side_left,
+ distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
+ first_p1, first_p2, last_p1, last_p2);
}
+ collection.finish_ring();
}
};
@@ -160,6 +166,8 @@ inline void offset(Geometry const& geometry, GeometryOut& out,
point_type
> end_strategy;
+ strategy::buffer::buffer_side side_strategy;
+
dispatch::offset
<
typename tag::type,
@@ -169,11 +177,13 @@ inline void offset(Geometry const& geometry, GeometryOut& out,
>::apply(collection,
geometry,
distance_strategy,
+ side_strategy,
join_strategy,
end_strategy,
+ robust_policy,
reverse);
- collection.assign_offsetted_rings(out);
+ // TODO collection.template assign(out);
}
diff --git a/include/boost/geometry/multi/algorithms/num_points.hpp b/include/boost/geometry/multi/algorithms/num_points.hpp
index 180523a98..ac10ddff4 100644
--- a/include/boost/geometry/multi/algorithms/num_points.hpp
+++ b/include/boost/geometry/multi/algorithms/num_points.hpp
@@ -15,6 +15,7 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
+#include
#include
@@ -34,7 +35,8 @@ namespace detail { namespace num_points
struct multi_count
{
template
- static inline size_t apply(MultiGeometry const& geometry, bool add_for_open)
+ static inline
+ std::size_t apply(MultiGeometry const& geometry, bool add_for_open)
{
typedef typename boost::range_value::type geometry_type;
typedef typename boost::range_iterator
diff --git a/include/boost/geometry/strategies/agnostic/buffer_end_skip.hpp b/include/boost/geometry/strategies/agnostic/buffer_end_skip.hpp
deleted file mode 100644
index 798980194..000000000
--- a/include/boost/geometry/strategies/agnostic/buffer_end_skip.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2012-2014 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_STRATEGIES_AGNOSTIC_BUFFER_END_SKIP_HPP
-#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_END_SKIP_HPP
-
-#include
-
-
-namespace boost { namespace geometry
-{
-
-
-namespace strategy { namespace buffer
-{
-
-
-template
-<
- typename PointIn,
- typename PointOut
->
-class end_skip
-{
-public :
-
- template
- 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_STRATEGIES_AGNOSTIC_BUFFER_END_SKIP_HPP
diff --git a/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp b/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
index 24d7470ae..e6161b677 100644
--- a/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
+++ b/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
@@ -33,6 +33,78 @@ namespace boost { namespace geometry
namespace strategy { namespace within
{
+
+// Fix for https://svn.boost.org/trac/boost/ticket/9628
+// For floating point coordinates, the <1> coordinate of a point is compared
+// with the segment's points using some EPS. If the coordinates are "equal"
+// the sides are calculated. Therefore we can treat a segment as a long areal
+// geometry having some width. There is a small ~triangular area somewhere
+// between the segment's effective area and a segment's line used in sides
+// calculation where the segment is on the one side of the line but on the
+// other side of a segment (due to the width).
+// For the s1 of a segment going NE the real side is RIGHT but the point may
+// be detected as LEFT, like this:
+// RIGHT
+// ___----->
+// ^ O Pt __ __
+// EPS __ __
+// v__ __ BUT DETECTED AS LEFT OF THIS LINE
+// _____7
+// _____/
+// _____/
+template
+struct winding_side_equal
+{
+ typedef typename strategy::side::services::default_strategy
+ <
+ CSTag
+ >::type strategy_side_type;
+
+ template
+ static inline int apply(Point const& point,
+ PointOfSegment const& se,
+ int count)
+ {
+ // Create a vertical segment intersecting the original segment's endpoint
+ // equal to the point, with the derived direction (UP/DOWN).
+ // Set only the 2 first coordinates, the other ones are ignored
+ PointOfSegment ss1, ss2;
+ set<1-D>(ss1, get<1-D>(se));
+ set<1-D>(ss2, get<1-D>(se));
+ if ( count > 0 ) // UP
+ {
+ set(ss1, 0);
+ set(ss2, 1);
+ }
+ else // DOWN
+ {
+ set(ss1, 1);
+ set(ss2, 0);
+ }
+ // Check the side using this vertical segment
+ return strategy_side_type::apply(ss1, ss2, point);
+ }
+};
+
+// The optimization for cartesian
+template <>
+struct winding_side_equal
+{
+ template
+ static inline int apply(Point const& point,
+ PointOfSegment const& se,
+ int count)
+ {
+ return math::equals(get<1-D>(point), get<1-D>(se)) ?
+ 0 :
+ get<1-D>(point) < get<1-D>(se) ?
+ // assuming count is equal to 1 or -1
+ count : // ( count > 0 ? 1 : -1) :
+ -count; // ( count > 0 ? -1 : 1) ;
+ }
+};
+
+
/*!
\brief Within detection using winding rule
\ingroup strategies
@@ -112,21 +184,21 @@ class winding
template
static inline int check_segment(Point const& point,
PointOfSegment const& seg1, PointOfSegment const& seg2,
- counter& state)
+ counter& state, bool& eq1, bool& eq2)
{
calculation_type const p = get(point);
calculation_type const s1 = get(seg1);
calculation_type const s2 = get(seg2);
// Check if one of segment endpoints is at same level of point
- bool eq1 = math::equals(s1, p);
- bool eq2 = math::equals(s2, p);
+ eq1 = math::equals(s1, p);
+ eq2 = math::equals(s2, p);
if (eq1 && eq2)
{
// Both equal p -> segment is horizontal (or vertical for D=0)
// The only thing which has to be done is check if point is ON segment
- return check_touch<1 - D>(point, seg1, seg2,state);
+ return check_touch<1 - D>(point, seg1, seg2, state);
}
return
@@ -138,8 +210,6 @@ class winding
}
-
-
public :
// Typedefs and static methods to fulfill the concept
@@ -151,10 +221,24 @@ public :
PointOfSegment const& s1, PointOfSegment const& s2,
counter& state)
{
- int count = check_segment<1>(point, s1, s2, state);
+ bool eq1 = false;
+ bool eq2 = false;
+ boost::ignore_unused(eq2);
+
+ int count = check_segment<1>(point, s1, s2, state, eq1, eq2);
if (count != 0)
{
- int side = strategy_side_type::apply(s1, s2, point);
+ int side = 0;
+ if ( count == 1 || count == -1 )
+ {
+ side = winding_side_equal::type>
+ ::template apply<1>(point, eq1 ? s1 : s2, count);
+ }
+ else
+ {
+ side = strategy_side_type::apply(s1, s2, point);
+ }
+
if (side == 0)
{
// Point is lying on segment
diff --git a/include/boost/geometry/strategies/buffer.hpp b/include/boost/geometry/strategies/buffer.hpp
index 6b27c35bd..7dbe03b4a 100644
--- a/include/boost/geometry/strategies/buffer.hpp
+++ b/include/boost/geometry/strategies/buffer.hpp
@@ -65,7 +65,7 @@ enum piece_type
buffered_join,
buffered_round_end,
buffered_flat_end,
- buffered_circle,
+ buffered_point,
buffered_concave // always on the inside
};
diff --git a/include/boost/geometry/strategies/cartesian/buffer_circle.hpp b/include/boost/geometry/strategies/cartesian/buffer_circle.hpp
new file mode 100644
index 000000000..5ff3d30e6
--- /dev/null
+++ b/include/boost/geometry/strategies/cartesian/buffer_circle.hpp
@@ -0,0 +1,109 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Copyright (c) 2012-2014 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_STRATEGIES_CARTESIAN_BUFFER_CIRCLE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_CIRCLE_HPP
+
+#include
+
+#include
+
+#include
+
+#include
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace buffer
+{
+
+/*!
+\brief Create a circular buffer around a point
+\ingroup strategies
+\details This strategy can be used as PointStrategy for the buffer algorithm.
+ It creates a circular buffer around a point. It can be applied
+ for points and multi_points, but also for a linestring (if it is degenerate,
+ so consisting of only one point) and for polygons (if it is degenerate).
+ This strategy is only applicable for Cartesian coordinate systems.
+
+\qbk{
+[heading Example]
+[buffer_circle]
+[heading Output]
+[$img/strategies/buffer_circle.png]
+[heading See also]
+\* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
+}
+ */
+class buffer_circle
+{
+public :
+ //! Constructs the strategy with default number of points (90)
+ buffer_circle()
+ : m_count(90)
+ {}
+
+ //! Constructs the strategy specifying the nuber of points
+ explicit buffer_circle(std::size_t count)
+ : m_count(count)
+ {}
+
+ //! Fills output_range with a circle around point using distance_strategy
+ template
+ <
+ typename Point,
+ typename OutputRange,
+ typename DistanceStrategy
+ >
+ inline void apply(Point const& point,
+ DistanceStrategy const& distance_strategy,
+ OutputRange& output_range) const
+ {
+ typedef typename boost::range_value::type output_point_type;
+
+ typedef typename geometry::select_most_precise
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type::type,
+ typename geometry::coordinate_type::type
+ >::type,
+ double
+ >::type promoted_type;
+
+ promoted_type const buffer_distance = distance_strategy.apply(point, point,
+ strategy::buffer::buffer_side_left);
+
+ promoted_type const two = 2.0;
+ promoted_type const two_pi = two * geometry::math::pi();
+
+ promoted_type const diff = two_pi / promoted_type(m_count);
+ promoted_type a = 0;
+
+ for (std::size_t i = 0; i < m_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));
+ output_range.push_back(p);
+ }
+
+ // Close it:
+ output_range.push_back(output_range.front());
+ }
+
+private :
+ std::size_t m_count;
+};
+
+
+}} // namespace strategy::buffer
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_CIRCLE_HPP
diff --git a/include/boost/geometry/strategies/cartesian/buffer_end_flat.hpp b/include/boost/geometry/strategies/cartesian/buffer_end_flat.hpp
index 871902c5f..88b2938c9 100644
--- a/include/boost/geometry/strategies/cartesian/buffer_end_flat.hpp
+++ b/include/boost/geometry/strategies/cartesian/buffer_end_flat.hpp
@@ -27,38 +27,28 @@ namespace strategy { namespace buffer
{
-template
-<
- typename PointIn,
- typename PointOut
->
class end_flat
{
- typedef typename strategy::side::services::default_strategy::type>::type side;
- typedef typename coordinate_type::type coordinate_type;
-
- typedef typename geometry::select_most_precise
- <
- typename geometry::select_most_precise
- <
- typename geometry::coordinate_type::type,
- typename geometry::coordinate_type::type
- >::type,
- double
- >::type promoted_type;
-
public :
- template
- inline void apply(PointIn const& penultimate_point,
- PointIn const& perp_left_point,
- PointIn const& ultimate_point,
- PointIn const& perp_right_point,
+ template
+ inline void apply(Point const& penultimate_point,
+ Point const& perp_left_point,
+ Point const& ultimate_point,
+ Point const& perp_right_point,
buffer_side_selector side,
DistanceStrategy const& distance,
RangeOut& range_out) const
{
+ typedef typename coordinate_type::type coordinate_type;
+
+ typedef typename geometry::select_most_precise
+ <
+ coordinate_type,
+ double
+ >::type promoted_type;
+
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);
diff --git a/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp b/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp
index 76f9411ab..bfc04c3d1 100644
--- a/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp
+++ b/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp
@@ -11,13 +11,13 @@
#include
#include
-#include
#include
#include
#include
+#include
namespace boost { namespace geometry
{
@@ -27,40 +27,29 @@ namespace strategy { namespace buffer
{
-template
-<
- typename PointIn,
- typename PointOut
->
class end_round
{
- typedef typename strategy::side::services::default_strategy::type>::type side;
- typedef typename coordinate_type::type coordinate_type;
-
- typedef typename geometry::select_most_precise
- <
- typename geometry::select_most_precise
- <
- typename geometry::coordinate_type::type,
- typename geometry::coordinate_type::type
- >::type,
- double
- >::type promoted_type;
-
+private :
int m_steps_per_circle;
- template
- inline void generate_points(PointIn const& point,
- promoted_type alpha,
- promoted_type const& buffer_distance,
+ template
+ <
+ typename Point,
+ typename PromotedType,
+ typename DistanceType,
+ typename RangeOut
+ >
+ inline void generate_points(Point const& point,
+ PromotedType alpha, // by value
+ DistanceType const& buffer_distance,
RangeOut& range_out) const
{
- promoted_type const two = 2.0;
- promoted_type const two_pi = two * geometry::math::pi();
+ PromotedType const two = 2.0;
+ PromotedType const two_pi = two * geometry::math::pi();
int point_buffer_count = m_steps_per_circle;
- promoted_type const diff = two_pi / promoted_type(point_buffer_count);
+ PromotedType const diff = two_pi / PromotedType(point_buffer_count);
// For half circle:
point_buffer_count /= 2;
@@ -89,16 +78,24 @@ public :
: m_steps_per_circle(steps_per_circle)
{}
- template
- inline void apply(PointIn const& penultimate_point,
- PointIn const& perp_left_point,
- PointIn const& ultimate_point,
- PointIn const& ,
+ template
+ inline void apply(Point const& penultimate_point,
+ Point const& perp_left_point,
+ Point const& ultimate_point,
+ Point const& ,
buffer_side_selector side,
DistanceStrategy const& distance,
RangeOut& range_out) const
{
- promoted_type alpha = calculate_angle(perp_left_point, ultimate_point);
+ typedef typename coordinate_type::type coordinate_type;
+
+ typedef typename geometry::select_most_precise
+ <
+ coordinate_type,
+ double
+ >::type promoted_type;
+
+ promoted_type const alpha = calculate_angle(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);
@@ -116,7 +113,7 @@ public :
dist_half_diff = -dist_half_diff;
}
- PointIn shifted_point;
+ Point 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);
diff --git a/include/boost/geometry/strategies/cartesian/buffer_join_miter.hpp b/include/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
index c3989b887..2e81f6321 100644
--- a/include/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
+++ b/include/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
@@ -9,8 +9,9 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
+#include
#include
-#include
+#include
#include
#include
@@ -25,42 +26,51 @@ namespace strategy { namespace buffer
// TODO: condider merging/baseclassing join strategies to avoid duplicate code
-template
-<
- typename PointIn,
- typename PointOut
->
struct join_miter
{
- typedef typename coordinate_type::type coordinate_type;
// Constructor compatible with other join strategies:
inline join_miter(int = 0)
{}
- template
- inline bool apply(PointIn const& ip, PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2,
- coordinate_type const& buffer_distance,
+ template
+ inline bool apply(Point const& ip, Point const& vertex,
+ Point const& perp1, Point const& perp2,
+ DistanceType const& buffer_distance,
RangeOut& range_out) const
{
- PointIn p = ip;
+ geometry::equal_to equals;
+ if (equals(ip, vertex))
+ {
+ return false;
+ }
+
+ typedef typename coordinate_type::type coordinate_type;
+ typedef typename geometry::select_most_precise
+ <
+ coordinate_type,
+ double
+ >::type promoted_type;
+
+ Point p = ip;
// Normalize it and give it X*dist.
- coordinate_type dx = get<0>(ip) - get<0>(vertex);
- coordinate_type dy = get<1>(ip) - get<1>(vertex);
+ coordinate_type const dx = get<0>(ip) - get<0>(vertex);
+ coordinate_type const dy = get<1>(ip) - get<1>(vertex);
- coordinate_type length = geometry::math::sqrt(dx * dx + dy * dy);
+ promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);
+
+ BOOST_ASSERT(length != 0.0); // because ip/vertex are not equal
// TODO: make max-mitre-limit flexible
- const coordinate_type ten = 10.0;
- const coordinate_type zero_seven = 1.7;
+ promoted_type const ten = 10.0;
+ promoted_type const zero_seven = 0.7;
- const coordinate_type max = ten * geometry::math::abs(buffer_distance);
+ promoted_type const max = ten * geometry::math::abs(buffer_distance);
if (length > max)
{
- const coordinate_type prop = zero_seven * buffer_distance / length;
+ promoted_type const prop = zero_seven * buffer_distance / length;
set<0>(p, get<0>(vertex) + dx * prop);
set<1>(p, get<1>(vertex) + dy * prop);
}
diff --git a/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp b/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp
index 00d4a40a8..0e9b2b0b0 100644
--- a/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp
+++ b/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp
@@ -9,10 +9,10 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
+#include
#include
#include
#include
-#include
#include
#include
@@ -29,47 +29,35 @@ namespace strategy { namespace buffer
{
-template
-<
- typename PointIn,
- typename PointOut
->
class join_round
{
-private :
- geometry::equal_to equals;
-
public :
inline join_round(int steps_per_circle = 100)
: m_steps_per_circle(steps_per_circle)
{}
- typedef typename coordinate_type::type coordinate_type;
+ template
+ inline void generate_points(Point const& vertex,
+ Point const& perp1, Point const& perp2,
+ DistanceType const& buffer_distance,
+ RangeOut& range_out) const
+ {
+ typedef typename coordinate_type::type coordinate_type;
- typedef typename geometry::select_most_precise
+ typedef typename geometry::select_most_precise
<
- typename geometry::select_most_precise
- <
- typename geometry::coordinate_type::type,
- typename geometry::coordinate_type::type
- >::type,
+ coordinate_type,
double
>::type promoted_type;
- int m_steps_per_circle;
-
- template
- inline void generate_points(PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2,
- promoted_type const& buffer_distance,
- RangeOut& range_out) const
- {
promoted_type dx1 = get<0>(perp1) - get<0>(vertex);
promoted_type dy1 = get<1>(perp1) - get<1>(vertex);
promoted_type dx2 = get<0>(perp2) - get<0>(vertex);
promoted_type dy2 = get<1>(perp2) - get<1>(vertex);
+ BOOST_ASSERT(buffer_distance != 0);
+
dx1 /= buffer_distance;
dy1 /= buffer_distance;
dx2 /= buffer_distance;
@@ -82,6 +70,8 @@ public :
int n = boost::numeric_cast(steps * angle_diff
/ (two * geometry::math::pi()));
+//std::cout << "n= " << n << " angle=" << geometry::math::r2d * angle_diff << std::endl;
+
if (n > 1000)
{
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
@@ -102,19 +92,22 @@ public :
for (int i = 0; i < n - 1; i++, a -= diff)
{
- PointIn p;
+ Point p;
set<0>(p, get<0>(vertex) + buffer_distance * cos(a));
set<1>(p, get<1>(vertex) + buffer_distance * sin(a));
range_out.push_back(p);
}
}
- template
- inline bool apply(PointIn const& ip, PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2,
- coordinate_type const& buffer_distance,
+ template
+ inline bool apply(Point const& ip, Point const& vertex,
+ Point const& perp1, Point const& perp2,
+ DistanceType const& buffer_distance,
RangeOut& range_out) const
{
+ typedef typename coordinate_type::type coordinate_type;
+
+ geometry::equal_to equals;
if (equals(perp1, perp2))
{
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
@@ -127,13 +120,11 @@ public :
coordinate_type vix = (get<0>(ip) - get<0>(vertex));
coordinate_type viy = (get<1>(ip) - get<1>(vertex));
- coordinate_type length_i =
- geometry::math::sqrt(vix * vix + viy * viy);
-
+ coordinate_type length_i = geometry::math::sqrt(vix * vix + viy * viy);
coordinate_type const bd = geometry::math::abs(buffer_distance);
coordinate_type prop = bd / length_i;
- PointIn bp;
+ Point bp;
set<0>(bp, get<0>(vertex) + vix * prop);
set<1>(bp, get<1>(vertex) + viy * prop);
@@ -142,6 +133,9 @@ public :
range_out.push_back(perp2);
return true;
}
+
+private :
+ int m_steps_per_circle;
};
diff --git a/include/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp b/include/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
index ee1267257..525828475 100644
--- a/include/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
+++ b/include/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
@@ -9,10 +9,10 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
+#include
#include
#include
#include
-#include
#include
#include
@@ -28,81 +28,76 @@ namespace strategy { namespace buffer
{
-template
-<
- typename PointIn,
- typename PointOut
->
class join_round_by_divide
{
-private :
- geometry::equal_to equals;
-
public :
inline join_round_by_divide(int max_level = 4)
: m_max_level(max_level)
{}
- typedef typename coordinate_type::type coordinate_type;
-
- typedef typename geometry::select_most_precise
- <
- typename geometry::select_most_precise
- <
- typename geometry::coordinate_type