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) 2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017-2020.
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
// This file was modified by Oracle on 2017-2021.
// Modifications copyright (c) 2017-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
@ -41,8 +41,7 @@
#include <boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
#include <boost/geometry/util/range.hpp>
@ -144,17 +143,6 @@ template
>
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
{
template <typename Point1, typename Point2>
@ -175,11 +163,16 @@ struct range_to_range
{
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
// point for open output.
view_type view(rview);
view_type const view(source);
typedef typename boost::range_size<Range1>::type size_type;
size_type n = boost::size(view);

View File

@ -537,7 +537,7 @@ struct buffer_inserter_ring
if (n >= min_points)
{
detail::normalized_view<RingInput const> view(simplified);
detail::reverse_close_view<RingInput const> view(simplified);
if (distance.negative())
{
// 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)
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);
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) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017, 2019.
// Modifications copyright (c) 2017, 2019 Oracle and/or its affiliates.
// This file was modified by Oracle on 2017-2021.
// Modifications copyright (c) 2017-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
@ -327,17 +326,13 @@ struct range_collect_vectors
static inline void apply(Collection& collection, Range const& range)
{
typedef geometry::detail::normalized_view
<
Range const
> normalized_range_type;
apply_impl(collection, normalized_range_type(range));
apply_impl(collection,
detail::reverse_close_view<Range const>(range));
}
private:
template <typename NormalizedRange>
static inline void apply_impl(Collection& collection, NormalizedRange const& range)
template <typename RevClRange>
static inline void apply_impl(Collection& collection, RevClRange const& range)
{
if (boost::size(range) < 2)
{
@ -347,14 +342,12 @@ private:
typedef typename boost::range_size<Collection>::type collection_size_t;
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;
iterator it = boost::begin(range);
for (iterator prev = it++;
it != boost::end(range);
prev = it++)
for (iterator prev = it++; it != boost::end(range); 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/geometries/concepts/check.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
namespace boost { namespace geometry
@ -60,20 +59,14 @@ struct copy_segment_point_range
SegmentIdentifier const& seg_id, signed_size_type offset,
PointOut& point)
{
typedef typename closeable_view
<
Range const,
closure<Range>::value
>::type cview_type;
using view_type = detail::close_reverse_view
<
Range const,
closure<Range>::value,
Reverse ? iterate_reverse : iterate_forward
>;
typedef typename reversible_view
<
cview_type const,
Reverse ? iterate_reverse : iterate_forward
>::type rview_type;
cview_type cview(range);
rview_type view(cview);
view_type view(range);
std::size_t const segment_count = boost::size(view) - 1;
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.
// This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014-2021.
// 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 Adam Wulkiewicz, on behalf of Oracle
@ -41,8 +41,7 @@
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
namespace boost { namespace geometry
@ -72,24 +71,17 @@ struct copy_segments_ring
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
typedef typename closeable_view
<
Ring const,
closure<Ring>::value
>::type cview_type;
using view_type = detail::close_reverse_view
<
Ring const,
closure<Ring>::value,
Reverse ? iterate_reverse : iterate_forward
>;
typedef typename reversible_view
<
cview_type const,
Reverse ? iterate_reverse : iterate_forward
>::type rview_type;
using iterator = typename boost::range_iterator<view_type const>::type;
using ec_iterator = geometry::ever_circling_iterator<iterator>;
typedef typename boost::range_iterator<rview_type const>::type iterator;
typedef geometry::ever_circling_iterator<iterator> ec_iterator;
cview_type cview(ring);
rview_type view(cview);
view_type view(ring);
// The problem: sometimes we want to from "3" to "2"
// -> end = "3" -> end == begin

View File

@ -62,8 +62,7 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/type_traits.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
@ -215,40 +214,24 @@ template
>
class get_turns_in_sections
{
typedef typename closeable_view
using range1_view = detail::close_reverse_view
<
typename ring_type<Geometry1>::type const,
closure<Geometry1>::value
>::type cview_type1;
typedef typename closeable_view
geometry::closure<Geometry1>::value,
Reverse1 ? iterate_reverse : iterate_forward
>;
using range2_view = detail::close_reverse_view
<
typename ring_type<Geometry2>::type const,
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,
geometry::closure<Geometry2>::value,
Reverse2 ? iterate_reverse : iterate_forward
>::type view_type2;
>;
typedef typename boost::range_iterator
<
view_type1 const
>::type range1_iterator;
using range1_iterator = typename boost::range_iterator<range1_view const>::type;
using range2_iterator = typename boost::range_iterator<range2_view const>::type;
typedef typename boost::range_iterator
<
view_type2 const
>::type range2_iterator;
typedef ever_circling_iterator<range1_iterator> circular1_iterator;
typedef ever_circling_iterator<range2_iterator> circular2_iterator;
using circular1_iterator = ever_circling_iterator<range1_iterator>;
using circular2_iterator = ever_circling_iterator<range2_iterator>;
template <typename Geometry, typename Section>
static inline bool adjacent(Section const& section,
@ -298,10 +281,8 @@ public :
return true;
}
cview_type1 cview1(range_by_section(geometry1, sec1));
cview_type2 cview2(range_by_section(geometry2, sec2));
view_type1 view1(cview1);
view_type2 view2(cview2);
range1_view const view1(range_by_section(geometry1, sec1));
range2_view const view2(range_by_section(geometry2, sec2));
range1_iterator begin_range_1 = boost::begin(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.
// 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++;
// 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,
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++;
for (prev2 = it2++, next2++;
@ -592,22 +573,14 @@ struct get_turns_cs
typedef typename geometry::point_type<Box>::type box_point_type;
typedef boost::array<box_point_type, 4> box_array;
typedef typename closeable_view
using view_type = detail::close_reverse_view
<
Range const,
closure<Range>::value
>::type cview_type;
typedef typename reversible_view
<
cview_type const,
geometry::closure<Range>::value,
ReverseRange ? iterate_reverse : iterate_forward
>::type view_type;
>;
typedef typename boost::range_iterator
<
view_type const
>::type iterator_type;
using iterator_type = typename boost::range_iterator<view_type const>::type;
struct unique_sub_range_from_box_policy
{
@ -693,8 +666,7 @@ struct get_turns_cs
box_array box_points;
assign_box_corners_oriented<ReverseBox>(box, box_points);
cview_type cview(range);
view_type view(cview);
view_type const view(range);
// TODO: in this code, possible duplicate points are not yet taken
// 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
range1 = sub_range(geometry1, turn.operations[op_id].seg_id);
typedef detail::normalized_view<typename ring_type<Geometry2>::type const> const range2_type;
typedef typename boost::range_iterator<range2_type>::type range2_iterator;
range2_type range2(sub_range(geometry2, turn.operations[other_op_id].seg_id));
using range2_view = detail::reverse_close_view<typename ring_type<Geometry2>::type const>;
using range2_iterator = typename boost::range_iterator<range2_view const>::type;
range2_view const range2(sub_range(geometry2, turn.operations[other_op_id].seg_id));
BOOST_GEOMETRY_ASSERT(boost::size(range1));
std::size_t const s2 = boost::size(range2);

View File

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

View File

@ -181,7 +181,7 @@ struct point_in_geometry<Ring, ring_tag>
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,
strategy.relate(point, ring));
}

View File

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

View File

@ -36,10 +36,11 @@ namespace boost { namespace geometry {
namespace detail {
template <typename Geometry>
struct normalized_view
struct reverse_close_view
{
using reversible_type = typename reversible_view
using reverse_view = typename reversible_view
<
Geometry const,
order_as_direction
@ -48,26 +49,58 @@ struct normalized_view
>::value
>::type;
using closeable_type = typename closeable_view
using view = typename closeable_view
<
reversible_type const,
reverse_view const,
geometry::closure<Geometry>::value
>::type;
explicit inline normalized_view(Geometry const& g)
: m_closeable(reversible_type(g))
explicit inline reverse_close_view(Geometry const& g)
: m_view(reverse_view(g))
{}
using iterator = typename boost::range_iterator<closeable_type const>::type;
using const_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<view const>::type;
inline const_iterator begin() const { return boost::begin(m_closeable); }
inline const_iterator end() const { return boost::end(m_closeable); }
inline const_iterator begin() const { return boost::begin(m_view); }
inline const_iterator end() const { return boost::end(m_view); }
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
#endif // DOXYGEN_NO_DETAIL

View File

@ -5,6 +5,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// 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
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -21,272 +25,130 @@ template <typename Point1, typename Point2>
void test_mixed_point_types()
{
// Point
test_mixed_identical_result<Point1, Point2>("POINT(1 2)");
check<Point1, Point2>("POINT(1 2)");
// Box
test_mixed_identical_result
<
bg::model::box<Point1>,
bg::model::box<Point2>
>
("POLYGON((1 2,1 4,3 4,3 2,1 2))");
check<bg::model::box<Point1>, bg::model::box<Point2>>("POLYGON((1 2,1 4,3 4,3 2,1 2))");
test_mixed_identical_result
<
bg::model::segment<Point1>,
bg::model::segment<Point2>
>
("LINESTRING(1 1,2 2)");
// Segment
check<bg::model::segment<Point1>, bg::model::segment<Point2>>("LINESTRING(1 1,2 2)");
// Linestring
test_mixed_identical_result
<
bg::model::linestring<Point1>,
bg::model::linestring<Point2>
>
("LINESTRING(1 1,2 2)");
check<bg::model::linestring<Point1>, bg::model::linestring<Point2>>("LINESTRING(1 1,2 2)");
// Ring
test_mixed_identical_result
<
bg::model::ring<Point1>,
bg::model::ring<Point2>
>
("POLYGON((1 1,2 2,3 0,1 1))");
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);
check<bg::model::ring<Point1, true, true>, bg::model::ring<Point2, false, true>>(
"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))", 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
<
bg::model::ring<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))"
);
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);
check<bg::model::ring<Point1, false, true>, bg::model::ring<Point2, false, true>>(
"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);
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))", 3);
test_mixed
<
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))",
3
);
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);
check<bg::model::ring<Point1, true, false>, bg::model::ring<Point2, false, true>>(
"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);
check<bg::model::ring<Point1, true, false>, bg::model::ring<Point2, false, false>>(
"POLYGON((1 1,2 2,3 0))", "POLYGON((1 1,3 0,2 2))", 3);
test_mixed
<
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
);
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);
check<bg::model::ring<Point1, false, false>, bg::model::ring<Point2, false, 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);
check<bg::model::ring<Point1, false, false>, bg::model::ring<Point2, false, false>>(
"POLYGON((1 1,3 0,2 2))", "POLYGON((1 1,3 0,2 2))", 3);
// Polygon
test_mixed_reversible_result
<
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))",
"POLYGON((0 0,5 0,5 5,0 5,0 0),(1 1,2 4,3 2,1 1))"
);
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))",
"POLYGON((0 0,5 0,5 5,0 5,0 0),(1 1,2 4,3 2,1 1))");
test_mixed
<
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))",
"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
);
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))",
"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)
// Combinations:
// ring <-> polygon
test_mixed_identical_result
<
bg::model::polygon<Point1>,
bg::model::ring<Point2>
>
("POLYGON((1 1,2 2,3 0,1 1))");
check<bg::model::polygon<Point1>, bg::model::ring<Point2>>(
"POLYGON((1 1,2 2,3 0,1 1))");
test_mixed_reversible_result
<
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))"
);
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))");
// Any hole will be omitted going from polygon to ring
test_mixed
<
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))",
"POLYGON((0 0,0 5,5 5,5 0,0 0))",
5
);
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))",
"POLYGON((0 0,0 5,5 5,5 0,0 0))",
5);
// point -> box
test_mixed
<
Point1,
bg::model::box<Point2>
>
(
"POINT(0 0)",
"POLYGON((0 0,0 0,0 0,0 0,0 0))",
4
);
check<Point1, bg::model::box<Point2>>(
"POINT(0 0)", "POLYGON((0 0,0 0,0 0,0 0,0 0))", 4);
// segment -> line
test_mixed
<
bg::model::segment<Point1>,
bg::model::linestring<Point2>
>
(
"LINESTRING(0 0,1 1)",
"LINESTRING(0 0,1 1)",
2
);
check<bg::model::segment<Point1>, bg::model::linestring<Point2>>(
"LINESTRING(0 0,1 1)", "LINESTRING(0 0,1 1)", 2);
// box -> ring ( <- is NYI)
test_mixed
<
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
);
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);
test_mixed
<
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
);
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);
test_mixed
<
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
);
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);
test_mixed
<
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
);
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);
// box -> polygon ( <- is NYI)
test_mixed
<
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
);
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);
check<bg::model::box<Point1>, bg::model::polygon<Point2, false>>(
"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))",
4); // WKT is closed, polygon is open
test_mixed
<
bg::model::box<Point1>,
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
);
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))",
4); // WKT is closed, polygon is open
}
template <typename Point1, typename Point2>
void test_mixed_point_types_3d()
{
// Point
test_mixed_identical_result<Point1, Point2>("POINT(1 2 3)");
check<Point1, Point2>("POINT(1 2 3)");
test_mixed_identical_result
<
bg::model::segment<Point1>,
bg::model::segment<Point2>
>
("LINESTRING(1 2 3,4 5 6)");
check<bg::model::segment<Point1>, bg::model::segment<Point2>>(
"LINESTRING(1 2 3,4 5 6)");
// Linestring
test_mixed_identical_result
<
bg::model::linestring<Point1>,
bg::model::linestring<Point2>
>
("LINESTRING(1 2 3,4 5 6,7 8 9)");
check<bg::model::linestring<Point1>, bg::model::linestring<Point2>>(
"LINESTRING(1 2 3,4 5 6,7 8 9)");
// segment -> line
test_mixed
<
bg::model::segment<Point1>,
bg::model::linestring<Point2>
>
(
"LINESTRING(1 2 3,4 5 6)",
"LINESTRING(1 2 3,4 5 6)",
2
);
check<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)
//
// 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)
@ -11,70 +16,48 @@
template <typename Point1, typename Point2>
void test_mixed_point_types()
{
test_mixed_identical_result
<
bg::model::multi_point<Point1>,
bg::model::multi_point<Point2>
>
("MULTIPOINT((1 1),(2 2),(3 3))");
check<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<Point2> >
>
("MULTILINESTRING((1 1,2 2),(3 3,4 4))");
>("MULTILINESTRING((1 1,2 2),(3 3,4 4))");
// Single -> multi (always possible)
test_mixed
<
Point1, bg::model::multi_point<Point2>
>
(
"POINT(1 1)",
"MULTIPOINT((1 1))",
1
);
test_mixed
check<Point1, bg::model::multi_point<Point2>>(
"POINT(1 1)", "MULTIPOINT((1 1))", 1);
check
<
bg::model::linestring<Point1>,
bg::model::multi_linestring<bg::model::linestring<Point2> >
>
(
"LINESTRING(1 1,2 2)",
"MULTILINESTRING((1 1,2 2))",
2
);
test_mixed
>("LINESTRING(1 1,2 2)", "MULTILINESTRING((1 1,2 2))", 2);
check
<
bg::model::segment<Point1>,
bg::model::multi_linestring<bg::model::linestring<Point2> >
>
(
"LINESTRING(1 1,2 2)",
"MULTILINESTRING((1 1,2 2))",
2
);
test_mixed
>("LINESTRING(1 1,2 2)", "MULTILINESTRING((1 1,2 2))", 2);
check
<
bg::model::box<Point1>,
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
);
test_mixed
>("BOX(0 0,1 1)", "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))", 5);
check
<
bg::model::ring<Point1, true>,
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))", "MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))", 5);
check
<
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)
}

View File

@ -2,6 +2,11 @@
// Unit Test
// 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,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// 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>
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;
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>
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;
bg::read_wkt(wkt, geometry1);
check_mixed<Geometry2>(geometry1, expected, expected_point_count);
check_mixed<Geometry2>(boost::variant<Geometry1>(geometry1), expected, expected_point_count);
std::string const& used_expected = expected.empty() ? wkt : expected;
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>
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
#endif // BOOST_GEOMETRY_TEST_CONVERT_HPP