diff --git a/doc/reference/status/convert_status.qbk b/doc/reference/status/convert_status.qbk index aacf812a4c..0a0fa38b73 100644 --- a/doc/reference/status/convert_status.qbk +++ b/doc/reference/status/convert_status.qbk @@ -4,10 +4,10 @@ [[Point][ [$img/ok.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/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] [[Box][ [$img/ok.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/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] +[[Linestring][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] [[Ring][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] [[Polygon][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] -[[MultiPoint][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ]] -[[MultiLinestring][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ]] -[[MultiPolygon][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ]] +[[MultiPoint][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[MultiLinestring][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ]] +[[MultiPolygon][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/ok.png] ][ [$img/ok.png] ][ [$img/nyi.png] ][ [$img/nyi.png] ][ [$img/ok.png] ]]] ] diff --git a/include/boost/geometry/algorithms/convert.hpp b/include/boost/geometry/algorithms/convert.hpp index d9cb61e843..41d8d3b886 100644 --- a/include/boost/geometry/algorithms/convert.hpp +++ b/include/boost/geometry/algorithms/convert.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2007-2025 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2014-2024 Adam Wulkiewicz, Lodz, Poland. @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -102,9 +103,10 @@ struct point_to_box {} }; -template +template struct box_to_range { + template static inline void apply(Box const& box, Range& range) { traits::resize::apply(range, Close ? 5 : 4); @@ -131,12 +133,6 @@ struct segment_to_range } }; -template -< - typename Range1, - typename Range2, - bool Reverse = false -> struct range_to_range { struct default_policy @@ -148,22 +144,25 @@ struct range_to_range } }; + template static inline void apply(Range1 const& source, Range2& destination) { apply(source, destination, default_policy()); } - template + template static inline ConvertPointPolicy apply(Range1 const& source, Range2& destination, ConvertPointPolicy convert_point) { geometry::clear(destination); + constexpr bool reverse = geometry::point_order::value != geometry::point_order::value; + using view_type = detail::closed_clockwise_view < Range1 const, geometry::closure::value, - Reverse ? counterclockwise : clockwise + reverse ? counterclockwise : clockwise >; // We consider input always as closed, and skip last @@ -193,21 +192,27 @@ struct range_to_range } }; +// Converts a polygon to an output iterator of ranges. +// The iterator is updated such that it can used iteratively. +struct polygon_to_multi_range +{ + template + static inline void apply(Polygon const& source, OutputIterator& it) + { + range_to_range::apply(geometry::exterior_ring(source), *it++); + for (auto const& ring : geometry::interior_rings(source)) + { + range_to_range::apply(ring, *it++); + } + } +}; + template struct polygon_to_polygon { - using per_ring = range_to_range - < - geometry::ring_type_t, - geometry::ring_type_t, - geometry::point_order::value != geometry::point_order::value - >; - static inline void apply(Polygon1 const& source, Polygon2& destination) { - // Clearing managed per ring, and in the resizing of interior rings - - per_ring::apply(geometry::exterior_ring(source), + range_to_range::apply(geometry::exterior_ring(source), geometry::exterior_ring(destination)); // Container should be resizeable @@ -227,25 +232,80 @@ struct polygon_to_polygon for ( ; it_source != boost::end(rings_source); ++it_source, ++it_dest) { - per_ring::apply(*it_source, *it_dest); + range_to_range::apply(*it_source, *it_dest); } } }; -template -struct single_to_multi: private Policy +struct range_to_multi_point +{ + template + static inline void append_from_source(Range const& source, Iterator& it) + { + for (auto const& point : source) + { + detail::conversion::convert_point_to_point(point, *it); + ++it; + } + } + + template + static inline void apply(Range const& source, MultiPoint& destination) + { + traits::resize::apply(destination, boost::size(source)); + auto it = boost::begin(destination); + append_from_source(source, it); + } +}; + +struct polygon_to_range +{ + template + static inline void append_from_polygon(Polygon const& source, Iterator& it) + { + range_to_multi_point::append_from_source(geometry::exterior_ring(source), it); + for (auto const& ring : geometry::interior_rings(source)) + { + range_to_multi_point::append_from_source(ring, it); + } + } + + template + static inline void apply(Polygon const& source, MultiPoint& destination) + { + traits::resize::apply(destination, geometry::num_points(source)); + auto it = boost::begin(destination); + append_from_polygon(source, it); + } +}; + +struct multi_polygon_to_range +{ + template + static inline void apply(MultiPolygon const& source, MultiPoint& destination) + { + traits::resize::apply(destination, geometry::num_points(source)); + auto it = boost::begin(destination); + for (auto const& polygon : source) + { + polygon_to_range::append_from_polygon(polygon, it); + } + } +}; + +template +struct single_to_multi { static inline void apply(Single const& single, Multi& multi) { traits::resize::apply(multi, 1); - Policy::apply(single, *boost::begin(multi)); + ConversionAlgorithm::apply(single, *boost::begin(multi)); } }; - -template -struct multi_to_multi: private Policy +template +struct multi_to_multi { static inline void apply(Multi1 const& multi1, Multi2& multi2) { @@ -256,7 +316,7 @@ struct multi_to_multi: private Policy for (; it1 != boost::end(multi1); ++it1, ++it2) { - Policy::apply(*it1, *it2); + ConversionAlgorithm::apply(*it1, *it2); } } }; @@ -277,8 +337,8 @@ namespace dispatch template < typename Geometry1, typename Geometry2, - typename Tag1 = tag_cast_t, multi_tag>, - typename Tag2 = tag_cast_t, multi_tag>, + typename Tag1 = tag_t, + typename Tag2 = tag_t, std::size_t DimensionCount = dimension::value, bool UseAssignment = std::is_same::value && !std::is_array::value @@ -300,7 +360,7 @@ template > struct convert { - // Same geometry type -> copy whole geometry + // Same geometry type -> copy geometry static inline void apply(Geometry1 const& source, Geometry2& destination) { destination = source; @@ -308,31 +368,19 @@ struct convert }; -template -< - typename Geometry1, typename Geometry2, - std::size_t DimensionCount -> +template struct convert : detail::conversion::point_to_point {}; -template -< - typename Box1, typename Box2, - std::size_t DimensionCount -> +template struct convert : detail::conversion::indexed_to_indexed {}; -template -< - typename Segment1, typename Segment2, - std::size_t DimensionCount -> +template struct convert : detail::conversion::indexed_to_indexed {}; @@ -347,16 +395,11 @@ struct convert struct convert : detail::conversion::range_to_range - < - Ring1, - Ring2, - geometry::point_order::value != geometry::point_order::value - > {}; template struct convert - : detail::conversion::range_to_range + : detail::conversion::range_to_range {}; template @@ -364,17 +407,25 @@ struct convert {}; +template +struct convert + : detail::conversion::box_to_range +{}; + template struct convert : detail::conversion::box_to_range < - Box, - Ring, geometry::closure::value == closed, geometry::point_order::value == counterclockwise > {}; +template +struct convert + : detail::conversion::box_to_range +{}; + template struct convert @@ -422,7 +473,7 @@ struct convert } }; - +// Polygon to ring, this ignores interior rings template struct convert { @@ -437,31 +488,79 @@ struct convert } }; +template +struct convert + : detail::conversion::range_to_multi_point {}; -// Dispatch for multi <-> multi, specifying their single-version as policy. -// Note that, even if the multi-types are mutually different, their single -// version types might be the same and therefore we call std::is_same again +template +struct convert + : detail::conversion::range_to_multi_point {}; -template -struct convert - : detail::conversion::multi_to_multi - < - Multi1, - Multi2, - convert - < - typename boost::range_value::type, - typename boost::range_value::type, - single_tag_of_t>, - single_tag_of_t>, - DimensionCount - > - > -{}; +template +struct convert + : detail::conversion::polygon_to_range {}; + template +struct convert + : detail::conversion::multi_polygon_to_range {}; -template -struct convert +template +struct convert +{ + static inline void apply(MultiLineString const& source, MultiPoint& destination) + { + traits::resize::apply(destination, geometry::num_points(source)); + auto it = boost::begin(destination); + for (auto const& linestring : source) + { + detail::conversion::range_to_multi_point::append_from_source(linestring, it); + } + } +}; + +template +struct convert +{ + static inline void apply(Ring const& source, MultiLinestring& destination) + { + traits::resize::apply(destination, 1); + detail::conversion::range_to_range::apply(source, *boost::begin(destination)); + } +}; + +template +struct convert +{ + static inline void apply(Polygon const& source, MultiLinestring& destination) + { + traits::resize::apply(destination, 1 + geometry::num_interior_rings(source)); + auto it = boost::begin(destination); + detail::conversion::polygon_to_multi_range::apply(source, it); + } +}; + +template +struct convert +{ + static inline void apply(MultiPolygon const& source, MultiLinestring& destination) + { + std::size_t ring_count = boost::size(source); + for (auto const& polygon : source) + { + ring_count += geometry::num_interior_rings(polygon); + } + traits::resize::apply(destination, ring_count); + + auto it = boost::begin(destination); + for (auto const& polygon : source) + { + detail::conversion::polygon_to_multi_range::apply(polygon, it); + } + } +}; + +template +struct single_to_multi_convert : detail::conversion::single_to_multi < Single, @@ -478,6 +577,62 @@ struct convert > {}; +template +struct multi_to_multi_convert + : detail::conversion::multi_to_multi + < + Multi1, + Multi2, + convert + < + typename boost::range_value::type, + typename boost::range_value::type, + single_tag_of_t>, + single_tag_of_t>, + DimensionCount + > + > +{}; + +// Multi to multi of the same tag type +template +struct convert + : multi_to_multi_convert {}; + +template +struct convert + : multi_to_multi_convert {}; + +template +struct convert + : multi_to_multi_convert {}; + +// Single to multi of the same topological tag type +template +struct convert + : single_to_multi_convert {}; + +template +struct convert + : single_to_multi_convert {}; + +template +struct convert + : single_to_multi_convert {}; + +// To multi_polygon (box, ring, polygon) +template +struct convert + : single_to_multi_convert {}; + +template +struct convert + : single_to_multi_convert {}; + +template +struct convert + : single_to_multi_convert {}; + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/srs/projection.hpp b/include/boost/geometry/srs/projection.hpp index f4ebd41f88..6c3fd37801 100644 --- a/include/boost/geometry/srs/projection.hpp +++ b/include/boost/geometry/srs/projection.hpp @@ -157,11 +157,8 @@ struct project_range template static inline bool apply(R1 const& r1, R2 & r2, Proj const& proj) { - return geometry::detail::conversion::range_to_range - < - R1, R2, - geometry::point_order::value != geometry::point_order::value - >::apply(r1, r2, convert_policy(proj)).result(); + return geometry::detail::conversion::range_to_range::apply(r1, r2, + convert_policy(proj)).result(); } }; diff --git a/include/boost/geometry/srs/transformation.hpp b/include/boost/geometry/srs/transformation.hpp index fc2e30c8bd..64f9873c57 100644 --- a/include/boost/geometry/srs/transformation.hpp +++ b/include/boost/geometry/srs/transformation.hpp @@ -140,12 +140,8 @@ struct transform_geometry_range_base // Out - either Geometry or std::vector // So the order and closure of In and Geometry shoudl be compared // std::vector's order is assumed to be the same as of Geometry - geometry::detail::conversion::range_to_range - < - In, - Out, - geometry::point_order::value != geometry::point_order::value - >::apply(in, out, convert_strategy(enable_angles)); + geometry::detail::conversion::range_to_range::apply(in, out, + convert_strategy(enable_angles)); } }; diff --git a/test/algorithms/CMakeLists.txt b/test/algorithms/CMakeLists.txt index c8a84356ae..e1818d383a 100644 --- a/test/algorithms/CMakeLists.txt +++ b/test/algorithms/CMakeLists.txt @@ -34,7 +34,6 @@ foreach(item IN ITEMS centroid_multi comparable_distance convert - convert_multi correct correct_multi correct_closure diff --git a/test/algorithms/Jamfile b/test/algorithms/Jamfile index a94b0fbd5d..e843264f51 100644 --- a/test/algorithms/Jamfile +++ b/test/algorithms/Jamfile @@ -25,7 +25,6 @@ test-suite boost-geometry-algorithms [ run centroid_multi.cpp : : : : algorithms_centroid_multi ] [ run comparable_distance.cpp : : : : algorithms_comparable_distance ] [ run convert.cpp : : : : algorithms_convert ] - [ run convert_multi.cpp : : : : algorithms_convert_multi ] [ run correct.cpp : : : : algorithms_correct ] [ run correct_multi.cpp : : : : algorithms_correct_multi ] [ run correct_closure.cpp : : : : algorithms_correct_closure ] diff --git a/test/algorithms/convert.cpp b/test/algorithms/convert.cpp index e565c0b672..c2a1379761 100644 --- a/test/algorithms/convert.cpp +++ b/test/algorithms/convert.cpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2007-2025 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. @@ -22,145 +22,190 @@ template -void test_mixed_point_types() +void test_mixed_orientation_and_closure() { - // Point - check("POINT(1 2)"); - - // Box - check, bg::model::box>("POLYGON((1 2,1 4,3 4,3 2,1 2))"); - - // Segment - check, bg::model::segment>("LINESTRING(1 1,2 2)"); - - // Linestring - check, bg::model::linestring>("LINESTRING(1 1,2 2)"); + namespace model = boost::geometry::model; - // Ring - check, bg::model::ring>( + // Ring, (counter)clockwise, closed/open + check, model::ring>( "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,2 2,3 0,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,3 0,2 2,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,2 2,3 0))", 3); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,3 0,2 2))", 3); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,2 2,3 0,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,3 0,2 2,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,2 2,3 0))", 3); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,3 0,2 2))", 3); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,2 2,3 0,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,3 0,2 2,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,2 2,3 0))", 3); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,3 0,2 2))", 3); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,2 2,3 0,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,3 0,2 2,1 1))", 4); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,2 2,3 0))", 3); - check, bg::model::ring>( + check, model::ring>( "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,3 0,2 2))", 3); - // Polygon - check, bg::model::polygon>( + // Polygon (using ring underneath, so most combinations can be omitted) + check, model::polygon>( "POLYGON((0 0,0 5,5 5,5 0,0 0),(1 1,3 2,2 4,1 1))", "POLYGON((0 0,5 0,5 5,0 5,0 0),(1 1,2 4,3 2,1 1))"); - check, bg::model::polygon>( + check, model::polygon>( "POLYGON((0 0,0 5,5 5,5 0,0 0),(1 1,3 2,2 4,1 1))", "POLYGON((0 0,5 0,5 5,0 5,0 0),(1 1,2 4,3 2,1 1))", - 7); // WKT is closed, polygon is open - // (polygon uses ring, so other tests omitted here) + 7); - // Combinations: - // ring <-> polygon - check, bg::model::ring>( - "POLYGON((1 1,2 2,3 0,1 1))"); + check, model::ring>("POLYGON((1 1,2 2,3 0,1 1))", + "POLYGON((1 1,3 0,2 2,1 1))"); - check, bg::model::ring>( - "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,3 0,2 2,1 1))"); + using box1_t = model::box; - // Any hole will be omitted going from polygon to ring - check, bg::model::ring>( - "POLYGON((0 0,0 5,5 5,5 0,0 0),(1 1,3 2,2 4,1 1))", - "POLYGON((0 0,0 5,5 5,5 0,0 0))", - 5); - - // point -> box - check>( - "POINT(0 0)", "POLYGON((0 0,0 0,0 0,0 0,0 0))", 4); - - // segment -> line - check, bg::model::linestring>( - "LINESTRING(0 0,1 1)", "LINESTRING(0 0,1 1)", 2); - - // box -> ring ( <- is NYI) - check, bg::model::ring>( - "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", 5); - - check, bg::model::ring>( - "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2,0 0))", 5); - - check, bg::model::ring>( - "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0))", 4); - - check, bg::model::ring>( - "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2))", 4); - - // box -> polygon ( <- is NYI) - check, bg::model::polygon>( - "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", 5); - check, bg::model::polygon>( - "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2,0 0))", 5); - check, bg::model::polygon>( - "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", - 4); // WKT is closed, polygon is open - - check, bg::model::polygon>( - "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2,0 0))", - 4); // WKT is closed, polygon is open + check>("BOX(0 0,2 2)", + "POLYGON((0 0,2 0,2 2,0 2,0 0))", 5); + + check>("BOX(0 0,2 2)", + "POLYGON((0 0,0 2,2 2,2 0))", 4); + + check>("BOX(0 0,2 2)", + "POLYGON((0 0,2 0,2 2,0 2))", 4); + + check>("BOX(0 0,2 2)", + "POLYGON((0 0,2 0,2 2,0 2,0 0))", 5); + check>("BOX(0 0,2 2)", + "POLYGON((0 0,0 2,2 2,2 0,0 0))", 4); + check>("BOX(0 0,2 2)", + "POLYGON((0 0,2 0,2 2,0 2,0 0))", 4); +} + +template +void test_mixed_point_types() +{ + namespace model = boost::geometry::model; + + const std::string point_simplex = "POINT(0 0)"; + const std::string ls_simplex = "LINESTRING(1 1,2 2)"; + const std::string mls_simplex = "MULTILINESTRING((1 1,2 2),(3 3,4 4))"; + const std::string mpoint_simplex = "MULTIPOINT((1 1),(2 2))"; + + const std::string box_simplex = "BOX(0 0,1 1)"; + const std::string ring_simplex = "POLYGON((0 0,0 1,1 1,1 0,0 0))"; + const std::string poly_simplex = "POLYGON((0 0,0 5,5 5,5 0,0 0),(2 2,3 2,3 3,2 2))"; + const std::string mpoly_simplex = "MULTIPOLYGON(" + "((0 0,0 5,5 5,5 0,0 0),(2 2,3 2,3 3,2 2))," + "((6 6,6 7,7 7,7 6,6 6))" + ")"; + + using segment1_t = model::segment; + using segment2_t = model::segment; + using ls1_t = model::linestring; + using ls2_t = model::linestring; + + using box1_t = model::box; + using box2_t = model::box; + using ring1_t = model::ring; + using ring2_t = model::ring; + using poly1_t = model::polygon; + using poly2_t = model::polygon; + + using mpoint1_t = model::multi_point; + using mpoint2_t = model::multi_point; + using mls1_t = model::multi_linestring; + using mls2_t = model::multi_linestring; + using mpoly1_t = model::multi_polygon; + using mpoly2_t = model::multi_polygon; + + check(point_simplex); + check(ring_simplex); + check(ls_simplex); + check(ls_simplex); + check(ring_simplex); + check(poly_simplex); + check(mpoint_simplex); + check(mls_simplex); + check(mpoly_simplex); + + check(point_simplex, "POLYGON((0 0,0 0,0 0,0 0,0 0))"); + check(ls_simplex); + check(box_simplex, "LINESTRING(0 0,0 1,1 1,1 0,0 0)"); + check(box_simplex, ring_simplex); + check(box_simplex, ring_simplex); + + check(ring_simplex); + check(ring_simplex); + + // Interior rings are omitted going from polygon to ring + check(poly_simplex, "POLYGON((0 0,0 5,5 5,5 0,0 0))"); + + // single -> multi + check(point_simplex, "MULTIPOINT((0 0))"); + check(ls_simplex, "MULTILINESTRING((1 1,2 2))"); + check(ls_simplex, "MULTILINESTRING((1 1,2 2))"); + + check(ls_simplex, "MULTIPOINT((1 1),(2 2))"); + check(box_simplex, "MULTIPOINT((0 0),(0 1),(1 1),(1 0))"); + check(ring_simplex, "MULTIPOINT((0 0),(0 1),(1 1),(1 0),(0 0))"); + check(ring_simplex, "MULTIPOINT((0 0),(0 1),(1 1),(1 0),(0 0))"); + check(mls_simplex, "MULTIPOINT((1 1),(2 2),(3 3),(4 4))"); + check(mpoly_simplex, + "MULTIPOINT((0 0),(0 5),(5 5),(5 0),(0 0),(2 2),(3 2),(3 3),(2 2),(6 6),(6 7),(7 7),(7 6),(6 6))"); + + check(ring_simplex, "MULTILINESTRING((0 0,0 1,1 1,1 0,0 0))"); + check(ring_simplex, "MULTILINESTRING((0 0,0 1,1 1,1 0,0 0))"); + check(poly_simplex, + "MULTILINESTRING((0 0,0 5,5 5,5 0,0 0),(2 2,3 2,3 3,2 2))"); + check(mpoly_simplex, + "MULTILINESTRING((0 0,0 5,5 5,5 0,0 0),(2 2,3 2,3 3,2 2),(6 6,6 7,7 7,7 6,6 6))"); + + check(box_simplex, "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))"); + check(ring_simplex, "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))"); + check(ring_simplex, "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))"); + check(poly_simplex, + "MULTIPOLYGON(((0 0,0 5,5 5,5 0,0 0),(2 2,3 2,3 3,2 2)))"); } template void test_mixed_point_types_3d() { - // Point + namespace model = boost::geometry::model; check("POINT(1 2 3)"); - check, bg::model::segment>( + check, model::segment>( "LINESTRING(1 2 3,4 5 6)"); - // Linestring - check, bg::model::linestring>( + check, model::linestring>( "LINESTRING(1 2 3,4 5 6,7 8 9)"); - // segment -> line - check, bg::model::linestring>( + check, model::linestring>( "LINESTRING(1 2 3,4 5 6)", "LINESTRING(1 2 3,4 5 6)", 2); } - - template void test_mixed_types() { test_mixed_point_types(); test_mixed_point_types(); + test_mixed_orientation_and_closure(); + test_mixed_orientation_and_closure(); } - template void test_mixed_types_3d() { diff --git a/test/algorithms/convert_multi.cpp b/test/algorithms/convert_multi.cpp deleted file mode 100644 index 67089e6586..0000000000 --- a/test/algorithms/convert_multi.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. - -// This file was modified by Oracle on 2021. -// Modifications copyright (c) 2021, Oracle and/or its affiliates. -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - -// 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 - - -template -void test_mixed_point_types() -{ - check, bg::model::multi_point>( - "MULTIPOINT((1 1),(2 2),(3 3))"); - - check - < - bg::model::multi_linestring >, - bg::model::multi_linestring > - >("MULTILINESTRING((1 1,2 2),(3 3,4 4))"); - - // Single -> multi (always possible) - check>( - "POINT(1 1)", "MULTIPOINT((1 1))", 1); - - check - < - bg::model::linestring, - bg::model::multi_linestring > - >("LINESTRING(1 1,2 2)", "MULTILINESTRING((1 1,2 2))", 2); - - check - < - bg::model::segment, - bg::model::multi_linestring > - >("LINESTRING(1 1,2 2)", "MULTILINESTRING((1 1,2 2))", 2); - - check - < - bg::model::box, - bg::model::multi_polygon > - >("BOX(0 0,1 1)", "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))", 5); - - check - < - bg::model::ring, - bg::model::multi_polygon > - >("POLYGON((0 0,0 1,1 1,1 0,0 0))", "MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))", 5); - - check - < - bg::model::ring, - bg::model::multi_polygon > - >("POLYGON((0 0,1 0,1 1,0 1))", "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))", 5); - - // Multi -> single: should not compile (because multi often have 0 or >1 elements) -} - -template -void test_mixed_types() -{ - test_mixed_point_types(); - test_mixed_point_types(); -} - -int test_main( int , char* [] ) -{ - test_mixed_types - < - bg::model::point, - bg::model::point - >(); - - return 0; -}