mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-12 00:02:09 +00:00
[set ops] update linear-linear set op computation based on Adam's modification of turn info that now contains the is_collinear member;
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_FOLLOW_LINEAR_LINEAR_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/follow.hpp>
|
||||
#include <boost/geometry/algorithms/detail/turns/debug_turn.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -63,7 +64,6 @@ static inline bool is_staying_inside(Turn const& turn,
|
||||
template <typename Turn, typename Operation>
|
||||
static inline bool is_leaving(Turn const& turn,
|
||||
Operation const& operation,
|
||||
Operation const& reverse_operation,
|
||||
bool entered)
|
||||
{
|
||||
if ( !entered )
|
||||
@@ -89,29 +89,29 @@ static inline bool is_leaving(Turn const& turn,
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( turn.operations[1].operation == operation_intersection )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ASSERT( turn.operations[1].operation == operation_union
|
||||
|| turn.operations[1].operation == operation_blocked );
|
||||
|
||||
return reverse_operation.operation == operation_intersection;
|
||||
return operation.is_collinear;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename Turn, typename Operation>
|
||||
static inline bool is_isolated_point(Turn const& turn,
|
||||
Operation const& operation,
|
||||
Operation const& reverse_operation,
|
||||
bool entered)
|
||||
bool entered,
|
||||
bool is_point1,
|
||||
bool is_point2)
|
||||
{
|
||||
if ( entered )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( turn.method == method_collinear && (is_point1 || is_point2) )
|
||||
{
|
||||
BOOST_ASSERT( operation.operation == operation_continue );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( turn.method == method_crosses )
|
||||
{
|
||||
return true;
|
||||
@@ -132,17 +132,42 @@ static inline bool is_isolated_point(Turn const& turn,
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( turn.operations[1].operation == operation_intersection )
|
||||
return !operation.is_collinear;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <bool Enable>
|
||||
struct is_point
|
||||
{
|
||||
template <typename Linestring>
|
||||
static inline bool apply(Linestring const& linestring)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct is_point<true>
|
||||
{
|
||||
template <typename Linestring>
|
||||
static inline bool apply(Linestring const& linestring)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(linestring) >= 2 );
|
||||
|
||||
return boost::size(linestring) == 2
|
||||
&& geometry::equals(*boost::begin(linestring),
|
||||
*(++boost::begin(linestring))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
BOOST_ASSERT( turn.operations[1].operation == operation_union
|
||||
|| turn.operations[1].operation == operation_blocked );
|
||||
|
||||
return reverse_operation.operation == operation_union
|
||||
|| reverse_operation.operation == operation_blocked;
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
@@ -166,11 +191,14 @@ protected:
|
||||
typename OutputIterator
|
||||
>
|
||||
static inline OutputIterator
|
||||
process_turn(TurnIterator it, TurnIterator it_r,
|
||||
TurnOperationIterator op_it, TurnOperationIterator op_it_r,
|
||||
process_turn(TurnIterator it,
|
||||
TurnOperationIterator op_it,
|
||||
bool& first, bool& entered,
|
||||
std::size_t& enter_count,
|
||||
LineString1 const& linestring1, LineString2 const&,
|
||||
LineString1 const& linestring1,
|
||||
LineString2 const& linestring2,
|
||||
bool is_point1,
|
||||
bool is_point2,
|
||||
LineStringOut& current_piece,
|
||||
SegmentIdentifier& current_segment_id,
|
||||
OutputIterator oit)
|
||||
@@ -178,7 +206,7 @@ protected:
|
||||
if ( is_entering(*it, *op_it) )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
detail::overlay::debug_traverse(*it, *op_it, "-> Entering");
|
||||
detail::turns::debug_turn(*it, *op_it, "-> Entering");
|
||||
#endif
|
||||
|
||||
entered = true;
|
||||
@@ -191,18 +219,10 @@ protected:
|
||||
}
|
||||
++enter_count;
|
||||
}
|
||||
else if ( is_staying_inside(*it, *op_it, entered) )
|
||||
else if ( is_leaving(*it, *op_it, entered) )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
detail::overlay::debug_traverse(*it, *op_it, "-> Staying inside");
|
||||
#endif
|
||||
|
||||
entered = true;
|
||||
}
|
||||
else if ( is_leaving(*it, *op_it, *op_it_r, entered) )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
detail::overlay::debug_traverse(*it, *op_it, "-> Leaving");
|
||||
detail::turns::debug_turn(*it, *op_it, "-> Leaving");
|
||||
#endif
|
||||
|
||||
--enter_count;
|
||||
@@ -216,11 +236,11 @@ protected:
|
||||
}
|
||||
}
|
||||
#ifndef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS
|
||||
else if ( FollowIsolatedPoints &&
|
||||
is_isolated_point(*it, *op_it, *op_it_r, entered) )
|
||||
else if ( FollowIsolatedPoints
|
||||
&& is_isolated_point(*it, *op_it, entered, is_point1, is_point2) )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
detail::overlay::debug_traverse(*it, *op_it, "-> Isolated point");
|
||||
detail::turns::debug_turn(*it, *op_it, "-> Isolated point");
|
||||
#endif
|
||||
|
||||
action::isolated_point(current_piece, linestring1,
|
||||
@@ -229,6 +249,14 @@ protected:
|
||||
it->point, *op_it, oit);
|
||||
}
|
||||
#endif
|
||||
else if ( is_staying_inside(*it, *op_it, entered) )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
detail::turns::debug_turn(*it, *op_it, "-> Staying inside");
|
||||
#endif
|
||||
|
||||
entered = true;
|
||||
}
|
||||
first = false;
|
||||
return oit;
|
||||
}
|
||||
@@ -267,11 +295,8 @@ public:
|
||||
static inline OutputIterator apply(LineString1 const& linestring1,
|
||||
LineString2 const& linestring2,
|
||||
Turns const& turns,
|
||||
Turns const& reverse_turns,
|
||||
OutputIterator oit)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
|
||||
|
||||
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
|
||||
typedef typename boost::range_value<Turns>::type TurnInfo;
|
||||
typedef typename boost::range_iterator
|
||||
@@ -289,17 +314,17 @@ public:
|
||||
bool first = true;
|
||||
std::size_t enter_count = 0;
|
||||
|
||||
TurnIterator it = boost::begin(turns);
|
||||
TurnIterator it_r = boost::begin(reverse_turns);
|
||||
for (; it != boost::end(turns); ++it, ++it_r)
|
||||
bool is_point1 = is_point<FollowIsolatedPoints>::apply(linestring1);
|
||||
bool is_point2 = is_point<FollowIsolatedPoints>::apply(linestring2);
|
||||
|
||||
for (TurnIterator it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
TurnOperationIterator op_it = boost::begin(it->operations);
|
||||
TurnOperationIterator op_it_r = boost::begin(it_r->operations);
|
||||
++op_it_r;
|
||||
|
||||
oit = process_turn(it, it_r, op_it, op_it_r,
|
||||
oit = process_turn(it, op_it,
|
||||
first, entered, enter_count,
|
||||
linestring1, linestring2,
|
||||
is_point1, is_point2,
|
||||
current_piece, current_segment_id,
|
||||
oit);
|
||||
}
|
||||
@@ -348,11 +373,8 @@ public:
|
||||
static inline OutputIterator apply(LineString const& linestring,
|
||||
MultiLineString const& multilinestring,
|
||||
Turns const& turns,
|
||||
Turns const& reverse_turns,
|
||||
OutputIterator oit)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
|
||||
|
||||
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
|
||||
typedef typename boost::range_value<Turns>::type TurnInfo;
|
||||
typedef typename boost::range_iterator
|
||||
@@ -370,20 +392,20 @@ public:
|
||||
bool first = true;
|
||||
std::size_t enter_count = 0;
|
||||
|
||||
TurnIterator it = boost::begin(turns);
|
||||
TurnIterator it_r = boost::begin(reverse_turns);
|
||||
for (; it != boost::end(turns); ++it, ++it_r)
|
||||
bool is_point1 = is_point<FollowIsolatedPoints>::apply(linestring);
|
||||
|
||||
for (TurnIterator it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
TurnOperationIterator op_it = boost::begin(it->operations);
|
||||
TurnOperationIterator op_it_r = boost::begin(it_r->operations);
|
||||
++op_it_r;
|
||||
|
||||
LineString2 const* linestring2 =
|
||||
&*(boost::begin(multilinestring) + op_it->other_id.multi_index);
|
||||
|
||||
oit = Base::process_turn(it, it_r, op_it, op_it_r,
|
||||
oit = Base::process_turn(it, op_it,
|
||||
first, entered, enter_count,
|
||||
linestring, *linestring2,
|
||||
is_point1,
|
||||
is_point<FollowIsolatedPoints>::apply(*linestring2),
|
||||
current_piece, current_segment_id,
|
||||
oit);
|
||||
}
|
||||
@@ -434,11 +456,8 @@ public:
|
||||
static inline OutputIterator apply(MultiLineString const& multilinestring,
|
||||
LineString const& linestring,
|
||||
Turns const& turns,
|
||||
Turns const& reverse_turns,
|
||||
OutputIterator oit)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
|
||||
|
||||
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
|
||||
typedef typename boost::range_value<Turns>::type TurnInfo;
|
||||
typedef typename boost::range_iterator
|
||||
@@ -461,13 +480,13 @@ public:
|
||||
// dummy initialization
|
||||
LineString1 const* linestring1 = &*boost::begin(multilinestring);
|
||||
|
||||
bool is_point1 = is_point<FollowIsolatedPoints>::apply(*linestring1);
|
||||
bool is_point2 = is_point<FollowIsolatedPoints>::apply(linestring);
|
||||
|
||||
TurnIterator it = boost::begin(turns);
|
||||
TurnIterator it_r = boost::begin(reverse_turns);
|
||||
for (; it != boost::end(turns); ++it, ++it_r)
|
||||
for (TurnIterator it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
TurnOperationIterator op_it = boost::begin(it->operations);
|
||||
TurnOperationIterator op_it_r = boost::begin(it_r->operations);
|
||||
++op_it_r;
|
||||
|
||||
if ( op_it->seg_id.multi_index != current_multi_id )
|
||||
{
|
||||
@@ -492,11 +511,13 @@ public:
|
||||
current_multi_id = op_it->seg_id.multi_index;
|
||||
linestring1 =
|
||||
&*(boost::begin(multilinestring) + current_multi_id);
|
||||
is_point1 = is_point<FollowIsolatedPoints>::apply(*linestring1);
|
||||
}
|
||||
|
||||
oit = Base::process_turn(it, it_r, op_it, op_it_r,
|
||||
oit = Base::process_turn(it, op_it,
|
||||
first, entered, enter_count,
|
||||
*linestring1, linestring,
|
||||
is_point1, is_point2,
|
||||
current_piece, current_segment_id,
|
||||
oit);
|
||||
}
|
||||
@@ -546,11 +567,8 @@ public:
|
||||
static inline OutputIterator apply(MultiLineString1 const& multilinestring1,
|
||||
MultiLineString2 const& multilinestring2,
|
||||
Turns const& turns,
|
||||
Turns const& reverse_turns,
|
||||
OutputIterator oit)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
|
||||
|
||||
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
|
||||
typedef typename boost::range_value<Turns>::type TurnInfo;
|
||||
typedef typename boost::range_iterator
|
||||
@@ -573,13 +591,11 @@ public:
|
||||
// dummy initialization
|
||||
LineString1 const* linestring1 = &*boost::begin(multilinestring1);
|
||||
|
||||
TurnIterator it = boost::begin(turns);
|
||||
TurnIterator it_r = boost::begin(reverse_turns);
|
||||
for (; it != boost::end(turns); ++it, ++it_r)
|
||||
bool is_point1 = is_point<FollowIsolatedPoints>::apply(*linestring1);
|
||||
|
||||
for (TurnIterator it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
TurnOperationIterator op_it = boost::begin(it->operations);
|
||||
TurnOperationIterator op_it_r = boost::begin(it_r->operations);
|
||||
++op_it_r;
|
||||
|
||||
if ( op_it->seg_id.multi_index != current_multi_id )
|
||||
{
|
||||
@@ -604,14 +620,16 @@ public:
|
||||
current_multi_id = op_it->seg_id.multi_index;
|
||||
linestring1 =
|
||||
&*(boost::begin(multilinestring1) + current_multi_id);
|
||||
is_point1 = is_point<FollowIsolatedPoints>::apply(*linestring1);
|
||||
}
|
||||
|
||||
LineString2 const* linestring2 =
|
||||
&*(boost::begin(multilinestring2) + op_it->other_id.multi_index);
|
||||
|
||||
oit = Base::process_turn(it, it_r, op_it, op_it_r,
|
||||
oit = Base::process_turn(it, op_it,
|
||||
first, entered, enter_count,
|
||||
*linestring1, *linestring2,
|
||||
is_point1,
|
||||
is_point<FollowIsolatedPoints>::apply(*linestring2),
|
||||
current_piece, current_segment_id,
|
||||
oit);
|
||||
}
|
||||
|
||||
@@ -13,20 +13,19 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/geometry/algorithms/append.hpp>
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/unique.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/turns/compare_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/turns/print_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp>
|
||||
|
||||
#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_FILTER_CONTINUE_TURNS
|
||||
#include <boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS
|
||||
#include <boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -111,6 +110,48 @@ struct linear_linear_no_intersections
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
bool Enable = false,
|
||||
typename GeometryTag = typename tag<Geometry>::type
|
||||
>
|
||||
struct remove_extra_points
|
||||
{
|
||||
static inline void apply(Geometry& ) {}
|
||||
};
|
||||
|
||||
|
||||
template <typename Linestring>
|
||||
struct remove_extra_points<Linestring, true, linestring_tag>
|
||||
{
|
||||
static inline void apply(Linestring& linestring)
|
||||
{
|
||||
geometry::unique(linestring);
|
||||
if ( boost::size(linestring) == 1 )
|
||||
{
|
||||
geometry::append(linestring, *boost::begin(linestring));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct remove_extra_points<MultiLinestring, true, multi_linestring_tag>
|
||||
{
|
||||
static inline void apply(MultiLinestring& multilinestring)
|
||||
{
|
||||
BOOST_AUTO_TPL(it, boost::begin(multilinestring));
|
||||
for (; it != boost::end(multilinestring); ++it)
|
||||
{
|
||||
remove_extra_points
|
||||
<
|
||||
typename boost::range_value<MultiLinestring>::type,
|
||||
true
|
||||
>::apply(*it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -126,7 +167,8 @@ template
|
||||
typename Linear2,
|
||||
typename LinestringOut,
|
||||
overlay_type OverlayType,
|
||||
bool EnableFilterContinueTurns = true,
|
||||
bool EnableRemoveExtraPoints = true,
|
||||
bool EnableFilterContinueTurns = false,
|
||||
bool EnableRemoveDuplicateTurns = true,
|
||||
bool EnableDegenerateTurns = true
|
||||
>
|
||||
@@ -136,11 +178,7 @@ protected:
|
||||
struct AssignPolicy
|
||||
{
|
||||
static bool const include_no_turn = false;
|
||||
#ifdef BOOST_GEOMETRY_DIFFERENCE_INCLUDE_DEGENERATE_TURNS
|
||||
static bool const include_degenerate = true;
|
||||
#else
|
||||
static bool const include_degenerate = EnableDegenerateTurns;
|
||||
#endif
|
||||
static bool const include_opposite = false;
|
||||
|
||||
template
|
||||
@@ -194,7 +232,6 @@ protected:
|
||||
typename OutputIterator
|
||||
>
|
||||
static inline OutputIterator follow_turns(Turns const& turns,
|
||||
Turns const& reverse_turns,
|
||||
LinearGeometry1 const& linear1,
|
||||
LinearGeometry2 const& linear2,
|
||||
OutputIterator oit)
|
||||
@@ -206,7 +243,7 @@ protected:
|
||||
LinearGeometry2,
|
||||
OverlayTypeForFollow,
|
||||
FollowIsolatedPoints
|
||||
>::apply(linear1, linear2, turns, reverse_turns, oit);
|
||||
>::apply(linear1, linear2, turns, oit);
|
||||
}
|
||||
|
||||
|
||||
@@ -221,54 +258,91 @@ protected:
|
||||
>
|
||||
static inline OutputIterator
|
||||
sort_and_follow_turns(Turns& turns,
|
||||
Turns& reverse_turns,
|
||||
LinearGeometry1 const& linear1,
|
||||
LinearGeometry2 const& linear2,
|
||||
OutputIterator oit)
|
||||
{
|
||||
#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_FILTER_CONTINUE_TURNS
|
||||
// remove turns that have no added value
|
||||
turns::filter_continue_turns
|
||||
<
|
||||
Turns, EnableFilterContinueTurns
|
||||
>::apply(turns);
|
||||
turns::filter_continue_turns
|
||||
<
|
||||
Turns, EnableFilterContinueTurns
|
||||
>::apply(reverse_turns);
|
||||
#endif
|
||||
|
||||
// sort by seg_id, distance, and operation
|
||||
std::sort(boost::begin(turns), boost::end(turns),
|
||||
detail::turns::less_seg_dist_other_op<>());
|
||||
|
||||
std::sort(boost::begin(reverse_turns), boost::end(reverse_turns),
|
||||
detail::turns::less_seg_dist_other_op<std::greater<int> >());
|
||||
|
||||
#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS
|
||||
// remove duplicate turns
|
||||
turns::remove_duplicate_turns
|
||||
<
|
||||
Turns, EnableRemoveDuplicateTurns
|
||||
>::apply(turns);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
Linear2 linear2_reverse(linear2);
|
||||
geometry::reverse(linear2_reverse);
|
||||
Turns reverse_turns;
|
||||
compute_turns(reverse_turns, linear1, linear2_reverse);
|
||||
|
||||
|
||||
Turns turns_copy(turns);
|
||||
Turns reverse_turns_copy(reverse_turns);
|
||||
|
||||
turns::filter_continue_turns
|
||||
<
|
||||
Turns, true //EnableFilterContinueTurns
|
||||
>::apply(turns_copy);
|
||||
|
||||
turns::filter_continue_turns
|
||||
<
|
||||
Turns, EnableFilterContinueTurns
|
||||
>::apply(reverse_turns);
|
||||
|
||||
turns::filter_continue_turns
|
||||
<
|
||||
Turns, true //EnableFilterContinueTurns
|
||||
>::apply(reverse_turns_copy);
|
||||
|
||||
std::sort(boost::begin(turns_copy), boost::end(turns_copy),
|
||||
detail::turns::less_seg_dist_other_op<>());
|
||||
|
||||
std::sort(boost::begin(reverse_turns), boost::end(reverse_turns),
|
||||
detail::turns::less_seg_dist_other_op<std::greater<int> >());
|
||||
|
||||
std::sort(boost::begin(reverse_turns_copy), boost::end(reverse_turns_copy),
|
||||
detail::turns::less_seg_dist_other_op<std::greater<int> >());
|
||||
|
||||
turns::remove_duplicate_turns
|
||||
<
|
||||
Turns, EnableRemoveDuplicateTurns
|
||||
>::apply(reverse_turns);
|
||||
#endif
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
turns::remove_duplicate_turns
|
||||
<
|
||||
Turns, EnableRemoveDuplicateTurns
|
||||
>::apply(reverse_turns_copy);
|
||||
|
||||
BOOST_ASSERT( boost::size(turns_copy) == boost::size(reverse_turns_copy) );
|
||||
|
||||
std::cout << std::endl << std::endl;
|
||||
std::cout << "### ORIGINAL TURNS ###" << std::endl;
|
||||
detail::turns::print_turns(linear1, linear2, turns);
|
||||
std::cout << std::endl << std::endl;
|
||||
Linear2 linear2_reverse = linear2;
|
||||
geometry::reverse(linear2_reverse);
|
||||
detail::turns::print_turns(linear1, linear2_reverse, reverse_turns);
|
||||
std::cout << "### ORIGINAL REVERSE TURNS ###" << std::endl;
|
||||
detail::turns::print_turns(linear1, linear2, reverse_turns);
|
||||
std::cout << std::endl << std::endl;
|
||||
std::cout << "### TURNS W/O CONTINUE TURNS ###" << std::endl;
|
||||
detail::turns::print_turns(linear1, linear2, turns_copy);
|
||||
std::cout << std::endl << std::endl;
|
||||
std::cout << "### REVERSE TURNS W/O CONTINUE TURNS ###" << std::endl;
|
||||
detail::turns::print_turns(linear1, linear2_reverse, reverse_turns_copy);
|
||||
std::cout << std::endl << std::endl;
|
||||
#endif
|
||||
|
||||
return follow_turns
|
||||
<
|
||||
OverlayTypeForFollow, FollowIsolatedPoints
|
||||
>(turns, reverse_turns, linear1, linear2, oit);
|
||||
>(turns, linear1, linear2, oit);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -276,15 +350,21 @@ public:
|
||||
<
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Linear1 const& linear1,
|
||||
Linear2 const& linear2,
|
||||
static inline OutputIterator apply(Linear1 const& lineargeometry1,
|
||||
Linear2 const& lineargeometry2,
|
||||
OutputIterator oit,
|
||||
Strategy const& )
|
||||
{
|
||||
typedef traversal_turn_info
|
||||
Linear1 linear1(lineargeometry1);
|
||||
Linear2 linear2(lineargeometry2);
|
||||
|
||||
remove_extra_points<Linear1, EnableRemoveExtraPoints>::apply(linear1);
|
||||
remove_extra_points<Linear2, EnableRemoveExtraPoints>::apply(linear2);
|
||||
|
||||
typedef typename detail::relate::turns::get_turns
|
||||
<
|
||||
typename point_type<LinestringOut>::type
|
||||
> turn_info;
|
||||
Linear1, Linear2
|
||||
>::turn_info turn_info;
|
||||
|
||||
typedef std::vector<turn_info> Turns;
|
||||
|
||||
@@ -306,16 +386,10 @@ public:
|
||||
>::apply(linear1, oit);
|
||||
}
|
||||
|
||||
|
||||
Turns reverse_turns;
|
||||
Linear2 linear2_reverse = linear2;
|
||||
geometry::reverse(linear2_reverse);
|
||||
compute_turns(reverse_turns, linear1, linear2_reverse);
|
||||
|
||||
return sort_and_follow_turns
|
||||
<
|
||||
OverlayType, OverlayType == overlay_intersection
|
||||
>(turns, reverse_turns, linear1, linear2, oit);
|
||||
>(turns, linear1, linear2, oit);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -326,19 +400,34 @@ template
|
||||
<
|
||||
typename Linear1,
|
||||
typename Linear2,
|
||||
typename LinestringOut
|
||||
typename LinestringOut,
|
||||
bool EnableRemoveExtraPoints,
|
||||
bool EnableFilterContinueTurns,
|
||||
bool EnableRemoveDuplicateTurns,
|
||||
bool EnableDegenerateTurns
|
||||
>
|
||||
struct linear_linear_linestring<Linear1, Linear2, LinestringOut, overlay_union>
|
||||
struct linear_linear_linestring
|
||||
<
|
||||
Linear1, Linear2, LinestringOut, overlay_union,
|
||||
EnableRemoveExtraPoints, EnableFilterContinueTurns,
|
||||
EnableRemoveDuplicateTurns, EnableDegenerateTurns
|
||||
>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Linear1 const& linear1,
|
||||
Linear2 const& linear2,
|
||||
static inline OutputIterator apply(Linear1 const& lineargeometry1,
|
||||
Linear2 const& lineargeometry2,
|
||||
OutputIterator oit,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Linear1 linear1(lineargeometry1);
|
||||
Linear2 linear2(lineargeometry2);
|
||||
|
||||
remove_extra_points<Linear1, EnableRemoveExtraPoints>::apply(linear1);
|
||||
remove_extra_points<Linear2, EnableRemoveExtraPoints>::apply(linear2);
|
||||
|
||||
oit = linear_linear_no_intersections
|
||||
<
|
||||
LinestringOut,
|
||||
@@ -349,7 +438,9 @@ struct linear_linear_linestring<Linear1, Linear2, LinestringOut, overlay_union>
|
||||
|
||||
return linear_linear_linestring
|
||||
<
|
||||
Linear2, Linear1, LinestringOut, overlay_difference
|
||||
Linear2, Linear1, LinestringOut, overlay_difference,
|
||||
false, EnableFilterContinueTurns,
|
||||
EnableRemoveDuplicateTurns, EnableDegenerateTurns
|
||||
>::apply(linear2, linear1, oit, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user