diff --git a/doc/generated/buffer_status.qbk b/doc/generated/buffer_status.qbk new file mode 100644 index 000000000..6caf4c90c --- /dev/null +++ b/doc/generated/buffer_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[ ][Point][Segment][Box][Linestring][Ring][Polygon][MultiPoint][MultiLinestring][MultiPolygon]] +[[Point][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[Segment][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[Box][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[Linestring][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[Ring][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[Polygon][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[MultiPoint][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[MultiLinestring][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[MultiPolygon][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +] diff --git a/doc/generated/centroid_status.qbk b/doc/generated/centroid_status.qbk new file mode 100644 index 000000000..10e064127 --- /dev/null +++ b/doc/generated/centroid_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/nyi.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/for_each_point_status.qbk b/doc/generated/for_each_point_status.qbk new file mode 100644 index 000000000..b5383e0d1 --- /dev/null +++ b/doc/generated/for_each_point_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/nyi.png] ]] +[[Box][ [$img/nyi.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/for_each_segment_status.qbk b/doc/generated/for_each_segment_status.qbk new file mode 100644 index 000000000..b5383e0d1 --- /dev/null +++ b/doc/generated/for_each_segment_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/nyi.png] ]] +[[Box][ [$img/nyi.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/length_status.qbk b/doc/generated/length_status.qbk new file mode 100644 index 000000000..e4d8d3023 --- /dev/null +++ b/doc/generated/length_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/num_geometries_status.qbk b/doc/generated/num_geometries_status.qbk new file mode 100644 index 000000000..e4d8d3023 --- /dev/null +++ b/doc/generated/num_geometries_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/num_interior_rings_status.qbk b/doc/generated/num_interior_rings_status.qbk new file mode 100644 index 000000000..e4d8d3023 --- /dev/null +++ b/doc/generated/num_interior_rings_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/num_points_status.qbk b/doc/generated/num_points_status.qbk new file mode 100644 index 000000000..e4d8d3023 --- /dev/null +++ b/doc/generated/num_points_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/perimeter_status.qbk b/doc/generated/perimeter_status.qbk new file mode 100644 index 000000000..e4d8d3023 --- /dev/null +++ b/doc/generated/perimeter_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/reverse_status.qbk b/doc/generated/reverse_status.qbk new file mode 100644 index 000000000..e4d8d3023 --- /dev/null +++ b/doc/generated/reverse_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/simplify_status.qbk b/doc/generated/simplify_status.qbk new file mode 100644 index 000000000..b5383e0d1 --- /dev/null +++ b/doc/generated/simplify_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/nyi.png] ]] +[[Box][ [$img/nyi.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/generated/transform_status.qbk b/doc/generated/transform_status.qbk new file mode 100644 index 000000000..d7d9e977e --- /dev/null +++ b/doc/generated/transform_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[ ][Point][Segment][Box][Linestring][Ring][Polygon][MultiPoint][MultiLinestring][MultiPolygon]] +[[Point][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +] diff --git a/doc/generated/unique_status.qbk b/doc/generated/unique_status.qbk new file mode 100644 index 000000000..e4d8d3023 --- /dev/null +++ b/doc/generated/unique_status.qbk @@ -0,0 +1,13 @@ +[heading Supported geometries] +[table +[[Geometry][Status]] +[[Point][ [$img/ok.png] ]] +[[Segment][ [$img/ok.png] ]] +[[Box][ [$img/ok.png] ]] +[[Linestring][ [$img/ok.png] ]] +[[Ring][ [$img/ok.png] ]] +[[Polygon][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/ok.png] ]] +] diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 445c03862..1bb40e2bc 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -13,6 +13,28 @@ [section:release_notes Release Notes] +[/=================] +[heading Boost 1.53] +[/=================] + +[*Bugfixes] + +* avoid generating output polygons with interior rings below minimum size (e.g. one or two points) +* `geometry::disjoint` for degenerate segments (patched by Karsten Ahnert) +* problem in `geometry::difference` for missing handling tangency, reported by H2 +* fixed `geometry::for_each` for use with Lambda's +* fixed `geometry::comparable_distance` point-linestring (and -range, -polygon) + +[*Additional functionality] + +* combinations for `geometry::disjoint`: point/ring, point/polygon, point/multi_polygon +* combinations for `geometry::intersects`: point/ring, point/polygon, point/multi_polygon + +[*Internal changes] + +* updates in specializations/not_implemented for various algorithms (as in an earlier version, these changes are still going on; they take care for simplified structs, better error reporting, and automatized documentation) +* fixes in unit tests + [/=================] [heading Boost 1.51] [/=================] diff --git a/doc/src/docutils/tools/support_status/support_status.cpp b/doc/src/docutils/tools/support_status/support_status.cpp index b1cc806e6..d3c788db3 100644 --- a/doc/src/docutils/tools/support_status/support_status.cpp +++ b/doc/src/docutils/tools/support_status/support_status.cpp @@ -22,19 +22,49 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include "text_outputter.hpp" @@ -76,13 +106,31 @@ typedef boost::mpl::vector< {}; DECLARE_BINARY_ALGORITHM(append) -DECLARE_UNARY_ALGORITHM (area) -DECLARE_UNARY_ALGORITHM (clear) +DECLARE_UNARY_ALGORITHM(area) +DECLARE_BINARY_ALGORITHM(buffer) +DECLARE_UNARY_ALGORITHM(centroid) +DECLARE_UNARY_ALGORITHM(clear) DECLARE_BINARY_ALGORITHM(convert) -DECLARE_UNARY_ALGORITHM (convex_hull) -DECLARE_UNARY_ALGORITHM (correct) +DECLARE_UNARY_ALGORITHM(convex_hull) +DECLARE_UNARY_ALGORITHM(correct) DECLARE_BINARY_ALGORITHM(covered_by) +DECLARE_BINARY_ALGORITHM(disjoint) DECLARE_BINARY_ALGORITHM(distance) +DECLARE_UNARY_ALGORITHM(envelope) +DECLARE_BINARY_ALGORITHM(equals) +DECLARE_BINARY_ALGORITHM(expand) +DECLARE_UNARY_ALGORITHM(for_each_point) +DECLARE_UNARY_ALGORITHM(for_each_segment) +DECLARE_UNARY_ALGORITHM(length) +DECLARE_UNARY_ALGORITHM(num_geometries) +DECLARE_UNARY_ALGORITHM(num_interior_rings) +DECLARE_UNARY_ALGORITHM(num_points) +DECLARE_BINARY_ALGORITHM(overlaps) +DECLARE_UNARY_ALGORITHM(perimeter) +DECLARE_UNARY_ALGORITHM(reverse) +DECLARE_UNARY_ALGORITHM(simplify) +DECLARE_BINARY_ALGORITHM(transform) +DECLARE_UNARY_ALGORITHM(unique) DECLARE_BINARY_ALGORITHM(within) @@ -194,12 +242,30 @@ void support_status() { test_binary_algorithm >, OutputFactory>("append"); test_unary_algorithm("area"); + test_binary_algorithm("buffer"); + test_unary_algorithm("centroid"); test_unary_algorithm("clear"); test_binary_algorithm("convert"); test_unary_algorithm("convex_hull"); test_unary_algorithm("correct"); test_binary_algorithm("covered_by"); + test_binary_algorithm("disjoint"); test_binary_algorithm("distance"); + test_unary_algorithm("envelope"); + test_binary_algorithm("equals"); + test_binary_algorithm("expand"); + test_unary_algorithm("for_each_point"); + test_unary_algorithm("for_each_segment"); + test_unary_algorithm("length"); + test_unary_algorithm("num_geometries"); + test_unary_algorithm("num_interior_rings"); + test_unary_algorithm("num_points"); + test_binary_algorithm("overlaps"); + test_unary_algorithm("perimeter"); + test_unary_algorithm("reverse"); + test_unary_algorithm("simplify"); + test_binary_algorithm("transform"); + test_unary_algorithm("unique"); test_binary_algorithm("within"); } diff --git a/example/with_external_libs/x04_wxwidgets_world_mapper.cpp b/example/with_external_libs/x04_wxwidgets_world_mapper.cpp index f507f4cb4..1a8bde389 100644 --- a/example/with_external_libs/x04_wxwidgets_world_mapper.cpp +++ b/example/with_external_libs/x04_wxwidgets_world_mapper.cpp @@ -357,15 +357,15 @@ void HelloWorldCanvas::DrawCountry(wxDC& dc, country_type const& country) BOOST_FOREACH(bg::model::polygon const& poly, country) { - // Use only outer, holes are (for the moment) ignored. This would need + // Use only exterior ring, holes are (for the moment) ignored. This would need // a holey-polygon compatible wx object - std::size_t n = boost::size(poly.outer()); + std::size_t n = boost::size(bg::exterior_ring(poly)); boost::scoped_array points(new wxPoint[n]); wxPointPointerPair pair = std::make_pair(points.get(), points.get() + n); - bg::transform(poly.outer(), pair, *m_map_transformer); + bg::transform(bg::exterior_ring(poly), pair, *m_map_transformer); dc.DrawPolygon(n, points.get()); } diff --git a/include/boost/geometry/algorithms/area.hpp b/include/boost/geometry/algorithms/area.hpp index 8193200ab..514134e0f 100644 --- a/include/boost/geometry/algorithms/area.hpp +++ b/include/boost/geometry/algorithms/area.hpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -26,6 +28,7 @@ #include #include +#include #include #include @@ -49,41 +52,33 @@ namespace boost { namespace geometry namespace detail { namespace area { -template struct box_area { - typedef typename coordinate_type::type return_type; - - static inline return_type apply(Box const& box, Strategy const&) + template + static inline typename coordinate_type::type + apply(Box const& box, Strategy const&) { // Currently only works for 2D Cartesian boxes assert_dimension(); - return_type const dx = get(box) - - get(box); - return_type const dy = get(box) - - get(box); - - return dx * dy; + return (get(box) - get(box)) + * (get(box) - get(box)); } }; template < - typename Ring, iterate_direction Direction, - closure_selector Closure, - typename Strategy + closure_selector Closure > struct ring_area { - BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy) ); - - typedef typename Strategy::return_type type; - - static inline type apply(Ring const& ring, Strategy const& strategy) + template + static inline typename Strategy::return_type + apply(Ring const& ring, Strategy const& strategy) { + BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy) ); assert_dimension(); // Ignore warning (because using static method sometimes) on strategy @@ -95,7 +90,7 @@ struct ring_area if (int(boost::size(ring)) < core_detail::closure::minimum_ring_size::value) { - return type(); + return typename Strategy::return_type(); } typedef typename reversible_view::type rview_type; @@ -136,71 +131,75 @@ namespace dispatch template < typename Geometry, - typename Strategy = typename strategy::area::services::default_strategy - < - typename cs_tag - < - typename point_type::type - >::type, - typename point_type::type - >::type, typename Tag = typename tag::type > -struct area - : detail::calculate_null - < - typename Strategy::return_type, - Geometry, - Strategy - > {}; +struct area : detail::calculate_null +{ + template + static inline typename Strategy::return_type apply(Geometry const& geometry, Strategy const& strategy) + { + return calculate_null::apply(geometry, strategy); + } +}; -template -< - typename Geometry, - typename Strategy -> -struct area - : detail::area::box_area +template +struct area, void> +{ + template + struct visitor: boost::static_visitor + { + Strategy const& m_strategy; + + visitor(Strategy const& strategy): m_strategy(strategy) {} + + template + typename Strategy::return_type operator()(Geometry const& geometry) const + { + return dispatch::area::apply(geometry, m_strategy); + } + }; + + template + static inline typename Strategy::return_type + apply(Variant const& variant_geometry, Strategy const& strategy) + { + return boost::apply_visitor(visitor(strategy), variant_geometry); + } +}; + + +template +struct area : detail::area::box_area {}; -template -< - typename Ring, - typename Strategy -> -struct area +template +struct area : detail::area::ring_area < - Ring, order_as_direction::value>::value, - geometry::closure::value, - Strategy + geometry::closure::value > {}; -template -< - typename Polygon, - typename Strategy -> -struct area - : detail::calculate_polygon_sum - < +template +struct area : detail::calculate_polygon_sum +{ + template + static inline typename Strategy::return_type apply(Polygon const& polygon, Strategy const& strategy) + { + return calculate_polygon_sum::apply< typename Strategy::return_type, - Polygon, - Strategy, detail::area::ring_area < - typename ring_type::type, order_as_direction::value>::value, - geometry::closure::value, - Strategy + geometry::closure::value > - > -{}; + >(polygon, strategy); + } +}; } // namespace dispatch @@ -243,10 +242,7 @@ inline typename default_area_result::type area(Geometry const& geometr // detail::throw_on_empty_input(geometry); - return dispatch::area - < - Geometry - >::apply(geometry, strategy_type()); + return dispatch::area::apply(geometry, strategy_type()); } /*! @@ -281,11 +277,7 @@ inline typename Strategy::return_type area( // detail::throw_on_empty_input(geometry); - return dispatch::area - < - Geometry, - Strategy - >::apply(geometry, strategy); + return dispatch::area::apply(geometry, strategy); } diff --git a/include/boost/geometry/algorithms/buffer.hpp b/include/boost/geometry/algorithms/buffer.hpp index e22e36add..2edce0a09 100644 --- a/include/boost/geometry/algorithms/buffer.hpp +++ b/include/boost/geometry/algorithms/buffer.hpp @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -75,15 +76,23 @@ inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out) namespace dispatch { -template -struct buffer {}; +template +< + typename Input, + typename Output, + typename TagIn = typename tag::type, + typename TagOut = typename tag::type +> +struct buffer: not_implemented +{}; -template -struct buffer +template +struct buffer { - static inline void apply(BoxIn const& box_in, T const& distance, - T const& , BoxIn& box_out) + template + static inline void apply(BoxIn const& box_in, Distance const& distance, + Distance const& , BoxIn& box_out) { detail::buffer::buffer_box(box_in, distance, box_out); } @@ -122,10 +131,7 @@ inline void buffer(Input const& geometry_in, Output& geometry_out, dispatch::buffer < - typename tag::type, - typename tag::type, Input, - Distance, Output >::apply(geometry_in, distance, chord_length, geometry_out); } @@ -152,10 +158,7 @@ Output return_buffer(Input const& geometry, T const& distance, T const& chord_le dispatch::buffer < - typename tag::type, - typename tag::type, Input, - T, Output >::apply(geometry, distance, chord_length, geometry_out); diff --git a/include/boost/geometry/algorithms/centroid.hpp b/include/boost/geometry/algorithms/centroid.hpp index 69ad9fe82..9be51f409 100644 --- a/include/boost/geometry/algorithms/centroid.hpp +++ b/include/boost/geometry/algorithms/centroid.hpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -77,9 +78,9 @@ public: namespace detail { namespace centroid { -template struct centroid_point { + template static inline void apply(Point const& point, PointCentroid& centroid, Strategy const&) { @@ -127,9 +128,9 @@ struct centroid_box_calculator }; -template struct centroid_box { + template static inline void apply(Box const& box, Point& centroid, Strategy const&) { @@ -173,9 +174,10 @@ inline bool range_ok(Range const& range, Point& centroid) /*! \brief Calculate the centroid of a ring. */ -template +template struct centroid_range_state { + template static inline void apply(Ring const& ring, Strategy const& strategy, typename Strategy::state_type& state) { @@ -196,21 +198,17 @@ struct centroid_range_state } }; -template +template struct centroid_range { + template static inline void apply(Range const& range, Point& centroid, Strategy const& strategy) { if (range_ok(range, centroid)) { typename Strategy::state_type state; - centroid_range_state - < - Range, - Closure, - Strategy - >::apply(range, strategy, state); + centroid_range_state::apply(range, strategy, state); strategy.result(state, centroid); } } @@ -222,20 +220,14 @@ struct centroid_range \note Because outer ring is clockwise, inners are counter clockwise, triangle approach is OK and works for polygons with rings. */ -template struct centroid_polygon_state { - typedef typename ring_type::type ring_type; - + template static inline void apply(Polygon const& poly, Strategy const& strategy, typename Strategy::state_type& state) { - typedef centroid_range_state - < - ring_type, - geometry::closure::value, - Strategy - > per_ring; + typedef typename ring_type::type ring_type; + typedef centroid_range_state::value> per_ring; per_ring::apply(exterior_ring(poly), strategy, state); @@ -248,20 +240,16 @@ struct centroid_polygon_state } }; -template struct centroid_polygon { + template static inline void apply(Polygon const& poly, Point& centroid, Strategy const& strategy) { if (range_ok(exterior_ring(poly), centroid)) { typename Strategy::state_type state; - centroid_polygon_state - < - Polygon, - Strategy - >::apply(poly, strategy, state); + centroid_polygon_state::apply(poly, strategy, state); strategy.result(state, centroid); } } @@ -278,58 +266,35 @@ namespace dispatch template < - typename Tag, typename Geometry, - typename Point, - typename Strategy + typename Tag = typename tag::type > -struct centroid {}; - -template -< - typename Geometry, - typename Point, - typename Strategy -> -struct centroid - : detail::centroid::centroid_point +struct centroid: not_implemented {}; -template -< - typename Box, - typename Point, - typename Strategy -> -struct centroid - : detail::centroid::centroid_box +template +struct centroid + : detail::centroid::centroid_point {}; -template -struct centroid - : detail::centroid::centroid_range - < - Ring, - Point, - geometry::closure::value, - Strategy - > +template +struct centroid + : detail::centroid::centroid_box {}; -template -struct centroid - : detail::centroid::centroid_range - < - Linestring, - Point, - closed, - Strategy - > +template +struct centroid + : detail::centroid::centroid_range::value> +{}; + +template +struct centroid + : detail::centroid::centroid_range {}; -template -struct centroid - : detail::centroid::centroid_polygon +template +struct centroid + : detail::centroid::centroid_polygon {}; } // namespace dispatch @@ -365,13 +330,7 @@ inline void centroid(Geometry const& geometry, Point& c, // Call dispatch apply method. That one returns true if centroid // should be taken from state. - dispatch::centroid - < - typename tag::type, - Geometry, - Point, - Strategy - >::apply(geometry, c, strategy); + dispatch::centroid::apply(geometry, c, strategy); } diff --git a/include/boost/geometry/algorithms/convex_hull.hpp b/include/boost/geometry/algorithms/convex_hull.hpp index 56b87c8c1..d31efe9e4 100644 --- a/include/boost/geometry/algorithms/convex_hull.hpp +++ b/include/boost/geometry/algorithms/convex_hull.hpp @@ -40,18 +40,13 @@ namespace boost { namespace geometry namespace detail { namespace convex_hull { -template -< - typename Geometry, - order_selector Order, - typename Strategy -> +template struct hull_insert { // Member template function (to avoid inconvenient declaration // of output-iterator-type, from hull_to_geometry) - template + template static inline OutputIterator apply(Geometry const& geometry, OutputIterator out, Strategy const& strategy) { @@ -63,22 +58,15 @@ struct hull_insert } }; -template -< - typename Geometry, - typename Strategy -> struct hull_to_geometry { - template + template static inline void apply(Geometry const& geometry, OutputGeometry& out, Strategy const& strategy) { hull_insert < - Geometry, - geometry::point_order::value, - Strategy + geometry::point_order::value >::apply(geometry, std::back_inserter( // Handle linestring, ring and polygon the same: @@ -113,21 +101,16 @@ namespace dispatch template < typename Geometry, - typename Strategy = typename detail::convex_hull::default_strategy::type, typename Tag = typename tag::type > struct convex_hull - : detail::convex_hull::hull_to_geometry + : detail::convex_hull::hull_to_geometry {}; -template -< - typename Box, - typename Strategy -> -struct convex_hull +template +struct convex_hull { - template + template static inline void apply(Box const& box, OutputGeometry& out, Strategy const& ) { @@ -149,13 +132,9 @@ struct convex_hull -template -< - order_selector Order, - typename Geometry, typename Strategy -> +template struct convex_hull_insert - : detail::convex_hull::hull_insert + : detail::convex_hull::hull_insert {}; @@ -181,11 +160,7 @@ inline void convex_hull(Geometry const& geometry, return; } - dispatch::convex_hull - < - Geometry, - Strategy - >::apply(geometry, out, strategy); + dispatch::convex_hull::apply(geometry, out, strategy); } @@ -232,8 +207,7 @@ inline OutputIterator convex_hull_insert(Geometry const& geometry, return dispatch::convex_hull_insert < - geometry::point_order::value, - Geometry, Strategy + geometry::point_order::value >::apply(geometry, out, strategy); } diff --git a/include/boost/geometry/algorithms/correct.hpp b/include/boost/geometry/algorithms/correct.hpp index 583e395f8..39249e7de 100644 --- a/include/boost/geometry/algorithms/correct.hpp +++ b/include/boost/geometry/algorithms/correct.hpp @@ -119,10 +119,8 @@ struct correct_ring typedef detail::area::ring_area < - Ring, order_as_direction::value>::value, - geometry::closure::value, - strategy_type + geometry::closure::value > ring_area_type; diff --git a/include/boost/geometry/algorithms/detail/calculate_null.hpp b/include/boost/geometry/algorithms/detail/calculate_null.hpp index 4b48d62fc..3ebca8350 100644 --- a/include/boost/geometry/algorithms/detail/calculate_null.hpp +++ b/include/boost/geometry/algorithms/detail/calculate_null.hpp @@ -21,9 +21,9 @@ namespace boost { namespace geometry namespace detail { -template struct calculate_null { + template static inline ReturnType apply(Geometry const& , Strategy const&) { return ReturnType(); diff --git a/include/boost/geometry/algorithms/detail/calculate_sum.hpp b/include/boost/geometry/algorithms/detail/calculate_sum.hpp index 2ad349080..dd0399bb1 100644 --- a/include/boost/geometry/algorithms/detail/calculate_sum.hpp +++ b/include/boost/geometry/algorithms/detail/calculate_sum.hpp @@ -26,16 +26,9 @@ namespace detail { -template -< - typename ReturnType, - typename Polygon, - typename Strategy, - typename Policy -> class calculate_polygon_sum { - template + template static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy) { ReturnType sum = ReturnType(); @@ -47,10 +40,11 @@ class calculate_polygon_sum } public : + template static inline ReturnType apply(Polygon const& poly, Strategy const& strategy) { return Policy::apply(exterior_ring(poly), strategy) - + sum_interior_rings(interior_rings(poly), strategy) + + sum_interior_rings(interior_rings(poly), strategy) ; } }; diff --git a/include/boost/geometry/algorithms/detail/disjoint.hpp b/include/boost/geometry/algorithms/detail/disjoint.hpp index 2ced5b1ce..e944e5169 100644 --- a/include/boost/geometry/algorithms/detail/disjoint.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint.hpp @@ -26,6 +26,7 @@ #include #include +#include #include @@ -165,6 +166,19 @@ struct box_box }; +template +< + typename Geometry1, typename Geometry2 +> +struct reverse_covered_by +{ + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + { + return ! geometry::covered_by(geometry1, geometry2); + } +}; + + /*! \brief Internal utility function to detect of boxes are disjoint diff --git a/include/boost/geometry/algorithms/detail/get_left_turns.hpp b/include/boost/geometry/algorithms/detail/get_left_turns.hpp index 62f0f7f0f..d23f1e4c2 100644 --- a/include/boost/geometry/algorithms/detail/get_left_turns.hpp +++ b/include/boost/geometry/algorithms/detail/get_left_turns.hpp @@ -120,10 +120,10 @@ inline bool include_left_turn_of_all( bool result = false; std::pair pair = ordered_pair(outgoing_seg_id, incoming_seg_id); - auto it = turn_segment_indices.find(pair); + typename boost::range_iterator::type it = turn_segment_indices.find(pair); if (it != turn_segment_indices.end()) { - for (auto sit = it->second.begin(); sit != it->second.end(); ++sit) + for (std::set::const_iterator sit = it->second.begin(); sit != it->second.end(); ++sit) { if (process_include(outgoing_seg_id, incoming_seg_id, *sit, turns[*sit], keep_indices, priority)) { @@ -148,14 +148,17 @@ inline bool prefer_by_other(Turns const& turns, std::set& indices) { std::map map; - for (auto sit = indices.begin(); sit != indices.end(); ++sit) + for (std::set::const_iterator sit = indices.begin(); + sit != indices.end(); + ++sit) { map[turns[*sit].operations[0].seg_id]++; map[turns[*sit].operations[1].seg_id]++; } std::set segment_occuring_once; - for (auto mit = map.begin(); mit != map.end(); ++mit) + for (std::map::const_iterator mit = map.begin(); + mit != map.end();++mit) { if (mit->second == 1) { @@ -176,13 +179,14 @@ inline bool prefer_by_other(Turns const& turns, segment_identifier back = *soo_it; std::pair pair = ordered_pair(front, back); - auto it = turn_segment_indices.find(pair); + + typename boost::range_iterator::type it = turn_segment_indices.find(pair); if (it != turn_segment_indices.end()) { // debug_turns_by_indices("Found", it->second); // Check which is the union/continue segment_identifier good; - for (auto sit = it->second.begin(); sit != it->second.end(); ++sit) + for (std::set::const_iterator sit = it->second.begin(); sit != it->second.end(); ++sit) { if (turns[*sit].operations[0].operation == detail::overlay::operation_union) { @@ -200,7 +204,7 @@ inline bool prefer_by_other(Turns const& turns, // Find in indexes-to-keep this segment with the union. Discard the other one std::set ok_indices; - for (auto sit = indices.begin(); sit != indices.end(); ++sit) + for (std::set::const_iterator sit = indices.begin(); sit != indices.end(); ++sit) { if (corresponds<0>(turns[*sit], good) || corresponds<1>(turns[*sit], good)) { @@ -223,7 +227,7 @@ inline void prefer_by_priority(Turns const& turns, std::set& indices) { // Find max prio int min_prio = 1024, max_prio = 0; - for (auto sit = indices.begin(); sit != indices.end(); ++sit) + for (std::set::const_iterator sit = indices.begin(); sit != indices.end(); ++sit) { if (turns[*sit].priority > max_prio) { @@ -242,7 +246,7 @@ inline void prefer_by_priority(Turns const& turns, std::set& indices) // Only keep indices with high prio std::set ok_indices; - for (auto sit = indices.begin(); sit != indices.end(); ++sit) + for (std::set::const_iterator sit = indices.begin(); sit != indices.end(); ++sit) { if (turns[*sit].priority >= max_prio) { diff --git a/include/boost/geometry/algorithms/detail/occupation_info.hpp b/include/boost/geometry/algorithms/detail/occupation_info.hpp index e147ba12d..6d15f2dd6 100644 --- a/include/boost/geometry/algorithms/detail/occupation_info.hpp +++ b/include/boost/geometry/algorithms/detail/occupation_info.hpp @@ -10,7 +10,7 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP #if ! defined(NDEBUG) - #define BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION +// #define BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION #endif #include diff --git a/include/boost/geometry/algorithms/detail/overlay/add_rings.hpp b/include/boost/geometry/algorithms/detail/overlay/add_rings.hpp index 74595fedd..5ff0b57d6 100644 --- a/include/boost/geometry/algorithms/detail/overlay/add_rings.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/add_rings.hpp @@ -75,15 +75,15 @@ inline OutputIterator add_rings(SelectionMap const& map, OutputIterator out) { typedef typename SelectionMap::const_iterator iterator; - typedef typename SelectionMap::mapped_type property_type; - typedef typename property_type::area_type area_type; + typedef typename SelectionMap::mapped_type property_type; + typedef typename property_type::area_type area_type; - area_type const zero = 0; - std::size_t const min_num_points = core_detail::closure::minimum_ring_size - < - geometry::closure - < - typename boost::range_value + area_type const zero = 0; + std::size_t const min_num_points = core_detail::closure::minimum_ring_size + < + geometry::closure + < + typename boost::range_value < RingCollection const >::type @@ -117,15 +117,14 @@ inline OutputIterator add_rings(SelectionMap const& map, } } - // Only add rings if they satisfy minimal requirements. - // This cannot be done earlier (during traversal), not - // everything is figured out yet (sum of positive/negative rings) - // TODO: individual rings can still contain less than 3 points. - if (geometry::num_points(result) >= min_num_points - && math::larger(geometry::area(result), zero)) - { - *out++ = result; - } + // Only add rings if they satisfy minimal requirements. + // This cannot be done earlier (during traversal), not + // everything is figured out yet (sum of positive/negative rings) + if (geometry::num_points(result) >= min_num_points + && math::larger(geometry::area(result), zero)) + { + *out++ = result; + } } } return out; diff --git a/include/boost/geometry/algorithms/detail/overlay/convert_ring.hpp b/include/boost/geometry/algorithms/detail/overlay/convert_ring.hpp index 05bd721e7..51955b515 100644 --- a/include/boost/geometry/algorithms/detail/overlay/convert_ring.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/convert_ring.hpp @@ -77,12 +77,23 @@ struct convert_ring } else { - interior_rings(destination).resize( - interior_rings(destination).size() + 1); - geometry::convert(source, interior_rings(destination).back()); - if (reverse) + // Avoid adding interior rings which are invalid + // because of its number of points: + std::size_t const min_num_points + = core_detail::closure::minimum_ring_size + < + geometry::closure::value + >::value; + + if (geometry::num_points(source) >= min_num_points) { - boost::reverse(interior_rings(destination).back()); + interior_rings(destination).resize( + interior_rings(destination).size() + 1); + geometry::convert(source, interior_rings(destination).back()); + if (reverse) + { + boost::reverse(interior_rings(destination).back()); + } } } } diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp index 1e878ca52..84ec16f23 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp @@ -252,6 +252,32 @@ private : : order == 1; } + inline bool consider_ix_ix(Indexed const& left, Indexed const& right + , std::string const& // header + ) const + { + // Take first intersection, then blocked. + if (left.subject.operation == operation_intersection + && right.subject.operation == operation_blocked) + { + return true; + } + else if (left.subject.operation == operation_blocked + && right.subject.operation == operation_intersection) + { + return false; + } + + // Default case, should not occur + +#ifdef BOOST_GEOMETRY_DEBUG_ENRICH + std::cout << "ix/ix unhandled" << std::endl; +#endif + //debug_consider(0, left, right, header, false, "-> return", ret); + + return left.index < right.index; + } + inline bool consider_iu_iu(Indexed const& left, Indexed const& right, std::string const& header) const @@ -446,6 +472,11 @@ public : { return consider_iu_iu(left, right, "iu/iu"); } + else if (m_turn_points[left.index].combination(operation_intersection, operation_blocked) + && m_turn_points[right.index].combination(operation_intersection, operation_blocked)) + { + return consider_ix_ix(left, right, "ix/ix"); + } else if (m_turn_points[left.index].both(operation_intersection) && m_turn_points[right.index].both(operation_intersection)) { @@ -493,7 +524,7 @@ public : << "/" << operation_char(m_turn_points[right.index].operations[0].operation) << operation_char(m_turn_points[right.index].operations[1].operation) << " " << " Take " << left.index << " < " << right.index - << std::cout; + << std::endl; #endif return default_order; diff --git a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp index 8bca790d7..f0307eaf8 100644 --- a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp @@ -41,14 +41,14 @@ namespace boost { namespace geometry namespace detail { namespace intersection { -template -< - typename Segment1, typename Segment2, - typename OutputIterator, typename PointOut, - typename Strategy -> +template struct intersection_segment_segment_point { + template + < + typename Segment1, typename Segment2, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(Segment1 const& segment1, Segment2 const& segment2, OutputIterator out, Strategy const& ) @@ -77,14 +77,14 @@ struct intersection_segment_segment_point } }; -template -< - typename Linestring1, typename Linestring2, - typename OutputIterator, typename PointOut, - typename Strategy -> +template struct intersection_linestring_linestring_point { + template + < + typename Linestring1, typename Linestring2, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(Linestring1 const& linestring1, Linestring2 const& linestring2, OutputIterator out, Strategy const& ) @@ -112,22 +112,12 @@ struct intersection_linestring_linestring_point */ template < - typename LineString, typename Areal, bool ReverseAreal, - typename OutputIterator, typename LineStringOut, - overlay_type OverlayType, - typename Strategy + typename LineStringOut, + overlay_type OverlayType > struct intersection_of_linestring_with_areal { - typedef detail::overlay::follow - < - LineStringOut, - LineString, - Areal, - OverlayType - > follower; - #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW) template static inline void debug_follow(Turn const& turn, Operation op, @@ -145,6 +135,11 @@ struct intersection_of_linestring_with_areal } #endif + template + < + typename LineString, typename Areal, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(LineString const& linestring, Areal const& areal, OutputIterator out, Strategy const& ) @@ -154,6 +149,14 @@ struct intersection_of_linestring_with_areal return out; } + typedef detail::overlay::follow + < + LineStringOut, + LineString, + Areal, + OverlayType + > follower; + typedef typename point_type::type point_type; typedef detail::overlay::traversal_turn_info turn_info; @@ -220,18 +223,22 @@ namespace dispatch template < - // tag dispatching: - typename TagIn1, typename TagIn2, typename TagOut, - // orientation - // metafunction finetuning helpers: - bool Areal1, bool Areal2, bool ArealOut, // real types typename Geometry1, typename Geometry2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, overlay_type OverlayType, - typename Strategy + // orientation + bool Reverse1 = detail::overlay::do_reverse::value>::value, + bool Reverse2 = detail::overlay::do_reverse::value>::value, + bool ReverseOut = detail::overlay::do_reverse::value>::value, + // tag dispatching: + typename TagIn1 = typename geometry::tag::type, + typename TagIn2 = typename geometry::tag::type, + typename TagOut = typename geometry::tag::type, + // metafunction finetuning helpers: + bool Areal1 = geometry::is_areal::value, + bool Areal2 = geometry::is_areal::value, + bool ArealOut = geometry::is_areal::value > struct intersection_insert { @@ -245,122 +252,103 @@ struct intersection_insert template < - typename TagIn1, typename TagIn2, typename TagOut, typename Geometry1, typename Geometry2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut, + typename TagIn1, typename TagIn2, typename TagOut > struct intersection_insert < - TagIn1, TagIn2, TagOut, - true, true, true, Geometry1, Geometry2, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + TagIn1, TagIn2, TagOut, + true, true, true > : detail::overlay::overlay - + {}; // Any areal type with box: template < - typename TagIn, typename TagOut, typename Geometry, typename Box, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut, + typename TagIn, typename TagOut > struct intersection_insert < - TagIn, box_tag, TagOut, - true, true, true, Geometry, Box, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + TagIn, box_tag, TagOut, + true, true, true > : detail::overlay::overlay - + {}; template < typename Segment1, typename Segment2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert < - segment_tag, segment_tag, point_tag, - false, false, false, Segment1, Segment2, + GeometryOut, + OverlayType, Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, - OverlayType, Strategy - > : detail::intersection::intersection_segment_segment_point - < - Segment1, Segment2, - OutputIterator, GeometryOut, - Strategy - > + segment_tag, segment_tag, point_tag, + false, false, false + > : detail::intersection::intersection_segment_segment_point {}; template < typename Linestring1, typename Linestring2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert < - linestring_tag, linestring_tag, point_tag, - false, false, false, Linestring1, Linestring2, + GeometryOut, + OverlayType, Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, - OverlayType, Strategy - > : detail::intersection::intersection_linestring_linestring_point - < - Linestring1, Linestring2, - OutputIterator, GeometryOut, - Strategy - > + linestring_tag, linestring_tag, point_tag, + false, false, false + > : detail::intersection::intersection_linestring_linestring_point {}; template < typename Linestring, typename Box, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert < - linestring_tag, box_tag, linestring_tag, - false, true, false, Linestring, Box, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + linestring_tag, box_tag, linestring_tag, + false, true, false > { + template static inline OutputIterator apply(Linestring const& linestring, Box const& box, OutputIterator out, Strategy const& ) { @@ -375,27 +363,23 @@ struct intersection_insert template < typename Linestring, typename Polygon, - bool ReverseLinestring, bool ReversePolygon, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool ReverseLinestring, bool ReversePolygon, bool ReverseOut > struct intersection_insert < - linestring_tag, polygon_tag, linestring_tag, - false, true, false, Linestring, Polygon, - ReverseLinestring, ReversePolygon, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + ReverseLinestring, ReversePolygon, ReverseOut, + linestring_tag, polygon_tag, linestring_tag, + false, true, false > : detail::intersection::intersection_of_linestring_with_areal < - Linestring, Polygon, ReversePolygon, - OutputIterator, GeometryOut, - OverlayType, - Strategy + GeometryOut, + OverlayType > {}; @@ -403,49 +387,44 @@ struct intersection_insert template < typename Linestring, typename Ring, - bool ReverseLinestring, bool ReverseRing, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool ReverseLinestring, bool ReverseRing, bool ReverseOut > struct intersection_insert < - linestring_tag, ring_tag, linestring_tag, - false, true, false, Linestring, Ring, - ReverseLinestring, ReverseRing, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + ReverseLinestring, ReverseRing, ReverseOut, + linestring_tag, ring_tag, linestring_tag, + false, true, false > : detail::intersection::intersection_of_linestring_with_areal < - Linestring, Ring, ReverseRing, - OutputIterator, GeometryOut, - OverlayType, - Strategy + GeometryOut, + OverlayType > {}; template < typename Segment, typename Box, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert < - segment_tag, box_tag, linestring_tag, - false, true, false, Segment, Box, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + segment_tag, box_tag, linestring_tag, + false, true, false > { + template static inline OutputIterator apply(Segment const& segment, Box const& box, OutputIterator out, Strategy const& ) { @@ -460,25 +439,24 @@ struct intersection_insert template < - typename Tag1, typename Tag2, - bool Areal1, bool Areal2, typename Geometry1, typename Geometry2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename PointOut, + typename PointOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut, + typename Tag1, typename Tag2, + bool Areal1, bool Areal2 > struct intersection_insert < - Tag1, Tag2, point_tag, - Areal1, Areal2, false, Geometry1, Geometry2, - Reverse1, Reverse2, ReverseOut, - OutputIterator, PointOut, + PointOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + Tag1, Tag2, point_tag, + Areal1, Areal2, false > { + template static inline OutputIterator apply(Geometry1 const& geometry1, Geometry2 const& geometry2, OutputIterator out, Strategy const& ) { @@ -504,29 +482,22 @@ struct intersection_insert template < - typename GeometryTag1, typename GeometryTag2, typename GeometryTag3, - bool Areal1, bool Areal2, bool ArealOut, - typename Geometry1, typename Geometry2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename Geometry1, typename Geometry2, typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert_reversed { + template static inline OutputIterator apply(Geometry1 const& g1, Geometry2 const& g2, OutputIterator out, Strategy const& strategy) { return intersection_insert < - GeometryTag2, GeometryTag1, GeometryTag3, - Areal2, Areal1, ArealOut, - Geometry2, Geometry1, - Reverse2, Reverse1, ReverseOut, - OutputIterator, GeometryOut, + Geometry2, Geometry1, GeometryOut, OverlayType, - Strategy + Reverse2, Reverse1, ReverseOut >::apply(g2, g1, out, strategy); } }; @@ -561,35 +532,20 @@ inline OutputIterator insert(Geometry1 const& geometry1, geometry::reverse_dispatch::type::value, geometry::dispatch::intersection_insert_reversed < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, Geometry1, Geometry2, + GeometryOut, + OverlayType, overlay::do_reverse::value>::value, overlay::do_reverse::value, ReverseSecond>::value, - overlay::do_reverse::value>::value, - OutputIterator, GeometryOut, - OverlayType, - Strategy + overlay::do_reverse::value>::value >, geometry::dispatch::intersection_insert < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, Geometry1, Geometry2, - geometry::detail::overlay::do_reverse::value>::value, - geometry::detail::overlay::do_reverse::value, ReverseSecond>::value, - geometry::detail::overlay::do_reverse::value>::value, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + geometry::detail::overlay::do_reverse::value>::value, + geometry::detail::overlay::do_reverse::value, ReverseSecond>::value > >::type::apply(geometry1, geometry2, out, strategy); } diff --git a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp index 41665e0af..8b89d39c5 100644 --- a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @@ -134,12 +134,12 @@ template < typename Geometry1, typename Geometry2, bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, - overlay_type Direction, - typename Strategy + typename GeometryOut, + overlay_type Direction > struct overlay { + template static inline OutputIterator apply( Geometry1 const& geometry1, Geometry2 const& geometry2, OutputIterator out, diff --git a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp index 12daafa0c..02dd01d6c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp @@ -17,7 +17,9 @@ #include #include #include +#include #include +#include #include #include @@ -233,6 +235,7 @@ public : detail::overlay::operation_type operation, Turns& turns, Rings& rings) { + typedef typename boost::range_value::type ring_type; typedef typename boost::range_iterator::type turn_iterator; typedef typename boost::range_value::type turn_type; typedef typename boost::range_iterator @@ -240,6 +243,12 @@ public : typename turn_type::container_type >::type turn_operation_iterator_type; + std::size_t const min_num_points + = core_detail::closure::minimum_ring_size + < + geometry::closure::value + >::value; + std::size_t size_at_start = boost::size(rings); typename Backtrack::state_type state; @@ -267,7 +276,7 @@ public : { set_visited_for_continue(*it, *iit); - typename boost::range_value::type current_output; + ring_type current_output; detail::overlay::append_no_duplicates(current_output, it->point, true); @@ -376,7 +385,10 @@ public : { iit->visited.set_finished(); detail::overlay::debug_traverse(*current, *iit, "->Finished"); - rings.push_back(current_output); + if (geometry::num_points(current_output) >= min_num_points) + { + rings.push_back(current_output); + } } } } diff --git a/include/boost/geometry/algorithms/difference.hpp b/include/boost/geometry/algorithms/difference.hpp index 480dd928d..2f32b344c 100644 --- a/include/boost/geometry/algorithms/difference.hpp +++ b/include/boost/geometry/algorithms/difference.hpp @@ -56,19 +56,11 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1, return geometry::dispatch::intersection_insert < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, Geometry1, Geometry2, - geometry::detail::overlay::do_reverse::value>::value, - geometry::detail::overlay::do_reverse::value, true>::value, - geometry::detail::overlay::do_reverse::value>::value, - OutputIterator, GeometryOut, + GeometryOut, overlay_difference, - Strategy + geometry::detail::overlay::do_reverse::value>::value, + geometry::detail::overlay::do_reverse::value, true>::value >::apply(geometry1, geometry2, out, strategy); } diff --git a/include/boost/geometry/algorithms/disjoint.hpp b/include/boost/geometry/algorithms/disjoint.hpp index f986cc24a..b2de6e01d 100644 --- a/include/boost/geometry/algorithms/disjoint.hpp +++ b/include/boost/geometry/algorithms/disjoint.hpp @@ -184,68 +184,82 @@ namespace dispatch template < - typename GeometryTag1, typename GeometryTag2, typename Geometry1, typename Geometry2, - std::size_t DimensionCount + std::size_t DimensionCount = dimension::type::value, + typename Tag1 = typename tag::type, + typename Tag2 = typename tag::type, + bool Reverse = reverse_dispatch::type::value > struct disjoint : detail::disjoint::general_areal {}; -template -struct disjoint - : detail::disjoint::point_point -{}; - - -template -struct disjoint - : detail::disjoint::box_box -{}; - - -template -struct disjoint - : detail::disjoint::point_box -{}; - -template -struct disjoint - : detail::disjoint::disjoint_linear -{}; - -template -struct disjoint - : detail::disjoint::disjoint_segment -{}; - -template -struct disjoint - : detail::disjoint::disjoint_linear -{}; - - +// If reversal is needed, perform it template < - typename GeometryTag1, typename GeometryTag2, typename Geometry1, typename Geometry2, - std::size_t DimensionCount + std::size_t DimensionCount, + typename Tag1, typename Tag2 > -struct disjoint_reversed +struct disjoint + : disjoint { static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) { return disjoint < - GeometryTag2, GeometryTag1, Geometry2, Geometry1, - DimensionCount + DimensionCount, + Tag2, Tag1 >::apply(g2, g1); } }; +template +struct disjoint + : detail::disjoint::point_point +{}; + + +template +struct disjoint + : detail::disjoint::box_box +{}; + + +template +struct disjoint + : detail::disjoint::point_box +{}; + +template +struct disjoint + : detail::disjoint::reverse_covered_by +{}; + +template +struct disjoint + : detail::disjoint::reverse_covered_by +{}; + +template +struct disjoint + : detail::disjoint::disjoint_linear +{}; + +template +struct disjoint + : detail::disjoint::disjoint_segment +{}; + +template +struct disjoint + : detail::disjoint::disjoint_linear +{}; + + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH @@ -272,26 +286,7 @@ inline bool disjoint(Geometry1 const& geometry1, Geometry2 const >(); - return boost::mpl::if_c - < - reverse_dispatch::type::value, - dispatch::disjoint_reversed - < - typename tag::type, - typename tag::type, - Geometry1, - Geometry2, - dimension::type::value - >, - dispatch::disjoint - < - typename tag::type, - typename tag::type, - Geometry1, - Geometry2, - dimension::type::value - > - >::type::apply(geometry1, geometry2); + return dispatch::disjoint::apply(geometry1, geometry2); } diff --git a/include/boost/geometry/algorithms/distance.hpp b/include/boost/geometry/algorithms/distance.hpp index 11c2bc929..c5a65ba15 100644 --- a/include/boost/geometry/algorithms/distance.hpp +++ b/include/boost/geometry/algorithms/distance.hpp @@ -369,7 +369,10 @@ struct distance < segment_tag, Point, - typename point_type::type + typename point_type::type, + typename cs_tag::type, + typename cs_tag::type>::type, + Strategy >::type ps_strategy_type; return detail::distance::point_to_range diff --git a/include/boost/geometry/algorithms/for_each.hpp b/include/boost/geometry/algorithms/for_each.hpp index 671f26a70..06a400cf6 100644 --- a/include/boost/geometry/algorithms/for_each.hpp +++ b/include/boost/geometry/algorithms/for_each.hpp @@ -18,8 +18,10 @@ #include #include +#include #include +#include #include #include #include @@ -39,53 +41,55 @@ namespace detail { namespace for_each { -template struct fe_point_per_point { - static inline Functor apply( - typename add_const_if_c::type& point, Functor f) + template + static inline void apply(Point& point, Functor& f) { f(point); - return f; } }; -template struct fe_point_per_segment { - static inline Functor apply( - typename add_const_if_c::type& , Functor f) + template + static inline void apply(Point& , Functor& f) { // TODO: if non-const, we should extract the points from the segment // and call the functor on those two points - return f; } }; -template struct fe_range_per_point { - static inline Functor apply( - typename add_const_if_c::type& range, - Functor f) + template + static inline void apply(Range& range, Functor& f) { - return (std::for_each(boost::begin(range), boost::end(range), f)); + // The previous implementation called the std library: + // return (std::for_each(boost::begin(range), boost::end(range), f)); + // But that is not accepted for capturing lambda's. + // It needs to do it like that to return the state of Functor f (f is passed by value in std::for_each). + + // So we now loop manually. + + for (typename boost::range_iterator::type it = boost::begin(range); it != boost::end(range); ++it) + { + f(*it); + } } }; -template struct fe_range_per_segment { - static inline Functor apply( - typename add_const_if_c::type& range, - Functor f) + template + static inline void apply(Range& range, Functor& f) { typedef typename add_const_if_c < - IsConst, + is_const::value, typename point_type::type >::type point_type; @@ -97,65 +101,41 @@ struct fe_range_per_segment f(s); previous = it++; } - - return f; } }; -template struct fe_polygon_per_point { - typedef typename add_const_if_c::type poly_type; - - static inline Functor apply(poly_type& poly, Functor f) + template + static inline void apply(Polygon& poly, Functor& f) { - typedef fe_range_per_point - < - typename ring_type::type, - Functor, - IsConst - > per_ring; + fe_range_per_point::apply(exterior_ring(poly), f); - f = per_ring::apply(exterior_ring(poly), f); - - typename interior_return_type::type rings + typename interior_return_type::type rings = interior_rings(poly); for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it) { - f = per_ring::apply(*it, f); + fe_range_per_point::apply(*it, f); } - - return f; } }; -template struct fe_polygon_per_segment { - typedef typename add_const_if_c::type poly_type; - - static inline Functor apply(poly_type& poly, Functor f) + template + static inline void apply(Polygon& poly, Functor& f) { - typedef fe_range_per_segment - < - typename ring_type::type, - Functor, - IsConst - > per_ring; + fe_range_per_segment::apply(exterior_ring(poly), f); - f = per_ring::apply(exterior_ring(poly), f); - - typename interior_return_type::type rings + typename interior_return_type::type rings = interior_rings(poly); for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it) { - f = per_ring::apply(*it, f); + fe_range_per_segment::apply(*it, f); } - - return f; } }; @@ -171,68 +151,66 @@ namespace dispatch template < - typename Tag, typename Geometry, - typename Functor, - bool IsConst + typename Tag = typename tag_cast::type, multi_tag>::type > -struct for_each_point {}; - - -template -struct for_each_point - : detail::for_each::fe_point_per_point +struct for_each_point: not_implemented {}; -template -struct for_each_point - : detail::for_each::fe_range_per_point +template +struct for_each_point + : detail::for_each::fe_point_per_point {}; -template -struct for_each_point - : detail::for_each::fe_range_per_point +template +struct for_each_point + : detail::for_each::fe_range_per_point {}; -template -struct for_each_point - : detail::for_each::fe_polygon_per_point +template +struct for_each_point + : detail::for_each::fe_range_per_point +{}; + + +template +struct for_each_point + : detail::for_each::fe_polygon_per_point {}; template < - typename Tag, typename Geometry, - typename Functor, - bool IsConst + typename Tag = typename tag_cast::type, multi_tag>::type > -struct for_each_segment {}; +struct for_each_segment: not_implemented +{}; -template -struct for_each_segment - : detail::for_each::fe_point_per_segment +template +struct for_each_segment + : detail::for_each::fe_point_per_segment {}; -template -struct for_each_segment - : detail::for_each::fe_range_per_segment +template +struct for_each_segment + : detail::for_each::fe_range_per_segment {}; -template -struct for_each_segment - : detail::for_each::fe_range_per_segment +template +struct for_each_segment + : detail::for_each::fe_range_per_segment {}; -template -struct for_each_segment - : detail::for_each::fe_polygon_per_segment +template +struct for_each_segment + : detail::for_each::fe_polygon_per_segment {}; @@ -240,35 +218,6 @@ struct for_each_segment #endif // DOXYGEN_NO_DISPATCH -/*! -\brief \brf_for_each{point} -\details \det_for_each{point} -\ingroup for_each -\param geometry \param_geometry -\param f \par_for_each_f{const point} -\tparam Geometry \tparam_geometry -\tparam Functor \tparam_functor - -\qbk{distinguish,const version} -\qbk{[include reference/algorithms/for_each_point.qbk]} -\qbk{[heading Example]} -\qbk{[for_each_point_const] [for_each_point_const_output]} -*/ -template -inline Functor for_each_point(Geometry const& geometry, Functor f) -{ - concept::check(); - - return dispatch::for_each_point - < - typename tag_cast::type, multi_tag>::type, - Geometry, - Functor, - true - >::apply(geometry, f); -} - - /*! \brief \brf_for_each{point} \details \det_for_each{point} @@ -281,48 +230,15 @@ inline Functor for_each_point(Geometry const& geometry, Functor f) \qbk{[include reference/algorithms/for_each_point.qbk]} \qbk{[heading Example]} \qbk{[for_each_point] [for_each_point_output]} +\qbk{[for_each_point_const] [for_each_point_const_output]} */ template inline Functor for_each_point(Geometry& geometry, Functor f) { concept::check(); - return dispatch::for_each_point - < - typename tag_cast::type, multi_tag>::type, - Geometry, - Functor, - false - >::apply(geometry, f); -} - - -/*! -\brief \brf_for_each{segment} -\details \det_for_each{segment} -\ingroup for_each -\param geometry \param_geometry -\param f \par_for_each_f{const segment} -\tparam Geometry \tparam_geometry -\tparam Functor \tparam_functor - -\qbk{distinguish,const version} -\qbk{[include reference/algorithms/for_each_segment.qbk]} -\qbk{[heading Example]} -\qbk{[for_each_segment_const] [for_each_segment_const_output]} -*/ -template -inline Functor for_each_segment(Geometry const& geometry, Functor f) -{ - concept::check(); - - return dispatch::for_each_segment - < - typename tag_cast::type, multi_tag>::type, - Geometry, - Functor, - true - >::apply(geometry, f); + dispatch::for_each_point::apply(geometry, f); + return f; } @@ -336,19 +252,16 @@ inline Functor for_each_segment(Geometry const& geometry, Functor f) \tparam Functor \tparam_functor \qbk{[include reference/algorithms/for_each_segment.qbk]} +\qbk{[heading Example]} +\qbk{[for_each_segment_const] [for_each_segment_const_output]} */ template inline Functor for_each_segment(Geometry& geometry, Functor f) { concept::check(); - return dispatch::for_each_segment - < - typename tag_cast::type, multi_tag>::type, - Geometry, - Functor, - false - >::apply(geometry, f); + dispatch::for_each_segment::apply(geometry, f); + return f; } diff --git a/include/boost/geometry/algorithms/intersection.hpp b/include/boost/geometry/algorithms/intersection.hpp index 8d3dd68b3..3125752db 100644 --- a/include/boost/geometry/algorithms/intersection.hpp +++ b/include/boost/geometry/algorithms/intersection.hpp @@ -22,15 +22,14 @@ namespace boost { namespace geometry namespace detail { namespace intersection { -template -< - typename Box1, typename Box2, - typename BoxOut, - typename Strategy, - std::size_t Dimension, std::size_t DimensionCount -> +template struct intersection_box_box { + template + < + typename Box1, typename Box2, typename BoxOut, + typename Strategy + > static inline bool apply(Box1 const& box1, Box2 const& box2, BoxOut& box_out, Strategy const& strategy) @@ -50,23 +49,19 @@ struct intersection_box_box set(box_out, min1 < min2 ? min2 : min1); set(box_out, max1 > max2 ? max2 : max1); - return intersection_box_box - < - Box1, Box2, BoxOut, Strategy, - Dimension + 1, DimensionCount - >::apply(box1, box2, box_out, strategy); + return intersection_box_box + ::apply(box1, box2, box_out, strategy); } }; -template -< - typename Box1, typename Box2, - typename BoxOut, - typename Strategy, - std::size_t DimensionCount -> -struct intersection_box_box +template +struct intersection_box_box { + template + < + typename Box1, typename Box2, typename BoxOut, + typename Strategy + > static inline bool apply(Box1 const&, Box2 const&, BoxOut&, Strategy const&) { return true; @@ -86,15 +81,14 @@ namespace dispatch // By default, all is forwarded to the intersection_insert-dispatcher template < - typename Tag1, typename Tag2, typename TagOut, typename Geometry1, typename Geometry2, - typename GeometryOut, - typename Strategy + typename Tag1 = typename geometry::tag::type, + typename Tag2 = typename geometry::tag::type, + bool Reverse = reverse_dispatch::type::value > struct intersection { - typedef std::back_insert_iterator output_iterator; - + template static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, GeometryOut& geometry_out, @@ -104,17 +98,8 @@ struct intersection intersection_insert < - Tag1, Tag2, typename geometry::tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, - Geometry1, Geometry2, - detail::overlay::do_reverse::value, false>::value, - detail::overlay::do_reverse::value, false>::value, - detail::overlay::do_reverse::value>::value, - output_iterator, OneOut, - overlay_intersection, - Strategy + Geometry1, Geometry2, OneOut, + overlay_intersection >::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy); return true; @@ -123,50 +108,50 @@ struct intersection }; +// If reversal is needed, perform it template < - typename Box1, typename Box2, - typename BoxOut, - typename Strategy + typename Geometry1, typename Geometry2, + typename Tag1, typename Tag2 > struct intersection - < - box_tag, box_tag, box_tag, - Box1, Box2, BoxOut, - Strategy - > : public detail::intersection::intersection_box_box - < - Box1, Box2, BoxOut, - Strategy, - 0, geometry::dimension::value - > -{}; - - -template < - typename Tag1, typename Tag2, typename TagOut, - typename Geometry1, typename Geometry2, - typename GeometryOut, - typename Strategy + Geometry1, Geometry2, + Tag1, Tag2, + true > -struct intersection_reversed + : intersection { - static inline bool apply(Geometry1 const& geometry1, - Geometry2 const& geometry2, - GeometryOut& geometry_out, - Strategy const& strategy) + template + static inline bool apply( + Geometry1 const& g1, + Geometry2 const& g2, + GeometryOut& out, + Strategy const& strategy) { - return intersection - < - Tag2, Tag1, TagOut, - Geometry2, Geometry1, - GeometryOut, Strategy - >::apply(geometry2, geometry1, geometry_out, strategy); + return intersection< + Geometry2, Geometry1, + Tag2, Tag1, + false + >::apply(g2, g1, out, strategy); } }; +template +< + typename Box1, typename Box2, bool Reverse +> +struct intersection + < + Box1, Box2, + box_tag, box_tag, + Reverse + > : public detail::intersection::intersection_box_box + < + 0, geometry::dimension::value + > +{}; } // namespace dispatch @@ -210,24 +195,10 @@ inline bool intersection(Geometry1 const& geometry1, > strategy; - return boost::mpl::if_c - < - geometry::reverse_dispatch::type::value, - dispatch::intersection_reversed - < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - Geometry1, Geometry2, GeometryOut, strategy - >, - dispatch::intersection - < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - Geometry1, Geometry2, GeometryOut, strategy - > - >::type::apply(geometry1, geometry2, geometry_out, strategy()); + return dispatch::intersection< + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, geometry_out, strategy()); } diff --git a/include/boost/geometry/algorithms/length.hpp b/include/boost/geometry/algorithms/length.hpp index de53a39e8..b537186a3 100644 --- a/include/boost/geometry/algorithms/length.hpp +++ b/include/boost/geometry/algorithms/length.hpp @@ -43,9 +43,10 @@ namespace detail { namespace length { -template +template struct segment_length { + template static inline typename default_length_result::type apply( Segment const& segment, Strategy const& strategy) { @@ -63,11 +64,12 @@ struct segment_length \note for_each could be used here, now that point_type is changed by boost range iterator */ -template +template struct range_length { typedef typename default_length_result::type return_type; + template static inline return_type apply( Range const& range, Strategy const& strategy) { @@ -106,28 +108,31 @@ namespace dispatch { -template +template ::type> struct length : detail::calculate_null - < - typename default_length_result::type, - Geometry, - Strategy - > -{}; +{ + typedef typename default_length_result::type return_type; + + template + static inline return_type apply(Geometry const& geometry, Strategy const& strategy) + { + return calculate_null::apply(geometry, strategy); + } +}; -template -struct length - : detail::length::range_length +template +struct length + : detail::length::range_length {}; // RING: length is currently 0; it might be argued that it is the "perimeter" -template -struct length - : detail::length::segment_length +template +struct length + : detail::length::segment_length {}; @@ -159,12 +164,7 @@ inline typename default_length_result::type length( point_tag, typename point_type::type >::type strategy_type; - return dispatch::length - < - typename tag::type, - Geometry, - strategy_type - >::apply(geometry, strategy_type()); + return dispatch::length::apply(geometry, strategy_type()); } @@ -190,12 +190,7 @@ inline typename default_length_result::type length( // detail::throw_on_empty_input(geometry); - return dispatch::length - < - typename tag::type, - Geometry, - Strategy - >::apply(geometry, strategy); + return dispatch::length::apply(geometry, strategy); } diff --git a/include/boost/geometry/algorithms/num_geometries.hpp b/include/boost/geometry/algorithms/num_geometries.hpp index 20f35e90d..58afe4b97 100644 --- a/include/boost/geometry/algorithms/num_geometries.hpp +++ b/include/boost/geometry/algorithms/num_geometries.hpp @@ -17,7 +17,7 @@ #include -#include +#include #include #include @@ -35,19 +35,22 @@ namespace dispatch { -template -struct num_geometries -{ - BOOST_MPL_ASSERT_MSG - ( - false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE - , (types) - ); -}; +template +< + typename Geometry, + typename Tag = typename tag_cast + < + typename tag::type, + single_tag, + multi_tag + >::type +> +struct num_geometries: not_implemented +{}; template -struct num_geometries +struct num_geometries { static inline std::size_t apply(Geometry const&) { @@ -76,16 +79,7 @@ inline std::size_t num_geometries(Geometry const& geometry) { concept::check(); - return dispatch::num_geometries - < - typename tag_cast - < - typename tag::type, - single_tag, - multi_tag - >::type, - Geometry - >::apply(geometry); + return dispatch::num_geometries::apply(geometry); } diff --git a/include/boost/geometry/algorithms/num_interior_rings.hpp b/include/boost/geometry/algorithms/num_interior_rings.hpp index 2149f4657..e815f5981 100644 --- a/include/boost/geometry/algorithms/num_interior_rings.hpp +++ b/include/boost/geometry/algorithms/num_interior_rings.hpp @@ -32,7 +32,7 @@ namespace dispatch { -template +template ::type> struct num_interior_rings { static inline std::size_t apply(Geometry const& ) @@ -44,7 +44,7 @@ struct num_interior_rings template -struct num_interior_rings +struct num_interior_rings { static inline std::size_t apply(Polygon const& polygon) { @@ -74,11 +74,7 @@ struct num_interior_rings template inline std::size_t num_interior_rings(Geometry const& geometry) { - return dispatch::num_interior_rings - < - typename tag::type, - Geometry - >::apply(geometry); + return dispatch::num_interior_rings::apply(geometry); } diff --git a/include/boost/geometry/algorithms/num_points.hpp b/include/boost/geometry/algorithms/num_points.hpp index c480068f4..e5a7aef6d 100644 --- a/include/boost/geometry/algorithms/num_points.hpp +++ b/include/boost/geometry/algorithms/num_points.hpp @@ -16,7 +16,6 @@ #include -#include #include #include @@ -27,6 +26,7 @@ #include #include +#include #include @@ -38,9 +38,9 @@ namespace detail { namespace num_points { -template struct range_count { + template static inline std::size_t apply(Range const& range, bool add_for_open) { std::size_t n = boost::size(range); @@ -60,30 +60,31 @@ struct range_count } }; -template +template struct other_count { + template static inline std::size_t apply(Geometry const&, bool) { return D; } }; -template -struct polygon_count +struct polygon_count: private range_count { + template static inline std::size_t apply(Polygon const& poly, bool add_for_open) { typedef typename geometry::ring_type::type ring_type; - std::size_t n = range_count::apply( + std::size_t n = range_count::apply( exterior_ring(poly), add_for_open); typename interior_return_type::type rings = interior_rings(poly); for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it) { - n += range_count::apply(*it, add_for_open); + n += range_count::apply(*it, add_for_open); } return n; @@ -98,44 +99,42 @@ struct polygon_count namespace dispatch { -template -struct num_points -{ - BOOST_MPL_ASSERT_MSG - ( - false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE - , (types) - ); -}; - -template -struct num_points - : detail::num_points::other_count +template +< + typename Geometry, + typename Tag = typename tag_cast::type, multi_tag>::type +> +struct num_points: not_implemented {}; template -struct num_points - : detail::num_points::other_count +struct num_points + : detail::num_points::other_count<1> {}; template -struct num_points - : detail::num_points::other_count +struct num_points + : detail::num_points::other_count<4> {}; template -struct num_points - : detail::num_points::range_count +struct num_points + : detail::num_points::other_count<2> {}; template -struct num_points - : detail::num_points::range_count +struct num_points + : detail::num_points::range_count {}; template -struct num_points - : detail::num_points::polygon_count +struct num_points + : detail::num_points::range_count +{}; + +template +struct num_points + : detail::num_points::polygon_count {}; } // namespace dispatch @@ -158,11 +157,7 @@ inline std::size_t num_points(Geometry const& geometry, bool add_for_open = fals { concept::check(); - return dispatch::num_points - < - typename tag_cast::type, multi_tag>::type, - Geometry - >::apply(geometry, add_for_open); + return dispatch::num_points::apply(geometry, add_for_open); } }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/perimeter.hpp b/include/boost/geometry/algorithms/perimeter.hpp index adeb0b05b..b70517e3e 100644 --- a/include/boost/geometry/algorithms/perimeter.hpp +++ b/include/boost/geometry/algorithms/perimeter.hpp @@ -33,40 +33,43 @@ namespace dispatch { // Default perimeter is 0.0, specializations implement calculated values -template +template ::type> struct perimeter : detail::calculate_null - < - typename default_length_result::type, - Geometry, - Strategy - > -{}; +{ + typedef typename default_length_result::type return_type; -template -struct perimeter + template + static inline return_type apply(Geometry const& geometry, Strategy const& strategy) + { + return calculate_null::apply(geometry, strategy); + } +}; + +template +struct perimeter : detail::length::range_length < Geometry, - Strategy, closure::value > {}; -template -struct perimeter - : detail::calculate_polygon_sum - < - typename default_length_result::type, - Polygon, - Strategy, - detail::length::range_length +template +struct perimeter : detail::calculate_polygon_sum +{ + typedef typename default_length_result::type return_type; + typedef detail::length::range_length < typename ring_type::type, - Strategy, closure::value - > - > -{}; + > policy; + + template + static inline return_type apply(Polygon const& polygon, Strategy const& strategy) + { + return calculate_polygon_sum::apply(polygon, strategy); + } +}; // box,n-sphere: to be implemented @@ -100,12 +103,7 @@ inline typename default_length_result::type perimeter( // detail::throw_on_empty_input(geometry); - return dispatch::perimeter - < - typename tag::type, - Geometry, - strategy_type - >::apply(geometry, strategy_type()); + return dispatch::perimeter::apply(geometry, strategy_type()); } /*! @@ -130,12 +128,7 @@ inline typename default_length_result::type perimeter( // detail::throw_on_empty_input(geometry); - return dispatch::perimeter - < - typename tag::type, - Geometry, - Strategy - >::apply(geometry, strategy); + return dispatch::perimeter::apply(geometry, strategy); } }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/reverse.hpp b/include/boost/geometry/algorithms/reverse.hpp index bf0ef2d9a..1e1168a5a 100644 --- a/include/boost/geometry/algorithms/reverse.hpp +++ b/include/boost/geometry/algorithms/reverse.hpp @@ -32,9 +32,9 @@ namespace detail { namespace reverse { -template struct range_reverse { + template static inline void apply(Range& range) { std::reverse(boost::begin(range), boost::end(range)); @@ -42,21 +42,20 @@ struct range_reverse }; -template -struct polygon_reverse +struct polygon_reverse: private range_reverse { + template static inline void apply(Polygon& polygon) { typedef typename geometry::ring_type::type ring_type; - typedef range_reverse per_range; - per_range::apply(exterior_ring(polygon)); + range_reverse::apply(exterior_ring(polygon)); typename interior_return_type::type rings = interior_rings(polygon); for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it) { - per_range::apply(*it); + range_reverse::apply(*it); } } }; @@ -71,11 +70,7 @@ namespace dispatch { -template -< - typename Tag, - typename Geometry -> +template ::type> struct reverse { static inline void apply(Geometry&) @@ -84,20 +79,20 @@ struct reverse template -struct reverse - : detail::reverse::range_reverse +struct reverse + : detail::reverse::range_reverse {}; template -struct reverse - : detail::reverse::range_reverse +struct reverse + : detail::reverse::range_reverse {}; template -struct reverse - : detail::reverse::polygon_reverse +struct reverse + : detail::reverse::polygon_reverse {}; @@ -121,11 +116,7 @@ inline void reverse(Geometry& geometry) { concept::check(); - dispatch::reverse - < - typename tag::type, - Geometry - >::apply(geometry); + dispatch::reverse::apply(geometry); } }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 225321d30..7e3aca401 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -33,6 +33,7 @@ #include #include +#include #include @@ -43,12 +44,11 @@ namespace boost { namespace geometry namespace detail { namespace simplify { -template struct simplify_range_insert { - template + template static inline void apply(Range const& range, OutputIterator out, - Distance const& max_distance, Strategy const& strategy) + Distance const& max_distance, Strategy const& strategy) { if (boost::size(range) <= 2 || max_distance < 0) { @@ -62,12 +62,11 @@ struct simplify_range_insert }; -template struct simplify_copy { - template + template static inline void apply(Range const& range, Range& out, - Distance const& , Strategy const& ) + Distance const& , Strategy const& ) { std::copy ( @@ -77,10 +76,10 @@ struct simplify_copy }; -template +template struct simplify_range { - template + template static inline void apply(Range const& range, Range& out, Distance const& max_distance, Strategy const& strategy) { @@ -101,14 +100,11 @@ struct simplify_range if (boost::size(range) <= int(Minimum) || max_distance < 0.0) { - simplify_copy::apply - ( - range, out, max_distance, strategy - ); + simplify_copy::apply(range, out, max_distance, strategy); } else { - simplify_range_insert::apply + simplify_range_insert::apply ( range, std::back_inserter(out), max_distance, strategy ); @@ -116,10 +112,9 @@ struct simplify_range } }; -template struct simplify_polygon { - template + template static inline void apply(Polygon const& poly_in, Polygon& poly_out, Distance const& max_distance, Strategy const& strategy) { @@ -133,9 +128,9 @@ struct simplify_polygon // Note that if there are inner rings, and distance is too large, // they might intersect with the outer ring in the output, // while it didn't in the input. - simplify_range::apply(exterior_ring(poly_in), - exterior_ring(poly_out), - max_distance, strategy); + simplify_range::apply(exterior_ring(poly_in), + exterior_ring(poly_out), + max_distance, strategy); traits::resize < @@ -154,8 +149,7 @@ struct simplify_polygon it_in != boost::end(rings_in); ++it_in, ++it_out) { - simplify_range::apply(*it_in, - *it_out, max_distance, strategy); + simplify_range::apply(*it_in, *it_out, max_distance, strategy); } } }; @@ -169,15 +163,18 @@ struct simplify_polygon namespace dispatch { -template -struct simplify -{ -}; +template +< + typename Geometry, + typename Tag = typename tag::type +> +struct simplify: not_implemented +{}; -template -struct simplify +template +struct simplify { - template + template static inline void apply(Point const& point, Point& out, Distance const& , Strategy const& ) { @@ -186,22 +183,15 @@ struct simplify }; -template -struct simplify - : detail::simplify::simplify_range - < - Linestring, - Strategy, - 2 - > +template +struct simplify + : detail::simplify::simplify_range<2> {}; -template -struct simplify +template +struct simplify : detail::simplify::simplify_range < - Ring, - Strategy, core_detail::closure::minimum_ring_size < geometry::closure::value @@ -209,38 +199,29 @@ struct simplify > {}; -template -struct simplify +template +struct simplify : detail::simplify::simplify_polygon - < - Polygon, - Strategy - > {}; -template -struct simplify_insert -{ -}; - - -template -struct simplify_insert - : detail::simplify::simplify_range_insert - < - Linestring, - Strategy - > +template +< + typename Geometry, + typename Tag = typename tag::type +> +struct simplify_insert: not_implemented {}; -template -struct simplify_insert + +template +struct simplify_insert + : detail::simplify::simplify_range_insert +{}; + +template +struct simplify_insert : detail::simplify::simplify_range_insert - < - Ring, - Strategy - > {}; @@ -275,12 +256,7 @@ inline void simplify(Geometry const& geometry, Geometry& out, geometry::clear(out); - dispatch::simplify - < - typename tag::type, - Geometry, - Strategy - >::apply(geometry, out, max_distance, strategy); + dispatch::simplify::apply(geometry, out, max_distance, strategy); } @@ -348,12 +324,7 @@ inline void simplify_insert(Geometry const& geometry, OutputIterator out, concept::check(); BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy) ); - dispatch::simplify_insert - < - typename tag::type, - Geometry, - Strategy - >::apply(geometry, out, max_distance, strategy); + dispatch::simplify_insert::apply(geometry, out, max_distance, strategy); } /*! @@ -387,12 +358,7 @@ inline void simplify_insert(Geometry const& geometry, OutputIterator out, point_type, ds_strategy_type > strategy_type; - dispatch::simplify_insert - < - typename tag::type, - Geometry, - strategy_type - >::apply(geometry, out, max_distance, strategy_type()); + dispatch::simplify_insert::apply(geometry, out, max_distance, strategy_type()); } }} // namespace detail::simplify diff --git a/include/boost/geometry/algorithms/sym_difference.hpp b/include/boost/geometry/algorithms/sym_difference.hpp index 6394576de..28affc43c 100644 --- a/include/boost/geometry/algorithms/sym_difference.hpp +++ b/include/boost/geometry/algorithms/sym_difference.hpp @@ -59,35 +59,20 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1, out = geometry::dispatch::intersection_insert < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, Geometry1, Geometry2, - geometry::detail::overlay::do_reverse::value>::value, - geometry::detail::overlay::do_reverse::value, true>::value, - geometry::detail::overlay::do_reverse::value>::value, - OutputIterator, GeometryOut, + GeometryOut, overlay_difference, - Strategy + geometry::detail::overlay::do_reverse::value>::value, + geometry::detail::overlay::do_reverse::value, true>::value >::apply(geometry1, geometry2, out, strategy); out = geometry::dispatch::intersection_insert < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, Geometry2, Geometry1, + GeometryOut, + overlay_difference, geometry::detail::overlay::do_reverse::value>::value, geometry::detail::overlay::do_reverse::value, true>::value, - geometry::detail::overlay::do_reverse::value>::value, - OutputIterator, GeometryOut, - overlay_difference, - Strategy + geometry::detail::overlay::do_reverse::value>::value >::apply(geometry2, geometry1, out, strategy); return out; } diff --git a/include/boost/geometry/algorithms/transform.hpp b/include/boost/geometry/algorithms/transform.hpp index 22b45dc77..52d195fe8 100644 --- a/include/boost/geometry/algorithms/transform.hpp +++ b/include/boost/geometry/algorithms/transform.hpp @@ -41,9 +41,9 @@ namespace boost { namespace geometry namespace detail { namespace transform { -template struct transform_point { + template static inline bool apply(Point1 const& p1, Point2& p2, Strategy const& strategy) { @@ -52,9 +52,9 @@ struct transform_point }; -template struct transform_box { + template static inline bool apply(Box1 const& b1, Box2& b2, Strategy const& strategy) { @@ -91,9 +91,9 @@ struct transform_box } }; -template struct transform_box_or_segment { + template static inline bool apply(Geometry1 const& source, Geometry2& target, Strategy const& strategy) { @@ -133,12 +133,7 @@ inline bool transform_range_out(Range const& range, it != boost::end(range); ++it) { - if (! transform_point - < - typename point_type::type, - PointOut, - Strategy - >::apply(*it, point_out, strategy)) + if (! transform_point::apply(*it, point_out, strategy)) { return false; } @@ -148,9 +143,9 @@ inline bool transform_range_out(Range const& range, } -template struct transform_polygon { + template static inline bool apply(Polygon1 const& poly1, Polygon2& poly2, Strategy const& strategy) { @@ -211,9 +206,9 @@ struct select_strategy >::type type; }; -template struct transform_range { + template static inline bool apply(Range1 const& range1, Range2& range2, Strategy const& strategy) { @@ -236,50 +231,50 @@ namespace dispatch template < - typename Tag1, typename Tag2, typename Geometry1, typename Geometry2, - typename Strategy + typename Tag1 = typename tag_cast::type, multi_tag>::type, + typename Tag2 = typename tag_cast::type, multi_tag>::type > struct transform {}; -template -struct transform - : detail::transform::transform_point +template +struct transform + : detail::transform::transform_point { }; -template +template struct transform < - linestring_tag, linestring_tag, - Linestring1, Linestring2, Strategy + Linestring1, Linestring2, + linestring_tag, linestring_tag > - : detail::transform::transform_range + : detail::transform::transform_range { }; -template -struct transform - : detail::transform::transform_range +template +struct transform + : detail::transform::transform_range { }; -template -struct transform - : detail::transform::transform_polygon +template +struct transform + : detail::transform::transform_polygon { }; -template -struct transform - : detail::transform::transform_box +template +struct transform + : detail::transform::transform_box { }; -template -struct transform - : detail::transform::transform_box_or_segment +template +struct transform + : detail::transform::transform_box_or_segment { }; @@ -310,14 +305,7 @@ inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2, concept::check(); concept::check(); - typedef dispatch::transform - < - typename tag_cast::type, multi_tag>::type, - typename tag_cast::type, multi_tag>::type, - Geometry1, - Geometry2, - Strategy - > transform_type; + typedef dispatch::transform transform_type; return transform_type::apply(geometry1, geometry2, strategy); } diff --git a/include/boost/geometry/algorithms/union.hpp b/include/boost/geometry/algorithms/union.hpp index 28d8e5dc0..479f556a1 100644 --- a/include/boost/geometry/algorithms/union.hpp +++ b/include/boost/geometry/algorithms/union.hpp @@ -10,14 +10,13 @@ #define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP -#include - #include #include #include #include #include +#include #include @@ -30,78 +29,70 @@ namespace dispatch template < - // tag dispatching: - typename TagIn1, typename TagIn2, typename TagOut, - // metafunction finetuning helpers: - bool Areal1, bool Areal2, bool ArealOut, - // real types - typename Geometry1, typename Geometry2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, - typename GeometryOut, - typename Strategy + typename Geometry1, typename Geometry2, typename GeometryOut, + typename TagIn1 = typename tag::type, + typename TagIn2 = typename tag::type, + typename TagOut = typename tag::type, + bool Areal1 = geometry::is_areal::value, + bool Areal2 = geometry::is_areal::value, + bool ArealOut = geometry::is_areal::value, + bool Reverse1 = detail::overlay::do_reverse::value>::value, + bool Reverse2 = detail::overlay::do_reverse::value>::value, + bool ReverseOut = detail::overlay::do_reverse::value>::value, + bool Reverse = geometry::reverse_dispatch::type::value > -struct union_insert -{ - BOOST_MPL_ASSERT_MSG - ( - false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES - , (types) - ); -}; - - -template -< - typename TagIn1, typename TagIn2, typename TagOut, - typename Geometry1, typename Geometry2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, - typename GeometryOut, - typename Strategy -> -struct union_insert - < - TagIn1, TagIn2, TagOut, - true, true, true, - Geometry1, Geometry2, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, - Strategy - > : detail::overlay::overlay - +struct union_insert: not_implemented {}; +// If reversal is needed, perform it first template < - typename GeometryTag1, typename GeometryTag2, typename GeometryTag3, - bool Areal1, bool Areal2, bool ArealOut, - typename Geometry1, typename Geometry2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, - typename Strategy + typename Geometry1, typename Geometry2, typename GeometryOut, + typename TagIn1, typename TagIn2, typename TagOut, + bool Reverse1, bool Reverse2, bool ReverseOut > -struct union_insert_reversed +struct union_insert + < + Geometry1, Geometry2, GeometryOut, + TagIn1, TagIn2, TagOut, + true, true, true, + Reverse1, Reverse2, ReverseOut, + true + >: union_insert { + template static inline OutputIterator apply(Geometry1 const& g1, Geometry2 const& g2, OutputIterator out, Strategy const& strategy) { return union_insert < - GeometryTag2, GeometryTag1, GeometryTag3, - Areal2, Areal1, ArealOut, - Geometry2, Geometry1, - Reverse2, Reverse1, ReverseOut, - OutputIterator, GeometryOut, - Strategy + Geometry2, Geometry1, GeometryOut >::apply(g2, g1, out, strategy); } }; +template +< + typename Geometry1, typename Geometry2, typename GeometryOut, + typename TagIn1, typename TagIn2, typename TagOut, + bool Reverse1, bool Reverse2, bool ReverseOut +> +struct union_insert + < + Geometry1, Geometry2, GeometryOut, + TagIn1, TagIn2, TagOut, + true, true, true, + Reverse1, Reverse2, ReverseOut, + false + > : detail::overlay::overlay + +{}; + + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH @@ -121,40 +112,10 @@ inline OutputIterator insert(Geometry1 const& geometry1, OutputIterator out, Strategy const& strategy) { - return boost::mpl::if_c - < - geometry::reverse_dispatch::type::value, - dispatch::union_insert_reversed - < - typename tag::type, - typename tag::type, - typename tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, - Geometry1, Geometry2, - overlay::do_reverse::value>::value, - overlay::do_reverse::value>::value, - overlay::do_reverse::value>::value, - OutputIterator, GeometryOut, - Strategy - >, - dispatch::union_insert - < - typename tag::type, - typename tag::type, - typename tag::type, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, - Geometry1, Geometry2, - overlay::do_reverse::value>::value, - overlay::do_reverse::value>::value, - overlay::do_reverse::value>::value, - OutputIterator, GeometryOut, - Strategy - > - >::type::apply(geometry1, geometry2, out, strategy); + return dispatch::union_insert + < + Geometry1, Geometry2, GeometryOut + >::apply(geometry1, geometry2, out, strategy); } /*! diff --git a/include/boost/geometry/algorithms/unique.hpp b/include/boost/geometry/algorithms/unique.hpp index 3bbf479f9..e11dc13c4 100644 --- a/include/boost/geometry/algorithms/unique.hpp +++ b/include/boost/geometry/algorithms/unique.hpp @@ -34,9 +34,9 @@ namespace detail { namespace unique { -template struct range_unique { + template static inline void apply(Range& range, ComparePolicy const& policy) { typename boost::range_iterator::type it @@ -52,21 +52,20 @@ struct range_unique }; -template struct polygon_unique { + template static inline void apply(Polygon& polygon, ComparePolicy const& policy) { typedef typename geometry::ring_type::type ring_type; - typedef range_unique per_range; - per_range::apply(exterior_ring(polygon), policy); + range_unique::apply(exterior_ring(polygon), policy); typename interior_return_type::type rings = interior_rings(polygon); for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it) { - per_range::apply(*it, policy); + range_unique::apply(*it, policy); } } }; @@ -85,32 +84,32 @@ namespace dispatch template < - typename Tag, typename Geometry, - typename ComparePolicy + typename Tag = typename tag::type > struct unique { + template static inline void apply(Geometry&, ComparePolicy const& ) {} }; -template -struct unique - : detail::unique::range_unique +template +struct unique + : detail::unique::range_unique {}; -template -struct unique - : detail::unique::range_unique +template +struct unique + : detail::unique::range_unique {}; -template -struct unique - : detail::unique::polygon_unique +template +struct unique + : detail::unique::polygon_unique {}; @@ -139,12 +138,7 @@ inline void unique(Geometry& geometry) > policy; - dispatch::unique - < - typename tag::type, - Geometry, - policy - >::apply(geometry, policy()); + dispatch::unique::apply(geometry, policy()); } }} // namespace boost::geometry diff --git a/include/boost/geometry/geometries/variant.hpp b/include/boost/geometry/geometries/variant.hpp new file mode 100644 index 000000000..9db11d5a8 --- /dev/null +++ b/include/boost/geometry/geometries/variant.hpp @@ -0,0 +1,34 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_VARIANT_GEOMETRY_HPP +#define BOOST_GEOMETRY_GEOMETRIES_VARIANT_GEOMETRY_HPP + + +#include + + +namespace boost { namespace geometry { + + +template +struct point_type > + : point_type +{}; + + +} // namespace geometry +} // namespace boost + + +#endif // BOOST_GEOMETRY_GEOMETRIES_VARIANT_GEOMETRY_HPP diff --git a/include/boost/geometry/multi/algorithms/area.hpp b/include/boost/geometry/multi/algorithms/area.hpp index 669568635..7d0206109 100644 --- a/include/boost/geometry/multi/algorithms/area.hpp +++ b/include/boost/geometry/multi/algorithms/area.hpp @@ -30,21 +30,20 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { -template -struct area - : detail::multi_sum - < - typename Strategy::return_type, - MultiGeometry, - Strategy, - area - < - typename boost::range_value::type, - Strategy, - polygon_tag - > - > -{}; +template +struct area : detail::multi_sum +{ + template + static inline typename Strategy::return_type + apply(MultiGeometry const& multi, Strategy const& strategy) + { + return multi_sum::apply + < + typename Strategy::return_type, + area::type> + >(multi, strategy); + } +}; } // namespace dispatch diff --git a/include/boost/geometry/multi/algorithms/centroid.hpp b/include/boost/geometry/multi/algorithms/centroid.hpp index 855ed22fd..e990f4eff 100644 --- a/include/boost/geometry/multi/algorithms/centroid.hpp +++ b/include/boost/geometry/multi/algorithms/centroid.hpp @@ -35,13 +35,9 @@ namespace detail { namespace centroid \brief Building block of a multi-point, to be used as Policy in the more generec centroid_multi */ -template -< - typename Point, - typename Strategy -> struct centroid_multi_point_state { + template static inline void apply(Point const& point, Strategy const& strategy, typename Strategy::state_type& state) { @@ -59,15 +55,10 @@ struct centroid_multi_point_state detail::centroid::centroid_multi */ -template -< - typename Multi, - typename Point, - typename Strategy, - typename Policy -> +template struct centroid_multi { + template static inline void apply(Multi const& multi, Point& centroid, Strategy const& strategy) { @@ -104,65 +95,28 @@ struct centroid_multi namespace dispatch { -template -< - typename MultiLinestring, - typename Point, - typename Strategy -> -struct centroid +template +struct centroid : detail::centroid::centroid_multi < - MultiLinestring, - Point, - Strategy, - detail::centroid::centroid_range_state - < - typename boost::range_value::type, - closed, - Strategy - > + detail::centroid::centroid_range_state > {}; -template -< - typename MultiPolygon, - typename Point, - typename Strategy -> -struct centroid +template +struct centroid : detail::centroid::centroid_multi < - MultiPolygon, - Point, - Strategy, detail::centroid::centroid_polygon_state - < - typename boost::range_value::type, - Strategy - > > {}; -template -< - typename MultiPoint, - typename Point, - typename Strategy -> -struct centroid +template +struct centroid : detail::centroid::centroid_multi < - MultiPoint, - Point, - Strategy, detail::centroid::centroid_multi_point_state - < - typename boost::range_value::type, - Strategy - > > {}; diff --git a/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp b/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp index a47685ceb..704c3e6a9 100644 --- a/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp +++ b/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp @@ -23,15 +23,9 @@ namespace boost { namespace geometry namespace detail { -template -< - typename ReturnType, - typename MultiGeometry, - typename Strategy, - typename Policy -> struct multi_sum { + template static inline ReturnType apply(MultiGeometry const& geometry, Strategy const& strategy) { ReturnType sum = ReturnType(); diff --git a/include/boost/geometry/multi/algorithms/disjoint.hpp b/include/boost/geometry/multi/algorithms/disjoint.hpp new file mode 100644 index 000000000..7d1bed794 --- /dev/null +++ b/include/boost/geometry/multi/algorithms/disjoint.hpp @@ -0,0 +1,41 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2012 Bruno Lalande, Paris, France. +// Copyright (c) 2012 Mateusz Loskot, London, UK. + +// 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_MULTI_ALGORITHMS_DISJOINT_HPP +#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP + + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +template +struct disjoint + : detail::disjoint::reverse_covered_by +{}; + +} // namespace dispatch + + +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP diff --git a/include/boost/geometry/multi/algorithms/for_each.hpp b/include/boost/geometry/multi/algorithms/for_each.hpp index 1be38e0a7..adf12dbba 100644 --- a/include/boost/geometry/multi/algorithms/for_each.hpp +++ b/include/boost/geometry/multi/algorithms/for_each.hpp @@ -36,24 +36,16 @@ namespace detail { namespace for_each // Implementation of multi, for both point and segment, // just calling the single version. -template -< - typename MultiGeometry, - typename Functor, - bool IsConst, - typename Policy -> +template struct for_each_multi { - static inline Functor apply( - typename add_const_if_c::type& multi, - Functor f) + template + static inline void apply(MultiGeometry& multi, Functor& f) { for(BOOST_AUTO_TPL(it, boost::begin(multi)); it != boost::end(multi); ++it) { - f = Policy::apply(*it, f); + Policy::apply(*it, f); } - return f; } }; @@ -66,55 +58,35 @@ struct for_each_multi namespace dispatch { -template -< - typename MultiGeometry, - typename Functor, - bool IsConst -> -struct for_each_point +template +struct for_each_point : detail::for_each::for_each_multi < - MultiGeometry, - Functor, - IsConst, // Specify the dispatch of the single-version as policy for_each_point < - typename single_tag_of + typename add_const_if_c < - typename tag::type - >::type, - typename boost::range_value::type, - Functor, - IsConst + is_const::value, + typename boost::range_value::type + >::type > > {}; -template -< - typename MultiGeometry, - typename Functor, - bool IsConst -> -struct for_each_segment +template +struct for_each_segment : detail::for_each::for_each_multi < - MultiGeometry, - Functor, - IsConst, // Specify the dispatch of the single-version as policy for_each_segment < - typename single_tag_of + typename add_const_if_c < - typename tag::type - >::type, - typename boost::range_value::type, - Functor, - IsConst + is_const::value, + typename boost::range_value::type + >::type > > {}; diff --git a/include/boost/geometry/multi/algorithms/intersection.hpp b/include/boost/geometry/multi/algorithms/intersection.hpp index 31e74a79b..0027a4e15 100644 --- a/include/boost/geometry/multi/algorithms/intersection.hpp +++ b/include/boost/geometry/multi/algorithms/intersection.hpp @@ -36,14 +36,14 @@ namespace detail { namespace intersection { -template -< - typename MultiLinestring1, typename MultiLinestring2, - typename OutputIterator, typename PointOut, - typename Strategy -> +template struct intersection_multi_linestring_multi_linestring_point { + template + < + typename MultiLinestring1, typename MultiLinestring2, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(MultiLinestring1 const& ml1, MultiLinestring2 const& ml2, OutputIterator out, Strategy const& strategy) @@ -64,12 +64,8 @@ struct intersection_multi_linestring_multi_linestring_point it2 != boost::end(ml2); ++it2) { - out = intersection_linestring_linestring_point - < - typename boost::range_value::type, - typename boost::range_value::type, - OutputIterator, PointOut, Strategy - >::apply(*it1, *it2, out, strategy); + out = intersection_linestring_linestring_point + ::apply(*it1, *it2, out, strategy); } } @@ -78,14 +74,14 @@ struct intersection_multi_linestring_multi_linestring_point }; -template -< - typename Linestring, typename MultiLinestring, - typename OutputIterator, typename PointOut, - typename Strategy -> +template struct intersection_linestring_multi_linestring_point { + template + < + typename Linestring, typename MultiLinestring, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(Linestring const& linestring, MultiLinestring const& ml, OutputIterator out, Strategy const& strategy) @@ -97,12 +93,8 @@ struct intersection_linestring_multi_linestring_point it != boost::end(ml); ++it) { - out = intersection_linestring_linestring_point - < - Linestring, - typename boost::range_value::type, - OutputIterator, PointOut, Strategy - >::apply(linestring, *it, out, strategy); + out = intersection_linestring_linestring_point + ::apply(linestring, *it, out, strategy); } return out; @@ -114,14 +106,17 @@ struct intersection_linestring_multi_linestring_point // is second (above) or first (below) argument, it is not trivial to merge them. template < - typename MultiLinestring, typename Areal, bool ReverseAreal, - typename OutputIterator, typename LineStringOut, - overlay_type OverlayType, - typename Strategy + typename LineStringOut, + overlay_type OverlayType > struct intersection_of_multi_linestring_with_areal { + template + < + typename MultiLinestring, typename Areal, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal, OutputIterator out, Strategy const& strategy) @@ -135,9 +130,7 @@ struct intersection_of_multi_linestring_with_areal { out = intersection_of_linestring_with_areal < - typename boost::range_value::type, - Areal, ReverseAreal, - OutputIterator, LineStringOut, OverlayType, Strategy + ReverseAreal, LineStringOut, OverlayType >::apply(*it, areal, out, strategy); } @@ -149,38 +142,38 @@ struct intersection_of_multi_linestring_with_areal // This one calls the one above with reversed arguments template < - typename Areal, typename MultiLinestring, bool ReverseAreal, - typename OutputIterator, typename LineStringOut, - overlay_type OverlayType, - typename Strategy + typename LineStringOut, + overlay_type OverlayType > struct intersection_of_areal_with_multi_linestring { + template + < + typename Areal, typename MultiLinestring, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml, OutputIterator out, Strategy const& strategy) { return intersection_of_multi_linestring_with_areal < - MultiLinestring, Areal, ReverseAreal, - OutputIterator, LineStringOut, - OverlayType, - Strategy + ReverseAreal, LineStringOut, OverlayType >::apply(ml, areal, out, strategy); } }; -template -< - typename MultiLinestring, typename Box, - typename OutputIterator, typename LinestringOut, - typename Strategy -> +template struct clip_multi_linestring { + template + < + typename MultiLinestring, typename Box, + typename OutputIterator, typename Strategy + > static inline OutputIterator apply(MultiLinestring const& multi_linestring, Box const& box, OutputIterator out, Strategy const& ) { @@ -211,25 +204,21 @@ namespace dispatch template < typename MultiLinestring1, typename MultiLinestring2, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert < - multi_linestring_tag, multi_linestring_tag, point_tag, - false, false, false, MultiLinestring1, MultiLinestring2, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + multi_linestring_tag, multi_linestring_tag, point_tag, + false, false, false > : detail::intersection::intersection_multi_linestring_multi_linestring_point < - MultiLinestring1, MultiLinestring2, - OutputIterator, GeometryOut, - Strategy + GeometryOut > {}; @@ -237,25 +226,21 @@ struct intersection_insert template < typename Linestring, typename MultiLinestring, - typename OutputIterator, typename GeometryOut, - bool Reverse1, bool Reverse2, bool ReverseOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert < - linestring_tag, multi_linestring_tag, point_tag, - false, false, false, Linestring, MultiLinestring, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + linestring_tag, multi_linestring_tag, point_tag, + false, false, false > : detail::intersection::intersection_linestring_multi_linestring_point < - Linestring, MultiLinestring, - OutputIterator, GeometryOut, - Strategy + GeometryOut > {}; @@ -263,25 +248,21 @@ struct intersection_insert template < typename MultiLinestring, typename Box, - bool Reverse1, bool Reverse2, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert < - multi_linestring_tag, box_tag, linestring_tag, - false, true, false, MultiLinestring, Box, - Reverse1, Reverse2, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + Reverse1, Reverse2, ReverseOut, + multi_linestring_tag, box_tag, linestring_tag, + false, true, false > : detail::intersection::clip_multi_linestring < - MultiLinestring, Box, - OutputIterator, GeometryOut, - Strategy + GeometryOut > {}; @@ -289,27 +270,23 @@ struct intersection_insert template < typename Linestring, typename MultiPolygon, - bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut > struct intersection_insert < - linestring_tag, multi_polygon_tag, linestring_tag, - false, true, false, Linestring, MultiPolygon, - ReverseLinestring, ReverseMultiPolygon, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + ReverseLinestring, ReverseMultiPolygon, ReverseOut, + linestring_tag, multi_polygon_tag, linestring_tag, + false, true, false > : detail::intersection::intersection_of_linestring_with_areal < - Linestring, MultiPolygon, ReverseMultiPolygon, - OutputIterator, GeometryOut, - OverlayType, - Strategy + GeometryOut, + OverlayType > {}; @@ -319,27 +296,23 @@ struct intersection_insert template < typename Polygon, typename MultiLinestring, - bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut > struct intersection_insert < - polygon_tag, multi_linestring_tag, linestring_tag, - true, false, false, Polygon, MultiLinestring, - ReversePolygon, ReverseMultiLinestring, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + ReversePolygon, ReverseMultiLinestring, ReverseOut, + polygon_tag, multi_linestring_tag, linestring_tag, + true, false, false > : detail::intersection::intersection_of_areal_with_multi_linestring < - Polygon, MultiLinestring, ReversePolygon, - OutputIterator, GeometryOut, - OverlayType, - Strategy + GeometryOut, + OverlayType > {}; @@ -347,54 +320,46 @@ struct intersection_insert template < typename MultiLinestring, typename Ring, - bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut > struct intersection_insert < - multi_linestring_tag, ring_tag, linestring_tag, - false, true, false, MultiLinestring, Ring, - ReverseMultiLinestring, ReverseRing, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + ReverseMultiLinestring, ReverseRing, ReverseOut, + multi_linestring_tag, ring_tag, linestring_tag, + false, true, false > : detail::intersection::intersection_of_multi_linestring_with_areal < - MultiLinestring, Ring, ReverseRing, - OutputIterator, GeometryOut, - OverlayType, - Strategy + GeometryOut, + OverlayType > {}; template < typename MultiLinestring, typename Polygon, - bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut > struct intersection_insert < - multi_linestring_tag, polygon_tag, linestring_tag, - false, true, false, MultiLinestring, Polygon, - ReverseMultiLinestring, ReverseRing, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + ReverseMultiLinestring, ReverseRing, ReverseOut, + multi_linestring_tag, polygon_tag, linestring_tag, + false, true, false > : detail::intersection::intersection_of_multi_linestring_with_areal < - MultiLinestring, Polygon, ReverseRing, - OutputIterator, GeometryOut, - OverlayType, - Strategy + GeometryOut, + OverlayType > {}; @@ -403,27 +368,23 @@ struct intersection_insert template < typename MultiLinestring, typename MultiPolygon, - bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut, - typename OutputIterator, typename GeometryOut, + typename GeometryOut, overlay_type OverlayType, - typename Strategy + bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut > struct intersection_insert < - multi_linestring_tag, multi_polygon_tag, linestring_tag, - false, true, false, MultiLinestring, MultiPolygon, - ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut, - OutputIterator, GeometryOut, + GeometryOut, OverlayType, - Strategy + ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut, + multi_linestring_tag, multi_polygon_tag, linestring_tag, + false, true, false > : detail::intersection::intersection_of_multi_linestring_with_areal < - MultiLinestring, MultiPolygon, ReverseMultiPolygon, - OutputIterator, GeometryOut, - OverlayType, - Strategy + GeometryOut, + OverlayType > {}; diff --git a/include/boost/geometry/multi/algorithms/length.hpp b/include/boost/geometry/multi/algorithms/length.hpp index 51ff9ef3c..ef5fb3c97 100644 --- a/include/boost/geometry/multi/algorithms/length.hpp +++ b/include/boost/geometry/multi/algorithms/length.hpp @@ -30,21 +30,25 @@ namespace boost { namespace geometry namespace dispatch { -template -struct length - : detail::multi_sum - < - typename default_length_result::type, - MultiLinestring, - Strategy, - detail::length::range_length - < - typename boost::range_value::type, - Strategy, - closed // no need to close it explicitly - > - > -{}; +template +struct length : detail::multi_sum +{ + template + static inline typename default_length_result::type + apply(MultiLinestring const& multi, Strategy const& strategy) + { + return multi_sum::apply + < + typename default_length_result::type, + detail::length::range_length + < + typename boost::range_value::type, + closed // no need to close it explicitly + > + >(multi, strategy); + + } +}; } // namespace dispatch diff --git a/include/boost/geometry/multi/algorithms/num_geometries.hpp b/include/boost/geometry/multi/algorithms/num_geometries.hpp index 213339a18..cc59655be 100644 --- a/include/boost/geometry/multi/algorithms/num_geometries.hpp +++ b/include/boost/geometry/multi/algorithms/num_geometries.hpp @@ -32,7 +32,7 @@ namespace dispatch { template -struct num_geometries +struct num_geometries { static inline std::size_t apply(MultiGeometry const& multi_geometry) { diff --git a/include/boost/geometry/multi/algorithms/num_interior_rings.hpp b/include/boost/geometry/multi/algorithms/num_interior_rings.hpp index 87b0bdea9..8390fe77a 100644 --- a/include/boost/geometry/multi/algorithms/num_interior_rings.hpp +++ b/include/boost/geometry/multi/algorithms/num_interior_rings.hpp @@ -34,7 +34,7 @@ namespace dispatch template -struct num_interior_rings +struct num_interior_rings { static inline std::size_t apply(MultiPolygon const& multi_polygon) { diff --git a/include/boost/geometry/multi/algorithms/num_points.hpp b/include/boost/geometry/multi/algorithms/num_points.hpp index 5ea53854e..1cc82b2f0 100644 --- a/include/boost/geometry/multi/algorithms/num_points.hpp +++ b/include/boost/geometry/multi/algorithms/num_points.hpp @@ -30,9 +30,9 @@ namespace detail { namespace num_points { -template struct multi_count { + template static inline size_t apply(MultiGeometry const& geometry, bool add_for_open) { typedef typename boost::range_value::type geometry_type; @@ -46,11 +46,7 @@ struct multi_count it != boost::end(geometry); ++it) { - n += dispatch::num_points - < - typename tag::type, - geometry_type - >::apply(*it, add_for_open); + n += dispatch::num_points::apply(*it, add_for_open); } return n; } @@ -67,8 +63,8 @@ namespace dispatch template -struct num_points - : detail::num_points::multi_count {}; +struct num_points + : detail::num_points::multi_count {}; } // namespace dispatch diff --git a/include/boost/geometry/multi/algorithms/perimeter.hpp b/include/boost/geometry/multi/algorithms/perimeter.hpp index 147f6fcc3..6a13f90e3 100644 --- a/include/boost/geometry/multi/algorithms/perimeter.hpp +++ b/include/boost/geometry/multi/algorithms/perimeter.hpp @@ -30,21 +30,20 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { -template -struct perimeter - : detail::multi_sum - < - typename default_length_result::type, - MultiPolygon, - Strategy, - perimeter - < - polygon_tag, - typename boost::range_value::type, - Strategy - > - > -{}; +template +struct perimeter : detail::multi_sum +{ + template + static inline typename default_length_result::type + apply(MultiPolygon const& multi, Strategy const& strategy) + { + return multi_sum::apply + < + typename default_length_result::type, + perimeter::type> + >(multi, strategy); + } +}; } // namespace dispatch #endif diff --git a/include/boost/geometry/multi/algorithms/reverse.hpp b/include/boost/geometry/multi/algorithms/reverse.hpp index f8a9442ac..910f1e3d1 100644 --- a/include/boost/geometry/multi/algorithms/reverse.hpp +++ b/include/boost/geometry/multi/algorithms/reverse.hpp @@ -34,27 +34,21 @@ namespace dispatch template -struct reverse +struct reverse : detail::multi_modify < Geometry, detail::reverse::range_reverse - < - typename boost::range_value::type - > > {}; template -struct reverse +struct reverse : detail::multi_modify < Geometry, detail::reverse::polygon_reverse - < - typename boost::range_value::type - > > {}; diff --git a/include/boost/geometry/multi/algorithms/simplify.hpp b/include/boost/geometry/multi/algorithms/simplify.hpp index dc3c7b593..1706c69f4 100644 --- a/include/boost/geometry/multi/algorithms/simplify.hpp +++ b/include/boost/geometry/multi/algorithms/simplify.hpp @@ -31,9 +31,10 @@ namespace boost { namespace geometry namespace detail { namespace simplify { -template +template struct simplify_multi { + template static inline void apply(MultiGeometry const& multi, MultiGeometry& out, double max_distance, Strategy const& strategy) { @@ -63,47 +64,21 @@ struct simplify_multi namespace dispatch { -template -struct simplify +template +struct simplify : detail::simplify::simplify_copy - < - MultiPoint, - Strategy - > - {}; -template -struct simplify - : detail::simplify::simplify_multi - < - MultiLinestring, - Strategy, - detail::simplify::simplify_range - < - typename boost::range_value::type, - Strategy, - 2 - > - > - +template +struct simplify + : detail::simplify::simplify_multi > {}; -template -struct simplify - : detail::simplify::simplify_multi - < - MultiPolygon, - Strategy, - detail::simplify::simplify_polygon - < - typename boost::range_value::type, - Strategy - > - > - +template +struct simplify + : detail::simplify::simplify_multi {}; diff --git a/include/boost/geometry/multi/algorithms/transform.hpp b/include/boost/geometry/multi/algorithms/transform.hpp index 09926778f..110e96958 100644 --- a/include/boost/geometry/multi/algorithms/transform.hpp +++ b/include/boost/geometry/multi/algorithms/transform.hpp @@ -31,10 +31,10 @@ namespace detail { namespace transform /*! \brief Is able to transform any multi-geometry, calling the single-version as policy */ -template +template struct transform_multi { - template + template static inline bool apply(Multi1 const& multi1, Multi2& multi2, S const& strategy) { traits::resize::apply(multi2, boost::size(multi1)); @@ -65,30 +65,18 @@ struct transform_multi namespace dispatch { -template +template struct transform < - multi_tag, multi_tag, Multi1, Multi2, - Strategy + multi_tag, multi_tag > : detail::transform::transform_multi < - Multi1, - Multi2, transform < - typename single_tag_of - < - typename tag::type - >::type, - typename single_tag_of - < - typename tag::type - >::type, typename boost::range_value::type, - typename boost::range_value::type, - Strategy + typename boost::range_value::type > > {}; diff --git a/include/boost/geometry/multi/algorithms/unique.hpp b/include/boost/geometry/multi/algorithms/unique.hpp index 5067e71f3..bda2234a6 100644 --- a/include/boost/geometry/multi/algorithms/unique.hpp +++ b/include/boost/geometry/multi/algorithms/unique.hpp @@ -30,9 +30,10 @@ namespace detail { namespace unique { -template +template struct multi_unique { + template static inline void apply(MultiGeometry& multi, ComparePolicy const& compare) { for (typename boost::range_iterator::type @@ -62,33 +63,15 @@ namespace dispatch // possible for multi-points as well, removing points at the same location. -template -struct unique - : detail::unique::multi_unique - < - MultiLineString, - ComparePolicy, - detail::unique::range_unique - < - typename boost::range_value::type, - ComparePolicy - > - > +template +struct unique + : detail::unique::multi_unique {}; -template -struct unique - : detail::unique::multi_unique - < - MultiPolygon, - ComparePolicy, - detail::unique::polygon_unique - < - typename boost::range_value::type, - ComparePolicy - > - > +template +struct unique + : detail::unique::multi_unique {}; diff --git a/include/boost/geometry/multi/multi.hpp b/include/boost/geometry/multi/multi.hpp index db33a9dd0..df10392cb 100644 --- a/include/boost/geometry/multi/multi.hpp +++ b/include/boost/geometry/multi/multi.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/geometry/strategies/cartesian/cart_intersect.hpp b/include/boost/geometry/strategies/cartesian/cart_intersect.hpp index ea92cf37b..564010f0a 100644 --- a/include/boost/geometry/strategies/cartesian/cart_intersect.hpp +++ b/include/boost/geometry/strategies/cartesian/cart_intersect.hpp @@ -120,6 +120,22 @@ struct relate_cartesian_segments typedef side::side_by_triangle side; side_info sides; + coordinate_type const zero = 0; + bool const a_is_point = math::equals(dx_a, zero) && math::equals(dy_a, zero); + bool const b_is_point = math::equals(dx_b, zero) && math::equals(dy_b, zero); + + if(a_is_point && b_is_point) + { + if(math::equals(get<1,0>(a), get<1,0>(b)) && math::equals(get<1,1>(a), get<1,1>(b))) + { + Policy::degenerate(a, true); + } + else + { + return Policy::disjoint(); + } + } + bool collinear_use_first = math::abs(dx_a) + math::abs(dx_b) >= math::abs(dy_a) + math::abs(dy_b); sides.set<0> @@ -143,7 +159,7 @@ struct relate_cartesian_segments bool collinear = sides.collinear(); - robustness_verify_collinear(a, b, sides, collinear); + robustness_verify_collinear(a, b, a_is_point, b_is_point, sides, collinear); robustness_verify_meeting(a, b, sides, collinear, collinear_use_first); if (sides.same<0>() || sides.same<1>()) @@ -156,12 +172,11 @@ struct relate_cartesian_segments } // Degenerate cases: segments of single point, lying on other segment, non disjoint - coordinate_type const zero = 0; - if (math::equals(dx_a, zero) && math::equals(dy_a, zero)) + if (a_is_point) { return Policy::degenerate(a, true); } - if (math::equals(dx_b, zero) && math::equals(dy_b, zero)) + if (b_is_point) { return Policy::degenerate(b, false); } @@ -281,10 +296,11 @@ private : static inline void robustness_verify_collinear( segment_type1 const& a, segment_type2 const& b, + bool a_is_point, bool b_is_point, side_info& sides, bool& collinear) { - if ((sides.zero<0>() && ! sides.zero<1>()) || (sides.zero<1>() && ! sides.zero<0>())) + if ((sides.zero<0>() && ! b_is_point && ! sides.zero<1>()) || (sides.zero<1>() && ! a_is_point && ! sides.zero<0>())) { // If one of the segments is collinear, the other must be as well. // So handle it as collinear. diff --git a/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp b/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp index 51d272266..c62cf749e 100644 --- a/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp @@ -42,8 +42,8 @@ struct compute_pythagoras { static inline T apply(Point1 const& p1, Point2 const& p2) { - T const c1 = boost::numeric_cast(get(p2)); - T const c2 = boost::numeric_cast(get(p1)); + T const c1 = boost::numeric_cast(get(p1)); + T const c2 = boost::numeric_cast(get(p2)); T const d = c1 - c2; return d * d + compute_pythagoras::apply(p1, p2); } diff --git a/include/boost/geometry/strategies/covered_by.hpp b/include/boost/geometry/strategies/covered_by.hpp index a878b26c8..a5aae7703 100644 --- a/include/boost/geometry/strategies/covered_by.hpp +++ b/include/boost/geometry/strategies/covered_by.hpp @@ -53,7 +53,7 @@ struct default_strategy { BOOST_MPL_ASSERT_MSG ( - false, NOT_IMPLEMENTED_FOR_THIS_TYPES + false, NOT_IMPLEMENTED_FOR_THESE_TYPES , (types) ); }; diff --git a/include/boost/geometry/strategies/within.hpp b/include/boost/geometry/strategies/within.hpp index 0852a22d2..d625bc40e 100644 --- a/include/boost/geometry/strategies/within.hpp +++ b/include/boost/geometry/strategies/within.hpp @@ -52,7 +52,7 @@ struct default_strategy { BOOST_MPL_ASSERT_MSG ( - false, NOT_IMPLEMENTED_FOR_THIS_TYPES + false, NOT_IMPLEMENTED_FOR_THESE_TYPES , (types) ); }; diff --git a/test/algorithms/area.cpp b/test/algorithms/area.cpp index 1b2dc49f5..1d05439f6 100644 --- a/test/algorithms/area.cpp +++ b/test/algorithms/area.cpp @@ -25,6 +25,8 @@ #include //#define GEOMETRY_TEST_DEBUG +#include + template void test_polygon() { @@ -222,6 +224,28 @@ void test_large_integers() BOOST_CHECK_CLOSE(int_area, double_area, 0.0001); } +void test_variant() +{ + typedef bg::model::point double_point_type; + typedef bg::model::polygon polygon_type; + typedef bg::model::box box_type; + + polygon_type poly; + std::string const polygon_li = "POLYGON((18 5,18 1,15 1,15 5,12 5,12 8,15 8,18 8,18 5))"; + bg::read_wkt(polygon_li, poly); + + box_type box; + std::string const box_li = "BOX(0 0,2 2)"; + bg::read_wkt(box_li, box); + + boost::variant v; + + v = poly; + BOOST_CHECK_CLOSE(bg::area(v), bg::area(poly), 0.0001); + v = box; + BOOST_CHECK_CLOSE(bg::area(v), bg::area(box), 0.0001); +} + int test_main(int, char* []) { test_all >(); @@ -242,6 +266,8 @@ int test_main(int, char* []) test_large_integers(); + test_variant(); + // test_empty_input >(); return 0; diff --git a/test/algorithms/comparable_distance.cpp b/test/algorithms/comparable_distance.cpp index 1f5266fdd..294321c4f 100644 --- a/test/algorithms/comparable_distance.cpp +++ b/test/algorithms/comparable_distance.cpp @@ -102,11 +102,11 @@ void test_distance_linestring() P p = bg::make

(2, 1); typename bg::coordinate_type

::type d = bg::comparable_distance(p, points); - BOOST_CHECK_CLOSE(d, 0.70710678, 0.001); + BOOST_CHECK_CLOSE(d, 0.5, 0.001); p = bg::make

(5, 5); d = bg::comparable_distance(p, points); - BOOST_CHECK_CLOSE(d, 2.828427, 0.001); + BOOST_CHECK_CLOSE(d, 8.0, 0.001); bg::model::linestring

line; @@ -117,11 +117,11 @@ void test_distance_linestring() p = bg::make

(5, 5); d = bg::comparable_distance(p, line); - BOOST_CHECK_CLOSE(d, 2.828427, 0.001); + BOOST_CHECK_CLOSE(d, 8.0, 0.001); // Reverse case d = bg::comparable_distance(line, p); - BOOST_CHECK_CLOSE(d, 2.828427, 0.001); + BOOST_CHECK_CLOSE(d, 8.0, 0.001); } template diff --git a/test/algorithms/difference.cpp b/test/algorithms/difference.cpp index e72af3c24..62269a93d 100644 --- a/test/algorithms/difference.cpp +++ b/test/algorithms/difference.cpp @@ -9,6 +9,8 @@ // #define TEST_ISOVIST +//#define HAVE_TTMATH + //#define BOOST_GEOMETRY_CHECK_WITH_POSTGIS //#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER @@ -111,8 +113,8 @@ void test_all() test_one("simplex_normal", simplex_normal[0], simplex_normal[1], - 3, 3, 2.52636706856656, - 3, 3, 3.52636706856656); + 3, 12, 2.52636706856656, + 3, 12, 3.52636706856656); test_one("simplex_with_empty", simplex_normal[0], polygon_empty, @@ -126,24 +128,24 @@ void test_all() test_one("two_bends", two_bends[0], two_bends[1], - 1, 7, 8.0, - 1, 7, 8.0); + 1, 5, 8.0, + 1, 5, 8.0); test_one("star_comb_15", star_comb_15[0], star_comb_15[1], - 30, 150, 227.658275102812, - 30, 150, 480.485775259312); + 30, 160, 227.658275102812, + 30, 198, 480.485775259312); test_one("new_hole", new_hole[0], new_hole[1], - 1, 10, 7.0, - 1, 10, 14.0); + 1, 9, 7.0, + 1, 13, 14.0); test_one("crossed", crossed[0], crossed[1], - 1, 0, 19.5, - 1, 0, 2.5); + 1, 18, 19.5, + 1, 7, 2.5); test_one("disjoint", disjoint[0], disjoint[1], @@ -152,35 +154,35 @@ void test_all() test_one("distance_zero", distance_zero[0], distance_zero[1], - 2, 0, 8.7048386, + 2, -1, 8.7048386, if_typed(1, 2), // The too small one is discarded for floating point - 0, 0.0098387); + -1, 0.0098387); test_one("equal_holes_disjoint", equal_holes_disjoint[0], equal_holes_disjoint[1], - 1, 0, 9.0, - 1, 0, 9.0); + 1, 5, 9.0, + 1, 5, 9.0); test_one("only_hole_intersections1", only_hole_intersections[0], only_hole_intersections[1], - 2, 0, 1.9090909, - 4, 0, 10.9090909); + 2, 10, 1.9090909, + 4, 16, 10.9090909); test_one("only_hole_intersection2", only_hole_intersections[0], only_hole_intersections[2], - 3, 0, 30.9090909, - 4, 0, 10.9090909); + 3, 20, 30.9090909, + 4, 16, 10.9090909); test_one("first_within_second", first_within_second[1], first_within_second[0], - 1, 1, 24, + 1, 10, 24, 0, 0, 0); test_one("fitting", fitting[0], fitting[1], - 1, 0, 21.0, - 1, 0, 4.0); + 1, 9, 21.0, + 1, 4, 4.0); test_one("identical", identical[0], identical[1], @@ -189,63 +191,63 @@ void test_all() test_one("intersect_exterior_and_interiors_winded", intersect_exterior_and_interiors_winded[0], intersect_exterior_and_interiors_winded[1], - 4, 0, 11.533333, - 5, 0, 29.783333); + 4, 20, 11.533333, + 5, 26, 29.783333); test_one("intersect_holes_intersect_and_disjoint", intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1], - 2, 0, 15.75, - 3, 0, 6.75); + 2, 16, 15.75, + 3, 17, 6.75); test_one("intersect_holes_intersect_and_touch", intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1], - 3, 0, 16.25, - 3, 0, 6.25); + 3, 21, 16.25, + 3, 17, 6.25); test_one("intersect_holes_new_ring", intersect_holes_new_ring[0], intersect_holes_new_ring[1], - 3, 0, 9.8961, - 4, 0, 121.8961, 0.01); + 3, 15, 9.8961, + 4, 25, 121.8961, 0.01); test_one("first_within_hole_of_second", first_within_hole_of_second[0], first_within_hole_of_second[1], - 1, -1, 1, - 1, -1, 16); + 1, 5, 1, + 1, 10, 16); test_one("intersect_holes_disjoint", intersect_holes_disjoint[0], intersect_holes_disjoint[1], - 2, 15, 16.0, - 2, 15, 6.0); + 2, 14, 16.0, + 2, 10, 6.0); test_one("intersect_holes_intersect", intersect_holes_intersect[0], intersect_holes_intersect[1], - 2, 14, 15.75, - 2, 14, 5.75); + 2, 16, 15.75, + 2, 12, 5.75); test_one( "case4", case_4[0], case_4[1], - 6, 22, 2.77878787878788, - 4, 27, 4.77878787878788); + 6, 28, 2.77878787878788, + 4, 22, 4.77878787878788); test_one( "case5", case_5[0], case_5[1], - 8, 22, 2.43452380952381, - 7, 27, 3.18452380952381); + 8, 36, 2.43452380952381, + 7, 33, 3.18452380952381); test_one("winded", winded[0], winded[1], - 3, 1, 61, - 1, 0, 13); + 3, 37, 61, + 1, 15, 13); test_one("within_holes_disjoint", within_holes_disjoint[0], within_holes_disjoint[1], - 2, 1, 25, - 1, 0, 1); + 2, 15, 25, + 1, 5, 1); test_one("side_side", side_side[0], side_side[1], - 1, 0, 1, - 1, 0, 1); + 1, 5, 1, + 1, 5, 1); /*** TODO: self-tangencies for difference test_one("wrapped_a", @@ -274,32 +276,35 @@ void test_all() test_one("ggl_list_20110306_javier", ggl_list_20110306_javier[0], ggl_list_20110306_javier[1], - 1, 0, 71495.3331, - 2, 0, 8960.49049); + 1, -1, 71495.3331, + 2, -1, 8960.49049); #endif test_one("ggl_list_20110307_javier", ggl_list_20110307_javier[0], ggl_list_20110307_javier[1], - 1, 0, 16815.6, - 1, 0, 3200.4, + 1, 13, 16815.6, + 1, 4, 3200.4, 0.01); if (! boost::is_same::value) { test_one("ggl_list_20110716_enrico", ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1], - 3, 0, 35723.8506317139, - 1, 0, 58456.4964294434 + 3, -1, 35723.8506317139, + 1, -1, 58456.4964294434 ); } test_one("ggl_list_20110820_christophe", ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1], - 1, 0, 2.8570121719168924, - 1, 0, 64.498061986388564); - - + 1, -1, 2.8570121719168924, + 1, -1, 64.498061986388564); + test_one("ggl_list_20120717_volker", + ggl_list_20120717_volker[0], ggl_list_20120717_volker[1], + 1, 11, 3370866.2295081965, + 1, 5, 384.2295081964694, 0.01); + #ifdef _MSC_VER // 2011-07-02 // Interesting FP-precision case. @@ -310,9 +315,9 @@ void test_all() // Because we cannot predict this, we only test for MSVC test_one("ggl_list_20110627_phillip", ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1], - if_typed_tt(1, 0), 0, + if_typed_tt(1, 0), -1, if_typed_tt(0.0000000000001105367, 0.0), - 1, 0, 3577.40960816756, + 1, -1, 3577.40960816756, 0.01 ); #endif @@ -325,17 +330,17 @@ void test_all() test_one( "ring_star_ring", example_ring, example_star, - 5, 22, 1.6701714, 5, 27, 1.1901714); + 5, 27, 1.6701714, 5, 22, 1.1901714); static std::string const clip = "POLYGON((2.5 0.5,5.5 2.5))"; test_one("star_box", clip, example_star, - 4, 11, 2.833333, 4, 11, 0.833333); + 4, 20, 2.833333, 4, 16, 0.833333); test_one("box_star", example_star, clip, - 4, 11, 0.833333, 4, 11, 2.833333); + 4, 16, 0.833333, 4, 20, 2.833333); } // Counter clockwise @@ -464,6 +469,19 @@ void test_difference_parcel_precision() } *****/ + +template +void test_specific() +{ + typedef bg::model::polygon polygon; + + test_one("ggl_list_20120717_volker", + ggl_list_20120717_volker[0], ggl_list_20120717_volker[1], + 1, 11, 3370866.2295081965, + 1, 5, 384, 0.01); +} + + int test_main(int, char* []) { //test_difference_parcel_precision(); @@ -471,6 +489,8 @@ int test_main(int, char* []) test_all >(); + test_specific, false, false>(); + #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) test_all >(); diff --git a/test/algorithms/disjoint.cpp b/test/algorithms/disjoint.cpp index 7cf3c683c..862035005 100644 --- a/test/algorithms/disjoint.cpp +++ b/test/algorithms/disjoint.cpp @@ -105,6 +105,16 @@ void test_all() test_disjoint("within_simplex_rr1", within_simplex[0], within_simplex[1], false); test_disjoint("within_simplex_rr2", within_simplex[1], within_simplex[0], false); + test_disjoint("point_ring1", "POINT(0 0)", "POLYGON((0 0,3 3,6 0,0 0))", false); + test_disjoint("point_ring2", "POINT(3 1)", "POLYGON((0 0,3 3,6 0,0 0))", false); + test_disjoint("point_ring3", "POINT(0 3)", "POLYGON((0 0,3 3,6 0,0 0))", true); + test_disjoint("point_polygon1", "POINT(0 0)", "POLYGON((0 0,3 3,6 0,0 0))", false); + test_disjoint("point_polygon2", "POINT(3 1)", "POLYGON((0 0,3 3,6 0,0 0))", false); + test_disjoint("point_polygon3", "POINT(0 3)", "POLYGON((0 0,3 3,6 0,0 0))", true); + + test_disjoint("point_ring2", "POLYGON((0 0,3 3,6 0,0 0))", "POINT(0 0)", false); + test_disjoint("point_polygon2", "POLYGON((0 0,3 3,6 0,0 0))", "POINT(0 0)", false); + // Linear typedef bg::model::linestring

ls; typedef bg::model::segment

segment; @@ -113,6 +123,12 @@ void test_all() test_disjoint("s/s 1", "linestring(0 0,1 1)", "linestring(1 0,0 1)", false); test_disjoint("s/s 2", "linestring(0 0,1 1)", "linestring(1 0,2 1)", true); + // Test degenerate segments (patched by Karsten Ahnert on 2012-07-25) + test_disjoint("s/s 3", "linestring(0 0,0 0)", "linestring(1 0,0 1)", true); + test_disjoint("s/s 4", "linestring(0 0,0 0)", "linestring(0 0,0 0)", false); + test_disjoint("s/s 5", "linestring(0 0,0 0)", "linestring(1 0,1 0)", true); + test_disjoint("s/s 6", "linestring(0 0,0 0)", "linestring(0 1,0 1)", true); + // Collinear opposite test_disjoint("ls/ls co", "linestring(0 0,2 2)", "linestring(1 1,0 0)", false); // Collinear opposite and equal diff --git a/test/algorithms/intersects.cpp b/test/algorithms/intersects.cpp index ab8a36ae9..feafb0437 100644 --- a/test/algorithms/intersects.cpp +++ b/test/algorithms/intersects.cpp @@ -17,13 +17,28 @@ template void test_all() { - // intersect <=> ! disjoint + typedef bg::model::polygon

polygon; + typedef bg::model::ring

ring; + + // intersect <=> ! disjoint (in most cases) // so most tests are done in disjoint test. - // We only test compilation of one case. + // We only test compilation of a few cases. test_geometry >("POINT(1 1)", "BOX(0 0,2 2)", true); + test_geometry >( + "POLYGON((1992 3240,1992 1440,3792 1800,3792 3240,1992 3240))", + "BOX(1941 2066, 2055 2166)", true); + + test_geometry >( + "POLYGON((1992 3240,1992 1440,3792 1800,3792 3240,1992 3240))", + "BOX(1941 2066, 2055 2166)", true); + + test_geometry >( + "POLYGON((1941 2066,2055 2066,2055 2166,1941 2166))", + "BOX(1941 2066, 2055 2166)", true); + + // self-intersecting is not tested in disjoint, so that is done here. - typedef bg::model::polygon

polygon; // Just a normal polygon test_self_intersects("POLYGON((0 0,0 4,1.5 2.5,2.5 1.5,4 0,0 0))", false); @@ -111,6 +126,28 @@ void test_all() "POLYGON((0 0,3 3,3 3,4 1,0 0))", false); test_self_intersects >( "POLYGON((0 0,3 3,3 3,4 1))", false); + + test_geometry >( + "POINT(0 0)", + "BOX(0 0,4 4)", + true); + test_geometry >( + "POINT(0 0)", + "POLYGON((0 0,3 3,3 3,4 1))", + true); + test_geometry >( + "POINT(0 0)", + "POLYGON((0 0,3 3,3 3,4 1))", + true); + + test_geometry, P>( + "POLYGON((0 0,3 3,3 3,4 1))", + "POINT(0 0)", + true); + test_geometry, P>( + "POLYGON((0 0,3 3,3 3,4 1))", + "POINT(0 0)", + true); } diff --git a/test/algorithms/overlay/overlay_cases.hpp b/test/algorithms/overlay/overlay_cases.hpp index a4326b07b..848ae8601 100644 --- a/test/algorithms/overlay/overlay_cases.hpp +++ b/test/algorithms/overlay/overlay_cases.hpp @@ -567,6 +567,13 @@ static std::string ggl_list_20120229_volker[3] = "POLYGON((1716 1554,2076 2250,2436 2352,2796 1248,3156 2484,3516 2688,3156 2483,2796 1247,2436 2351,2076 2249, 1716 1554))", }; +static std::string ggl_list_20120717_volker[2] = + { + "POLYGON((1031 1056,3232 1056,3232 2856,1031 2856))", + "POLYGON((1032 1458,1032 1212,2136 2328,3234 2220,3234 2412,2136 2646))" + }; + + static std::string buffer_rt_a[2] = { "POLYGON((1 7,1 8,1.0012 8.04907,1.00482 8.09802,1.01082 8.14673,1.01921 8.19509,1.02997 8.24298,1.04306 8.29028,1.05846 8.33689,1.07612 8.38268,1.09601 8.42756,1.11808 8.4714,1.14227 8.5141,1.16853 8.55557,1.19679 8.5957,1.22699 8.63439,1.25905 8.67156,1.29289 8.70711,1.32844 8.74095,1.36561 8.77301,1.4043 8.80321,1.44443 8.83147,1.4859 8.85773,1.5286 8.88192,1.57244 8.90399,1.61732 8.92388,1.66311 8.94154,1.70972 8.95694,1.75702 8.97003,1.80491 8.98079,1.85327 8.98918,1.90198 8.99518,1.95093 8.9988,2 9,3 9,3.04907 8.9988,3.09802 8.99518,3.14673 8.98918,3.19509 8.98079,3.24298 8.97003,3.29028 8.95694,3.33689 8.94154,3.38268 8.92388,3.42756 8.90399,3.4714 8.88192,3.5141 8.85773,3.55557 8.83147,3.5957 8.80321,3.63439 8.77301,3.67156 8.74095,3.70711 8.70711,3.74095 8.67156,3.77301 8.63439,3.80321 8.5957,3.83147 8.55557,3.85773 8.5141,3.88192 8.4714,3.90399 8.42756,3.92388 8.38268,3.94154 8.33689,3.95694 8.29028,3.97003 8.24298,3.98079 8.19509,3.98918 8.14673,3.99518 8.09802,3.9988 8.04907,4 8,4 7,3.9988 6.95093,3.99518 6.90198,3.98918 6.85327,3.98079 6.80491,3.97003 6.75702,3.95694 6.70972,3.94154 6.66311,3.92388 6.61732,3.90399 6.57244,3.88192 6.5286,3.85773 6.4859,3.83147 6.44443,3.80321 6.4043,3.77301 6.36561,3.74095 6.32844,3.70711 6.29289,3.67156 6.25905,3.63439 6.22699,3.5957 6.19679,3.55557 6.16853,3.5141 6.14227,3.4714 6.11808,3.42756 6.09601,3.38268 6.07612,3.33689 6.05846,3.29028 6.04306,3.24298 6.02997,3.19509 6.01921,3.14673 6.01082,3.09802 6.00482,3.04907 6.0012,3 6,2 6,1.95093 6.0012,1.90198 6.00482,1.85327 6.01082,1.80491 6.01921,1.75702 6.02997,1.70972 6.04306,1.66311 6.05846,1.61732 6.07612,1.57244 6.09601,1.5286 6.11808,1.4859 6.14227,1.44443 6.16853,1.4043 6.19679,1.36561 6.22699,1.32844 6.25905,1.29289 6.29289,1.25905 6.32844,1.22699 6.36561,1.19679 6.4043,1.16853 6.44443,1.14227 6.4859,1.11808 6.5286,1.09601 6.57244,1.07612 6.61732,1.05846 6.66311,1.04306 6.70972,1.02997 6.75702,1.01921 6.80491,1.01082 6.85327,1.00482 6.90198,1.0012 6.95093,1 7))", diff --git a/test/algorithms/overlay/traverse.cpp b/test/algorithms/overlay/traverse.cpp index cebd8b000..6d588c652 100644 --- a/test/algorithms/overlay/traverse.cpp +++ b/test/algorithms/overlay/traverse.cpp @@ -7,9 +7,10 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE +// #define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE // #define BOOST_GEOMETRY_OVERLAY_NO_THROW // #define TEST_WITH_SVG +// #define HAVE_TTMATH #include #include @@ -633,8 +634,7 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false) 2, 16, case_53[0], case_53[2]); if (test_self_tangencies) { - // The st_st version might generate one ring with area zero, which is OK - test_traverse::apply("54_st_st", 3, 20, case_54[0], case_54[2]); + test_traverse::apply("54_st_st", 2, 20, case_54[0], case_54[2]); test_traverse::apply("54_st_iet", 2, 20, case_54[0], case_54[3]); test_traverse::apply("54_iet_st", 2, 20, case_54[1], case_54[2]); } @@ -786,6 +786,7 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false) // the chance is 50% that the segments are not sorted correctly and the wrong // decision is taken. // Solved now (by sorting on sides in those cases) + if (! is_float_on_non_msvc) { test_traverse::apply("dz_1", 3, 16.887537949472005, dz_1[0], dz_1[1]); @@ -884,8 +885,10 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false) #if defined(_MSC_VER) double const expected = if_typed_tt(3.63794e-17, 0.0); + int expected_count = if_typed_tt(1, 0); #else double const expected = if_typed(2.77555756156289135106e-17, 0.0); + int expected_count = if_typed(1, 0); #endif // Calculate intersection/union of two triangles. Robustness case. @@ -893,7 +896,7 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false) // (which is even not accomplished by SQL Server/PostGIS) std::string const caseid = "ggl_list_20110820_christophe"; test_traverse::apply(caseid, - 1, expected, + expected_count, expected, ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1]); test_traverse::apply(caseid, 1, 67.3550722317627, @@ -905,7 +908,7 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false) buffer_rt_f[0], buffer_rt_f[1]); test_traverse::apply("buffer_rt_f", 1, 0.0002943725152286, - buffer_rt_f[0], buffer_rt_f[1]); + buffer_rt_f[0], buffer_rt_f[1], 0.01); test_traverse::apply("buffer_rt_g", 1, 16.571, diff --git a/test/algorithms/test_difference.hpp b/test/algorithms/test_difference.hpp index fab6fe3d2..1ea583fb8 100644 --- a/test/algorithms/test_difference.hpp +++ b/test/algorithms/test_difference.hpp @@ -38,7 +38,10 @@ #if defined(TEST_WITH_SVG) +# define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER +# define BOOST_GEOMETRY_DEBUG_IDENTIFIER # include +# include #endif @@ -79,7 +82,7 @@ void difference_output(std::string const& caseid, G1 const& g1, G2 const& g2, Ou template void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2, - std::size_t expected_count, std::size_t expected_point_count, + std::size_t expected_count, int expected_point_count, double expected_area, double percentage = 0.0001, bool sym = false) @@ -103,7 +106,7 @@ void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2, it != clip.end(); ++it) { - if (expected_point_count > 0) + if (expected_point_count >= 0) { n += bg::num_points(*it); } @@ -135,15 +138,15 @@ void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2, #if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST) - /*if (expected_point_count > 0) + if (expected_point_count >= 0) { - BOOST_CHECK_MESSAGE(n == expected_point_count, + BOOST_CHECK_MESSAGE(n == std::size_t(expected_point_count), "difference: " << caseid << " #points expected: " << expected_point_count << " detected: " << n << " type: " << string_from_type::name() ); - }*/ + } if (expected_count > 0) { @@ -171,11 +174,11 @@ template void test_one(std::string const& caseid, std::string const& wkt1, std::string const& wkt2, std::size_t expected_count1, - std::size_t expected_point_count1, + int expected_point_count1, double expected_area1, std::size_t expected_count2, - std::size_t expected_point_count2, + int expected_point_count2, double expected_area2, double percentage = 0.0001) @@ -256,7 +259,7 @@ template void test_one_lp(std::string const& caseid, std::string const& wkt1, std::string const& wkt2, std::size_t expected_count, - std::size_t expected_point_count, + int expected_point_count, double expected_length) { G1 g1; @@ -272,25 +275,29 @@ void test_one_lp(std::string const& caseid, typename bg::default_length_result::type length = 0; std::size_t n = 0; + std::size_t piece_count = 0; for (typename std::vector::iterator it = pieces.begin(); it != pieces.end(); ++it) { - if (expected_point_count > 0) + if (expected_point_count >= 0) { n += bg::num_points(*it); } - + piece_count++; length += bg::length(*it); } - BOOST_CHECK_MESSAGE(pieces.size() == expected_count, + BOOST_CHECK_MESSAGE(piece_count == expected_count, "difference: " << caseid << " #outputs expected: " << expected_count << " detected: " << pieces.size() ); - BOOST_CHECK_EQUAL(n, expected_point_count); + if (expected_point_count >= 0) + { + BOOST_CHECK_EQUAL(n, std::size_t(expected_point_count)); + } BOOST_CHECK_CLOSE(length, expected_length, 0.001); diff --git a/test/algorithms/test_for_each.hpp b/test/algorithms/test_for_each.hpp index 40c7d1f45..b93b72de3 100644 --- a/test/algorithms/test_for_each.hpp +++ b/test/algorithms/test_for_each.hpp @@ -11,6 +11,7 @@ #include +#include #include #include @@ -87,9 +88,29 @@ void test_per_point_const(Geometry const& geometry, int expected) { typedef typename bg::point_type::type point_type; + // Class (functor) sum_x_functor functor; functor = bg::for_each_point(geometry, functor); BOOST_CHECK_EQUAL(functor.sum, expected); + + + // Lambda +#if !defined(BOOST_NO_CXX11_LAMBDAS) + + typename bg::coordinate_type::type sum_x = 0; + + bg::for_each_point + ( + geometry, + [&sum_x](point_type const& p) + { + sum_x += bg::get<0>(p); + } + + ); + + BOOST_CHECK_EQUAL(sum_x, expected); +#endif } template @@ -97,6 +118,10 @@ void test_per_point_non_const(Geometry& geometry, std::string const& expected1, std::string const& expected2) { +#if !defined(BOOST_NO_CXX11_LAMBDAS) + Geometry copy = geometry; +#endif + typedef typename bg::point_type::type point_type; // function @@ -119,6 +144,41 @@ void test_per_point_non_const(Geometry& geometry, "for_each_point: " << " expected " << expected2 << " got " << bg::wkt(geometry)); + +#if !defined(BOOST_NO_CXX11_LAMBDAS) + // Lambda, both functions above together. Without / with capturing + + geometry = copy; + bg::for_each_point + ( + geometry, + [](point_type& p) + { + bg::set<0>(p, bg::get<0>(p) + 100); + } + + ); + + typename bg::coordinate_type::type scale = 100; + bg::for_each_point + ( + geometry, + [&](point_type& p) + { + bg::set<1>(p, bg::get<1>(p) * scale); + } + + ); + + std::ostringstream out3; + out3 << bg::wkt(geometry); + + BOOST_CHECK_MESSAGE(out3.str() == expected2, + "for_each_point (lambda): " + << " expected " << expected2 + << " got " << bg::wkt(geometry)); +#endif + } diff --git a/test/algorithms/test_intersects.hpp b/test/algorithms/test_intersects.hpp index 4f9922a76..dac1b1eae 100644 --- a/test/algorithms/test_intersects.hpp +++ b/test/algorithms/test_intersects.hpp @@ -32,12 +32,18 @@ void test_geometry(std::string const& wkt1, bg::read_wkt(wkt2, geometry2); bool detected = bg::intersects(geometry1, geometry2); + bool detected2 = bg::intersects(geometry2, geometry1); BOOST_CHECK_MESSAGE(detected == expected, "intersects: " << wkt1 << " with " << wkt2 << " -> Expected: " << expected << " detected: " << detected); + BOOST_CHECK_MESSAGE(detected2 == expected, + "intersects: " << wkt1 + << " with " << wkt2 + << " -> Expected: " << expected + << " detected: " << detected2); } diff --git a/test/core/point_type.cpp b/test/core/point_type.cpp index a1154295e..3178bcb91 100644 --- a/test/core/point_type.cpp +++ b/test/core/point_type.cpp @@ -14,12 +14,15 @@ #include #include +#include #include #include #include +#include + #include #include @@ -64,9 +67,12 @@ int test_main(int, char* []) test_geometry(); test_geometry, - boost::tuple >(); + boost::tuple >(); test_geometry, - boost::tuple >(); + boost::tuple >(); + + test_geometry > >, + boost::tuple >(); test_all >(); test_all >(); diff --git a/test/geometry_test_common.hpp b/test/geometry_test_common.hpp index 4777a0ab7..689408c77 100644 --- a/test/geometry_test_common.hpp +++ b/test/geometry_test_common.hpp @@ -89,6 +89,9 @@ template <> struct string_from_type template <> struct string_from_type { static std::string name() { return "e"; } }; +template <> struct string_from_type +{ static std::string name() { return "i"; } }; + #if defined(HAVE_TTMATH) template <> struct string_from_type { static std::string name() { return "t"; } }; diff --git a/test/multi/algorithms/Jamfile.v2 b/test/multi/algorithms/Jamfile.v2 index 813d6aafa..624193c21 100644 --- a/test/multi/algorithms/Jamfile.v2 +++ b/test/multi/algorithms/Jamfile.v2 @@ -23,6 +23,7 @@ test-suite boost-geometry-multi-algorithms [ run multi_equals.cpp ] [ run multi_for_each.cpp ] [ run multi_intersection.cpp ] + [ run multi_intersects.cpp ] [ run multi_length.cpp ] [ run multi_num_geometries.cpp ] [ run multi_num_interior_rings.cpp ] diff --git a/test/multi/algorithms/multi_difference.cpp b/test/multi/algorithms/multi_difference.cpp index e5e47bc5c..893d3009b 100644 --- a/test/multi/algorithms/multi_difference.cpp +++ b/test/multi/algorithms/multi_difference.cpp @@ -10,7 +10,8 @@ #include #include -// #define BOOST_GEOMETRY_DEBUG_ASSEMBLE +//#define HAVE_TTMATH +//#define BOOST_GEOMETRY_DEBUG_ASSEMBLE //#define BOOST_GEOMETRY_CHECK_WITH_SQLSERVER //#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER @@ -38,7 +39,7 @@ void test_areal() { test_one("simplex_multi", case_multi_simplex[0], case_multi_simplex[1], - 5, 12, 5.58, 4, 12, 2.58); + 5, 21, 5.58, 4, 17, 2.58); test_one("case_multi_no_ip", case_multi_no_ip[0], case_multi_no_ip[1], @@ -49,13 +50,13 @@ void test_areal() test_one("simplex_multi_mp_p", case_multi_simplex[0], case_single_simplex, - 5, 22, 5.58, 4, 17, 2.58); + 5, 21, 5.58, 4, 17, 2.58); test_one("simplex_multi_r_mp", case_single_simplex, case_multi_simplex[0], - 4, 17, 2.58, 5, 22, 5.58); + 4, 17, 2.58, 5, 21, 5.58); test_one("simplex_multi_mp_r", case_multi_simplex[0], case_single_simplex, - 5, 22, 5.58, 4, 17, 2.58); + 5, 21, 5.58, 4, 17, 2.58); // Constructed cases for multi/touch/equal/etc test_one("case_61_multi", @@ -69,7 +70,7 @@ void test_areal() 0, 0, 0, 1, 5, 1); test_one("case_64_multi", case_64_multi[0], case_64_multi[1], - 1, 1, 1, 1, 1, 1); + 1, 5, 1, 1, 5, 1); test_one("case_65_multi", case_65_multi[0], case_65_multi[1], 0, 0, 0, 2, 10, 3); @@ -84,22 +85,22 @@ void test_areal() test_one("case_78_multi", case_78_multi[0], case_78_multi[1], - 1, 1, 1.0, 1, 1, 1.0); + 1, 5, 1.0, 1, 5, 1.0); // Ticket on GGL list 2011/10/25 // to mix polygon/multipolygon in call to difference test_one("ggl_list_20111025_vd_pp", ggl_list_20111025_vd[0], ggl_list_20111025_vd[1], - 1, -999, 8.0, 1, -999, 12.5); + 1, 4, 8.0, 1, 4, 12.5); test_one("ggl_list_20111025_vd_pm", ggl_list_20111025_vd[0], ggl_list_20111025_vd[3], - 1, -999, 8.0, 1, -999, 12.5); + 1, 4, 8.0, 1, 4, 12.5); test_one("ggl_list_20111025_vd_mp", ggl_list_20111025_vd[2], ggl_list_20111025_vd[1], - 1, -999, 8.0, 1, -999, 12.5); + 1, 4, 8.0, 1, 4, 12.5); test_one("ggl_list_20111025_vd_mm", ggl_list_20111025_vd[2], ggl_list_20111025_vd[3], - 1, -999, 8.0, 1, -999, 12.5); + 1, 4, 8.0, 1, 4, 12.5); // Second case // This can be tested with this SQL for SQL-Server @@ -120,7 +121,19 @@ void test_areal() test_one("ggl_list_20111025_vd_2", ggl_list_20111025_vd_2[0], ggl_list_20111025_vd_2[1], - 1, -999, 10.0, 2, -999, 6.0); + 1, 7, 10.0, 2, 10, 6.0); + + test_one("ggl_list_20120915_h2_a", + ggl_list_20120915_h2[0], ggl_list_20120915_h2[1], + 2, 13, 17.0, 0, 0, 0.0); + test_one("ggl_list_20120915_h2_b", + ggl_list_20120915_h2[0], ggl_list_20120915_h2[2], + 2, 13, 17.0, 0, 0, 0.0); + + test_one("ggl_list_20120221_volker", + ggl_list_20120221_volker[0], ggl_list_20120221_volker[1], + 2, 12, 7962.66, 1, 18, 2775258.93, + 0.001); /* TODO: fix diff --git a/test/multi/algorithms/multi_disjoint.cpp b/test/multi/algorithms/multi_disjoint.cpp index a1b88ce21..9d374f7c7 100644 --- a/test/multi/algorithms/multi_disjoint.cpp +++ b/test/multi/algorithms/multi_disjoint.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,39 @@ void test_all() "MULTIPOLYGON(((2 12,2 18,8 18,8 12,2 12)),((22 2,28 2,28 8,22 8,22 2)))", "MULTIPOLYGON(((2 2,2 8,8 8,8 2,2 2)),((20 0,20 10,30 10,30 0,20 0)))", false); + + + test_disjoint("point_mp1", + "POINT(0 0)", + "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", + false); + + test_disjoint("point_mp2", + "POINT(5 5)", + "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", + false); + + test_disjoint("point_mp1", + "POINT(11 11)", + "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", + true); + + std::string polygon_inside_hole("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0), (2 2,8 2,8 8,2 8,2 2)),((4 4,4 6,6 6,6 4,4 4)))"); + test_disjoint("point_mp_pih1", + "POINT(5 5)", + polygon_inside_hole, + false); + + test_disjoint("point_mp_pih2", + "POINT(3 3)", + polygon_inside_hole, + true); + + test_disjoint("point_mp1rev", + "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", + "POINT(0 0)", + false); + } int test_main(int, char* []) diff --git a/test/multi/algorithms/multi_intersection.cpp b/test/multi/algorithms/multi_intersection.cpp index d479f5d11..fc94811f8 100644 --- a/test/multi/algorithms/multi_intersection.cpp +++ b/test/multi/algorithms/multi_intersection.cpp @@ -100,6 +100,13 @@ void test_areal() test_one("case_recursive_boxes_4", case_recursive_boxes_4[0], case_recursive_boxes_4[1], 13, 157, 67.0); // Area from SQL Server + + test_one("ggl_list_20120915_h2_a", + ggl_list_20120915_h2[0], ggl_list_20120915_h2[1], + 2, 10, 6.0); // Area from SQL Server + test_one("ggl_list_20120915_h2_b", + ggl_list_20120915_h2[0], ggl_list_20120915_h2[2], + 2, 10, 6.0); // Area from SQL Server } template diff --git a/test/multi/algorithms/multi_intersects.cpp b/test/multi/algorithms/multi_intersects.cpp new file mode 100644 index 000000000..d07b8b6cf --- /dev/null +++ b/test/multi/algorithms/multi_intersects.cpp @@ -0,0 +1,51 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + + +#include + +#include + +#include + +#include +#include +#include + +template +void test_all() +{ + typedef bg::model::polygon

polygon; + typedef bg::model::multi_polygon mp; + + test_geometry("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", + "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", + true); + + test_geometry("POINT(0 0)", + "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", + true); + +} + +int test_main(int, char* []) +{ + //test_all >(); + test_all >(); + +#ifdef HAVE_TTMATH + test_all >(); +#endif + + return 0; +} + diff --git a/test/multi/algorithms/multi_union.cpp b/test/multi/algorithms/multi_union.cpp index ffa694291..5cbe1e7a7 100644 --- a/test/multi/algorithms/multi_union.cpp +++ b/test/multi/algorithms/multi_union.cpp @@ -106,6 +106,13 @@ void test_areal() test_one("case_recursive_boxes_3", case_recursive_boxes_3[0], case_recursive_boxes_3[1], 17, 0, 159, 56.5); // Area from SQL Server + + test_one("ggl_list_20120915_h2_a", + ggl_list_20120915_h2[0], ggl_list_20120915_h2[1], + 1, 0, 12, 23.0); // Area from SQL Server + test_one("ggl_list_20120915_h2_b", + ggl_list_20120915_h2[0], ggl_list_20120915_h2[2], + 1, 0, 12, 23.0); // Area from SQL Server } template diff --git a/test/multi/algorithms/overlay/multi_overlay_cases.hpp b/test/multi/algorithms/overlay/multi_overlay_cases.hpp index 536aa0953..0ddd3a0a7 100644 --- a/test/multi/algorithms/overlay/multi_overlay_cases.hpp +++ b/test/multi/algorithms/overlay/multi_overlay_cases.hpp @@ -426,6 +426,21 @@ static std::string ggl_list_20111025_vd_2[2] = "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((4 0,4 2,6 2,6 0,4 0)))" }; +// Mail of h2 indicating that reversed order (in second polygon) has ix/ix problems +static std::string ggl_list_20120915_h2[3] = + { + "MULTIPOLYGON(((-2 5, -1 5, 0 5, 2 5, 2 -2, 1 -2, 1 -1, 0 -1,0 0, -1 0, -2 0, -2 5)))", + "MULTIPOLYGON(((0 0, 1 0, 1 -1, 0 -1, 0 0)), ((-1 5, 0 5, 0 0, -1 0, -1 5)))", + "MULTIPOLYGON(((-1 5, 0 5, 0 0, -1 0, -1 5)), ((0 0, 1 0, 1 -1, 0 -1, 0 0)))" + }; + +// Mail of volker, about another problem, but this specific example is causing two-point inner rings polygons which should be discarded +// (condition of num_points in detail/overlay/convert_ring.hpp) +static std::string ggl_list_20120221_volker[2] = + { + "MULTIPOLYGON(((1032 2130,1032 1764,2052 2712,1032 2130)),((3234 2580,2558 2690,3234 2532,3234 2580)),((2558 2690,2136 2790,2052 2712,2136 2760,2558 2690)))", + "MULTIPOLYGON(((3232 2532.469945355191,2136 2790,1032 1764,1032 1458,1032 1212,2136 2328,3232 2220.196721311475,3232 1056,1031 1056,1031 2856,3232 2856,3232 2532.469945355191),(3232 2412.426229508197,2136 2646,3232 2412.426229508197)))" + }; #endif // BOOST_GEOMETRY_TEST_MULTI_OVERLAY_CASES_HPP diff --git a/test/multi/algorithms/overlay/multi_traverse.cpp b/test/multi/algorithms/overlay/multi_traverse.cpp index f731f73cb..faacd3615 100644 --- a/test/multi/algorithms/overlay/multi_traverse.cpp +++ b/test/multi/algorithms/overlay/multi_traverse.cpp @@ -386,7 +386,7 @@ void test_geometries() test_traverse_union::apply ( - "case_recursive_boxes_3", 8, 49.5, + "case_recursive_boxes_3", 7, 49.5, case_recursive_boxes_3[0], case_recursive_boxes_3[1] );