mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-03 09:12:13 +00:00
Merge branch 'develop' of github.com:boostorg/geometry into develop
This commit is contained in:
@@ -109,9 +109,9 @@ class analyse_turn_wrt_piece
|
||||
return geometry::covered_by(point, box);
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
template <typename Point, typename Turn>
|
||||
static inline analyse_result check_segment(Point const& previous,
|
||||
Point const& current, Point const& point,
|
||||
Point const& current, Turn const& turn,
|
||||
bool from_monotonic)
|
||||
{
|
||||
typedef typename strategy::side::services::default_strategy
|
||||
@@ -125,12 +125,12 @@ class analyse_turn_wrt_piece
|
||||
<
|
||||
coordinate_type,
|
||||
coordinate_type
|
||||
>(previous, current, point);
|
||||
>(previous, current, turn.robust_point);
|
||||
|
||||
if (twice_area == 0)
|
||||
{
|
||||
// Collinear, only on segment if it is covered by its bbox
|
||||
if (in_box(previous, current, point))
|
||||
if (in_box(previous, current, turn.robust_point))
|
||||
{
|
||||
return analyse_on_offsetted;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ class analyse_turn_wrt_piece
|
||||
// segment is the hypothenusa. Check if it is close
|
||||
// (within rounding-area)
|
||||
if (twice_area * twice_area < geometry::comparable_distance(previous, current)
|
||||
&& in_box(previous, current, point))
|
||||
&& in_box(previous, current, turn.robust_point))
|
||||
{
|
||||
return analyse_near_offsetted;
|
||||
}
|
||||
@@ -161,9 +161,9 @@ class analyse_turn_wrt_piece
|
||||
}
|
||||
|
||||
|
||||
template <typename Point>
|
||||
template <typename Point, typename Turn>
|
||||
static inline analyse_result check_helper_segment(Point const& s1,
|
||||
Point const& s2, Point const& point,
|
||||
Point const& s2, Turn const& turn,
|
||||
bool is_original,
|
||||
Point const& offsetted)
|
||||
{
|
||||
@@ -172,7 +172,7 @@ class analyse_turn_wrt_piece
|
||||
typename cs_tag<Point>::type
|
||||
>::type side_strategy;
|
||||
|
||||
switch(side_strategy::apply(s1, s2, point))
|
||||
switch(side_strategy::apply(s1, s2, turn.robust_point))
|
||||
{
|
||||
case 1 :
|
||||
return analyse_disjoint; // left of segment
|
||||
@@ -186,11 +186,11 @@ class analyse_turn_wrt_piece
|
||||
geometry::expand(box, s1);
|
||||
geometry::expand(box, s2);
|
||||
|
||||
if (geometry::covered_by(point, box))
|
||||
if (geometry::covered_by(turn.robust_point, box))
|
||||
{
|
||||
// It is on the segment
|
||||
if (! is_original
|
||||
&& geometry::comparable_distance(point, offsetted) <= 1)
|
||||
&& geometry::comparable_distance(turn.robust_point, offsetted) <= 1)
|
||||
{
|
||||
// It is close to the offsetted-boundary, take
|
||||
// any rounding-issues into account
|
||||
@@ -217,12 +217,13 @@ class analyse_turn_wrt_piece
|
||||
return analyse_continue;
|
||||
}
|
||||
|
||||
template <typename Point, typename Piece>
|
||||
static inline analyse_result check_helper_segments(Point const& point, Piece const& piece)
|
||||
template <typename Turn, typename Piece>
|
||||
static inline analyse_result check_helper_segments(Turn const& turn, Piece const& piece)
|
||||
{
|
||||
geometry::equal_to<Point> comparator;
|
||||
typedef typename Turn::robust_point_type point_type;
|
||||
geometry::equal_to<point_type> comparator;
|
||||
|
||||
Point points[4];
|
||||
point_type points[4];
|
||||
|
||||
int helper_count = piece.robust_ring.size() - piece.offsetted_count;
|
||||
if (helper_count == 4)
|
||||
@@ -249,6 +250,7 @@ class analyse_turn_wrt_piece
|
||||
}
|
||||
|
||||
// First check point-equality
|
||||
point_type const& point = turn.robust_point;
|
||||
if (comparator(point, points[0]) || comparator(point, points[3]))
|
||||
{
|
||||
return analyse_on_offsetted;
|
||||
@@ -260,7 +262,7 @@ class analyse_turn_wrt_piece
|
||||
|
||||
// Right side of the piece
|
||||
analyse_result result
|
||||
= check_helper_segment(points[0], points[1], point,
|
||||
= check_helper_segment(points[0], points[1], turn,
|
||||
false, points[0]);
|
||||
if (result != analyse_continue)
|
||||
{
|
||||
@@ -268,7 +270,7 @@ class analyse_turn_wrt_piece
|
||||
}
|
||||
|
||||
// Left side of the piece
|
||||
result = check_helper_segment(points[2], points[3], point,
|
||||
result = check_helper_segment(points[2], points[3], turn,
|
||||
false, points[3]);
|
||||
if (result != analyse_continue)
|
||||
{
|
||||
@@ -278,7 +280,7 @@ class analyse_turn_wrt_piece
|
||||
if (! comparator(points[1], points[2]))
|
||||
{
|
||||
// Side of the piece at side of original geometry
|
||||
result = check_helper_segment(points[1], points[2], point,
|
||||
result = check_helper_segment(points[1], points[2], turn,
|
||||
true, point);
|
||||
if (result != analyse_continue)
|
||||
{
|
||||
@@ -293,7 +295,7 @@ class analyse_turn_wrt_piece
|
||||
// Not in offsetted-area. This makes a cheap check possible
|
||||
typedef typename strategy::side::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Point>::type
|
||||
typename cs_tag<point_type>::type
|
||||
>::type side_strategy;
|
||||
|
||||
switch(side_strategy::apply(points[3], points[0], point))
|
||||
@@ -307,15 +309,15 @@ class analyse_turn_wrt_piece
|
||||
return analyse_continue;
|
||||
}
|
||||
|
||||
template <typename Point, typename Piece, typename Compare>
|
||||
static inline analyse_result check_monotonic(Point const& point, Piece const& piece, Compare const& compare)
|
||||
template <typename Turn, typename Piece, typename Compare>
|
||||
static inline analyse_result check_monotonic(Turn const& turn, Piece const& piece, Compare const& compare)
|
||||
{
|
||||
typedef typename Piece::piece_robust_ring_type ring_type;
|
||||
typedef typename ring_type::const_iterator it_type;
|
||||
it_type end = piece.robust_ring.begin() + piece.offsetted_count;
|
||||
it_type it = std::lower_bound(piece.robust_ring.begin(),
|
||||
end,
|
||||
point,
|
||||
turn.robust_point,
|
||||
compare);
|
||||
|
||||
if (it != end
|
||||
@@ -325,22 +327,23 @@ class analyse_turn_wrt_piece
|
||||
// w.r.t. specified direction, and prev points to a point smaller
|
||||
// We now know if it is inside/outside
|
||||
it_type prev = it - 1;
|
||||
return check_segment(*prev, *it, point, true);
|
||||
return check_segment(*prev, *it, turn, true);
|
||||
}
|
||||
return analyse_continue;
|
||||
}
|
||||
|
||||
public :
|
||||
template <typename Point, typename Piece>
|
||||
static inline analyse_result apply(Point const& point, Piece const& piece)
|
||||
template <typename Turn, typename Piece>
|
||||
static inline analyse_result apply(Turn const& turn, Piece const& piece)
|
||||
{
|
||||
analyse_result code = check_helper_segments(point, piece);
|
||||
typedef typename Turn::robust_point_type point_type;
|
||||
analyse_result code = check_helper_segments(turn, piece);
|
||||
if (code != analyse_continue)
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
geometry::equal_to<Point> comparator;
|
||||
geometry::equal_to<point_type> comparator;
|
||||
|
||||
if (piece.offsetted_count > 8)
|
||||
{
|
||||
@@ -349,22 +352,22 @@ public :
|
||||
// We try it only once.
|
||||
if (piece.is_monotonic_increasing[0])
|
||||
{
|
||||
code = check_monotonic(point, piece, geometry::less<Point, 0>());
|
||||
code = check_monotonic(turn, piece, geometry::less<point_type, 0>());
|
||||
if (code != analyse_continue) return code;
|
||||
}
|
||||
else if (piece.is_monotonic_increasing[1])
|
||||
{
|
||||
code = check_monotonic(point, piece, geometry::less<Point, 1>());
|
||||
code = check_monotonic(turn, piece, geometry::less<point_type, 1>());
|
||||
if (code != analyse_continue) return code;
|
||||
}
|
||||
else if (piece.is_monotonic_decreasing[0])
|
||||
{
|
||||
code = check_monotonic(point, piece, geometry::greater<Point, 0>());
|
||||
code = check_monotonic(turn, piece, geometry::greater<point_type, 0>());
|
||||
if (code != analyse_continue) return code;
|
||||
}
|
||||
else if (piece.is_monotonic_decreasing[1])
|
||||
{
|
||||
code = check_monotonic(point, piece, geometry::greater<Point, 1>());
|
||||
code = check_monotonic(turn, piece, geometry::greater<point_type, 1>());
|
||||
if (code != analyse_continue) return code;
|
||||
}
|
||||
}
|
||||
@@ -374,14 +377,14 @@ public :
|
||||
|
||||
for (int i = 1; i < piece.offsetted_count; i++)
|
||||
{
|
||||
Point const& previous = piece.robust_ring[i - 1];
|
||||
Point const& current = piece.robust_ring[i];
|
||||
point_type const& previous = piece.robust_ring[i - 1];
|
||||
point_type const& current = piece.robust_ring[i];
|
||||
|
||||
// The robust ring can contain duplicates
|
||||
// (on which any side or side-value would return 0)
|
||||
if (! comparator(previous, current))
|
||||
{
|
||||
code = check_segment(previous, current, point, false);
|
||||
code = check_segment(previous, current, turn, false);
|
||||
if (code != analyse_continue)
|
||||
{
|
||||
return code;
|
||||
@@ -460,7 +463,7 @@ public:
|
||||
|
||||
// TODO: mutable_piece to make some on-demand preparations in analyse
|
||||
analyse_result analyse_code
|
||||
= analyse_turn_wrt_piece::apply(turn.robust_point, piece);
|
||||
= analyse_turn_wrt_piece::apply(turn, piece);
|
||||
|
||||
Turn& mutable_turn = m_turns[turn.turn_index];
|
||||
switch(analyse_code)
|
||||
|
||||
@@ -98,11 +98,10 @@ struct assign_disjoint_policy
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const&,
|
||||
IntersectionInfo const&, DirInfo const&)
|
||||
IntersectionInfo const&)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
@@ -26,7 +28,8 @@
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#endif
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#endif // BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -37,39 +40,67 @@ namespace detail { namespace is_simple
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
template <typename MultiLinestring>
|
||||
inline void debug_print_boundary_points(MultiLinestring const& multilinestring)
|
||||
template <typename Linear, typename Tag = typename tag<Linear>::type>
|
||||
struct debug_boundary_points_printer
|
||||
: not_implemented<Linear>
|
||||
{};
|
||||
|
||||
template <typename Linestring>
|
||||
struct debug_boundary_points_printer<Linestring, linestring_tag>
|
||||
{
|
||||
typedef typename point_type<MultiLinestring>::type point_type;
|
||||
typedef std::vector<point_type> point_vector;
|
||||
|
||||
point_vector boundary_points;
|
||||
for (typename boost::range_iterator<MultiLinestring const>::type it
|
||||
= boost::begin(multilinestring);
|
||||
it != boost::end(multilinestring); ++it)
|
||||
static inline void apply(Linestring const& linestring)
|
||||
{
|
||||
if ( boost::size(*it) > 1
|
||||
&& !geometry::equals(range::front(*it), range::back(*it)) )
|
||||
std::cout << "boundary points: ";
|
||||
std::cout << " " << geometry::dsv(range::front(linestring));
|
||||
std::cout << " " << geometry::dsv(range::back(linestring));
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct debug_boundary_points_printer<MultiLinestring, multi_linestring_tag>
|
||||
{
|
||||
static inline void apply(MultiLinestring const& multilinestring)
|
||||
{
|
||||
typedef typename point_type<MultiLinestring>::type point_type;
|
||||
typedef std::vector<point_type> point_vector;
|
||||
|
||||
point_vector boundary_points;
|
||||
for (typename boost::range_iterator<MultiLinestring const>::type it
|
||||
= boost::begin(multilinestring);
|
||||
it != boost::end(multilinestring); ++it)
|
||||
{
|
||||
boundary_points.push_back( range::front(*it) );
|
||||
boundary_points.push_back( range::back(*it) );
|
||||
if ( boost::size(*it) > 1
|
||||
&& !geometry::equals(range::front(*it), range::back(*it)) )
|
||||
{
|
||||
boundary_points.push_back( range::front(*it) );
|
||||
boundary_points.push_back( range::back(*it) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(boundary_points.begin(), boundary_points.end(),
|
||||
geometry::less<point_type>());
|
||||
std::sort(boundary_points.begin(), boundary_points.end(),
|
||||
geometry::less<point_type>());
|
||||
|
||||
std::cout << "boundary points: ";
|
||||
for (typename point_vector::const_iterator pit = boundary_points.begin();
|
||||
pit != boundary_points.end(); ++pit)
|
||||
{
|
||||
std::cout << " " << geometry::dsv(*pit);
|
||||
std::cout << "boundary points: ";
|
||||
for (typename point_vector::const_iterator
|
||||
pit = boundary_points.begin();
|
||||
pit != boundary_points.end(); ++pit)
|
||||
{
|
||||
std::cout << " " << geometry::dsv(*pit);
|
||||
}
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
std::cout << std::endl << std::endl;
|
||||
};
|
||||
|
||||
|
||||
template <typename Linear>
|
||||
inline void debug_print_boundary_points(Linear const& linear)
|
||||
{
|
||||
debug_boundary_points_printer<Linear>::apply(linear);
|
||||
}
|
||||
#else
|
||||
template <typename MultiLinestring>
|
||||
inline void debug_print_boundary_points(MultiLinestring const&)
|
||||
template <typename Linear>
|
||||
inline void debug_print_boundary_points(Linear const&)
|
||||
{
|
||||
}
|
||||
#endif // BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
@@ -29,8 +30,10 @@
|
||||
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
@@ -54,128 +57,210 @@ namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
template <typename Turn>
|
||||
inline bool check_segment_indices(Turn const& turn,
|
||||
signed_index_type last_index)
|
||||
{
|
||||
return
|
||||
(turn.operations[0].seg_id.segment_index == 0
|
||||
&& turn.operations[1].seg_id.segment_index == last_index)
|
||||
||
|
||||
(turn.operations[0].seg_id.segment_index == 0
|
||||
&& turn.operations[1].seg_id.segment_index == last_index);
|
||||
}
|
||||
|
||||
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
class is_acceptable_turn
|
||||
: not_implemented<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Linestring>
|
||||
class is_acceptable_turn<Linestring, linestring_tag>
|
||||
{
|
||||
public:
|
||||
is_acceptable_turn(Linestring const& linestring)
|
||||
: m_linestring(linestring)
|
||||
, m_is_closed(geometry::equals(range::front(linestring),
|
||||
range::back(linestring)))
|
||||
{}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool apply(Turn const& turn) const
|
||||
{
|
||||
BOOST_ASSERT(boost::size(m_linestring) > 1);
|
||||
return m_is_closed
|
||||
&& turn.method == overlay::method_none
|
||||
&& check_segment_indices(turn, boost::size(m_linestring) - 2)
|
||||
&& turn.operations[0].fraction.is_zero();
|
||||
}
|
||||
|
||||
private:
|
||||
Linestring const& m_linestring;
|
||||
bool const m_is_closed;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring>
|
||||
class is_acceptable_turn<MultiLinestring, multi_linestring_tag>
|
||||
{
|
||||
private:
|
||||
typedef typename boost::range_value<MultiLinestring>::type linestring_type;
|
||||
typedef is_acceptable_turn<linestring_type> base_type;
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
static inline bool is_boundary_point_of(Point const& point,
|
||||
Linestring const& linestring)
|
||||
{
|
||||
BOOST_ASSERT(boost::size(linestring) > 1);
|
||||
return
|
||||
! geometry::equals(range::front(linestring),
|
||||
range::back(linestring))
|
||||
&&
|
||||
(geometry::equals(point, range::front(linestring))
|
||||
|| geometry::equals(point, range::back(linestring)));
|
||||
}
|
||||
|
||||
template <typename Turn, typename Linestring>
|
||||
static inline bool is_closing_point_of(Turn const& turn,
|
||||
Linestring const& linestring)
|
||||
{
|
||||
BOOST_ASSERT(boost::size(linestring) > 1);
|
||||
return
|
||||
turn.method == overlay::method_none
|
||||
&&
|
||||
check_segment_indices(turn, boost::size(linestring) - 2)
|
||||
&&
|
||||
geometry::equals(range::front(linestring), range::back(linestring))
|
||||
&&
|
||||
turn.operations[0].fraction.is_zero();
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
static inline bool have_same_boundary_points(Linestring1 const& ls1,
|
||||
Linestring2 const& ls2)
|
||||
{
|
||||
return
|
||||
geometry::equals(range::front(ls1), range::front(ls2))
|
||||
?
|
||||
geometry::equals(range::back(ls1), range::back(ls2))
|
||||
:
|
||||
(geometry::equals(range::front(ls1), range::back(ls2))
|
||||
&&
|
||||
geometry::equals(range::back(ls1), range::front(ls2)))
|
||||
;
|
||||
}
|
||||
|
||||
public:
|
||||
is_acceptable_turn(MultiLinestring const& multilinestring)
|
||||
: m_multilinestring(multilinestring)
|
||||
{}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool apply(Turn const& turn) const
|
||||
{
|
||||
linestring_type const& ls1 =
|
||||
range::at(m_multilinestring, turn.operations[0].seg_id.multi_index);
|
||||
|
||||
linestring_type const& ls2 =
|
||||
range::at(m_multilinestring, turn.operations[1].seg_id.multi_index);
|
||||
|
||||
if (turn.operations[0].seg_id.multi_index
|
||||
== turn.operations[1].seg_id.multi_index)
|
||||
{
|
||||
return is_closing_point_of(turn, ls1);
|
||||
}
|
||||
|
||||
return
|
||||
is_boundary_point_of(turn.point, ls1)
|
||||
&& is_boundary_point_of(turn.point, ls2)
|
||||
&&
|
||||
( boost::size(ls1) != 2
|
||||
|| boost::size(ls2) != 2
|
||||
|| ! have_same_boundary_points(ls1, ls2) );
|
||||
}
|
||||
|
||||
private:
|
||||
MultiLinestring const& m_multilinestring;
|
||||
};
|
||||
|
||||
|
||||
template <typename Linear>
|
||||
inline bool has_self_intersections(Linear const& linear)
|
||||
{
|
||||
typedef typename point_type<Linear>::type point_type;
|
||||
|
||||
// compute self turns
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
geometry::segment_ratio
|
||||
<
|
||||
typename geometry::coordinate_type<point_type>::type
|
||||
>
|
||||
> turn_info;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::disjoint::assign_disjoint_policy
|
||||
> turn_policy;
|
||||
|
||||
is_acceptable_turn<Linear> predicate(linear);
|
||||
detail::overlay::predicate_based_interrupt_policy
|
||||
<
|
||||
is_acceptable_turn<Linear>
|
||||
> interrupt_policy(predicate);
|
||||
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
turn_policy
|
||||
>::apply(linear,
|
||||
detail::no_rescale_policy(),
|
||||
turns,
|
||||
interrupt_policy);
|
||||
|
||||
detail::is_valid::debug_print_turns(turns.begin(), turns.end());
|
||||
debug_print_boundary_points(linear);
|
||||
|
||||
return interrupt_policy.has_intersections;
|
||||
}
|
||||
|
||||
|
||||
template <typename Linestring, bool CheckSelfIntersections = true>
|
||||
struct is_simple_linestring
|
||||
{
|
||||
static inline bool apply(Linestring const& linestring)
|
||||
{
|
||||
return !detail::is_valid::has_duplicates
|
||||
return ! detail::is_valid::has_duplicates
|
||||
<
|
||||
Linestring, closed
|
||||
>::apply(linestring)
|
||||
&& !detail::is_valid::has_spikes
|
||||
&& ! detail::is_valid::has_spikes
|
||||
<
|
||||
Linestring, closed
|
||||
>::apply(linestring)
|
||||
&& !(CheckSelfIntersections && geometry::intersects(linestring));
|
||||
&& ! (CheckSelfIntersections && has_self_intersections(linestring));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename MultiLinestring>
|
||||
class is_simple_multilinestring
|
||||
struct is_simple_multilinestring
|
||||
{
|
||||
private:
|
||||
class is_acceptable_turn
|
||||
{
|
||||
private:
|
||||
template <typename Point, typename Linestring>
|
||||
static inline bool is_boundary_point_of(Point const& point,
|
||||
Linestring const& linestring)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(linestring) > 1 );
|
||||
return
|
||||
!geometry::equals(range::front(linestring),
|
||||
range::back(linestring))
|
||||
&&
|
||||
( geometry::equals(point, range::front(linestring))
|
||||
|| geometry::equals(point, range::back(linestring)) );
|
||||
}
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
static inline bool is_closing_point_of(Point const& point,
|
||||
Linestring const& linestring)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(linestring) > 1 );
|
||||
return
|
||||
geometry::equals(range::front(linestring),
|
||||
range::back(linestring))
|
||||
&&
|
||||
geometry::equals(range::front(linestring), point)
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
static inline bool have_same_boundary_points(Linestring1 const& ls1,
|
||||
Linestring2 const& ls2)
|
||||
{
|
||||
return
|
||||
geometry::equals(range::front(ls1), range::front(ls2))
|
||||
?
|
||||
geometry::equals(range::back(ls1), range::back(ls2))
|
||||
:
|
||||
(geometry::equals(range::front(ls1), range::back(ls2))
|
||||
&&
|
||||
geometry::equals(range::back(ls1), range::front(ls2))
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
public:
|
||||
is_acceptable_turn(MultiLinestring const& multilinestring)
|
||||
: m_multilinestring(multilinestring)
|
||||
{}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool apply(Turn const& turn) const
|
||||
{
|
||||
typedef typename boost::range_value
|
||||
<
|
||||
MultiLinestring
|
||||
>::type linestring;
|
||||
|
||||
linestring const& ls1 =
|
||||
range::at(m_multilinestring,
|
||||
turn.operations[0].seg_id.multi_index);
|
||||
|
||||
linestring const& ls2 =
|
||||
range::at(m_multilinestring,
|
||||
turn.operations[1].seg_id.multi_index);
|
||||
|
||||
if (turn.operations[0].seg_id.multi_index
|
||||
== turn.operations[1].seg_id.multi_index)
|
||||
{
|
||||
BOOST_ASSERT(is_closing_point_of(turn.point, ls1));
|
||||
return true;
|
||||
}
|
||||
|
||||
return
|
||||
is_boundary_point_of(turn.point, ls1)
|
||||
&& is_boundary_point_of(turn.point, ls2)
|
||||
&&
|
||||
( boost::size(ls1) != 2
|
||||
|| boost::size(ls2) != 2
|
||||
|| !have_same_boundary_points(ls1, ls2) );
|
||||
}
|
||||
|
||||
private:
|
||||
MultiLinestring const& m_multilinestring;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
static inline bool apply(MultiLinestring const& multilinestring)
|
||||
{
|
||||
typedef typename boost::range_value<MultiLinestring>::type linestring;
|
||||
typedef typename point_type<MultiLinestring>::type point_type;
|
||||
typedef point_type point;
|
||||
|
||||
|
||||
// check each of the linestrings for simplicity
|
||||
if ( !detail::check_iterator_range
|
||||
// but do not compute self-intersections yet; these will be
|
||||
// computed for the entire multilinestring
|
||||
if ( ! detail::check_iterator_range
|
||||
<
|
||||
is_simple_linestring<linestring>,
|
||||
is_simple_linestring
|
||||
<
|
||||
typename boost::range_value<MultiLinestring>::type,
|
||||
false // do not compute self-intersections
|
||||
>,
|
||||
false // do not allow empty multilinestring
|
||||
>::apply(boost::begin(multilinestring),
|
||||
boost::end(multilinestring))
|
||||
@@ -184,44 +269,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// compute self turns
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
geometry::segment_ratio
|
||||
<
|
||||
typename geometry::coordinate_type<point>::type
|
||||
>
|
||||
> turn_info;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::disjoint::assign_disjoint_policy
|
||||
> turn_policy;
|
||||
|
||||
is_acceptable_turn predicate(multilinestring);
|
||||
detail::overlay::predicate_based_interrupt_policy
|
||||
<
|
||||
is_acceptable_turn
|
||||
> interrupt_policy(predicate);
|
||||
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
turn_policy
|
||||
>::apply(multilinestring,
|
||||
detail::no_rescale_policy(),
|
||||
turns,
|
||||
interrupt_policy);
|
||||
|
||||
detail::is_valid::debug_print_turns(turns.begin(), turns.end());
|
||||
debug_print_boundary_points(multilinestring);
|
||||
|
||||
return !interrupt_policy.has_intersections;
|
||||
return ! has_self_intersections(multilinestring);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
@@ -45,6 +45,10 @@ inline void debug_print_turns(TurnIterator first, TurnIterator beyond)
|
||||
<< tit->operations[0].seg_id.ring_index
|
||||
<< ", "
|
||||
<< tit->operations[1].seg_id.ring_index
|
||||
<< "} {"
|
||||
<< tit->operations[0].seg_id.segment_index
|
||||
<< ", "
|
||||
<< tit->operations[1].seg_id.segment_index
|
||||
<< "} "
|
||||
<< geometry::dsv(tit->point)
|
||||
<< "]";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
@@ -144,7 +144,7 @@ struct is_valid_ring
|
||||
};
|
||||
|
||||
|
||||
}} // namespace dispatch
|
||||
}} // namespace detail::is_valid
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
@@ -503,14 +503,12 @@ struct equal_opposite : public base_turn_handler
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename OutputIterator,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline void apply(Point1 const& pi, Point2 const& qi,
|
||||
/* by value: */ TurnInfo tp,
|
||||
OutputIterator& out,
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
IntersectionInfo const& intersection_info)
|
||||
{
|
||||
// For equal-opposite segments, normally don't do anything.
|
||||
if (AssignPolicy::include_opposite)
|
||||
@@ -520,10 +518,10 @@ struct equal_opposite : public base_turn_handler
|
||||
{
|
||||
tp.operations[i].operation = operation_opposite;
|
||||
}
|
||||
for (unsigned int i = 0; i < intersection_info.count; i++)
|
||||
for (unsigned int i = 0; i < intersection_info.i_info().count; i++)
|
||||
{
|
||||
assign_point(tp, method_none, intersection_info, i);
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
assign_point(tp, method_none, intersection_info.i_info(), i);
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -715,7 +713,6 @@ public:
|
||||
typename Point2,
|
||||
typename OutputIterator,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo,
|
||||
typename SidePolicy
|
||||
>
|
||||
static inline void apply(
|
||||
@@ -727,10 +724,9 @@ public:
|
||||
OutputIterator& out,
|
||||
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info,
|
||||
SidePolicy const& side)
|
||||
{
|
||||
apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, dir_info, side, empty_transformer);
|
||||
apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, side, empty_transformer);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -740,7 +736,6 @@ public:
|
||||
typename Point2,
|
||||
typename OutputIterator,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo,
|
||||
typename SidePolicy,
|
||||
typename TurnTransformer
|
||||
>
|
||||
@@ -752,50 +747,52 @@ public:
|
||||
TurnInfo const& tp_model,
|
||||
OutputIterator& out,
|
||||
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info,
|
||||
IntersectionInfo const& info,
|
||||
SidePolicy const& side,
|
||||
TurnTransformer turn_transformer,
|
||||
bool const is_pk_valid = true, bool const is_qk_valid = true)
|
||||
{
|
||||
TurnInfo tp = tp_model;
|
||||
|
||||
int const p_arrival = info.d_info().arrival[0];
|
||||
int const q_arrival = info.d_info().arrival[1];
|
||||
|
||||
// If P arrives within Q, there is a turn dependent on P
|
||||
if ( dir_info.arrival[0] == 1
|
||||
if ( p_arrival == 1
|
||||
&& is_pk_valid
|
||||
&& set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info) )
|
||||
&& set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, info.i_info()) )
|
||||
{
|
||||
turn_transformer(tp);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
AssignPolicy::apply(tp, pi, qi, info);
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
// If Q arrives within P, there is a turn dependent on Q
|
||||
if ( dir_info.arrival[1] == 1
|
||||
if ( q_arrival == 1
|
||||
&& is_qk_valid
|
||||
&& set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info) )
|
||||
&& set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, info.i_info()) )
|
||||
{
|
||||
turn_transformer(tp);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
AssignPolicy::apply(tp, pi, qi, info);
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
if (AssignPolicy::include_opposite)
|
||||
{
|
||||
// Handle cases not yet handled above
|
||||
if ((dir_info.arrival[1] == -1 && dir_info.arrival[0] == 0)
|
||||
|| (dir_info.arrival[0] == -1 && dir_info.arrival[1] == 0))
|
||||
if ((q_arrival == -1 && p_arrival == 0)
|
||||
|| (p_arrival == -1 && q_arrival == 0))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
tp.operations[i].operation = operation_opposite;
|
||||
}
|
||||
for (unsigned int i = 0; i < intersection_info.count; i++)
|
||||
for (unsigned int i = 0; i < info.i_info().count; i++)
|
||||
{
|
||||
assign_point(tp, method_collinear, intersection_info, i);
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
assign_point(tp, method_collinear, info.i_info(), i);
|
||||
AssignPolicy::apply(tp, pi, qi, info);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -867,10 +864,9 @@ struct assign_null_policy
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&, DirInfo const&)
|
||||
static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&)
|
||||
{}
|
||||
|
||||
};
|
||||
@@ -933,7 +929,7 @@ struct get_turn_info
|
||||
&& inters.i_info().count > 0)
|
||||
{
|
||||
only_convert::apply(tp, inters.i_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -968,7 +964,7 @@ struct get_turn_info
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
swapped_side_calc);
|
||||
}
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -976,7 +972,7 @@ struct get_turn_info
|
||||
{
|
||||
crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -985,7 +981,7 @@ struct get_turn_info
|
||||
// Both touch (both arrive there)
|
||||
touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -997,7 +993,7 @@ struct get_turn_info
|
||||
// or collinear-and-ending at intersection point
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
else
|
||||
@@ -1007,7 +1003,7 @@ struct get_turn_info
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, qi,
|
||||
tp, out, inters.i_info(), inters.d_info());
|
||||
tp, out, inters);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1032,7 +1028,7 @@ struct get_turn_info
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
else
|
||||
@@ -1042,7 +1038,7 @@ struct get_turn_info
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, inters.i_info(), inters.d_info(), inters.sides());
|
||||
tp, out, inters, inters.sides());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1052,7 +1048,7 @@ struct get_turn_info
|
||||
if (AssignPolicy::include_degenerate)
|
||||
{
|
||||
only_convert::apply(tp, inters.i_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,7 +585,9 @@ struct get_turn_info_for_endpoint
|
||||
}
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
// TODO: this should get an intersection_info, which is unavailable here
|
||||
// Because the assign_null policy accepts any structure, we pass the result instead for now
|
||||
AssignPolicy::apply(tp, pi, qi, result);
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ struct get_turn_info_linear_areal
|
||||
calculate_spike_operation(tp.operations[0].operation,
|
||||
inters, is_p_last);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
|
||||
*out++ = tp;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ struct get_turn_info_linear_areal
|
||||
|
||||
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -222,7 +222,7 @@ struct get_turn_info_linear_areal
|
||||
inters, is_p_last);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
|
||||
if ( ! handle_spikes
|
||||
|| ignore_spike
|
||||
@@ -258,7 +258,7 @@ struct get_turn_info_linear_areal
|
||||
transformer(tp);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
@@ -275,7 +275,7 @@ struct get_turn_info_linear_areal
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, qi,
|
||||
tp, out, inters.i_info(), inters.d_info());
|
||||
tp, out, inters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,7 +321,7 @@ struct get_turn_info_linear_areal
|
||||
transformer(tp);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
@@ -353,7 +353,7 @@ struct get_turn_info_linear_areal
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, inters.i_info(), inters.d_info(),
|
||||
tp, out, inters,
|
||||
inters.sides(), transformer,
|
||||
!is_p_last, true); // qk is always valid
|
||||
}
|
||||
@@ -379,7 +379,7 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
// tp.operations[1].position = position_middle;
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -567,7 +567,7 @@ struct get_turn_info_linear_areal
|
||||
BOOST_ASSERT(inters.i_info().count > 1);
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1);
|
||||
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
|
||||
}
|
||||
|
||||
tp.operations[0].operation = operation_blocked;
|
||||
@@ -793,7 +793,7 @@ struct get_turn_info_linear_areal
|
||||
// here is_p_first_ip == true
|
||||
tp.operations[0].is_collinear = false;
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
|
||||
was_first_point_handled = true;
|
||||
@@ -846,7 +846,7 @@ struct get_turn_info_linear_areal
|
||||
int ip_index = ip_count > 1 ? 1 : 0;
|
||||
base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
|
||||
// don't ignore the first IP if the segment is opposite
|
||||
|
||||
@@ -120,7 +120,7 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[0].operation,
|
||||
tp.operations[1].operation);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ struct get_turn_info_linear_linear
|
||||
|
||||
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -260,7 +260,7 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[1].operation);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
|
||||
if ( ! handle_spikes
|
||||
|| ! append_opposite_spikes<append_touches>(tp, inters,
|
||||
@@ -293,18 +293,24 @@ struct get_turn_info_linear_linear
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
operation_type spike_op
|
||||
= ( tp.operations[0].operation != operation_continue
|
||||
|| tp.operations[1].operation != operation_continue ) ?
|
||||
operation_union :
|
||||
operation_continue;
|
||||
|
||||
// transform turn
|
||||
turn_transformer_ec transformer(method_touch);
|
||||
transformer(tp);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
|| ! append_collinear_spikes(tp, inters,
|
||||
is_p_last, is_q_last,
|
||||
method_touch, operation_union,
|
||||
method_touch, spike_op,
|
||||
out) )
|
||||
{
|
||||
*out++ = tp; // no spikes
|
||||
@@ -318,7 +324,7 @@ struct get_turn_info_linear_linear
|
||||
<
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, qi, tp, out, inters.i_info(), inters.d_info());
|
||||
>::apply(pi, qi, tp, out, inters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,7 +377,7 @@ struct get_turn_info_linear_linear
|
||||
transformer(tp);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
@@ -406,7 +412,7 @@ struct get_turn_info_linear_linear
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, inters.i_info(), inters.d_info(), inters.sides(),
|
||||
tp, out, inters, inters.sides(),
|
||||
transformer, !is_p_last, !is_q_last);
|
||||
}
|
||||
}
|
||||
@@ -441,7 +447,7 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[1].position = position_back;
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -482,6 +488,14 @@ struct get_turn_info_linear_linear
|
||||
|
||||
if ( is_p_spike && is_q_spike )
|
||||
{
|
||||
if ( tp.method == method_equal
|
||||
&& tp.operations[0].operation == operation_continue
|
||||
&& tp.operations[1].operation == operation_continue )
|
||||
{
|
||||
// treat both non-opposite collinear spikes as no-spikes
|
||||
return false;
|
||||
}
|
||||
|
||||
tp.method = method;
|
||||
tp.operations[0].operation = operation_blocked;
|
||||
tp.operations[1].operation = operation_blocked;
|
||||
@@ -564,8 +578,7 @@ struct get_turn_info_linear_linear
|
||||
base_turn_handler::assign_point(tp, method_touch_interior,
|
||||
inters.i_info(), 1);
|
||||
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(),
|
||||
inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
|
||||
}
|
||||
|
||||
tp.operations[0].operation = operation_blocked;
|
||||
@@ -595,8 +608,7 @@ struct get_turn_info_linear_linear
|
||||
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0);
|
||||
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(),
|
||||
inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
|
||||
}
|
||||
|
||||
tp.operations[0].operation = operation_intersection;
|
||||
|
||||
@@ -144,11 +144,10 @@ protected:
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const& ,
|
||||
IntersectionInfo const& , DirInfo const& )
|
||||
IntersectionInfo const& )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
@@ -174,7 +174,22 @@ BOOST_AUTO_TEST_CASE( test_is_simple_linestring )
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,3 0,5 0,4 0,2 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,3 0,2 0,5 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,2 0,2 2,1 0,0 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 0,2 2,1 0,0 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,10 0,10 10,0 10,0 0,0 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,0 10,5 10,0 0,10 10,10 5,10 0,0 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,0 0,10 0,10 10,0 10,0 0,0 0)"),
|
||||
false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,0 0,0 0,10 0,10 10,0 10,0 0,0 0,0 0,0 0)"),
|
||||
false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,0 0,10 0,10 10,10 10,10 10,10 10,10 10,0 10,0 0,0 0)"),
|
||||
false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 0,2 2,1 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(1 0,2 2,2 0,1 0,0 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 0,2 2,1 0,1 4,0 0)"), false);
|
||||
test_simple(from_wkt<G>("LINESTRING(4 1,10 8,4 6,4 1,10 5,10 3)"),
|
||||
false);
|
||||
test_simple(from_wkt<G>("LINESTRING(10 3,10 5,4 1,4 6,10 8,4 1)"),
|
||||
false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_simple_multilinestring )
|
||||
@@ -249,7 +264,12 @@ BOOST_AUTO_TEST_CASE( test_is_simple_multilinestring )
|
||||
false);
|
||||
test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(-1 -1,-1 0,0 0,0 -1,-1 -1))"),
|
||||
false);
|
||||
test_simple(from_wkt<G>("MULTILINESTRING((0 0,0 10,5 10,0 0,10 10,10 5,10 0,0 0))"), false);
|
||||
test_simple(from_wkt<G>("MULTILINESTRING((0 0,0 10,5 10,0 0,10 10,10 5,10 0,0 0))"),
|
||||
false);
|
||||
test_simple(from_wkt<G>("MULTILINESTRING((4 1,10 8,4 6,4 1,10 5,10 3))"),
|
||||
false);
|
||||
test_simple(from_wkt<G>("MULTILINESTRING((10 3,10 5,4 1,4 6,10 8,4 1))"),
|
||||
false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_simple_areal )
|
||||
|
||||
@@ -604,6 +604,52 @@ void test_open_polygons()
|
||||
false);
|
||||
test::apply(from_wkt<OG>("POLYGON((-10 -10,1 0,1 1,0 1),(-10 -10,-10 10,10 10,10 -10))"),
|
||||
false);
|
||||
|
||||
test::apply
|
||||
(from_wkt<OG>("POLYGON((-6 -10,-6.6923076923076925 -6.711538461538462,\
|
||||
-9 -7,-8.824742268041238 -6.123711340206185,\
|
||||
-10 -6,-8.583333333333332 -4.916666666666667,\
|
||||
-8.094117647058823 -2.4705882352941173,-10 -3,\
|
||||
-8.526315789473683 -0.05263157894736803,-10 1,\
|
||||
-10 10,-7.764705882352941 8.509803921568627,\
|
||||
-7.65090909090909 7.789090909090909,-10 10,\
|
||||
-7.574468085106383 7.304964539007091,-7.4375 6.4375,\
|
||||
-6.5 5.5,-6.4 6,-7.574468085106383 7.304964539007091,\
|
||||
-7.65090909090909 7.789090909090909,\
|
||||
-6.297029702970297 6.514851485148515,\
|
||||
0 0,-6.297029702970297 6.514851485148515,\
|
||||
-4.848484848484849 5.151515151515151,-4 6,\
|
||||
-6.117647058823529 7.411764705882352,\
|
||||
0 0,-6.11764705882353 7.411764705882353,\
|
||||
-7.764705882352941 8.509803921568627,-8 10,\
|
||||
-2.9473684210526314 7.052631578947368,-2 8,\
|
||||
-0.17821782178217824 6.633663366336634,1 10,\
|
||||
1.8095238095238098 5.142857142857142,\
|
||||
3.2038834951456314 4.097087378640777,7 7,\
|
||||
3.7142857142857144 3.7142857142857144,\
|
||||
4.4 3.1999999999999997,8 2,\
|
||||
6.540540540540541 1.5945945945945947,10 -1,\
|
||||
7.454545454545455 -4.393939393939394,8 -5,\
|
||||
7.320754716981132 -4.716981132075472,7 -6,\
|
||||
6.062068965517241 -5.117241379310345,\
|
||||
4.9504132231404965 -5.256198347107438,\
|
||||
6.1506849315068495 -7.123287671232877,9 -8,\
|
||||
6.548387096774194 -7.741935483870968,8 -10,\
|
||||
5.906976744186046 -7.674418604651163,\
|
||||
3.9107142857142856 -7.464285714285714,4 -8,\
|
||||
2.8043478260869565 -7.3478260869565215,\
|
||||
1.7829457364341086 -7.24031007751938,2 -8,\
|
||||
1.0728476821192054 -7.1655629139072845,\
|
||||
-4.3583617747440275 -6.593856655290103,-5 -9,\
|
||||
-5.2020725388601035 -7.720207253886011,-6 -10),\
|
||||
(5.127659574468085 -6.808510638297872,\
|
||||
3.72972972972973 -6.378378378378379,\
|
||||
3.571428571428571 -5.428571428571429,\
|
||||
3.8539325842696632 -5.393258426966292,\
|
||||
5.127659574468085 -6.808510638297872),\
|
||||
(-5.5 4.5,-6.5 5.5,-6.4 6,\
|
||||
-5.263157894736842 4.736842105263158,-5.5 4.5))"),
|
||||
false);
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
@@ -718,6 +764,24 @@ void test_open_multipolygons()
|
||||
// and the invalid case:
|
||||
test::apply(from_wkt<OG>("MULTIPOLYGON(((0 0,100 0,100 100,0 100),(3 3,3 97,97 97,97 3)),((2 2,98 2,98 98,2 98),(1 1,1 99,99 99,99 1)))"),
|
||||
false);
|
||||
|
||||
test::apply
|
||||
(from_wkt<OG>("MULTIPOLYGON(((-1 4,8 -10,-10 10,7 -6,8 -2,\
|
||||
-10 10,-10 1,-3 -4,4 1,-1 2,4 3,-8 10,-5 -9,-1 6,-5 0)),\
|
||||
((-10 -3,-8 1,2 -8,-2 6,-4 0,8 -5,-1 5,8 2)),\
|
||||
((-6 -10,1 10,4 -8,-7 -2,2 0,-4 3,-10 9)),\
|
||||
((10 -1,-2 8,-7 3,-6 8,-9 -7,7 -5)),\
|
||||
((7 7,-4 -4,9 -8,-10 -6)))"),
|
||||
false);
|
||||
|
||||
test::apply
|
||||
(from_wkt<OG>("MULTIPOLYGON(((-1 4,8 -10,-10 10,7 -6,8 -2,\
|
||||
-10 10,-10 1,-3 -4,4 1,-1 2,4 3,-8 10,-5 -9,-1 6,-5 0)),\
|
||||
((-10 -3,-8 1,2 -8,-2 6,-4 0,8 -5,-1 5,8 2)),\
|
||||
((-6 -10,-10 9,-4 3,2 0,-7 -2,4 -8,1 10)),\
|
||||
((10 -1,-2 8,-7 3,-6 8,-9 -7,7 -5)),\
|
||||
((7 7,-10 -6,9 -8,-4 -4)))"),
|
||||
false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_valid_multipolygon )
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
|
||||
//TEST
|
||||
//#include <to_svg.hpp>
|
||||
#include <to_svg.hpp>
|
||||
|
||||
template <typename T>
|
||||
void test_all()
|
||||
@@ -256,6 +256,26 @@ void test_all()
|
||||
"LINESTRING(2 0,0 0,-10 0)",
|
||||
expected("tiu+=")("mui=+"));
|
||||
|
||||
// 03.02.2015
|
||||
test_geometry<ls, ls>("LINESTRING(-7 -8,3 0,4 -1,-7 10)",
|
||||
"LINESTRING(-5 -4,3 0,4 -1,7 -4,2 -1)",
|
||||
expected("tii++")("txu==")("tiu==")("mui=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(-7 -8,3 0,4 -1,-7 10)",
|
||||
"LINESTRING(-5 -4,3 0,7 -4,2 -1)",
|
||||
expected("tii++")("mxu==")("miu==")("mui=+"));
|
||||
|
||||
if ( boost::is_same<T, double>::value )
|
||||
{
|
||||
// FAILING
|
||||
/*test_geometry<ls, ls>("LINESTRING(8 5,5 1,-2 3,1 10)",
|
||||
"LINESTRING(1.9375 1.875, 1.7441860465116283 1.9302325581395348, -0.7692307692307692 2.6483516483516487, -2 3, -1.0071942446043165 5.316546762589928)",
|
||||
expected(""));
|
||||
test_geometry<ls, ls>("LINESTRING(8 5,5 1,-2 3,1 10)",
|
||||
"LINESTRING(1.9375 1.875, 1.7441860465116283 1.9302325581395348, -0.7692307692307692 2.6483516483516487, -2 3, -0.5 6.5)",
|
||||
expected(""));*/
|
||||
}
|
||||
|
||||
|
||||
// TODO:
|
||||
//test_geometry<ls, ls>("LINESTRING(0 0,2 0,1 0)", "LINESTRING(0 1,0 0,2 0)", "1FF00F102");
|
||||
//test_geometry<ls, ls>("LINESTRING(2 0,0 0,1 0)", "LINESTRING(0 1,0 0,2 0)", "1FF00F102");
|
||||
|
||||
@@ -416,6 +416,125 @@ BOOST_AUTO_TEST_CASE( test_difference_linestring_linestring )
|
||||
from_wkt<ML>("MULTILINESTRING((1 1,2 1))"),
|
||||
"lldf25"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(6 0,0 0,5 0)"),
|
||||
from_wkt<L>("LINESTRING(2 0,-10 0)"),
|
||||
from_wkt<ML>("MULTILINESTRING((6 0,2 0),(2 0,5 0))"),
|
||||
"lldf27a"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(6 0,0 0,5 0)"),
|
||||
from_wkt<L>("LINESTRING(2 0,-1 0,-10 0)"),
|
||||
from_wkt<ML>("MULTILINESTRING((6 0,2 0),(2 0,5 0))"),
|
||||
"lldf27b"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(6 0,0 0,5 0)"),
|
||||
from_wkt<L>("LINESTRING(2 0,0 0,-10 0)"),
|
||||
from_wkt<ML>("MULTILINESTRING((6 0,2 0),(2 0,5 0))"),
|
||||
"lldf27c"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(2 0,0 0,-10 0)"),
|
||||
from_wkt<L>("LINESTRING(6 0,0 0,5 0)"),
|
||||
from_wkt<ML>("MULTILINESTRING((0 0,-10 0))"),
|
||||
"lldf27d"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5)"),
|
||||
from_wkt<L>("LINESTRING(-3 2,-3 0,-3 -10)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-3 6,-3 2),(-3 2,-3 5))"),
|
||||
"lldf28a"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-3 2,-3 0,-3 -10)"),
|
||||
from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-3 0,-3 -10))"),
|
||||
"lldf28b"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5)"),
|
||||
from_wkt<L>("LINESTRING(-3 2,-3 0,-3 -10)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-3 6,-3 2),(-3 2,-3 5))"),
|
||||
"lldf28c"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-7 -8,3 0,4 -1)"),
|
||||
from_wkt<L>("LINESTRING(-5 -4,3 0,4 -1,7 -4)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-7 -8,3 0))"),
|
||||
"lldf29a"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-7 -8,3 0,4 -1,-7 10)"),
|
||||
from_wkt<L>("LINESTRING(-5 -4,3 0,4 -1,2 -1)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-7 -8,3 0),(3 0,-7 10))"),
|
||||
"lldf29b"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-7 -8,3 0,4 -1,-7 10)"),
|
||||
from_wkt<L>("LINESTRING(-5 -4,3 0,4 -1,7 -4,2 -1)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-7 -8,3 0),(3 0,-7 10))"),
|
||||
"lldf29c"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-5 -4,3 0,4 -1,7 -4,2 -1)"),
|
||||
from_wkt<L>("LINESTRING(-7 -8,3 0,4 -1,-7 10)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-5 -4,3 0),(4 -1,7 -4,2 -1))"),
|
||||
"lldf29c-r"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,\
|
||||
3 0,4 -1,-7 10,-4 10)"),
|
||||
from_wkt<L>("LINESTRING(-5 -4,3 0,4 -1,7 -4,2 -1,-4 -1,-2 6)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,\
|
||||
3 0),(3 0,-7 10,-4 10))"),
|
||||
"lldf29d"
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_INCLUDE_FAILING_TESTS
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(8 5,5 1,-2 3,1 10)"),
|
||||
from_wkt<L>("LINESTRING(1.9375 1.875,\
|
||||
1.7441860465116283 1.9302325581395348,\
|
||||
-0.7692307692307692 2.6483516483516487,\
|
||||
-2 3,-1.0071942446043165 5.316546762589928)"),
|
||||
from_wkt<ML>("MULTILINESTRING()"),
|
||||
"lldf30a"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(1.9375 1.875,\
|
||||
1.7441860465116283 1.9302325581395348,\
|
||||
-0.7692307692307692 2.6483516483516487,\
|
||||
-2 3,-1.0071942446043165 5.316546762589928)"),
|
||||
from_wkt<L>("LINESTRING(8 5,5 1,-2 3,1 10)"),
|
||||
from_wkt<ML>("MULTILINESTRING()"),
|
||||
"lldf30b"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(5 -8,-7 -6,-3 6,-3 1,-5 4,-1 0,8 5,\
|
||||
5 1,-2 3,1 10,8 5,6 2,7 4)"),
|
||||
from_wkt<L>("LINESTRING(1.9375 1.875,\
|
||||
1.7441860465116283 1.9302325581395348,\
|
||||
-0.7692307692307692 2.6483516483516487,\
|
||||
-2 3,-1.0071942446043165 5.316546762589928)"),
|
||||
from_wkt<ML>("MULTILINESTRING()"),
|
||||
"lldf30c"
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -696,6 +815,31 @@ BOOST_AUTO_TEST_CASE( test_difference_multilinestring_linestring )
|
||||
from_wkt<ML>("MULTILINESTRING((-1 0,-1 10),(0 0,1 0),(19 0,20 0),(25 0,30 0))"),
|
||||
"mlldf05"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<ML>("MULTILINESTRING((-3 2,-3 0,-3 -10))"),
|
||||
from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-3 0,-3 -10))"),
|
||||
"mlldf06a"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<ML>("MULTILINESTRING((6 6,-3 2,-3 0,-3 -10,9 -2))"),
|
||||
from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5,2 -3,-6 10,5 0,2 8,\
|
||||
-6 1,10 -6)"),
|
||||
from_wkt<ML>("MULTILINESTRING((6 6,-3 2),(-3 0,-3 -10,9 -2))"),
|
||||
"mlldf06b"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<ML>("MULTILINESTRING((0 -3,5 4,6 6,-3 2,-3 0,-3 -10,\
|
||||
9 -2,9 5,5 -5,-4 -8,9 0))"),
|
||||
from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5,2 -3,-6 10,5 0,2 8,\
|
||||
-6 1,10 -6)"),
|
||||
from_wkt<ML>("MULTILINESTRING((0 -3,5 4,6 6,-3 2),\
|
||||
(-3 0,-3 -10,9 -2,9 5,5 -5,-4 -8,9 0))"),
|
||||
"mlldf06c"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -376,6 +376,17 @@ BOOST_AUTO_TEST_CASE( test_sym_difference_linestring_linestring )
|
||||
(2 2,5 -1,15 2,18 0))"),
|
||||
"llsdf21"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(0 -3,5 4,6 6,-3 2,-3 0,-3 -10,9 -2,\
|
||||
9 5,5 -5,-4 -8,9 0)"),
|
||||
from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5,2 -3,-6 10,5 0,\
|
||||
2 8,-6 1,10 -6)"),
|
||||
from_wkt<ML>("MULTILINESTRING((0 -3,5 4,6 6,-3 2),\
|
||||
(-3 0,-3 -10,9 -2,9 5,5 -5,-4 -8,9 0),(-3 6,-3 2),\
|
||||
(-3 2,-3 5,2 -3,-6 10,5 0,2 8,-6 1,10 -6))"),
|
||||
"llsdf22"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -617,6 +628,30 @@ BOOST_AUTO_TEST_CASE( test_sym_difference_linestring_multilinestring )
|
||||
(0 1,1 0),(19 0,20 1),(2 2,5 -1,15 2,25 0))"),
|
||||
"lmlsdf18d"
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_INCLUDE_FAILING_TESTS
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(1 5,4 2,1 -1.1,1 6,1 189.7654,2 5,-0.7654 3)"),
|
||||
from_wkt<ML>("MULTILINESTRING((2 5,-0.7654 2),\
|
||||
(-1032.34324 4,1 5,9 7,3 9,0.2 5,1 -0.3),\
|
||||
(1 0.9,1 6,1 -0.6,2.232432 -0.7654,0.9 3,1 5,\
|
||||
-0.7654 9,3 0.1,9 0,-6 8,-0.7 8,0 1,-1032.34324 0))"),
|
||||
/*
|
||||
from_wkt<ML>("MULTILINESTRING((-0.7654 2,2 5),\
|
||||
(1 -0.3,0.2 5,3 9,9 7,1 5,-1032.34 4),\
|
||||
(-1032.34 0,0 1,-0.7 8,-6 8,9 0,3 0.1,\
|
||||
-0.7654 9,1 5,0.9 3,2.23243 -0.7654,1 -0.6),\
|
||||
(-0.7654 3,2 5,1 189.765,1 6),\
|
||||
(1 -0.6,1 -1.1,4 2,1 5))"),
|
||||
*/
|
||||
from_wkt<ML>("MULTILINESTRING((1 5,4 2,1 -1.1,1 -0.6),\
|
||||
(1 6,1 189.7654,2 5,-0.7654 3),(2 5,-0.7654 2),\
|
||||
(-1032.34324 4,1 5,9 7,3 9,0.2 5,1 -0.3),\
|
||||
(1 -0.6,2.232432 -0.7654,0.9 3,1 5,-0.7654 9,\
|
||||
3 0.1,9 0,-6 8,-0.7 8,0 1,-1032.34324 0))"),
|
||||
"lmlsdf19"
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -669,6 +704,25 @@ BOOST_AUTO_TEST_CASE( test_sym_difference_multilinestring_linestring )
|
||||
(17 0,18 1,17 1,16 0),(4 0,3 1))"),
|
||||
"mllsdf04"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<ML>("MULTILINESTRING((0 -3,5 4,6 6,-3 2,-3 0,\
|
||||
-3 -10,9 -2,9 5,5 -5,-4 -8,9 0),\
|
||||
(-7 9,-4 -9,-5 -10,5 3),\
|
||||
(-8 -3,-6 6,-9 0,-4 -3,-1 -10),\
|
||||
(0 1,7 -1,-2 3,-7 1),\
|
||||
(-5 -9,-4 -10,7 -10,0 -6,1 6,2 -1,1 5,-5 -5))"),
|
||||
from_wkt<L>("LINESTRING(-3 6,-3 0,-3 5,2 -3,-6 10,5 0,2 8,\
|
||||
-6 1,10 -6)"),
|
||||
from_wkt<ML>("MULTILINESTRING((0 -3,5 4,6 6,-3 2),\
|
||||
(-3 0,-3 -10,9 -2,9 5,5 -5,-4 -8,9 0),\
|
||||
(-7 9,-4 -9,-5 -10,5 3),\
|
||||
(-8 -3,-6 6,-9 0,-4 -3,-1 -10),\
|
||||
(0 1,7 -1,-2 3,-7 1),\
|
||||
(-5 -9,-4 -10,7 -10,0 -6,1 6,2 -1,1 5,-5 -5),\
|
||||
(-3 6,-3 2),(-3 2,-3 5,2 -3,-6 10,5 0,2 8,-6 1,10 -6))"),
|
||||
"mllsdf05"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <boost/geometry/algorithms/reverse.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/turns/compare_turns.hpp>
|
||||
@@ -44,11 +46,10 @@ private:
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const& ,
|
||||
IntersectionInfo const& , DirInfo const& )
|
||||
IntersectionInfo const&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -461,6 +461,19 @@ BOOST_AUTO_TEST_CASE( test_union_linestring_linestring )
|
||||
(2 2,5 -1,15 2,18 0))"),
|
||||
"llu21a"
|
||||
);
|
||||
|
||||
tester::apply
|
||||
(from_wkt<L>("LINESTRING(-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,3 0,\
|
||||
4 -1,-7 10,-4 10)"),
|
||||
from_wkt<L>("LINESTRING(-5 -4,3 0,4 -1,7 -4,2 -1,-4 -1,-2 6)"),
|
||||
from_wkt<ML>("MULTILINESTRING((-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,3 0,\
|
||||
4 -1,-7 10,-4 10),(-5 -4,3 0),\
|
||||
(4 -1,7 -4,2 -1,-4 -1,-2 6))"),
|
||||
from_wkt<ML>("MULTILINESTRING((-5 -4,3 0,4 -1,7 -4,2 -1,-4 -1,-2 6),\
|
||||
(-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,3 0),\
|
||||
(3 0,-7 10,-4 10))"),
|
||||
"llu22"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user