Rename detail::normalized_view to detail::reverse_close_view.

Add detail::close_reverse_view performing closing and reversing in a
different order.

Use these views in algorithms.

Use different order of views in convert to preserve the starting point
of the original range.
This commit is contained in:
Adam Wulkiewicz 2021-06-06 16:38:30 +02:00
parent a9e5f267c3
commit d2434eeead
15 changed files with 245 additions and 435 deletions

View File

@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017-2020. // This file was modified by Oracle on 2017-2021.
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. // Modifications copyright (c) 2017-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@ -41,8 +41,7 @@
#include <boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp> #include <boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp> #include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/views/closeable_view.hpp> #include <boost/geometry/views/detail/normalized_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
@ -144,17 +143,6 @@ template
> >
struct range_to_range struct range_to_range
{ {
typedef typename reversible_view
<
Range1 const,
Reverse ? iterate_reverse : iterate_forward
>::type rview_type;
typedef typename closeable_view
<
rview_type const,
geometry::closure<Range1>::value
>::type view_type;
struct default_policy struct default_policy
{ {
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
@ -175,11 +163,16 @@ struct range_to_range
{ {
geometry::clear(destination); geometry::clear(destination);
rview_type rview(source); using view_type = detail::close_reverse_view
<
Range1 const,
geometry::closure<Range1>::value,
Reverse ? iterate_reverse : iterate_forward
>;
// We consider input always as closed, and skip last // We consider input always as closed, and skip last
// point for open output. // point for open output.
view_type view(rview); view_type const view(source);
typedef typename boost::range_size<Range1>::type size_type; typedef typename boost::range_size<Range1>::type size_type;
size_type n = boost::size(view); size_type n = boost::size(view);

View File

@ -537,7 +537,7 @@ struct buffer_inserter_ring
if (n >= min_points) if (n >= min_points)
{ {
detail::normalized_view<RingInput const> view(simplified); detail::reverse_close_view<RingInput const> view(simplified);
if (distance.negative()) if (distance.negative())
{ {
// Walk backwards (rings will be reversed afterwards) // Walk backwards (rings will be reversed afterwards)

View File

@ -702,7 +702,7 @@ struct buffered_piece_collection
// GeometryOut type, which might differ from the input ring type) // GeometryOut type, which might differ from the input ring type)
clockwise_ring_type clockwise_ring; clockwise_ring_type clockwise_ring;
typedef detail::normalized_view<InputRing const> view_type; using view_type = detail::reverse_close_view<InputRing const>;
view_type const view(input_ring); view_type const view(input_ring);
for (typename boost::range_iterator<view_type const>::type it = for (typename boost::range_iterator<view_type const>::type it =

View File

@ -5,9 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017, 2019. // This file was modified by Oracle on 2017-2021.
// Modifications copyright (c) 2017, 2019 Oracle and/or its affiliates. // Modifications copyright (c) 2017-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@ -327,17 +326,13 @@ struct range_collect_vectors
static inline void apply(Collection& collection, Range const& range) static inline void apply(Collection& collection, Range const& range)
{ {
typedef geometry::detail::normalized_view apply_impl(collection,
< detail::reverse_close_view<Range const>(range));
Range const
> normalized_range_type;
apply_impl(collection, normalized_range_type(range));
} }
private: private:
template <typename NormalizedRange> template <typename RevClRange>
static inline void apply_impl(Collection& collection, NormalizedRange const& range) static inline void apply_impl(Collection& collection, RevClRange const& range)
{ {
if (boost::size(range) < 2) if (boost::size(range) < 2)
{ {
@ -347,14 +342,12 @@ private:
typedef typename boost::range_size<Collection>::type collection_size_t; typedef typename boost::range_size<Collection>::type collection_size_t;
collection_size_t c_old_size = boost::size(collection); collection_size_t c_old_size = boost::size(collection);
typedef typename boost::range_iterator<NormalizedRange const>::type iterator; typedef typename boost::range_iterator<RevClRange const>::type iterator;
bool is_first = true; bool is_first = true;
iterator it = boost::begin(range); iterator it = boost::begin(range);
for (iterator prev = it++; for (iterator prev = it++; it != boost::end(range); prev = it++)
it != boost::end(range);
prev = it++)
{ {
typename boost::range_value<Collection>::type v(*prev, *it); typename boost::range_value<Collection>::type v(*prev, *it);

View File

@ -30,8 +30,7 @@
#include <boost/geometry/core/tags.hpp> #include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/closeable_view.hpp> #include <boost/geometry/views/detail/normalized_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -60,20 +59,14 @@ struct copy_segment_point_range
SegmentIdentifier const& seg_id, signed_size_type offset, SegmentIdentifier const& seg_id, signed_size_type offset,
PointOut& point) PointOut& point)
{ {
typedef typename closeable_view using view_type = detail::close_reverse_view
< <
Range const, Range const,
closure<Range>::value closure<Range>::value,
>::type cview_type; Reverse ? iterate_reverse : iterate_forward
>;
typedef typename reversible_view view_type view(range);
<
cview_type const,
Reverse ? iterate_reverse : iterate_forward
>::type rview_type;
cview_type cview(range);
rview_type view(cview);
std::size_t const segment_count = boost::size(view) - 1; std::size_t const segment_count = boost::size(view) - 1;
signed_size_type const target = circular_offset(segment_count, seg_id.segment_index, offset); signed_size_type const target = circular_offset(segment_count, seg_id.segment_index, offset);

View File

@ -2,8 +2,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014-2020. // This file was modified by Oracle on 2014-2021.
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -41,8 +41,7 @@
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/closeable_view.hpp> #include <boost/geometry/views/detail/normalized_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -72,24 +71,17 @@ struct copy_segments_ring
RobustPolicy const& robust_policy, RobustPolicy const& robust_policy,
RangeOut& current_output) RangeOut& current_output)
{ {
typedef typename closeable_view using view_type = detail::close_reverse_view
< <
Ring const, Ring const,
closure<Ring>::value closure<Ring>::value,
>::type cview_type; Reverse ? iterate_reverse : iterate_forward
>;
typedef typename reversible_view using iterator = typename boost::range_iterator<view_type const>::type;
< using ec_iterator = geometry::ever_circling_iterator<iterator>;
cview_type const,
Reverse ? iterate_reverse : iterate_forward
>::type rview_type;
typedef typename boost::range_iterator<rview_type const>::type iterator; view_type view(ring);
typedef geometry::ever_circling_iterator<iterator> ec_iterator;
cview_type cview(ring);
rview_type view(cview);
// The problem: sometimes we want to from "3" to "2" // The problem: sometimes we want to from "3" to "2"
// -> end = "3" -> end == begin // -> end = "3" -> end == begin

View File

@ -62,8 +62,7 @@
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/type_traits.hpp> #include <boost/geometry/util/type_traits.hpp>
#include <boost/geometry/views/closeable_view.hpp> #include <boost/geometry/views/detail/normalized_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION #ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
@ -215,40 +214,24 @@ template
> >
class get_turns_in_sections class get_turns_in_sections
{ {
typedef typename closeable_view using range1_view = detail::close_reverse_view
< <
typename ring_type<Geometry1>::type const, typename ring_type<Geometry1>::type const,
closure<Geometry1>::value geometry::closure<Geometry1>::value,
>::type cview_type1; Reverse1 ? iterate_reverse : iterate_forward
typedef typename closeable_view >;
using range2_view = detail::close_reverse_view
< <
typename ring_type<Geometry2>::type const, typename ring_type<Geometry2>::type const,
closure<Geometry2>::value geometry::closure<Geometry2>::value,
>::type cview_type2;
typedef typename reversible_view
<
cview_type1 const,
Reverse1 ? iterate_reverse : iterate_forward
>::type view_type1;
typedef typename reversible_view
<
cview_type2 const,
Reverse2 ? iterate_reverse : iterate_forward Reverse2 ? iterate_reverse : iterate_forward
>::type view_type2; >;
typedef typename boost::range_iterator using range1_iterator = typename boost::range_iterator<range1_view const>::type;
< using range2_iterator = typename boost::range_iterator<range2_view const>::type;
view_type1 const
>::type range1_iterator;
typedef typename boost::range_iterator using circular1_iterator = ever_circling_iterator<range1_iterator>;
< using circular2_iterator = ever_circling_iterator<range2_iterator>;
view_type2 const
>::type range2_iterator;
typedef ever_circling_iterator<range1_iterator> circular1_iterator;
typedef ever_circling_iterator<range2_iterator> circular2_iterator;
template <typename Geometry, typename Section> template <typename Geometry, typename Section>
static inline bool adjacent(Section const& section, static inline bool adjacent(Section const& section,
@ -298,10 +281,8 @@ public :
return true; return true;
} }
cview_type1 cview1(range_by_section(geometry1, sec1)); range1_view const view1(range_by_section(geometry1, sec1));
cview_type2 cview2(range_by_section(geometry2, sec2)); range2_view const view2(range_by_section(geometry2, sec2));
view_type1 view1(cview1);
view_type2 view2(cview2);
range1_iterator begin_range_1 = boost::begin(view1); range1_iterator begin_range_1 = boost::begin(view1);
range1_iterator end_range_1 = boost::end(view1); range1_iterator end_range_1 = boost::end(view1);
@ -321,7 +302,7 @@ public :
// We need a circular iterator because it might run through the closing point. // We need a circular iterator because it might run through the closing point.
// One circle is actually enough but this one is just convenient. // One circle is actually enough but this one is just convenient.
ever_circling_iterator<range1_iterator> next1(begin_range_1, end_range_1, it1, true); circular1_iterator next1(begin_range_1, end_range_1, it1, true);
next1++; next1++;
// Walk through section and stop if we exceed the other box // Walk through section and stop if we exceed the other box
@ -347,7 +328,7 @@ public :
get_start_point_iterator(sec2, view2, prev2, it2, end2, get_start_point_iterator(sec2, view2, prev2, it2, end2,
index2, ndi2, dir2, sec1.bounding_box, robust_policy); index2, ndi2, dir2, sec1.bounding_box, robust_policy);
ever_circling_iterator<range2_iterator> next2(begin_range_2, end_range_2, it2, true); circular2_iterator next2(begin_range_2, end_range_2, it2, true);
next2++; next2++;
for (prev2 = it2++, next2++; for (prev2 = it2++, next2++;
@ -592,22 +573,14 @@ struct get_turns_cs
typedef typename geometry::point_type<Box>::type box_point_type; typedef typename geometry::point_type<Box>::type box_point_type;
typedef boost::array<box_point_type, 4> box_array; typedef boost::array<box_point_type, 4> box_array;
typedef typename closeable_view using view_type = detail::close_reverse_view
< <
Range const, Range const,
closure<Range>::value geometry::closure<Range>::value,
>::type cview_type;
typedef typename reversible_view
<
cview_type const,
ReverseRange ? iterate_reverse : iterate_forward ReverseRange ? iterate_reverse : iterate_forward
>::type view_type; >;
typedef typename boost::range_iterator using iterator_type = typename boost::range_iterator<view_type const>::type;
<
view_type const
>::type iterator_type;
struct unique_sub_range_from_box_policy struct unique_sub_range_from_box_policy
{ {
@ -693,8 +666,7 @@ struct get_turns_cs
box_array box_points; box_array box_points;
assign_box_corners_oriented<ReverseBox>(box, box_points); assign_box_corners_oriented<ReverseBox>(box, box_points);
cview_type cview(range); view_type const view(range);
view_type view(cview);
// TODO: in this code, possible duplicate points are not yet taken // TODO: in this code, possible duplicate points are not yet taken
// into account (not in the iterator, nor in the retrieve policy) // into account (not in the iterator, nor in the retrieve policy)

View File

@ -1218,9 +1218,9 @@ struct linear_areal
typename sub_range_return_type<Geometry1 const>::type typename sub_range_return_type<Geometry1 const>::type
range1 = sub_range(geometry1, turn.operations[op_id].seg_id); range1 = sub_range(geometry1, turn.operations[op_id].seg_id);
typedef detail::normalized_view<typename ring_type<Geometry2>::type const> const range2_type; using range2_view = detail::reverse_close_view<typename ring_type<Geometry2>::type const>;
typedef typename boost::range_iterator<range2_type>::type range2_iterator; using range2_iterator = typename boost::range_iterator<range2_view const>::type;
range2_type range2(sub_range(geometry2, turn.operations[other_op_id].seg_id)); range2_view const range2(sub_range(geometry2, turn.operations[other_op_id].seg_id));
BOOST_GEOMETRY_ASSERT(boost::size(range1)); BOOST_GEOMETRY_ASSERT(boost::size(range1));
std::size_t const s2 = boost::size(range2); std::size_t const s2 = boost::size(range2);

View File

@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2020. // This file was modified by Oracle on 2013-2021.
// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2013-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -59,8 +59,7 @@
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/sequence.hpp> #include <boost/geometry/util/sequence.hpp>
#include <boost/geometry/views/closeable_view.hpp> #include <boost/geometry/views/detail/normalized_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
// TEMP // TEMP
#include <boost/geometry/strategy/envelope.hpp> #include <boost/geometry/strategy/envelope.hpp>
@ -582,15 +581,12 @@ struct sectionalize_range
ring_identifier ring_id, ring_identifier ring_id,
std::size_t max_count) std::size_t max_count)
{ {
typedef typename closeable_view<Range const, Closure>::type cview_type; detail::close_reverse_view
typedef typename reversible_view
< <
cview_type const, Range const,
Closure,
Reverse ? iterate_reverse : iterate_forward Reverse ? iterate_reverse : iterate_forward
>::type view_type; > const view(range);
cview_type cview(range);
view_type view(cview);
std::size_t const n = boost::size(view); std::size_t const n = boost::size(view);
if (n == 0) if (n == 0)

View File

@ -181,7 +181,7 @@ struct point_in_geometry<Ring, ring_tag>
return -1; return -1;
} }
detail::normalized_view<Ring const> view(ring); detail::reverse_close_view<Ring const> view(ring);
return detail::within::point_in_range(point, view, return detail::within::point_in_range(point, view,
strategy.relate(point, ring)); strategy.relate(point, ring));
} }

View File

@ -65,10 +65,10 @@ struct ring_is_convex
// Walk in clockwise direction, consider ring as closed // Walk in clockwise direction, consider ring as closed
// (though closure is not important in this algorithm - any dupped // (though closure is not important in this algorithm - any dupped
// point is skipped) // point is skipped)
typedef detail::normalized_view<Ring const> view_type; using view_type = detail::reverse_close_view<Ring const>;
view_type view(ring); view_type const view(ring);
typedef geometry::ever_circling_range_iterator<view_type const> it_type; using it_type = geometry::ever_circling_range_iterator<view_type const>;
it_type previous(view); it_type previous(view);
it_type current(view); it_type current(view);
current++; current++;

View File

@ -36,10 +36,11 @@ namespace boost { namespace geometry {
namespace detail { namespace detail {
template <typename Geometry> template <typename Geometry>
struct normalized_view struct reverse_close_view
{ {
using reversible_type = typename reversible_view using reverse_view = typename reversible_view
< <
Geometry const, Geometry const,
order_as_direction order_as_direction
@ -48,26 +49,58 @@ struct normalized_view
>::value >::value
>::type; >::type;
using closeable_type = typename closeable_view using view = typename closeable_view
< <
reversible_type const, reverse_view const,
geometry::closure<Geometry>::value geometry::closure<Geometry>::value
>::type; >::type;
explicit inline normalized_view(Geometry const& g) explicit inline reverse_close_view(Geometry const& g)
: m_closeable(reversible_type(g)) : m_view(reverse_view(g))
{} {}
using iterator = typename boost::range_iterator<closeable_type const>::type; using iterator = typename boost::range_iterator<view const>::type;
using const_iterator = typename boost::range_iterator<closeable_type const>::type; using const_iterator = typename boost::range_iterator<view const>::type;
inline const_iterator begin() const { return boost::begin(m_closeable); } inline const_iterator begin() const { return boost::begin(m_view); }
inline const_iterator end() const { return boost::end(m_closeable); } inline const_iterator end() const { return boost::end(m_view); }
private: private:
closeable_type m_closeable; view m_view;
}; };
template
<
typename Geometry,
closure_selector Closure = geometry::closure<Geometry>::value,
iterate_direction Direction = order_as_direction
<
geometry::point_order<Geometry>::value
>::value
>
struct close_reverse_view
{
// These utilities are inconsistent since Closure defines the property of
// the Geometry while Direction defines what to do with the Geometry.
using close_view = typename closeable_view<Geometry const, Closure>::type;
using view = typename reversible_view<close_view const, Direction>::type;
explicit inline close_reverse_view(Geometry const& g)
: m_view(close_view(g))
{}
using iterator = typename boost::range_iterator<view const>::type;
using const_iterator = typename boost::range_iterator<view const>::type;
inline const_iterator begin() const { return boost::begin(m_view); }
inline const_iterator end() const { return boost::end(m_view); }
private:
view m_view;
};
} // namespace detail } // namespace detail
#endif // DOXYGEN_NO_DETAIL #endif // DOXYGEN_NO_DETAIL

View File

@ -5,6 +5,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -21,272 +25,130 @@ template <typename Point1, typename Point2>
void test_mixed_point_types() void test_mixed_point_types()
{ {
// Point // Point
test_mixed_identical_result<Point1, Point2>("POINT(1 2)"); check<Point1, Point2>("POINT(1 2)");
// Box // Box
test_mixed_identical_result check<bg::model::box<Point1>, bg::model::box<Point2>>("POLYGON((1 2,1 4,3 4,3 2,1 2))");
<
bg::model::box<Point1>,
bg::model::box<Point2>
>
("POLYGON((1 2,1 4,3 4,3 2,1 2))");
test_mixed_identical_result // Segment
< check<bg::model::segment<Point1>, bg::model::segment<Point2>>("LINESTRING(1 1,2 2)");
bg::model::segment<Point1>,
bg::model::segment<Point2>
>
("LINESTRING(1 1,2 2)");
// Linestring // Linestring
test_mixed_identical_result check<bg::model::linestring<Point1>, bg::model::linestring<Point2>>("LINESTRING(1 1,2 2)");
<
bg::model::linestring<Point1>,
bg::model::linestring<Point2>
>
("LINESTRING(1 1,2 2)");
// Ring // Ring
test_mixed_identical_result check<bg::model::ring<Point1, true, true>, bg::model::ring<Point2, true, true>>(
< "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,2 2,3 0,1 1))", 4);
bg::model::ring<Point1>, check<bg::model::ring<Point1, true, true>, bg::model::ring<Point2, false, true>>(
bg::model::ring<Point2> "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,3 0,2 2,1 1))", 4);
> check<bg::model::ring<Point1, true, true>, bg::model::ring<Point2, true, false>>(
("POLYGON((1 1,2 2,3 0,1 1))"); "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,2 2,3 0))", 3);
check<bg::model::ring<Point1, true, true>, bg::model::ring<Point2, false, false>>(
"POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,3 0,2 2))", 3);
test_mixed_reversible_result check<bg::model::ring<Point1, false, true>, bg::model::ring<Point2, true, true>>(
< "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,2 2,3 0,1 1))", 4);
bg::model::ring<Point1, true>, check<bg::model::ring<Point1, false, true>, bg::model::ring<Point2, false, true>>(
bg::model::ring<Point2, false> "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,3 0,2 2,1 1))", 4);
> check<bg::model::ring<Point1, false, true>, bg::model::ring<Point2, true, false>>(
( "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,2 2,3 0))", 3);
"POLYGON((1 1,2 2,3 0,1 1))", check<bg::model::ring<Point1, false, true>, bg::model::ring<Point2, false, false>>(
"POLYGON((1 1,3 0,2 2,1 1))" "POLYGON((1 1,3 0,2 2,1 1))", "POLYGON((1 1,3 0,2 2))", 3);
);
test_mixed check<bg::model::ring<Point1, true, false>, bg::model::ring<Point2, true, true>>(
< "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,2 2,3 0,1 1))", 4);
bg::model::ring<Point1, true, true>, check<bg::model::ring<Point1, true, false>, bg::model::ring<Point2, false, true>>(
bg::model::ring<Point2, true, false> "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,3 0,2 2,1 1))", 4);
> check<bg::model::ring<Point1, true, false>, bg::model::ring<Point2, true, false>>(
( "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,2 2,3 0))", 3);
"POLYGON((1 1,2 2,3 0,1 1))", check<bg::model::ring<Point1, true, false>, bg::model::ring<Point2, false, false>>(
"POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,3 0,2 2))", 3);
3
);
test_mixed check<bg::model::ring<Point1, false, false>, bg::model::ring<Point2, true, true>>(
< "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,2 2,3 0,1 1))", 4);
bg::model::ring<Point1, true, false>, check<bg::model::ring<Point1, false, false>, bg::model::ring<Point2, false, true>>(
bg::model::ring<Point2, true, true> "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,3 0,2 2,1 1))", 4);
> check<bg::model::ring<Point1, false, false>, bg::model::ring<Point2, true, false>>(
( "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,2 2,3 0))", 3);
"POLYGON((1 1,2 2,3 0))", check<bg::model::ring<Point1, false, false>, bg::model::ring<Point2, false, false>>(
"POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,3 0,2 2))", 3);
4
);
// Polygon // Polygon
test_mixed_reversible_result check<bg::model::polygon<Point1, true>, bg::model::polygon<Point2, false>>(
< "POLYGON((0 0,0 5,5 5,5 0,0 0),(1 1,3 2,2 4,1 1))",
bg::model::polygon<Point1, true>, "POLYGON((0 0,5 0,5 5,0 5,0 0),(1 1,2 4,3 2,1 1))");
bg::model::polygon<Point2, false>
>
(
"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))"
);
test_mixed check<bg::model::polygon<Point1>, bg::model::polygon<Point2, false, false>>(
< "POLYGON((0 0,0 5,5 5,5 0,0 0),(1 1,3 2,2 4,1 1))",
bg::model::polygon<Point1>, "POLYGON((0 0,5 0,5 5,0 5,0 0),(1 1,2 4,3 2,1 1))",
bg::model::polygon<Point2, false, false> 7); // WKT is closed, polygon is open
>
(
"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) // (polygon uses ring, so other tests omitted here)
// Combinations: // Combinations:
// ring <-> polygon // ring <-> polygon
test_mixed_identical_result check<bg::model::polygon<Point1>, bg::model::ring<Point2>>(
< "POLYGON((1 1,2 2,3 0,1 1))");
bg::model::polygon<Point1>,
bg::model::ring<Point2>
>
("POLYGON((1 1,2 2,3 0,1 1))");
test_mixed_reversible_result check<bg::model::polygon<Point1, true>, bg::model::ring<Point2, false>>(
< "POLYGON((1 1,2 2,3 0,1 1))", "POLYGON((1 1,3 0,2 2,1 1))");
bg::model::polygon<Point1, true>,
bg::model::ring<Point2, false>
>
(
"POLYGON((1 1,2 2,3 0,1 1))",
"POLYGON((1 1,3 0,2 2,1 1))"
);
// Any hole will be omitted going from polygon to ring // Any hole will be omitted going from polygon to ring
test_mixed check<bg::model::polygon<Point1>, bg::model::ring<Point2>>(
< "POLYGON((0 0,0 5,5 5,5 0,0 0),(1 1,3 2,2 4,1 1))",
bg::model::polygon<Point1>, "POLYGON((0 0,0 5,5 5,5 0,0 0))",
bg::model::ring<Point2> 5);
>
(
"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 // point -> box
test_mixed check<Point1, bg::model::box<Point2>>(
< "POINT(0 0)", "POLYGON((0 0,0 0,0 0,0 0,0 0))", 4);
Point1,
bg::model::box<Point2>
>
(
"POINT(0 0)",
"POLYGON((0 0,0 0,0 0,0 0,0 0))",
4
);
// segment -> line // segment -> line
test_mixed check<bg::model::segment<Point1>, bg::model::linestring<Point2>>(
< "LINESTRING(0 0,1 1)", "LINESTRING(0 0,1 1)", 2);
bg::model::segment<Point1>,
bg::model::linestring<Point2>
>
(
"LINESTRING(0 0,1 1)",
"LINESTRING(0 0,1 1)",
2
);
// box -> ring ( <- is NYI) // box -> ring ( <- is NYI)
test_mixed check<bg::model::box<Point1>, bg::model::ring<Point2>>(
< "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", 5);
bg::model::box<Point1>,
bg::model::ring<Point2>
>
(
"BOX(0 0,2 2)",
"POLYGON((0 0,0 2,2 2,2 0,0 0))",
5
);
test_mixed check<bg::model::box<Point1>, bg::model::ring<Point2, false>>(
< "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2,0 0))", 5);
bg::model::box<Point1>,
bg::model::ring<Point2, false>
>
(
"BOX(0 0,2 2)",
"POLYGON((0 0,2 0,2 2,0 2,0 0))",
5
);
test_mixed check<bg::model::box<Point1>, bg::model::ring<Point2, true, false>>(
< "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0))", 4);
bg::model::box<Point1>,
bg::model::ring<Point2, true, false>
>
(
"BOX(0 0,2 2)",
"POLYGON((0 0,0 2,2 2,2 0))",
4
);
test_mixed check<bg::model::box<Point1>, bg::model::ring<Point2, false, false>>(
< "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2))", 4);
bg::model::box<Point1>,
bg::model::ring<Point2, false, false>
>
(
"BOX(0 0,2 2)",
"POLYGON((0 0,2 0,2 2,0 2))",
4
);
// box -> polygon ( <- is NYI) // box -> polygon ( <- is NYI)
test_mixed check<bg::model::box<Point1>, bg::model::polygon<Point2>>(
< "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", 5);
bg::model::box<Point1>, check<bg::model::box<Point1>, bg::model::polygon<Point2, false>>(
bg::model::polygon<Point2> "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2,0 0))", 5);
> check<bg::model::box<Point1>, bg::model::polygon<Point2, true, false>>(
( "BOX(0 0,2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))",
"BOX(0 0,2 2)", 4); // WKT is closed, polygon is open
"POLYGON((0 0,0 2,2 2,2 0,0 0))",
5
);
test_mixed check<bg::model::box<Point1>, bg::model::polygon<Point2, false, false>>(
< "BOX(0 0,2 2)", "POLYGON((0 0,2 0,2 2,0 2,0 0))",
bg::model::box<Point1>, 4); // WKT is closed, polygon is open
bg::model::polygon<Point2, false>
>
(
"BOX(0 0,2 2)",
"POLYGON((0 0,2 0,2 2,0 2,0 0))",
5
);
test_mixed
<
bg::model::box<Point1>,
bg::model::polygon<Point2, true, false>
>
(
"BOX(0 0,2 2)",
"POLYGON((0 0,0 2,2 2,2 0,0 0))",
4 // WKT is closed, polygon is open
);
test_mixed
<
bg::model::box<Point1>,
bg::model::polygon<Point2, false, false>
>
(
"BOX(0 0,2 2)",
"POLYGON((0 0,2 0,2 2,0 2,0 0))",
4 // WKT is closed, polygon is open
);
} }
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
void test_mixed_point_types_3d() void test_mixed_point_types_3d()
{ {
// Point // Point
test_mixed_identical_result<Point1, Point2>("POINT(1 2 3)"); check<Point1, Point2>("POINT(1 2 3)");
test_mixed_identical_result check<bg::model::segment<Point1>, bg::model::segment<Point2>>(
< "LINESTRING(1 2 3,4 5 6)");
bg::model::segment<Point1>,
bg::model::segment<Point2>
>
("LINESTRING(1 2 3,4 5 6)");
// Linestring // Linestring
test_mixed_identical_result check<bg::model::linestring<Point1>, bg::model::linestring<Point2>>(
< "LINESTRING(1 2 3,4 5 6,7 8 9)");
bg::model::linestring<Point1>,
bg::model::linestring<Point2>
>
("LINESTRING(1 2 3,4 5 6,7 8 9)");
// segment -> line // segment -> line
test_mixed check<bg::model::segment<Point1>, bg::model::linestring<Point2>>(
< "LINESTRING(1 2 3,4 5 6)", "LINESTRING(1 2 3,4 5 6)", 2);
bg::model::segment<Point1>,
bg::model::linestring<Point2>
>
(
"LINESTRING(1 2 3,4 5 6)",
"LINESTRING(1 2 3,4 5 6)",
2
);
} }

View File

@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
//
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // 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, // Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
@ -11,70 +16,48 @@
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
void test_mixed_point_types() void test_mixed_point_types()
{ {
test_mixed_identical_result check<bg::model::multi_point<Point1>, bg::model::multi_point<Point2>>(
< "MULTIPOINT((1 1),(2 2),(3 3))");
bg::model::multi_point<Point1>,
bg::model::multi_point<Point2>
>
("MULTIPOINT((1 1),(2 2),(3 3))");
test_mixed_identical_result check
< <
bg::model::multi_linestring<bg::model::linestring<Point1> >, bg::model::multi_linestring<bg::model::linestring<Point1> >,
bg::model::multi_linestring<bg::model::linestring<Point2> > bg::model::multi_linestring<bg::model::linestring<Point2> >
> >("MULTILINESTRING((1 1,2 2),(3 3,4 4))");
("MULTILINESTRING((1 1,2 2),(3 3,4 4))");
// Single -> multi (always possible) // Single -> multi (always possible)
test_mixed check<Point1, bg::model::multi_point<Point2>>(
< "POINT(1 1)", "MULTIPOINT((1 1))", 1);
Point1, bg::model::multi_point<Point2>
> check
(
"POINT(1 1)",
"MULTIPOINT((1 1))",
1
);
test_mixed
< <
bg::model::linestring<Point1>, bg::model::linestring<Point1>,
bg::model::multi_linestring<bg::model::linestring<Point2> > bg::model::multi_linestring<bg::model::linestring<Point2> >
> >("LINESTRING(1 1,2 2)", "MULTILINESTRING((1 1,2 2))", 2);
(
"LINESTRING(1 1,2 2)", check
"MULTILINESTRING((1 1,2 2))",
2
);
test_mixed
< <
bg::model::segment<Point1>, bg::model::segment<Point1>,
bg::model::multi_linestring<bg::model::linestring<Point2> > bg::model::multi_linestring<bg::model::linestring<Point2> >
> >("LINESTRING(1 1,2 2)", "MULTILINESTRING((1 1,2 2))", 2);
(
"LINESTRING(1 1,2 2)", check
"MULTILINESTRING((1 1,2 2))",
2
);
test_mixed
< <
bg::model::box<Point1>, bg::model::box<Point1>,
bg::model::multi_polygon<bg::model::polygon<Point2> > bg::model::multi_polygon<bg::model::polygon<Point2> >
> >("BOX(0 0,1 1)", "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))", 5);
(
"BOX(0 0,1 1)", check
"MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))",
5
);
test_mixed
< <
bg::model::ring<Point1, true>, bg::model::ring<Point1, true>,
bg::model::multi_polygon<bg::model::polygon<Point2, false> > bg::model::multi_polygon<bg::model::polygon<Point2, false> >
> >("POLYGON((0 0,0 1,1 1,1 0,0 0))", "MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))", 5);
(
"POLYGON((0 0,0 1,1 1,1 0,0 0))", check
"MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))", <
5 bg::model::ring<Point1, false, false>,
); bg::model::multi_polygon<bg::model::polygon<Point2> >
>("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) // Multi -> single: should not compile (because multi often have 0 or >1 elements)
} }

View File

@ -2,6 +2,11 @@
// Unit Test // Unit Test
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2012 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, // Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
@ -33,7 +38,7 @@ BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
template <typename Geometry2, typename Geometry1> template <typename Geometry2, typename Geometry1>
void check_mixed(Geometry1 const& geometry1, std::string const& expected, int expected_point_count) void check(Geometry1 const& geometry1, std::string const& expected, int expected_point_count = -1)
{ {
Geometry2 geometry2; Geometry2 geometry2;
bg::convert(geometry1, geometry2); bg::convert(geometry1, geometry2);
@ -52,26 +57,14 @@ void check_mixed(Geometry1 const& geometry1, std::string const& expected, int ex
} }
template <typename Geometry1, typename Geometry2> template <typename Geometry1, typename Geometry2>
void test_mixed(std::string const& wkt, std::string const& expected, int expected_point_count) void check(std::string const& wkt, std::string const& expected = "", int expected_point_count = -1)
{ {
Geometry1 geometry1; Geometry1 geometry1;
bg::read_wkt(wkt, geometry1); bg::read_wkt(wkt, geometry1);
check_mixed<Geometry2>(geometry1, expected, expected_point_count); std::string const& used_expected = expected.empty() ? wkt : expected;
check_mixed<Geometry2>(boost::variant<Geometry1>(geometry1), expected, expected_point_count); check<Geometry2>(geometry1, used_expected, expected_point_count);
check<Geometry2>(boost::variant<Geometry1>(geometry1), used_expected, expected_point_count);
} }
template <typename Geometry1, typename Geometry2>
void test_mixed_identical_result(std::string const& wkt)
{
test_mixed<Geometry1, Geometry2>(wkt, wkt, -1);
test_mixed<Geometry2, Geometry1>(wkt, wkt, -1);
}
template <typename Geometry1, typename Geometry2> #endif // BOOST_GEOMETRY_TEST_CONVERT_HPP
void test_mixed_reversible_result(std::string const& wkt1, std::string const& wkt2)
{
test_mixed<Geometry1, Geometry2>(wkt1, wkt2, -1);
test_mixed<Geometry2, Geometry1>(wkt2, wkt1, -1);
}
#endif