stylistic changes according to Barend's review;

This commit is contained in:
Menelaos Karavelas
2014-03-04 16:24:38 +02:00
parent 1c318af64a
commit 9bbac740b7
6 changed files with 242 additions and 253 deletions

View File

@@ -29,19 +29,21 @@ namespace following { namespace linear
// follower for linear/linear geometries set operations
template <typename Turn, typename Operation>
static inline bool is_entering(Turn const& turn, Operation const& op)
static inline bool is_entering(Turn const& turn,
Operation const& operation)
{
if ( turn.method != method_touch && turn.method != method_touch_interior )
{
return false;
}
return op.operation == operation_intersection;
return operation.operation == operation_intersection;
}
template <typename Turn, typename Operation>
static inline bool is_staying_inside(Turn const& turn, Operation const& op,
static inline bool is_staying_inside(Turn const& turn,
Operation const& operation,
bool entered)
{
if ( !entered )
@@ -53,14 +55,15 @@ static inline bool is_staying_inside(Turn const& turn, Operation const& op,
{
return false;
}
return op.operation == operation_continue;
return operation.operation == operation_continue;
}
template <typename Turn, typename Operation>
static inline bool is_leaving(Turn const& turn, Operation const& op,
Operation const& reverse_op,
static inline bool is_leaving(Turn const& turn,
Operation const& operation,
Operation const& reverse_operation,
bool entered)
{
if ( !entered )
@@ -68,20 +71,20 @@ static inline bool is_leaving(Turn const& turn, Operation const& op,
return false;
}
if ( turn.method != method_touch &&
turn.method != method_touch_interior &&
turn.method != method_equal &&
turn.method != method_collinear )
if ( turn.method != method_touch
&& turn.method != method_touch_interior
&& turn.method != method_equal
&& turn.method != method_collinear )
{
return false;
}
if ( op.operation == operation_blocked )
if ( operation.operation == operation_blocked )
{
return true;
}
if ( op.operation != operation_union )
if ( operation.operation != operation_union )
{
return false;
}
@@ -91,16 +94,17 @@ static inline bool is_leaving(Turn const& turn, Operation const& op,
return true;
}
BOOST_ASSERT( turn.operations[1].operation == operation_union ||
turn.operations[1].operation == operation_blocked );
BOOST_ASSERT( turn.operations[1].operation == operation_union
|| turn.operations[1].operation == operation_blocked );
return reverse_op.operation == operation_intersection;
return reverse_operation.operation == operation_intersection;
}
template <typename Turn, typename Operation>
static inline bool is_isolated_point(Turn const& turn, Operation const& op,
Operation const& reverse_op,
static inline bool is_isolated_point(Turn const& turn,
Operation const& operation,
Operation const& reverse_operation,
bool entered)
{
if ( entered )
@@ -118,12 +122,12 @@ static inline bool is_isolated_point(Turn const& turn, Operation const& op,
return false;
}
if ( op.operation == operation_blocked )
if ( operation.operation == operation_blocked )
{
return true;
}
if ( op.operation != operation_union )
if ( operation.operation != operation_union )
{
return false;
}
@@ -133,11 +137,11 @@ static inline bool is_isolated_point(Turn const& turn, Operation const& op,
return false;
}
BOOST_ASSERT( turn.operations[1].operation == operation_union ||
turn.operations[1].operation == operation_blocked );
BOOST_ASSERT( turn.operations[1].operation == operation_union
|| turn.operations[1].operation == operation_blocked );
return reverse_op.operation == operation_union
|| reverse_op.operation == operation_blocked;
return reverse_operation.operation == operation_union
|| reverse_operation.operation == operation_blocked;
}
@@ -152,82 +156,77 @@ template
class follow_linestring_linestring_linestring
{
protected:
typedef typename point_type<LineStringOut>::type PointOut;
typedef traversal_turn_info<PointOut> turn_info;
typedef typename boost::range_iterator
<
typename turn_info::container_type const
>::type turn_operation_iterator_type;
typedef following::action_selector<OverlayType> action;
template
<
typename TurnIt,
typename TurnOpIt,
typename TurnIterator,
typename TurnOperationIterator,
typename SegmentIdentifier,
typename OutputIterator
>
static inline OutputIterator
process_turn(TurnIt it, TurnIt it_r,
TurnOpIt iit, TurnOpIt iit_r,
process_turn(TurnIterator it, TurnIterator it_r,
TurnOperationIterator op_it, TurnOperationIterator op_it_r,
bool& first, bool& entered,
std::size_t& enter_count,
LineString1 const& ls1, LineString2 const&,
LineString1 const& linestring1, LineString2 const&,
LineStringOut& current_piece,
SegmentIdentifier& current_segment_id,
OutputIterator oit)
{
if ( is_entering(*it, *iit) )
if ( is_entering(*it, *op_it) )
{
#ifdef GEOMETRY_TEST_DEBUG
detail::overlay::debug_traverse(*it, *iit, "-> Entering");
detail::overlay::debug_traverse(*it, *op_it, "-> Entering");
#endif
entered = true;
if ( enter_count == 0 )
{
action::enter(current_piece, ls1, current_segment_id,
iit->seg_id.segment_index,
it->point, *iit, oit);
action::enter(current_piece, linestring1,
current_segment_id,
op_it->seg_id.segment_index,
it->point, *op_it, oit);
}
++enter_count;
}
else if ( is_staying_inside(*it, *iit, entered) )
else if ( is_staying_inside(*it, *op_it, entered) )
{
#ifdef GEOMETRY_TEST_DEBUG
detail::overlay::debug_traverse(*it, *iit, "-> Staying inside");
detail::overlay::debug_traverse(*it, *op_it, "-> Staying inside");
#endif
entered = true;
}
else if ( is_leaving(*it, *iit, *iit_r, entered) )
else if ( is_leaving(*it, *op_it, *op_it_r, entered) )
{
#ifdef GEOMETRY_TEST_DEBUG
detail::overlay::debug_traverse(*it, *iit, "-> Leaving");
detail::overlay::debug_traverse(*it, *op_it, "-> Leaving");
#endif
--enter_count;
if ( enter_count == 0 )
{
entered = false;
action::leave(current_piece, ls1, current_segment_id,
iit->seg_id.segment_index,
it->point, *iit, oit);
action::leave(current_piece, linestring1,
current_segment_id,
op_it->seg_id.segment_index,
it->point, *op_it, oit);
}
}
#ifndef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS
else if ( FollowIsolatedPoints &&
is_isolated_point(*it, *iit, *iit_r, entered) )
is_isolated_point(*it, *op_it, *op_it_r, entered) )
{
#ifdef GEOMETRY_TEST_DEBUG
detail::overlay::debug_traverse(*it, *iit, "-> Isolated point");
detail::overlay::debug_traverse(*it, *op_it, "-> Isolated point");
#endif
action::isolated_point(current_piece, ls1, current_segment_id,
iit->seg_id.segment_index,
it->point, *iit, oit);
action::isolated_point(current_piece, linestring1,
current_segment_id,
op_it->seg_id.segment_index,
it->point, *op_it, oit);
}
#endif
first = false;
@@ -248,7 +247,8 @@ protected:
{
if ( action::is_entered(entered) )
{
geometry::copy_segments<false>(linestring1, current_segment_id,
geometry::copy_segments<false>(linestring1,
current_segment_id,
boost::size(linestring1) - 1,
current_piece);
}
@@ -272,7 +272,12 @@ public:
{
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
typedef typename boost::range_iterator<Turns const>::type TurnIt;
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
typedef typename boost::range_value<Turns>::type TurnInfo;
typedef typename boost::range_iterator
<
typename TurnInfo::container_type const
>::type TurnOperationIterator;
// Iterate through all intersection points (they are
// ordered along the each line)
@@ -284,15 +289,15 @@ public:
bool first = true;
std::size_t enter_count = 0;
TurnIt it = boost::begin(turns);
TurnIt it_r = boost::begin(reverse_turns);
TurnIterator it = boost::begin(turns);
TurnIterator it_r = boost::begin(reverse_turns);
for (; it != boost::end(turns); ++it, ++it_r)
{
turn_operation_iterator_type iit = boost::begin(it->operations);
turn_operation_iterator_type iit_r = boost::begin(it_r->operations);
++iit_r;
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, iit, iit_r,
oit = process_turn(it, it_r, op_it, op_it_r,
first, entered, enter_count,
linestring1, linestring2,
current_piece, current_segment_id,
@@ -336,14 +341,6 @@ protected:
OverlayType, FollowIsolatedPoints
> Base;
typedef typename point_type<LineStringOut>::type PointOut;
typedef traversal_turn_info<PointOut> turn_info;
typedef typename boost::range_iterator
<
typename turn_info::container_type const
>::type turn_operation_iterator_type;
typedef following::action_selector<OverlayType> action;
public:
@@ -356,7 +353,12 @@ public:
{
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
typedef typename boost::range_iterator<Turns const>::type TurnIt;
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
typedef typename boost::range_value<Turns>::type TurnInfo;
typedef typename boost::range_iterator
<
typename TurnInfo::container_type const
>::type TurnOperationIterator;
// Iterate through all intersection points (they are
// ordered along the each line)
@@ -368,20 +370,20 @@ public:
bool first = true;
std::size_t enter_count = 0;
TurnIt it = boost::begin(turns);
TurnIt it_r = boost::begin(reverse_turns);
TurnIterator it = boost::begin(turns);
TurnIterator it_r = boost::begin(reverse_turns);
for (; it != boost::end(turns); ++it, ++it_r)
{
turn_operation_iterator_type iit = boost::begin(it->operations);
turn_operation_iterator_type iit_r = boost::begin(it_r->operations);
++iit_r;
TurnOperationIterator op_it = boost::begin(it->operations);
TurnOperationIterator op_it_r = boost::begin(it_r->operations);
++op_it_r;
LineString2 const* ls2 =
&*(boost::begin(multilinestring) + iit->other_id.multi_index);
LineString2 const* linestring2 =
&*(boost::begin(multilinestring) + op_it->other_id.multi_index);
oit = Base::process_turn(it, it_r, iit, iit_r,
oit = Base::process_turn(it, it_r, op_it, op_it_r,
first, entered, enter_count,
linestring, *ls2,
linestring, *linestring2,
current_piece, current_segment_id,
oit);
}
@@ -425,14 +427,6 @@ protected:
OverlayType, FollowIsolatedPoints
> Base;
typedef typename point_type<LineStringOut>::type PointOut;
typedef traversal_turn_info<PointOut> turn_info;
typedef typename boost::range_iterator
<
typename turn_info::container_type const
>::type turn_operation_iterator_type;
typedef following::action_selector<OverlayType> action;
public:
@@ -445,7 +439,12 @@ public:
{
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
typedef typename boost::range_iterator<Turns const>::type TurnIt;
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
typedef typename boost::range_value<Turns>::type TurnInfo;
typedef typename boost::range_iterator
<
typename TurnInfo::container_type const
>::type TurnOperationIterator;
// Iterate through all intersection points (they are
// ordered along the each line)
@@ -460,17 +459,17 @@ public:
std::size_t enter_count = 0;
// dummy initialization
LineString1 const* ls1 = &*boost::begin(multilinestring);
LineString1 const* linestring1 = &*boost::begin(multilinestring);
TurnIt it = boost::begin(turns);
TurnIt it_r = boost::begin(reverse_turns);
TurnIterator it = boost::begin(turns);
TurnIterator it_r = boost::begin(reverse_turns);
for (; it != boost::end(turns); ++it, ++it_r)
{
turn_operation_iterator_type iit = boost::begin(it->operations);
turn_operation_iterator_type iit_r = boost::begin(it_r->operations);
++iit_r;
TurnOperationIterator op_it = boost::begin(it->operations);
TurnOperationIterator op_it_r = boost::begin(it_r->operations);
++op_it_r;
if ( iit->seg_id.multi_index != current_multi_id )
if ( op_it->seg_id.multi_index != current_multi_id )
{
if ( first_turn )
{
@@ -478,7 +477,7 @@ public:
}
else
{
oit = Base::process_end(entered, *ls1,
oit = Base::process_end(entered, *linestring1,
current_segment_id, current_piece,
oit);
@@ -490,20 +489,21 @@ public:
= geometry::segment_identifier(0, -1, -1, -1);
geometry::clear(current_piece);
}
current_multi_id = iit->seg_id.multi_index;
ls1 = &*(boost::begin(multilinestring) + current_multi_id);
current_multi_id = op_it->seg_id.multi_index;
linestring1 =
&*(boost::begin(multilinestring) + current_multi_id);
}
oit = Base::process_turn(it, it_r, iit, iit_r,
oit = Base::process_turn(it, it_r, op_it, op_it_r,
first, entered, enter_count,
*ls1, linestring,
*linestring1, linestring,
current_piece, current_segment_id,
oit);
}
BOOST_ASSERT( enter_count == 0 );
return Base::process_end(entered, *ls1,
return Base::process_end(entered, *linestring1,
current_segment_id, current_piece,
oit);
}
@@ -539,14 +539,6 @@ protected:
OverlayType, FollowIsolatedPoints
> Base;
typedef typename point_type<LineStringOut>::type PointOut;
typedef traversal_turn_info<PointOut> turn_info;
typedef typename boost::range_iterator
<
typename turn_info::container_type const
>::type turn_operation_iterator_type;
typedef following::action_selector<OverlayType> action;
public:
@@ -559,7 +551,12 @@ public:
{
BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) );
typedef typename boost::range_iterator<Turns const>::type TurnIt;
typedef typename boost::range_iterator<Turns const>::type TurnIterator;
typedef typename boost::range_value<Turns>::type TurnInfo;
typedef typename boost::range_iterator
<
typename TurnInfo::container_type const
>::type TurnOperationIterator;
// Iterate through all intersection points (they are
// ordered along the each line)
@@ -574,17 +571,17 @@ public:
std::size_t enter_count = 0;
// dummy initialization
LineString1 const* ls1 = &*boost::begin(multilinestring1);
LineString1 const* linestring1 = &*boost::begin(multilinestring1);
TurnIt it = boost::begin(turns);
TurnIt it_r = boost::begin(reverse_turns);
TurnIterator it = boost::begin(turns);
TurnIterator it_r = boost::begin(reverse_turns);
for (; it != boost::end(turns); ++it, ++it_r)
{
turn_operation_iterator_type iit = boost::begin(it->operations);
turn_operation_iterator_type iit_r = boost::begin(it_r->operations);
++iit_r;
TurnOperationIterator op_it = boost::begin(it->operations);
TurnOperationIterator op_it_r = boost::begin(it_r->operations);
++op_it_r;
if ( iit->seg_id.multi_index != current_multi_id )
if ( op_it->seg_id.multi_index != current_multi_id )
{
if ( first_turn )
{
@@ -592,7 +589,7 @@ public:
}
else
{
oit = Base::process_end(entered, *ls1,
oit = Base::process_end(entered, *linestring1,
current_segment_id, current_piece,
oit);
@@ -604,23 +601,24 @@ public:
= geometry::segment_identifier(0, -1, -1, -1);
geometry::clear(current_piece);
}
current_multi_id = iit->seg_id.multi_index;
ls1 = &*(boost::begin(multilinestring1) + current_multi_id);
current_multi_id = op_it->seg_id.multi_index;
linestring1 =
&*(boost::begin(multilinestring1) + current_multi_id);
}
LineString2 const* ls2 =
&*(boost::begin(multilinestring2) + iit->other_id.multi_index);
LineString2 const* linestring2 =
&*(boost::begin(multilinestring2) + op_it->other_id.multi_index);
oit = Base::process_turn(it, it_r, iit, iit_r,
oit = Base::process_turn(it, it_r, op_it, op_it_r,
first, entered, enter_count,
*ls1, *ls2,
*linestring1, *linestring2,
current_piece, current_segment_id,
oit);
}
BOOST_ASSERT( enter_count == 0 );
return Base::process_end(entered, *ls1,
return Base::process_end(entered, *linestring1,
current_segment_id, current_piece,
oit);
}
@@ -636,8 +634,8 @@ template
overlay_type OverlayType,
bool FollowIsolatedPoints,
typename TagOut = typename tag<GeometryOut>::type,
typename Tag1 = typename tag<Geometry1>::type,
typename Tag2 = typename tag<Geometry2>::type
typename TagIn1 = typename tag<Geometry1>::type,
typename TagIn2 = typename tag<Geometry2>::type
>
struct follow_dispatch
: not_implemented<GeometryOut, Geometry1, Geometry2>

View File

@@ -523,8 +523,8 @@ struct get_turn_info_for_endpoint
tp.method = method;
tp.operations[0].operation = op0;
tp.operations[1].operation = op1;
tp.operations[0].position = pos0;
tp.operations[1].position = pos1;
// tp.operations[0].position = pos0;
// tp.operations[1].position = pos1;
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
*out++ = tp;
}

View File

@@ -513,12 +513,38 @@ struct intersection_insert_reversed
};
// dispatch for non-linear geometries
template
<
typename Geometry1, typename Geometry2, typename GeometryOut,
overlay_type OverlayType,
bool Reverse1, bool Reverse2, bool ReverseOut,
typename TagIn1, typename TagIn2, typename TagOut
>
struct intersection_insert
<
Geometry1, Geometry2, GeometryOut,
OverlayType,
Reverse1, Reverse2, ReverseOut,
TagIn1, TagIn2, TagOut,
false, false, false
> : intersection_insert
<
Geometry1, Geometry2, GeometryOut,
OverlayType,
Reverse1, Reverse2, ReverseOut,
typename tag_cast<TagIn1, pointlike_tag, linear_tag>::type,
typename tag_cast<TagIn2, pointlike_tag, linear_tag>::type,
TagOut,
false, false, false
>
{};
// dispatch for difference of linear geometries
template
<
typename Linear1, typename Linear2,
typename LineStringOut,
typename Linear1, typename Linear2, typename LineStringOut,
bool Reverse1, bool Reverse2, bool ReverseOut
>
struct intersection_insert
@@ -526,9 +552,7 @@ struct intersection_insert
Linear1, Linear2, LineStringOut,
overlay_difference,
Reverse1, Reverse2, ReverseOut,
typename geometry::tag<Linear1>::type,
typename geometry::tag<Linear2>::type,
linestring_tag,
linear_tag, linear_tag, linestring_tag,
false, false, false
> : detail::overlay::linear_linear_linestring
<
@@ -536,11 +560,12 @@ struct intersection_insert
>
{};
// dispatch for intersection of linear geometries
template
<
typename Linear1, typename Linear2,
typename LineStringOut,
typename Linear1, typename Linear2, typename LineStringOut,
bool Reverse1, bool Reverse2, bool ReverseOut
>
struct intersection_insert
@@ -548,9 +573,7 @@ struct intersection_insert
Linear1, Linear2, LineStringOut,
overlay_intersection,
Reverse1, Reverse2, ReverseOut,
typename geometry::tag<Linear1>::type,
typename geometry::tag<Linear2>::type,
linestring_tag,
linear_tag, linear_tag, linestring_tag,
false, false, false
> : detail::overlay::linear_linear_linestring
<
@@ -559,9 +582,6 @@ struct intersection_insert
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -13,6 +13,7 @@
#include <algorithm>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
#include <boost/geometry/algorithms/detail/turns/compare_turns.hpp>
@@ -30,37 +31,6 @@ namespace detail { namespace overlay
{
namespace core
{
template <typename Tag>
struct is_linear : not_implemented<Tag>
{};
template <>
struct is_linear<linestring_tag>
{};
template <>
struct is_linear<multi_linestring_tag>
{};
template <typename Tag1, typename Tag2>
struct are_linear
: is_linear<Tag1>, is_linear<Tag2>
{};
template <typename Tag>
struct are_linear<Tag, Tag>
: is_linear<Tag>
{};
} // namespace core
//===========================================================================
//===========================================================================
//===========================================================================
@@ -151,19 +121,8 @@ template
overlay_type OverlayType
>
class linear_linear_linestring
: core::are_linear
<
typename tag<Linear1>::type, typename tag<Linear2>::type
>
{
protected:
typedef typename point_type<LinestringOut>::type PointOut;
typedef traversal_turn_info<PointOut> turn_info;
typedef std::vector<turn_info> Turns;
typedef typename Turns::iterator TurnIt;
typedef detail::get_turns::no_interrupt_policy InterruptPolicy;
struct AssignPolicy
{
static bool const include_no_turn = false;
@@ -186,25 +145,28 @@ protected:
};
struct IsContinueTurn
class IsContinueTurn
{
private:
template <typename Operation>
inline bool is_continue_or_opposite(Operation const& operation) const
{
return operation == operation_continue
|| operation == operation_opposite;
}
public:
template <typename Turn>
bool operator()(Turn const& turn) const
{
if ( turn.method != method_collinear &&
turn.method != method_equal )
if ( turn.method != method_collinear
&& turn.method != method_equal )
{
return false;
}
operation_type op[2];
op[0] = turn.operations[0].operation;
op[1] = turn.operations[1].operation;
return
(op[0] == operation_continue ||
op[0] == operation_opposite) &&
(op[1] == operation_continue ||
op[1] == operation_opposite);
return is_continue_or_opposite(turn.operations[0].operation)
&& is_continue_or_opposite(turn.operations[1].operation);
}
};
@@ -319,13 +281,11 @@ protected:
filter_turns(reverse_turns);
// sort by seg_id, distance, and operation
typedef detail::turns::less_seg_dist_other_op<> less;
std::sort(boost::begin(turns), boost::end(turns), less());
std::sort(boost::begin(turns), boost::end(turns),
detail::turns::less_seg_dist_other_op<>());
typedef
detail::turns::less_seg_dist_other_op<std::greater<int> > rev_less;
std::sort(boost::begin(reverse_turns), boost::end(reverse_turns),
rev_less());
detail::turns::less_seg_dist_other_op<std::greater<int> >());
#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS
// remove duplicate turns
@@ -357,32 +317,12 @@ public:
OutputIterator oit,
Strategy const& )
{
typedef geometry::model::multi_linestring
typedef traversal_turn_info
<
LinestringOut
> MultiLinestringOut;
typename point_type<LinestringOut>::type
> turn_info;
// MultiLinestringOut mls1, mls2;
// geometry::convert(multilinestring1, mls1);
// geometry::convert(multilinestring2, mls2);
// assert( boost::size(mls1) > 0 );
// assert( boost::size(mls2) > 0 );
// canonical<LinestringOut>::apply(ls1);
// canonical<LinestringOut>::apply(ls2);
// typedef typename point_type<LinestringOut>::type PointOut;
#if 0
typedef //overlay::assign_null_policy
overlay::calculate_distance_policy AssignPolicy;
#endif
// typedef //overlay::assign_null_policy
// detail::union_::assign_union_policy AssignPolicy;
// typedef detail::disjoint::disjoint_interrupt_policy InterruptPolicy;
typedef std::vector<turn_info> Turns;
Turns turns;
compute_turns(turns, linear1, linear2);
@@ -425,20 +365,7 @@ template
typename LinestringOut
>
struct linear_linear_linestring<Linear1, Linear2, LinestringOut, overlay_union>
: linear_linear_linestring
<
Linear1, Linear2, LinestringOut, overlay_difference
>
{
protected:
typedef linear_linear_linestring
<
Linear1, Linear2, LinestringOut, overlay_difference
> Base;
typedef typename Base::Turns Turns;
public:
template
<
typename OutputIterator, typename Strategy

View File

@@ -36,10 +36,10 @@ struct less_seg_dist_other_op
{
BOOST_STATIC_ASSERT(OpId < 2);
template <typename Op> static inline
int order_op(Op const& op)
template <typename Op>
static inline int order_op(Op const& op)
{
switch(op.operation)
switch (op.operation)
{
case detail::overlay::operation_none : return N;
case detail::overlay::operation_union : return U;
@@ -51,14 +51,14 @@ struct less_seg_dist_other_op
return -1;
}
template <typename Op> static inline
bool use_operation(Op const& left, Op const& right)
template <typename Op>
static inline bool use_operation(Op const& left, Op const& right)
{
return order_op(left) < order_op(right);
}
template <typename Op> static inline
bool use_other_multi_ring_id(Op const& left, Op const& right)
template <typename Op>
static inline bool use_other_id(Op const& left, Op const& right)
{
if ( left.other_id.multi_index != right.other_id.multi_index )
{
@@ -76,13 +76,14 @@ struct less_seg_dist_other_op
return use_operation(left, right);
}
template <typename Op> static inline
bool use_distance(Op const& left, Op const& right)
template <typename Op>
static inline bool use_distance(Op const& left, Op const& right)
{
return left.enriched.distance < right.enriched.distance || (
geometry::math::equals(left.enriched.distance, right.enriched.distance) &&
use_other_multi_ring_id(left, right)
);
return left.enriched.distance < right.enriched.distance
|| ( geometry::math::equals(left.enriched.distance,
right.enriched.distance)
&& use_other_id(left, right)
);
}
template <typename Turn>

View File

@@ -22,7 +22,7 @@
#include <boost/geometry/core/reverse_dispatch.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>\
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
@@ -100,17 +100,43 @@ struct union_insert
{};
// dispatch for union of non-areal geometries
template
<
typename Geometry1, typename Geometry2, typename GeometryOut,
typename TagIn1, typename TagIn2, typename TagOut,
bool Reverse1, bool Reverse2, bool ReverseOut
>
struct union_insert
<
Geometry1, Geometry2, GeometryOut,
TagIn1, TagIn2, TagOut,
false, false, false,
Reverse1, Reverse2, ReverseOut,
false
> : union_insert
<
Geometry1, Geometry2, GeometryOut,
typename tag_cast<TagIn1, pointlike_tag, linear_tag>::type,
typename tag_cast<TagIn2, pointlike_tag, linear_tag>::type,
TagOut,
false, false, false,
Reverse1, Reverse2, ReverseOut,
false
>
{};
// dispatch for union of linear geometries
template
<
typename Linear1, typename Linear2, typename LineStringOut,
typename TagIn1, typename TagIn2,
bool Reverse1, bool Reverse2, bool ReverseOut
>
struct union_insert
<
Linear1, Linear2, LineStringOut,
TagIn1, TagIn2, linestring_tag,
linear_tag, linear_tag, linestring_tag,
false, false, false,
Reverse1, Reverse2, ReverseOut,
false
@@ -121,6 +147,23 @@ struct union_insert
{};
// dispatch for point-like geometries
template
<
typename PointLike1, typename PointLike2, typename PointOut,
bool Reverse1, bool Reverse2, bool ReverseOut
>
struct union_insert
<
PointLike1, PointLike2, PointOut,
pointlike_tag, pointlike_tag, point_tag,
false, false, false,
Reverse1, Reverse2, ReverseOut,
false
> : not_implemented<PointLike1, PointLike2, PointOut>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH