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 @@

- Contributions + Contributions

Boost.Geometry contains contributions by:

-
- +

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::type, - typename geometry::coordinate_type::type - >::type, - double - >::type promoted_type; - - - int m_max_level; - - template - inline void mid_points(PointIn const& vertex, - PointIn const& p1, PointIn const& p2, - coordinate_type const& buffer_distance, + template + < + typename PromotedType, + typename Point, + typename DistanceType, + typename RangeOut + > + inline void mid_points(Point const& vertex, + Point const& p1, Point const& p2, + DistanceType const& buffer_distance, RangeOut& range_out, int level = 1) const { - // Generate 'vectors' - coordinate_type vp1_x = get<0>(p1) - get<0>(vertex); - coordinate_type vp1_y = get<1>(p1) - get<1>(vertex); + typedef typename coordinate_type::type coordinate_type; - coordinate_type vp2_x = (get<0>(p2) - get<0>(vertex)); - coordinate_type vp2_y = (get<1>(p2) - get<1>(vertex)); + // Generate 'vectors' + coordinate_type const vp1_x = get<0>(p1) - get<0>(vertex); + coordinate_type const vp1_y = get<1>(p1) - get<1>(vertex); + + coordinate_type const vp2_x = (get<0>(p2) - get<0>(vertex)); + coordinate_type const vp2_y = (get<1>(p2) - get<1>(vertex)); // Average them to generate vector in between - coordinate_type two = 2; - coordinate_type v_x = (vp1_x + vp2_x) / two; - coordinate_type v_y = (vp1_y + vp2_y) / two; + coordinate_type const two = 2; + coordinate_type const v_x = (vp1_x + vp2_x) / two; + coordinate_type const v_y = (vp1_y + vp2_y) / two; - coordinate_type length2 = geometry::math::sqrt(v_x * v_x + v_y * v_y); + PromotedType const length2 = geometry::math::sqrt(v_x * v_x + v_y * v_y); - coordinate_type prop = buffer_distance / length2; + PromotedType prop = buffer_distance / length2; - PointIn mid_point; + Point mid_point; set<0>(mid_point, get<0>(vertex) + v_x * prop); set<1>(mid_point, get<1>(vertex) + v_y * prop); if (level < m_max_level) { - mid_points(vertex, p1, mid_point, buffer_distance, range_out, level + 1); + mid_points(vertex, p1, mid_point, buffer_distance, range_out, level + 1); } range_out.push_back(mid_point); if (level < m_max_level) { - mid_points(vertex, mid_point, p2, buffer_distance, range_out, level + 1); + mid_points(vertex, mid_point, p2, buffer_distance, range_out, level + 1); } } - 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; + + typedef typename geometry::select_most_precise + < + coordinate_type, + double + >::type promoted_type; + + geometry::equal_to equals; + if (equals(perp1, perp2)) { #ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN @@ -112,16 +107,15 @@ public : } // Generate 'vectors' - coordinate_type vix = (get<0>(ip) - get<0>(vertex)); - coordinate_type viy = (get<1>(ip) - get<1>(vertex)); + coordinate_type const vix = (get<0>(ip) - get<0>(vertex)); + coordinate_type const viy = (get<1>(ip) - get<1>(vertex)); - coordinate_type length_i = - geometry::math::sqrt(vix * vix + viy * viy); + promoted_type const length_i = geometry::math::sqrt(vix * vix + viy * viy); - coordinate_type const bd = geometry::math::abs(buffer_distance); - coordinate_type prop = bd / length_i; + promoted_type const bd = geometry::math::abs(buffer_distance); + promoted_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); @@ -129,9 +123,9 @@ public : if (m_max_level > 1) { - mid_points(vertex, perp1, bp, bd, range_out); + mid_points(vertex, perp1, bp, bd, range_out); range_out.push_back(bp); - mid_points(vertex, bp, perp2, bd, range_out); + mid_points(vertex, bp, perp2, bd, range_out); } else if (m_max_level == 1) { @@ -141,6 +135,9 @@ public : range_out.push_back(perp2); return true; } + +private : + int m_max_level; }; diff --git a/include/boost/geometry/strategies/cartesian/buffer_side.hpp b/include/boost/geometry/strategies/cartesian/buffer_side.hpp index abae27e6f..d84b24918 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_side.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_side.hpp @@ -8,24 +8,16 @@ #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_HPP #include -#include -#include - -#include - -#include -#include +#include +#include +#include #include #include #include -#include -#include -#include -#include namespace boost { namespace geometry diff --git a/include/boost/geometry/strategies/cartesian/buffer_square.hpp b/include/boost/geometry/strategies/cartesian/buffer_square.hpp new file mode 100644 index 000000000..5c4fd7586 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/buffer_square.hpp @@ -0,0 +1,107 @@ +// 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_SQUARE_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SQUARE_HPP + +#include + +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace buffer +{ + +/*! +\brief Create a squared form buffer around a point +\ingroup strategies +\details This strategy can be used as PointStrategy for the buffer algorithm. + It creates a square from each point, where the point lies in the center. + 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_square] +[heading Output] +[$img/strategies/buffer_square.png] +[heading See also] +\* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)] +} + */ +class buffer_square +{ +private : + template + < + typename Point, + typename DistanceType, + typename OutputRange + > + inline void add_point(Point const& point, + DistanceType const& distance, + DistanceType const& x, + DistanceType const& y, + OutputRange& output_range) const + { + typename boost::range_value::type p; + set<0>(p, get<0>(point) + x * distance); + set<1>(p, get<1>(point) + y * distance); + output_range.push_back(p); + } + + template + < + typename Point, + typename DistanceType, + typename OutputRange + > + inline void add_points(Point const& point, + DistanceType const& distance, + OutputRange& output_range) const + { + add_point(point, distance, -1.0, -1.0, output_range); + add_point(point, distance, -1.0, +1.0, output_range); + add_point(point, distance, +1.0, +1.0, output_range); + add_point(point, distance, +1.0, -1.0, output_range); + + // Close it: + output_range.push_back(output_range.front()); + } + +public : + + //! Fills output_range with a square around point using distance_strategy + template + < + typename Point, + typename DistanceStrategy, + typename OutputRange + > + inline void apply(Point const& point, + DistanceStrategy const& distance_strategy, + OutputRange& output_range) const + { + add_points(point, distance_strategy.apply(point, point, + strategy::buffer::buffer_side_left), output_range); + } + +}; + + +}} // namespace strategy::buffer + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SQUARE_HPP diff --git a/include/boost/geometry/strategies/cartesian/distance_projected_point_ax.hpp b/include/boost/geometry/strategies/cartesian/distance_projected_point_ax.hpp index 71ac637f2..c4090044f 100644 --- a/include/boost/geometry/strategies/cartesian/distance_projected_point_ax.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_projected_point_ax.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #include diff --git a/include/boost/geometry/strategies/strategies.hpp b/include/boost/geometry/strategies/strategies.hpp index 2183add15..37327eed9 100644 --- a/include/boost/geometry/strategies/strategies.hpp +++ b/include/boost/geometry/strategies/strategies.hpp @@ -35,11 +35,14 @@ #include #include +#include #include #include #include #include #include +#include +#include #include #include #include @@ -62,7 +65,6 @@ #include #include -#include #include #include #include diff --git a/test/algorithms/buffer/aimes_linestring_buffer.cpp b/test/algorithms/buffer/aimes_linestring_buffer.cpp index ff930e7df..18a44e6ae 100644 --- a/test/algorithms/buffer/aimes_linestring_buffer.cpp +++ b/test/algorithms/buffer/aimes_linestring_buffer.cpp @@ -7,6 +7,8 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#define BOOST_GEOMETRY_BUFFER_SIMPLIFY_WITH_AX + #include #include @@ -464,6 +466,8 @@ void test_aimes() #endif // Aimes tested originally with 0.000018 degrees (around 2 m) + std::size_t self_ip_count = 0; + int expectation_index = 0; for (int width = 18; width <= 36; width += 18, expectation_index += 2) { @@ -485,17 +489,18 @@ void test_aimes() name.str(), testcases[i], expectations[i][expectation_index], aimes_width, aimes_width, - false + self_ip_count, 0.00001 ); test_one ( name.str(), testcases[i], expectations[i][expectation_index + 1], aimes_width, aimes_width, - false + self_ip_count, 0.00001 ); } } + std::cout << "Total self-ips: " << self_ip_count << std::endl; } diff --git a/test/algorithms/buffer/multi_point_buffer.cpp b/test/algorithms/buffer/multi_point_buffer.cpp index 1b92b8d9d..2a134d6d4 100644 --- a/test/algorithms/buffer/multi_point_buffer.cpp +++ b/test/algorithms/buffer/multi_point_buffer.cpp @@ -114,7 +114,8 @@ double test_growth(Geometry const& geometry, int n, int d, double distance) rescale_policy_type rescale_policy = bg::get_rescale_policy(geometry); - bg::buffer_inserter(geometry, std::back_inserter(buffered), + bg::detail::buffer::buffer_inserter(geometry, + std::back_inserter(buffered), distance_strategy, join_strategy, end_strategy, diff --git a/test/algorithms/buffer/multi_polygon_buffer.cpp b/test/algorithms/buffer/multi_polygon_buffer.cpp index af9747060..eb77f30dc 100644 --- a/test/algorithms/buffer/multi_polygon_buffer.cpp +++ b/test/algorithms/buffer/multi_polygon_buffer.cpp @@ -228,112 +228,112 @@ void test_all() typedef bg::model::polygon

polygon_type; typedef bg::model::multi_polygon multi_polygon_type; - test_one("triangles424", triangles, 417.910, 4.24); - test_one("triangles425", triangles, 418.918, 4.25); - test_one("triangles426", triangles, 419.927, 4.26); - test_one("zonethru_10", zonethru, 96.0000, 1.0); + test_one("triangles424", triangles, 417.910, 4.24); + test_one("triangles425", triangles, 418.918, 4.25); + test_one("triangles426", triangles, 419.927, 4.26); + test_one("zonethru_10", zonethru, 96.0000, 1.0); - test_one("multi_simplex_05", simplex, 23.7030, 0.5); - test_one("multi_simplex_05", simplex, 24.5965, 0.5); - test_one("multi_simplex_10", simplex, 34.2532, 1.0); - test_one("multi_simplex_10", simplex, 38.1379, 1.0); - test_one("multi_simplex_20", simplex, 59.9159, 2.0); - test_one("multi_simplex_20", simplex, 77.7060, 2.0); - test_one("multi_simplex_50", simplex, 174.46, 5.0); - test_one("multi_simplex_50", simplex, 298.797, 5.0); + test_one("multi_simplex_05", simplex, 23.7030, 0.5); + test_one("multi_simplex_05", simplex, 24.5965, 0.5); + test_one("multi_simplex_10", simplex, 34.2532, 1.0); + test_one("multi_simplex_10", simplex, 38.1379, 1.0); + test_one("multi_simplex_20", simplex, 59.9159, 2.0); + test_one("multi_simplex_20", simplex, 77.7060, 2.0); + test_one("multi_simplex_50", simplex, 174.46, 5.0); + test_one("multi_simplex_50", simplex, 298.797, 5.0); // This one does not work: - // test_one("multi_simplex_50", simplex, 'd', 174.46, 5.0); + // test_one("multi_simplex_50", simplex, 'd', 174.46, 5.0); - test_one("zonethru_05", zonethru, 67.4627, 0.5); - test_one("zonethru_05", zonethru, 68.0000, 0.5); - test_one("zonethru_10", zonethru, 93.8508, 1.0); - test_one("zonethru_10", zonethru, 96.0000, 1.0); - test_one("zonethru_15", zonethru, 114.584, 1.5); - test_one("zonethru_15", zonethru, 117.000, 1.5); - test_one("wrapped_05", wrapped, 104.570, 0.5); - test_one("wrapped_05", wrapped, 105.000, 0.5); - test_one("wrapped_10", wrapped, 142.281, 1.0); - test_one("wrapped_10", wrapped, 144.000, 1.0); - test_one("wrapped_15", wrapped, 167.066, 1.5); - test_one("wrapped_15", wrapped, 169.000, 1.5); + test_one("zonethru_05", zonethru, 67.4627, 0.5); + test_one("zonethru_05", zonethru, 68.0000, 0.5); + test_one("zonethru_10", zonethru, 93.8508, 1.0); + test_one("zonethru_10", zonethru, 96.0000, 1.0); + test_one("zonethru_15", zonethru, 114.584, 1.5); + test_one("zonethru_15", zonethru, 117.000, 1.5); + test_one("wrapped_05", wrapped, 104.570, 0.5); + test_one("wrapped_05", wrapped, 105.000, 0.5); + test_one("wrapped_10", wrapped, 142.281, 1.0); + test_one("wrapped_10", wrapped, 144.000, 1.0); + test_one("wrapped_15", wrapped, 167.066, 1.5); + test_one("wrapped_15", wrapped, 169.000, 1.5); // TODO: there is still an undetected hole inside rt_a - test_one("rt_a", rt_a, 34.5381, 1.0); + test_one("rt_a", rt_a, 34.5381, 1.0); - test_one("rt_a", rt_a, 36, 1.0); - test_one("rt_b", rt_b, 31.4186, 1.0); - test_one("rt_b", rt_b, 34, 1.0); - test_one("rt_c", rt_c, 14.7093, 1.0); - test_one("rt_c", rt_c, 16, 1.0); - test_one("rt_d", rt_d, 18.8726, 0.3); - test_one("rt_d", rt_d, 19.8823, 0.3); - test_one("rt_e", rt_e, 14.1866, 0.3); - test_one("rt_e", rt_e, 15.1198, 0.3); - // This does not add anything: test_one("rt_f", rt_f, 4.28937, 0.3); + test_one("rt_a", rt_a, 36, 1.0); + test_one("rt_b", rt_b, 31.4186, 1.0); + test_one("rt_b", rt_b, 34, 1.0); + test_one("rt_c", rt_c, 14.7093, 1.0); + test_one("rt_c", rt_c, 16, 1.0); + test_one("rt_d", rt_d, 18.8726, 0.3); + test_one("rt_d", rt_d, 19.8823, 0.3); + test_one("rt_e", rt_e, 14.1866, 0.3); + test_one("rt_e", rt_e, 15.1198, 0.3); + // This does not add anything: test_one("rt_f", rt_f, 4.28937, 0.3); - test_one("rt_f", rt_f, 4.60853, 0.3); + test_one("rt_f", rt_f, 4.60853, 0.3); - test_one("rt_g1", rt_g1, 24.719, 1.0); - test_one("rt_g1", rt_g1, 30.3137, 1.0); - test_one("rt_g2", rt_g2, 18.5711, 1.0); - test_one("rt_g3", rt_g3, 16.5711, 1.0); + test_one("rt_g1", rt_g1, 24.719, 1.0); + test_one("rt_g1", rt_g1, 30.3137, 1.0); + test_one("rt_g2", rt_g2, 18.5711, 1.0); + test_one("rt_g3", rt_g3, 16.5711, 1.0); - test_one("rt_h", rt_h, 47.6012, 1.0); - test_one("rt_h", rt_h, 61.7058, 1.0); - test_one("rt_i", rt_i, 10.7528, 1.0); - test_one("rt_i", rt_i, 13.6569, 1.0); - test_one("rt_j", rt_j, 28.7309, 1.0); - test_one("rt_j", rt_j, 35.1421, 1.0); - test_one("rt_k", rt_k, 42.0092, 1.0); - test_one("rt_k", rt_k, 48.0563, 1.0); - // This does not add anything: test_one("rt_l", rt_l, 14.1074, 1.0); - test_one("rt_l", rt_l, 19.3995, 1.0); - test_one("rt_m1", rt_m1, 14.1074, 1.0); - test_one("rt_m1", rt_m1, 19.4853, 1.0); - test_one("rt_m2", rt_m2, 21.4853, 1.0); + test_one("rt_h", rt_h, 47.6012, 1.0); + test_one("rt_h", rt_h, 61.7058, 1.0); + test_one("rt_i", rt_i, 10.7528, 1.0); + test_one("rt_i", rt_i, 13.6569, 1.0); + test_one("rt_j", rt_j, 28.7309, 1.0); + test_one("rt_j", rt_j, 35.1421, 1.0); + test_one("rt_k", rt_k, 42.0092, 1.0); + test_one("rt_k", rt_k, 48.0563, 1.0); + // This does not add anything: test_one("rt_l", rt_l, 14.1074, 1.0); + test_one("rt_l", rt_l, 19.3995, 1.0); + test_one("rt_m1", rt_m1, 14.1074, 1.0); + test_one("rt_m1", rt_m1, 19.4853, 1.0); + test_one("rt_m2", rt_m2, 21.4853, 1.0); - // This does not add anything: test_one("rt_n", rt_n, 14.1074, 1.0); - test_one("rt_n", rt_n, 18.4853, 1.0); + // This does not add anything: test_one("rt_n", rt_n, 14.1074, 1.0); + test_one("rt_n", rt_n, 18.4853, 1.0); - test_one("rt_o1", rt_o1, 17.536, 1.0); - //test_one("rt_o1", rt_o1, 20.9142, 1.0); + test_one("rt_o1", rt_o1, 17.536, 1.0); + //test_one("rt_o1", rt_o1, 20.9142, 1.0); - test_one("rt_o2", rt_o2, 25.7426, 1.0); - test_one("rt_o3", rt_o3, 28.8247, 1.0); - test_one("rt_o4", rt_o4, 34.6532, 1.0); + test_one("rt_o2", rt_o2, 25.7426, 1.0); + test_one("rt_o3", rt_o3, 28.8247, 1.0); + test_one("rt_o4", rt_o4, 34.6532, 1.0); - test_one("rt_p1", rt_p1, 24.8211, 1.0); - test_one("rt_p2", rt_p2, 21.4853, 1.0); - test_one("rt_p3", rt_p3, 22.3995, 1.0); - test_one("rt_p4", rt_p4, 33.0563, 1.0); - test_one("rt_p5", rt_p5, 17, 1.0); - test_one("rt_p6", rt_p6, 18.4853, 1.0); - test_one("rt_p7", rt_p7, 26.2279, 1.0); - test_one("rt_p8", rt_p8, 29.0563, 1.0); - test_one("rt_p9", rt_p9, 26.1421, 1.0); - test_one("rt_p10", rt_p10, 23.3995, 1.0); + test_one("rt_p1", rt_p1, 24.8211, 1.0); + test_one("rt_p2", rt_p2, 21.4853, 1.0); + test_one("rt_p3", rt_p3, 22.3995, 1.0); + test_one("rt_p4", rt_p4, 33.0563, 1.0); + test_one("rt_p5", rt_p5, 17, 1.0); + test_one("rt_p6", rt_p6, 18.4853, 1.0); + test_one("rt_p7", rt_p7, 26.2279, 1.0); + test_one("rt_p8", rt_p8, 29.0563, 1.0); + test_one("rt_p9", rt_p9, 26.1421, 1.0); + test_one("rt_p10", rt_p10, 23.3995, 1.0); - test_one("rt_p11", rt_p11, 28.7426, 1.0); - test_one("rt_p12", rt_p12, 22.5711, 1.0); - test_one("rt_p13", rt_p13, 19.9142, 1.0); - test_one("rt_p14", rt_p14, 20.8284, 1.0); - test_one("rt_p15", rt_p15, 23.6569, 1.0); - test_one("rt_p16", rt_p16, 23.4853, 1.0); - test_one("rt_p17", rt_p17, 25.3137, 1.0); - test_one("rt_p18", rt_p18, 23.3137, 1.0); - test_one("rt_p19", rt_p19, 25.5637, 1.0); - test_one("rt_p20", rt_p20, 25.4853, 1.0); - test_one("rt_p21", rt_p21, 17.1716, 1.0); - test_one("rt_p22", rt_p22, 26.5711, 1.0); + test_one("rt_p11", rt_p11, 28.7426, 1.0); + test_one("rt_p12", rt_p12, 22.5711, 1.0); + test_one("rt_p13", rt_p13, 19.9142, 1.0); + test_one("rt_p14", rt_p14, 20.8284, 1.0); + test_one("rt_p15", rt_p15, 23.6569, 1.0); + test_one("rt_p16", rt_p16, 23.4853, 1.0); + test_one("rt_p17", rt_p17, 25.3137, 1.0); + test_one("rt_p18", rt_p18, 23.3137, 1.0); + test_one("rt_p19", rt_p19, 25.5637, 1.0); + test_one("rt_p20", rt_p20, 25.4853, 1.0); + test_one("rt_p21", rt_p21, 17.1716, 1.0); + test_one("rt_p22", rt_p22, 26.5711, 1.0); - test_one("rt_q1", rt_q1, 27, 1.0); - test_one("rt_q2", rt_q2, 26.4853, 1.0); + test_one("rt_q1", rt_q1, 27, 1.0); + test_one("rt_q2", rt_q2, 26.4853, 1.0); - test_one("rt_r", rt_r, 21.0761, 1.0); - test_one("rt_s1", rt_s1, 20.4853, 1.0); - test_one("rt_s2", rt_s2, 24.6495, 1.0); - test_one("rt_t", rt_t, 15.6569, 1.0); + test_one("rt_r", rt_r, 21.0761, 1.0); + test_one("rt_s1", rt_s1, 20.4853, 1.0); + test_one("rt_s2", rt_s2, 24.6495, 1.0); + test_one("rt_t", rt_t, 15.6569, 1.0); } int point_buffer_count; diff --git a/test/algorithms/buffer/polygon_buffer.cpp b/test/algorithms/buffer/polygon_buffer.cpp index 78229e594..f858c84b3 100644 --- a/test/algorithms/buffer/polygon_buffer.cpp +++ b/test/algorithms/buffer/polygon_buffer.cpp @@ -89,11 +89,11 @@ void test_all() typedef bg::model::polygon

polygon_type; - test_one("simplex", simplex, 47.9408, 1.5); - test_one("simplex", simplex, 52.8733, 1.5); + test_one("simplex", simplex, 47.9408, 1.5); + test_one("simplex", simplex, 52.8733, 1.5); - test_one("concave_simplex", concave_simplex, 14.5616, 0.5); - test_one("concave_simplex", concave_simplex, 16.3861, 0.5); + test_one("concave_simplex", concave_simplex, 14.5616, 0.5); + test_one("concave_simplex", concave_simplex, 16.3861, 0.5); test_one("spike_simplex15", spike_simplex, 50.3633, 1.5); test_one("spike_simplex15", spike_simplex, 51.5509, 1.5); @@ -109,110 +109,110 @@ void test_all() test_one("join_types", join_types, 88.2060, 1.5); - test_one("chained_box", chained_box, 83.1403, 1.0); - test_one("chained_box", chained_box, 84, 1.0); - test_one("L", letter_L, 13.7314, 0.5); - test_one("L", letter_L, 14.0, 0.5); + test_one("chained_box", chained_box, 83.1403, 1.0); + test_one("chained_box", chained_box, 84, 1.0); + test_one("L", letter_L, 13.7314, 0.5); + test_one("L", letter_L, 14.0, 0.5); - test_one("chained_box", chained_box, 84, 1.0); - test_one("chained_box", chained_box, 83.1403, 1.0); + test_one("chained_box", chained_box, 84, 1.0); + test_one("chained_box", chained_box, 83.1403, 1.0); - test_one("indentation4", indentation, 25.7741, 0.4); - test_one("indentation4", indentation, 25.5695, 0.4); - test_one("indentation5", indentation, 28.2426, 0.5); - test_one("indentation5", indentation, 27.9953, 0.5); - test_one("indentation6", indentation, 30.6712, 0.6); + test_one("indentation4", indentation, 25.7741, 0.4); + test_one("indentation4", indentation, 25.5695, 0.4); + test_one("indentation5", indentation, 28.2426, 0.5); + test_one("indentation5", indentation, 27.9953, 0.5); + test_one("indentation6", indentation, 30.6712, 0.6); // SQL Server gives 30.34479159164 - test_one("indentation6", indentation, 30.3445, 0.6); + test_one("indentation6", indentation, 30.3445, 0.6); - test_one("indentation7", indentation, 33.0958, 0.7); - test_one("indentation7", indentation, 32.6533, 0.7); + test_one("indentation7", indentation, 33.0958, 0.7); + test_one("indentation7", indentation, 32.6533, 0.7); - test_one("indentation8", indentation, 35.5943, 0.8); - test_one("indentation8", indentation, 35.0164, 0.8); - test_one("indentation12", indentation, 46.3541, 1.2); - test_one("indentation12", indentation, 45.0537, 1.2); + test_one("indentation8", indentation, 35.5943, 0.8); + test_one("indentation8", indentation, 35.0164, 0.8); + test_one("indentation12", indentation, 46.3541, 1.2); + test_one("indentation12", indentation, 45.0537, 1.2); // TODO: fix, the buffered pieces are currently counterclockwise, that should be reversed - //test_one("indentation4_neg", indentation, 6.99098413022335, -0.4); - //test_one("indentation4_neg", indentation, 7.25523322189147, -0.4); - //test_one("indentation8_neg", indentation, 1.36941992048731, -0.8); - //test_one("indentation8_neg", indentation, 1.37375487490664, -0.8); - //test_one("indentation12_neg", indentation, 0, -1.2); - //test_one("indentation12_neg", indentation, 0, -1.2); + //test_one("indentation4_neg", indentation, 6.99098413022335, -0.4); + //test_one("indentation4_neg", indentation, 7.25523322189147, -0.4); + //test_one("indentation8_neg", indentation, 1.36941992048731, -0.8); + //test_one("indentation8_neg", indentation, 1.37375487490664, -0.8); + //test_one("indentation12_neg", indentation, 0, -1.2); + //test_one("indentation12_neg", indentation, 0, -1.2); - test_one("donut_simplex6", donut_simplex, 53.648, 0.6); - test_one("donut_simplex6", donut_simplex, 52.820, 0.6); - test_one("donut_simplex8", donut_simplex, 61.132, 0.8); - test_one("donut_simplex8", donut_simplex, 59.6713, 0.8); - test_one("donut_simplex10", donut_simplex, 68.670, 1.0); - test_one("donut_simplex10", donut_simplex, 66.387, 1.0); - test_one("donut_simplex12", donut_simplex, 76.605, 1.2); - test_one("donut_simplex12", donut_simplex, 73.3179, 1.2); - test_one("donut_simplex14", donut_simplex, 84.974, 1.4); - test_one("donut_simplex14", donut_simplex, 80.500, 1.4); - test_one("donut_simplex16", donut_simplex, 93.777, 1.6); - test_one("donut_simplex16", donut_simplex, 87.933, 1.6); + test_one("donut_simplex6", donut_simplex, 53.648, 0.6); + test_one("donut_simplex6", donut_simplex, 52.820, 0.6); + test_one("donut_simplex8", donut_simplex, 61.132, 0.8); + test_one("donut_simplex8", donut_simplex, 59.6713, 0.8); + test_one("donut_simplex10", donut_simplex, 68.670, 1.0); + test_one("donut_simplex10", donut_simplex, 66.387, 1.0); + test_one("donut_simplex12", donut_simplex, 76.605, 1.2); + test_one("donut_simplex12", donut_simplex, 73.3179, 1.2); + test_one("donut_simplex14", donut_simplex, 84.974, 1.4); + test_one("donut_simplex14", donut_simplex, 80.500, 1.4); + test_one("donut_simplex16", donut_simplex, 93.777, 1.6); + test_one("donut_simplex16", donut_simplex, 87.933, 1.6); - test_one("donut_diamond1", donut_diamond, 280.0, 1.0); - test_one("donut_diamond4", donut_diamond, 529.0, 4.0); - test_one("donut_diamond5", donut_diamond, 625.0, 5.0); - test_one("donut_diamond6", donut_diamond, 729.0, 6.0); + test_one("donut_diamond1", donut_diamond, 280.0, 1.0); + test_one("donut_diamond4", donut_diamond, 529.0, 4.0); + test_one("donut_diamond5", donut_diamond, 625.0, 5.0); + test_one("donut_diamond6", donut_diamond, 729.0, 6.0); - test_one("arrow4", arrow, 28.265, 0.4); - test_one("arrow4", arrow, 27.039, 0.4); - test_one("arrow5", arrow, 31.500, 0.5); - test_one("arrow5", arrow, 29.621, 0.5); - test_one("arrow6", arrow, 34.903, 0.6); - test_one("arrow6", arrow, 32.268, 0.6); + test_one("arrow4", arrow, 28.265, 0.4); + test_one("arrow4", arrow, 27.039, 0.4); + test_one("arrow5", arrow, 31.500, 0.5); + test_one("arrow5", arrow, 29.621, 0.5); + test_one("arrow6", arrow, 34.903, 0.6); + test_one("arrow6", arrow, 32.268, 0.6); - test_one("tipped_aitch3", tipped_aitch, 55.36, 0.3); - test_one("tipped_aitch9", tipped_aitch, 77.44, 0.9); - test_one("tipped_aitch13", tipped_aitch, 92.16, 1.3); + test_one("tipped_aitch3", tipped_aitch, 55.36, 0.3); + test_one("tipped_aitch9", tipped_aitch, 77.44, 0.9); + test_one("tipped_aitch13", tipped_aitch, 92.16, 1.3); // SQL Server: 55.205415532967 76.6468846383224 90.642916957136 - test_one("tipped_aitch3", tipped_aitch, 55.2053, 0.3); - test_one("tipped_aitch9", tipped_aitch, 76.6457, 0.9); - test_one("tipped_aitch13", tipped_aitch, 90.641, 1.3); + test_one("tipped_aitch3", tipped_aitch, 55.2053, 0.3); + test_one("tipped_aitch9", tipped_aitch, 76.6457, 0.9); + test_one("tipped_aitch13", tipped_aitch, 90.641, 1.3); - test_one("snake4", snake, 64.44, 0.4); - test_one("snake5", snake, 72, 0.5); - test_one("snake6", snake, 75.44, 0.6); - test_one("snake16", snake, 114.24, 1.6); + test_one("snake4", snake, 64.44, 0.4); + test_one("snake5", snake, 72, 0.5); + test_one("snake6", snake, 75.44, 0.6); + test_one("snake16", snake, 114.24, 1.6); - test_one("funnelgate2", funnelgate, 120.982, 2); - test_one("funnelgate3", funnelgate, 13*13, 3); - test_one("funnelgate4", funnelgate, 15*15, 4); - test_one("gammagate1", gammagate, 88, 1); - test_one("fork_a1", fork_a, 88, 1); - test_one("fork_b1", fork_b, 154, 1); - test_one("fork_c1", fork_c, 152, 1); - test_one("triangle", triangle, 14.6569, 1.0); + test_one("funnelgate2", funnelgate, 120.982, 2); + test_one("funnelgate3", funnelgate, 13*13, 3); + test_one("funnelgate4", funnelgate, 15*15, 4); + test_one("gammagate1", gammagate, 88, 1); + test_one("fork_a1", fork_a, 88, 1); + test_one("fork_b1", fork_b, 154, 1); + test_one("fork_c1", fork_c, 152, 1); + test_one("triangle", triangle, 14.6569, 1.0); - test_one("gammagate2", gammagate, 130, 2); + test_one("gammagate2", gammagate, 130, 2); - test_one("flower1", flower, 67.614, 0.1); - test_one("flower20", flower, 74.894, 0.20); - test_one("flower25", flower, 78.226, 0.25); - test_one("flower30", flower, 81.492494146177947, 0.30); - test_one("flower35", flower, 84.694183819917185, 0.35); - test_one("flower40", flower, 87.8306529577, 0.40); - test_one("flower45", flower, 90.901901559536029, 0.45); - test_one("flower50", flower, 93.907929625415662, 0.50); - test_one("flower55", flower, 96.848737155342079, 0.55); - test_one("flower60", flower, 99.724324149315279, 0.60); + test_one("flower1", flower, 67.614, 0.1); + test_one("flower20", flower, 74.894, 0.20); + test_one("flower25", flower, 78.226, 0.25); + test_one("flower30", flower, 81.492494146177947, 0.30); + test_one("flower35", flower, 84.694183819917185, 0.35); + test_one("flower40", flower, 87.8306529577, 0.40); + test_one("flower45", flower, 90.901901559536029, 0.45); + test_one("flower50", flower, 93.907929625415662, 0.50); + test_one("flower55", flower, 96.848737155342079, 0.55); + test_one("flower60", flower, 99.724324149315279, 0.60); - test_one("flower10", flower, 67.486, 0.10); - test_one("flower20", flower, 74.702, 0.20); - test_one("flower25", flower, 78.071, 0.25); - test_one("flower30", flower, 81.352, 0.30); - test_one("flower35", flower, 84.547, 0.35); - test_one("flower40", flower, 87.665, 0.40); - test_one("flower45", flower, 90.709, 0.45); - test_one("flower50", flower, 93.680, 0.50); - test_one("flower55", flower, 96.580, 0.55); - test_one("flower60", flower, 99.408, 0.60); + test_one("flower10", flower, 67.486, 0.10); + test_one("flower20", flower, 74.702, 0.20); + test_one("flower25", flower, 78.071, 0.25); + test_one("flower30", flower, 81.352, 0.30); + test_one("flower35", flower, 84.547, 0.35); + test_one("flower40", flower, 87.665, 0.40); + test_one("flower45", flower, 90.709, 0.45); + test_one("flower50", flower, 93.680, 0.50); + test_one("flower55", flower, 96.580, 0.55); + test_one("flower60", flower, 99.408, 0.60); // Saw { @@ -235,8 +235,8 @@ void test_all() { std::ostringstream out; out << "saw_" << i; - test_one(out.str(), saw, expected_round[i - 1], double(i) / 2.0, -999, true, 0.1); - test_one(out.str(), saw, expected_miter[i - 1], double(i) / 2.0); + test_one(out.str(), saw, expected_round[i - 1], double(i) / 2.0, -999, true, 0.1); + test_one(out.str(), saw, expected_miter[i - 1], double(i) / 2.0); } } @@ -262,33 +262,33 @@ void test_all() { std::ostringstream out; out << "bowl_" << i; - test_one(out.str(), bowl, expected_round[i - 1], double(i) / 2.0, -999, true, 0.1); - test_one(out.str(), bowl, expected_miter[i - 1], double(i) / 2.0); + test_one(out.str(), bowl, expected_round[i - 1], double(i) / 2.0, -999, true, 0.1); + test_one(out.str(), bowl, expected_miter[i - 1], double(i) / 2.0); } } - test_one("county1", county1, 0.00114092, 0.01); - test_one("county1", county1, 0.00132859, 0.01); + test_one("county1", county1, 0.00114092, 0.01); + test_one("county1", county1, 0.00132859, 0.01); - test_one("parcel1_10", parcel1, 7571.39121246337891, 10.0); - test_one("parcel1_10", parcel1, 8207.45314788818359, 10.0); - test_one("parcel1_20", parcel1, 11648.0537185668945, 20.0); - test_one("parcel1_20", parcel1, 14184.0223083496094, 20.0); - test_one("parcel1_30", parcel1, 16350.3611068725586, 30.0); - test_one("parcel1_30", parcel1, 22046.5098342895508, 30.0); + test_one("parcel1_10", parcel1, 7571.39121246337891, 10.0); + test_one("parcel1_10", parcel1, 8207.45314788818359, 10.0); + test_one("parcel1_20", parcel1, 11648.0537185668945, 20.0); + test_one("parcel1_20", parcel1, 14184.0223083496094, 20.0); + test_one("parcel1_30", parcel1, 16350.3611068725586, 30.0); + test_one("parcel1_30", parcel1, 22046.5098342895508, 30.0); - test_one("parcel2_10", parcel2, 5000.85063171386719, 10.0); - test_one("parcel2_10", parcel2, 5091.12226867675781, 10.0); - test_one("parcel2_20", parcel2, 9049.60844421386719, 20.0); - test_one("parcel2_20", parcel2, 9410.69154357910156, 20.0); - test_one("parcel2_30", parcel2, 13726.3790588378906, 30.0); - test_one("parcel2_30", parcel2, 14535.2319564819336, 30.0); + test_one("parcel2_10", parcel2, 5000.85063171386719, 10.0); + test_one("parcel2_10", parcel2, 5091.12226867675781, 10.0); + test_one("parcel2_20", parcel2, 9049.60844421386719, 20.0); + test_one("parcel2_20", parcel2, 9410.69154357910156, 20.0); + test_one("parcel2_30", parcel2, 13726.3790588378906, 30.0); + test_one("parcel2_30", parcel2, 14535.2319564819336, 30.0); test_one("parcel3_10", parcel3, 19992.6824035644531, 10.0); - test_one("parcel3_10", parcel3, 20024.5579376220703, 10.0); - test_one("parcel3_20", parcel3, 34505.0746192932129, 20.0); - test_one("parcel3_20", parcel3, 34633.2606201171875, 20.0); - test_one("parcel3_30", parcel3, 45261.4196014404297, 30.0); - test_one("parcel3_30", parcel3, 45567.3875694274902, 30.0); + test_one("parcel3_10", parcel3, 20024.5579376220703, 10.0); + test_one("parcel3_20", parcel3, 34505.0746192932129, 20.0); + test_one("parcel3_20", parcel3, 34633.2606201171875, 20.0); + test_one("parcel3_30", parcel3, 45261.4196014404297, 30.0); + test_one("parcel3_30", parcel3, 45567.3875694274902, 30.0); test_one("parcel3_bend_10", parcel3_bend, 155.6188, 5.0); test_one("parcel3_bend_10", parcel3_bend, 458.4187, 10.0); @@ -297,15 +297,15 @@ void test_all() // Negative buffers making polygons smaller - test_one("simplex", simplex, 7.04043, -0.5); - test_one("simplex", simplex, 7.04043, -0.5); - test_one("concave_simplex", concave_simplex, 0.777987, -0.5); - test_one("concave_simplex", concave_simplex, 0.724208, -0.5); + test_one("simplex", simplex, 7.04043, -0.5); + test_one("simplex", simplex, 7.04043, -0.5); + test_one("concave_simplex", concave_simplex, 0.777987, -0.5); + test_one("concave_simplex", concave_simplex, 0.724208, -0.5); - test_one("donut_simplex3", donut_simplex, 19.7636, -0.3); - test_one("donut_simplex3", donut_simplex, 19.8861, -0.3); - test_one("donut_simplex6", donut_simplex, 12.8920, -0.6); - test_one("donut_simplex6", donut_simplex, 12.9157, -0.6); + test_one("donut_simplex3", donut_simplex, 19.7636, -0.3); + test_one("donut_simplex3", donut_simplex, 19.8861, -0.3); + test_one("donut_simplex6", donut_simplex, 12.8920, -0.6); + test_one("donut_simplex6", donut_simplex, 12.9157, -0.6); } diff --git a/test/algorithms/buffer/test_buffer.hpp b/test/algorithms/buffer/test_buffer.hpp index b65fbc68e..bcbcc12d3 100644 --- a/test/algorithms/buffer/test_buffer.hpp +++ b/test/algorithms/buffer/test_buffer.hpp @@ -32,11 +32,11 @@ #include #include +#include #include #include -#include @@ -46,7 +46,6 @@ #if defined(TEST_WITH_SVG) #include -#include template void post_map(Geometry const& geometry, Mapper& mapper, RescalePolicy const& rescale_policy) @@ -255,7 +254,7 @@ struct svg_visitor #endif //----------------------------------------------------------------------------- -template class JoinStrategy> +template struct JoinTestProperties { }; template<> struct JoinTestProperties @@ -275,7 +274,7 @@ template<> struct JoinTestProperties class EndStrategy> +template struct EndTestProperties { }; template<> struct EndTestProperties @@ -288,22 +287,41 @@ template<> struct EndTestProperties static std::string name() { return "flat"; } }; -template<> struct EndTestProperties -{ - static std::string name() { return ""; } -}; + + +template +std::size_t count_self_ips(Geometry const& geometry, RescalePolicy const& rescale_policy) +{ + typedef typename bg::point_type::type point_type; + typedef bg::detail::overlay::turn_info + < + point_type, + typename bg::segment_ratio_type::type + > turn_info; + + std::vector turns; + + bg::detail::self_get_turn_points::no_interrupt_policy policy; + bg::self_turns + < + bg::detail::overlay::assign_null_policy + >(geometry, rescale_policy, turns, policy); + + return turns.size(); +} template < typename GeometryOut, - template class JoinStrategy, - template class EndStrategy, + typename JoinStrategy, + typename EndStrategy, typename Geometry > void test_buffer(std::string const& caseid, Geometry const& geometry, bool check_self_intersections, double expected_area, double distance_left, double distance_right, - double tolerance) + double tolerance, + std::size_t* self_ip_count) { namespace bg = boost::geometry; @@ -372,17 +390,9 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, bg::detail::buffer::visit_pieces_default_policy visitor; #endif - JoinStrategy - < - point_type, - output_point_type - > join_strategy; + JoinStrategy join_strategy; - EndStrategy - < - point_type, - output_point_type - > end_strategy; + EndStrategy end_strategy; bg::strategy::buffer::distance_asymmetric < @@ -392,6 +402,11 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, bg::strategy::buffer::buffer_side side_strategy; + // For (multi)points a buffer with 88 points is used for testing. + // More points will give a more precise result - expected area should be + // adapted then + bg::strategy::buffer::buffer_circle circle_strategy(88); + typedef typename bg::point_type::type point_type; typedef typename bg::rescale_policy_type::type rescale_policy_type; @@ -401,11 +416,13 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, std::vector buffered; - bg::buffer_inserter(geometry, std::back_inserter(buffered), + bg::detail::buffer::buffer_inserter(geometry, + std::back_inserter(buffered), distance_strategy, side_strategy, join_strategy, end_strategy, + circle_strategy, rescale_policy, visitor); @@ -461,6 +478,17 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, post_map(polygon, mapper, rescale_policy); } #endif + + if (self_ip_count != NULL) + { + std::size_t count = 0; + BOOST_FOREACH(GeometryOut const& polygon, buffered) + { + count += count_self_ips(polygon, rescale_policy); + } + + *self_ip_count += count; + } } @@ -471,8 +499,8 @@ static int counter = 0; template < typename Geometry, - template class JoinStrategy, - template class EndStrategy, + typename JoinStrategy, + typename EndStrategy, typename GeometryOut > void test_one(std::string const& caseid, std::string const& wkt, @@ -501,9 +529,32 @@ void test_one(std::string const& caseid, std::string const& wkt, test_buffer (caseid, g, check_self_intersections, expected_area, - distance_left, distance_right, tolerance); + distance_left, distance_right, tolerance, NULL); +} + +// Version (currently for the Aimes test) counting self-ip's instead of checking +template +< + typename Geometry, + typename JoinStrategy, + typename EndStrategy, + typename GeometryOut +> +void test_one(std::string const& caseid, std::string const& wkt, + double expected_area, + double distance_left, double distance_right, + std::size_t& self_ip_count, + double tolerance = 0.01) +{ + namespace bg = boost::geometry; + Geometry g; + bg::read_wkt(wkt, g); + bg::correct(g); + + test_buffer + (caseid, g, false, expected_area, + distance_left, distance_right, tolerance, &self_ip_count); } - #endif diff --git a/test/algorithms/within_pointlike_xxx.cpp b/test/algorithms/within_pointlike_xxx.cpp index db281aecf..aa0a96929 100644 --- a/test/algorithms/within_pointlike_xxx.cpp +++ b/test/algorithms/within_pointlike_xxx.cpp @@ -181,6 +181,46 @@ void test_large_integers() BOOST_CHECK_MESSAGE(wi == wd, "within different from within"); } +void test_tickets() +{ + typedef boost::geometry::model::d2::point_xy pt; + typedef boost::geometry::model::ring ring; + + // https://svn.boost.org/trac/boost/ticket/9628 + { + ring r; + r.push_back(pt(-19155.669324773193,54820.312032458620)); + r.push_back(pt(-13826.169324773080,54820.312032458627)); + r.push_back(pt(-13826.169324773078,52720.312032458663)); + r.push_back(pt(-12755.169324773129,52720.312032458663)); + r.push_back(pt(-12755.169324773129,51087.312032458671)); + r.push_back(pt(-12760.669324773080,51087.312032458671)); + r.push_back(pt(-12760.669324773082,51070.312032458627)); + r.push_back(pt(-19155.669324779392,51070.312032458620)); + r.push_back(pt(-19155.669324773193,54820.312032458620)); + + pt p( -12260.669324773118, 54820.312032458634 ); + + //boost::geometry::correct(r); + + bool within = boost::geometry::within(p, r); + BOOST_CHECK_EQUAL(within, false); + } + // similar + { + ring r; + r.push_back(pt(-14155.6,54820.312032458620)); + r.push_back(pt(-13826.1,54820.312032458625)); + r.push_back(pt(-12155.6,53720.3)); + r.push_back(pt(-14155.6,54820.312032458620)); + + pt p( -13826.0, 54820.312032458634 ); + + bool within = boost::geometry::within(p, r); + BOOST_CHECK_EQUAL(within, false); + } +} + int test_main( int , char* [] ) { test_large_integers(); @@ -195,5 +235,7 @@ int test_main( int , char* [] ) test_spherical > >(); #endif + test_tickets(); + return 0; }