mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into feature/setops
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp>
|
||||
|
||||
// Silence warning C4127: conditional expression is constant
|
||||
#if defined(_MSC_VER)
|
||||
@@ -60,36 +60,6 @@ public:
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
template <typename PointP, typename PointQ,
|
||||
typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
|
||||
typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
|
||||
>
|
||||
struct side_calculator
|
||||
{
|
||||
typedef boost::geometry::strategy::side::side_by_triangle<> side; // todo: get from coordinate system
|
||||
|
||||
inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
|
||||
Qi const& qi, Qj const& qj, Qk const& qk)
|
||||
: m_pi(pi), m_pj(pj), m_pk(pk)
|
||||
, m_qi(qi), m_qj(qj), m_qk(qk)
|
||||
{}
|
||||
|
||||
inline int pk_wrt_p1() const { return side::apply(m_pi, m_pj, m_pk); }
|
||||
inline int pk_wrt_q1() const { return side::apply(m_qi, m_qj, m_pk); }
|
||||
inline int qk_wrt_p1() const { return side::apply(m_pi, m_pj, m_qk); }
|
||||
inline int qk_wrt_q1() const { return side::apply(m_qi, m_qj, m_qk); }
|
||||
|
||||
inline int pk_wrt_q2() const { return side::apply(m_qj, m_qk, m_pk); }
|
||||
inline int qk_wrt_p2() const { return side::apply(m_pj, m_pk, m_qk); }
|
||||
|
||||
Pi const& m_pi;
|
||||
Pj const& m_pj;
|
||||
Pk const& m_pk;
|
||||
Qi const& m_qi;
|
||||
Qj const& m_qj;
|
||||
Qk const& m_qk;
|
||||
};
|
||||
|
||||
struct base_turn_handler
|
||||
{
|
||||
// Returns true if both sides are opposite
|
||||
@@ -741,7 +711,7 @@ private :
|
||||
}
|
||||
|
||||
public:
|
||||
static inline void empty_replacer(method_type &, operation_type &, operation_type &) {}
|
||||
static inline void empty_transformer(TurnInfo &) {}
|
||||
|
||||
template
|
||||
<
|
||||
@@ -764,7 +734,7 @@ public:
|
||||
DirInfo const& dir_info,
|
||||
SidePolicy const& side)
|
||||
{
|
||||
apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, dir_info, side, empty_replacer);
|
||||
apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, dir_info, side, empty_transformer);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -776,7 +746,7 @@ public:
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo,
|
||||
typename SidePolicy,
|
||||
typename MethodAndOperationsReplacer
|
||||
typename TurnTransformer
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
@@ -789,7 +759,7 @@ public:
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info,
|
||||
SidePolicy const& side,
|
||||
MethodAndOperationsReplacer method_and_operations_replacer,
|
||||
TurnTransformer turn_transformer,
|
||||
bool const is_pk_valid = true, bool const is_qk_valid = true)
|
||||
{
|
||||
TurnInfo tp = tp_model;
|
||||
@@ -799,7 +769,7 @@ public:
|
||||
&& is_pk_valid
|
||||
&& set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info) )
|
||||
{
|
||||
method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
turn_transformer(tp);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
*out++ = tp;
|
||||
@@ -810,7 +780,7 @@ public:
|
||||
&& is_qk_valid
|
||||
&& set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info) )
|
||||
{
|
||||
method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
turn_transformer(tp);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
*out++ = tp;
|
||||
@@ -947,41 +917,12 @@ struct get_turn_info
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef typename geometry::robust_point_type
|
||||
<
|
||||
Point1, RobustPolicy
|
||||
>::type robust_point_type;
|
||||
typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
|
||||
inters_info;
|
||||
|
||||
robust_point_type pi_rob, pj_rob, pk_rob, qi_rob, qj_rob, qk_rob;
|
||||
geometry::recalculate(pi_rob, pi, robust_policy);
|
||||
geometry::recalculate(pj_rob, pj, robust_policy);
|
||||
geometry::recalculate(pk_rob, pk, robust_policy);
|
||||
geometry::recalculate(qi_rob, qi, robust_policy);
|
||||
geometry::recalculate(qj_rob, qj, robust_policy);
|
||||
geometry::recalculate(qk_rob, qk, robust_policy);
|
||||
inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
|
||||
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
typedef model::referring_segment<Point2 const> segment_type2;
|
||||
segment_type1 p1(pi, pj);
|
||||
segment_type2 q1(qi, qj);
|
||||
|
||||
side_calculator<robust_point_type, robust_point_type> side_calc(pi_rob, pj_rob, pk_rob, qi_rob, qj_rob, qk_rob);
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<typename TurnInfo::point_type>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
typename TurnInfo::point_type,
|
||||
RobustPolicy
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
typename strategy::return_type result = strategy::apply(p1, q1,
|
||||
robust_policy, pi_rob, pj_rob, qi_rob, qj_rob);
|
||||
|
||||
char const method = result.template get<1>().how;
|
||||
char const method = inters.d_info().how;
|
||||
|
||||
// Copy, to copy possibly extended fields
|
||||
TurnInfo tp = tp_model;
|
||||
@@ -993,11 +934,10 @@ struct get_turn_info
|
||||
case 'f' : // collinear, "from"
|
||||
case 's' : // starts from the middle
|
||||
if (AssignPolicy::include_no_turn
|
||||
&& result.template get<0>().count > 0)
|
||||
&& inters.i_info().count > 0)
|
||||
{
|
||||
only_convert::apply(tp,
|
||||
result.template get<0>());
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
only_convert::apply(tp, inters.i_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -1013,29 +953,34 @@ struct get_turn_info
|
||||
> policy;
|
||||
|
||||
// If Q (1) arrives (1)
|
||||
if (result.template get<1>().arrival[1] == 1)
|
||||
if ( inters.d_info().arrival[1] == 1 )
|
||||
{
|
||||
policy::template apply<0>(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(),
|
||||
side_calc);
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
inters.sides());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swap p/q
|
||||
side_calculator<Point2, Point1> swapped_side_calc(qi, qj, qk, pi, pj, pk);
|
||||
side_calculator
|
||||
<
|
||||
typename inters_info::robust_point2_type,
|
||||
typename inters_info::robust_point1_type
|
||||
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
|
||||
inters.rpi(), inters.rpj(), inters.rpk());
|
||||
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
|
||||
tp, result.template get<0>(), result.template get<1>(),
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
swapped_side_calc);
|
||||
}
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
case 'i' :
|
||||
{
|
||||
crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
tp, inters.i_info(), inters.d_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -1043,20 +988,20 @@ struct get_turn_info
|
||||
{
|
||||
// Both touch (both arrive there)
|
||||
touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
{
|
||||
if (! result.template get<1>().opposite)
|
||||
if ( ! inters.d_info().opposite )
|
||||
{
|
||||
// Both equal
|
||||
// or collinear-and-ending at intersection point
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
else
|
||||
@@ -1066,21 +1011,21 @@ struct get_turn_info
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, qi,
|
||||
tp, out, result.template get<0>(), result.template get<1>());
|
||||
tp, out, inters.i_info(), inters.d_info());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'c' :
|
||||
{
|
||||
// Collinear
|
||||
if (! result.template get<1>().opposite)
|
||||
if ( ! inters.d_info().opposite )
|
||||
{
|
||||
|
||||
if (result.template get<1>().arrival[0] == 0)
|
||||
if ( inters.d_info().arrival[0] == 0 )
|
||||
{
|
||||
// Collinear, but similar thus handled as equal
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
// override assigned method
|
||||
tp.method = method_collinear;
|
||||
@@ -1088,10 +1033,10 @@ struct get_turn_info
|
||||
else
|
||||
{
|
||||
collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
else
|
||||
@@ -1101,7 +1046,7 @@ struct get_turn_info
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, out, inters.i_info(), inters.d_info(), inters.sides());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1110,8 +1055,8 @@ struct get_turn_info
|
||||
// degenerate points
|
||||
if (AssignPolicy::include_degenerate)
|
||||
{
|
||||
only_convert::apply(tp, result.template get<0>());
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
only_convert::apply(tp, inters.i_info());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,177 +15,13 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay {
|
||||
|
||||
// TURN_OPERATION
|
||||
|
||||
enum turn_position { position_middle, position_front, position_back };
|
||||
|
||||
template <typename SegmentRatio>
|
||||
struct turn_operation_linear
|
||||
: public turn_operation<SegmentRatio>
|
||||
{
|
||||
turn_operation_linear()
|
||||
: position(position_middle)
|
||||
, is_collinear(false)
|
||||
{}
|
||||
|
||||
turn_position position;
|
||||
bool is_collinear; // valid only for Linear geometry
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
|
||||
class intersection_info
|
||||
{
|
||||
typedef typename strategy_intersection
|
||||
<
|
||||
typename cs_tag<TurnPoint>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
TurnPoint,
|
||||
RobustPolicy
|
||||
>::segment_intersection_strategy_type strategy;
|
||||
|
||||
public:
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
typedef model::referring_segment<Point2 const> segment_type2;
|
||||
typedef side_calculator<Point1, Point2> side_calculator_type;
|
||||
|
||||
typedef typename strategy::return_type result_type;
|
||||
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
|
||||
typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info
|
||||
|
||||
intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
RobustPolicy const& robust_policy)
|
||||
: m_result(strategy::apply(segment_type1(pi, pj),
|
||||
segment_type2(qi, qj),
|
||||
robust_policy))
|
||||
, m_side_calc(pi, pj, pk, qi, qj, qk)
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
inline Point1 const& pi() const { return m_side_calc.m_pi; }
|
||||
inline Point1 const& pj() const { return m_side_calc.m_pj; }
|
||||
inline Point1 const& pk() const { return m_side_calc.m_pk; }
|
||||
|
||||
inline Point2 const& qi() const { return m_side_calc.m_qi; }
|
||||
inline Point2 const& qj() const { return m_side_calc.m_qj; }
|
||||
inline Point2 const& qk() const { return m_side_calc.m_qk; }
|
||||
|
||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||
inline result_type const& result() const { return m_result; }
|
||||
inline i_info_type const& i_info() const { return m_result.template get<0>(); }
|
||||
inline d_info_type const& d_info() const { return m_result.template get<1>(); }
|
||||
|
||||
// TODO: not it's more like is_spike_ip_p
|
||||
inline bool is_spike_p() const
|
||||
{
|
||||
if ( m_side_calc.pk_wrt_p1() == 0 )
|
||||
{
|
||||
if ( ! is_ip_j<0>() )
|
||||
return false;
|
||||
|
||||
int const qk_p1 = m_side_calc.qk_wrt_p1();
|
||||
int const qk_p2 = m_side_calc.qk_wrt_p2();
|
||||
|
||||
if ( qk_p1 == -qk_p2 )
|
||||
{
|
||||
if ( qk_p1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(pi(), pj(), pk());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: not it's more like is_spike_ip_q
|
||||
inline bool is_spike_q() const
|
||||
{
|
||||
if ( m_side_calc.qk_wrt_q1() == 0 )
|
||||
{
|
||||
if ( ! is_ip_j<1>() )
|
||||
return false;
|
||||
|
||||
int const pk_q1 = m_side_calc.pk_wrt_q1();
|
||||
int const pk_q2 = m_side_calc.pk_wrt_q2();
|
||||
|
||||
if ( pk_q1 == -pk_q2 )
|
||||
{
|
||||
if ( pk_q1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(qi(), qj(), qk());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Point>
|
||||
inline bool is_spike_of_collinear(Point const& i, Point const& j, Point const& k) const
|
||||
{
|
||||
typedef model::referring_segment<Point const> seg_t;
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<Point>::type, Point, Point, Point, RobustPolicy
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
typename strategy::return_type result
|
||||
= strategy::apply(seg_t(i, j), seg_t(j, k), m_robust_policy);
|
||||
|
||||
return result.template get<0>().count == 2;
|
||||
}
|
||||
|
||||
template <std::size_t OpId>
|
||||
bool is_ip_j() const
|
||||
{
|
||||
int arrival = d_info().arrival[OpId];
|
||||
bool same_dirs = d_info().dir_a == 0 && d_info().dir_b == 0;
|
||||
|
||||
if ( same_dirs )
|
||||
{
|
||||
if ( i_info().count == 2 )
|
||||
{
|
||||
if ( ! d_info().opposite )
|
||||
{
|
||||
return arrival != -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return arrival != -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return arrival == 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return arrival == 1;
|
||||
}
|
||||
}
|
||||
|
||||
result_type m_result;
|
||||
side_calculator_type m_side_calc;
|
||||
RobustPolicy const& m_robust_policy;
|
||||
};
|
||||
|
||||
// SEGMENT_INTERSECTION RESULT
|
||||
|
||||
// C H0 H1 A0 A1 O IP1 IP2
|
||||
@@ -484,20 +320,24 @@ struct get_turn_info_for_endpoint
|
||||
|
||||
if ( append_first || append_last )
|
||||
{
|
||||
bool handled = handle_internal(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first_ip, is_p_last_ip,
|
||||
is_q_first_ip, is_q_last_ip,
|
||||
ip_info.is_qi, ip_info.is_qj,
|
||||
tp_model, inters.result(), ip_index,
|
||||
p_operation, q_operation);
|
||||
bool handled = handle_internal<0>(pi, pj, pk, qi, qj, qk,
|
||||
inters.rpi(), inters.rpj(), inters.rpk(),
|
||||
inters.rqi(), inters.rqj(), inters.rqk(),
|
||||
is_p_first_ip, is_p_last_ip,
|
||||
is_q_first_ip, is_q_last_ip,
|
||||
ip_info.is_qi, ip_info.is_qj,
|
||||
tp_model, inters, ip_index,
|
||||
p_operation, q_operation);
|
||||
if ( !handled )
|
||||
{
|
||||
handle_internal(qi, qj, qk, pi, pj, pk,
|
||||
is_q_first_ip, is_q_last_ip,
|
||||
is_p_first_ip, is_p_last_ip,
|
||||
ip_info.is_pi, ip_info.is_pj,
|
||||
tp_model, inters.result(), ip_index,
|
||||
q_operation, p_operation);
|
||||
handle_internal<1>(qi, qj, qk, pi, pj, pk,
|
||||
inters.rqi(), inters.rqj(), inters.rqk(),
|
||||
inters.rpi(), inters.rpj(), inters.rpk(),
|
||||
is_q_first_ip, is_q_last_ip,
|
||||
is_p_first_ip, is_p_last_ip,
|
||||
ip_info.is_pi, ip_info.is_pj,
|
||||
tp_model, inters, ip_index,
|
||||
q_operation, p_operation);
|
||||
}
|
||||
|
||||
if ( p_operation != operation_none )
|
||||
@@ -516,9 +356,9 @@ struct get_turn_info_for_endpoint
|
||||
&& inters.is_spike_p() )
|
||||
{
|
||||
assign(pi, qi, inters.result(), ip_index, method, operation_blocked, q_operation,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
p_pos, q_pos, is_p_first_ip, is_q_first_ip, true, false, tp_model, out);
|
||||
assign(pi, qi, inters.result(), ip_index, method, operation_intersection, q_operation,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
p_pos, q_pos, is_p_first_ip, is_q_first_ip, true, false, tp_model, out);
|
||||
}
|
||||
// Q is spike and should be handled
|
||||
else if ( !is_q_last
|
||||
@@ -527,15 +367,15 @@ struct get_turn_info_for_endpoint
|
||||
&& inters.is_spike_q() )
|
||||
{
|
||||
assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_blocked,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, true, tp_model, out);
|
||||
assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_intersection,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, true, tp_model, out);
|
||||
}
|
||||
// no spikes
|
||||
else
|
||||
{
|
||||
assign(pi, qi, inters.result(), ip_index, method, p_operation, q_operation,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, false, tp_model, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -546,16 +386,21 @@ struct get_turn_info_for_endpoint
|
||||
// TODO: IT'S ALSO PROBABLE THAT ALL THIS FUNCTION COULD BE INTEGRATED WITH handle_segment
|
||||
// however now it's lazily calculated and then it would be always calculated
|
||||
|
||||
template<typename Point1,
|
||||
template<std::size_t G1Index,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename RobustPoint1,
|
||||
typename RobustPoint2,
|
||||
typename TurnInfo,
|
||||
typename IntersectionResult
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline bool handle_internal(Point1 const& i1, Point1 const& j1, Point1 const& /*k1*/,
|
||||
Point2 const& i2, Point2 const& j2, Point2 const& k2,
|
||||
RobustPoint1 const& ri1, RobustPoint1 const& rj1, RobustPoint1 const& /*rk1*/,
|
||||
RobustPoint2 const& ri2, RobustPoint2 const& rj2, RobustPoint2 const& rk2,
|
||||
bool first1, bool last1, bool first2, bool last2,
|
||||
bool ip_i2, bool ip_j2, TurnInfo const& tp_model,
|
||||
IntersectionResult const& result, int ip_index,
|
||||
IntersectionInfo const& inters, int ip_index,
|
||||
operation_type & op1, operation_type & op2)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(ip_index);
|
||||
@@ -568,7 +413,7 @@ struct get_turn_info_for_endpoint
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR
|
||||
// may this give false positives for INTs?
|
||||
typename IntersectionResult::point_type const&
|
||||
inters_pt = result.template get<0>().intersections[ip_index];
|
||||
inters_pt = inters.i_info().intersections[ip_index];
|
||||
BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
|
||||
BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
|
||||
#endif
|
||||
@@ -581,7 +426,8 @@ struct get_turn_info_for_endpoint
|
||||
}
|
||||
else if ( ip_j2 )
|
||||
{
|
||||
side_calculator<Point1, Point2, Point2> side_calc(i2, i1, j1, i2, j2, k2);
|
||||
side_calculator<RobustPoint1, RobustPoint2, RobustPoint2>
|
||||
side_calc(ri2, ri1, rj1, ri2, rj2, rk2);
|
||||
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = operations_of_equal(side_calc);
|
||||
@@ -591,11 +437,16 @@ struct get_turn_info_for_endpoint
|
||||
|
||||
if ( operations_both(operations, operation_continue) )
|
||||
{
|
||||
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
|
||||
bool opposite = result.template get<1>().opposite;
|
||||
if ( op1 != operation_union
|
||||
|| op2 != operation_union
|
||||
|| ! ( G1Index == 0 ? inters.is_spike_q() : inters.is_spike_p() ) )
|
||||
{
|
||||
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
|
||||
bool opposite = inters.d_info().opposite;
|
||||
|
||||
op1 = operation_intersection;
|
||||
op2 = opposite ? operation_union : operation_intersection;
|
||||
op1 = operation_intersection;
|
||||
op2 = opposite ? operation_union : operation_intersection;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -613,7 +464,7 @@ struct get_turn_info_for_endpoint
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR
|
||||
// may this give false positives for INTs?
|
||||
typename IntersectionResult::point_type const&
|
||||
inters_pt = result.template get<0>().intersections[ip_index];
|
||||
inters_pt = inters.i_info().intersections[ip_index];
|
||||
BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
|
||||
BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
|
||||
#endif
|
||||
@@ -626,7 +477,8 @@ struct get_turn_info_for_endpoint
|
||||
}
|
||||
else if ( ip_j2 )
|
||||
{
|
||||
side_calculator<Point1, Point2, Point2> side_calc(i2, j1, i1, i2, j2, k2);
|
||||
side_calculator<RobustPoint1, RobustPoint2, RobustPoint2>
|
||||
side_calc(ri2, rj1, ri1, ri2, rj2, rk2);
|
||||
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = operations_of_equal(side_calc);
|
||||
@@ -636,11 +488,16 @@ struct get_turn_info_for_endpoint
|
||||
|
||||
if ( operations_both(operations, operation_continue) )
|
||||
{
|
||||
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
|
||||
bool second_going_out = result.template get<0>().count > 1;
|
||||
if ( op1 != operation_blocked
|
||||
|| op2 != operation_union
|
||||
|| ! ( G1Index == 0 ? inters.is_spike_q() : inters.is_spike_p() ) )
|
||||
{
|
||||
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
|
||||
bool second_going_out = inters.i_info().count > 1;
|
||||
|
||||
op1 = operation_blocked;
|
||||
op2 = second_going_out ? operation_union : operation_intersection;
|
||||
op1 = operation_blocked;
|
||||
op2 = second_going_out ? operation_union : operation_intersection;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -684,6 +541,8 @@ struct get_turn_info_for_endpoint
|
||||
method_type method,
|
||||
operation_type op0, operation_type op1,
|
||||
turn_position pos0, turn_position pos1,
|
||||
bool is_p_first_ip, bool is_q_first_ip,
|
||||
bool is_p_spike, bool is_q_spike,
|
||||
TurnInfo const& tp_model,
|
||||
OutputIterator out)
|
||||
{
|
||||
@@ -698,13 +557,23 @@ struct get_turn_info_for_endpoint
|
||||
tp.operations[0].position = pos0;
|
||||
tp.operations[1].position = pos1;
|
||||
|
||||
// NOTE: this probably shouldn't be set for the first point
|
||||
// for which there is no preceding segment
|
||||
if ( result.template get<0>().count > 1 )
|
||||
{
|
||||
// NOTE: is_collinear is NOT set for the first endpoint
|
||||
// for which there is no preceding segment
|
||||
|
||||
//BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
|
||||
tp.operations[0].is_collinear = true;
|
||||
tp.operations[1].is_collinear = true;
|
||||
if ( ! is_p_first_ip )
|
||||
{
|
||||
tp.operations[0].is_collinear = op0 != operation_intersection
|
||||
|| is_p_spike;
|
||||
}
|
||||
|
||||
if ( ! is_q_first_ip )
|
||||
{
|
||||
tp.operations[1].is_collinear = op1 != operation_intersection
|
||||
|| is_q_spike;
|
||||
}
|
||||
}
|
||||
else //if ( result.template get<0>().count == 1 )
|
||||
{
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
|
||||
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay {
|
||||
|
||||
enum turn_position { position_middle, position_front, position_back };
|
||||
|
||||
template <typename SegmentRatio>
|
||||
struct turn_operation_linear
|
||||
: public turn_operation<SegmentRatio>
|
||||
{
|
||||
turn_operation_linear()
|
||||
: position(position_middle)
|
||||
, is_collinear(false)
|
||||
{}
|
||||
|
||||
turn_position position;
|
||||
bool is_collinear; // valid only for Linear geometry
|
||||
};
|
||||
|
||||
template <typename PointP, typename PointQ,
|
||||
typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
|
||||
typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
|
||||
>
|
||||
struct side_calculator
|
||||
{
|
||||
typedef boost::geometry::strategy::side::side_by_triangle<> side; // todo: get from coordinate system
|
||||
|
||||
inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
|
||||
Qi const& qi, Qj const& qj, Qk const& qk)
|
||||
: m_pi(pi), m_pj(pj), m_pk(pk)
|
||||
, m_qi(qi), m_qj(qj), m_qk(qk)
|
||||
{}
|
||||
|
||||
inline int pk_wrt_p1() const { return side::apply(m_pi, m_pj, m_pk); }
|
||||
inline int pk_wrt_q1() const { return side::apply(m_qi, m_qj, m_pk); }
|
||||
inline int qk_wrt_p1() const { return side::apply(m_pi, m_pj, m_qk); }
|
||||
inline int qk_wrt_q1() const { return side::apply(m_qi, m_qj, m_qk); }
|
||||
|
||||
inline int pk_wrt_q2() const { return side::apply(m_qj, m_qk, m_pk); }
|
||||
inline int qk_wrt_p2() const { return side::apply(m_pj, m_pk, m_qk); }
|
||||
|
||||
Pi const& m_pi;
|
||||
Pj const& m_pj;
|
||||
Pk const& m_pk;
|
||||
Qi const& m_qi;
|
||||
Qj const& m_qj;
|
||||
Qk const& m_qk;
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2, typename RobustPolicy>
|
||||
struct robust_points
|
||||
{
|
||||
typedef typename geometry::robust_point_type
|
||||
<
|
||||
Point1, RobustPolicy
|
||||
>::type robust_point1_type;
|
||||
// TODO: define robust_point2_type using Point2?
|
||||
typedef robust_point1_type robust_point2_type;
|
||||
|
||||
inline robust_points(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
geometry::recalculate(m_rpi, pi, robust_policy);
|
||||
geometry::recalculate(m_rpj, pj, robust_policy);
|
||||
geometry::recalculate(m_rpk, pk, robust_policy);
|
||||
geometry::recalculate(m_rqi, qi, robust_policy);
|
||||
geometry::recalculate(m_rqj, qj, robust_policy);
|
||||
geometry::recalculate(m_rqk, qk, robust_policy);
|
||||
}
|
||||
|
||||
robust_point1_type m_rpi, m_rpj, m_rpk;
|
||||
robust_point2_type m_rqi, m_rqj, m_rqk;
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2, typename RobustPolicy>
|
||||
class intersection_info_base
|
||||
: private robust_points<Point1, Point2, RobustPolicy>
|
||||
{
|
||||
typedef robust_points<Point1, Point2, RobustPolicy> base_t;
|
||||
|
||||
public:
|
||||
typedef Point1 point1_type;
|
||||
typedef Point2 point2_type;
|
||||
|
||||
typedef typename base_t::robust_point1_type robust_point1_type;
|
||||
typedef typename base_t::robust_point2_type robust_point2_type;
|
||||
|
||||
typedef side_calculator<robust_point1_type, robust_point2_type> side_calculator_type;
|
||||
|
||||
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
RobustPolicy const& robust_policy)
|
||||
: base_t(pi, pj, pk, qi, qj, qk, robust_policy)
|
||||
, m_side_calc(base_t::m_rpi, base_t::m_rpj, base_t::m_rpk,
|
||||
base_t::m_rqi, base_t::m_rqj, base_t::m_rqk)
|
||||
, m_pi(pi), m_pj(pj), m_pk(pk)
|
||||
, m_qi(qi), m_qj(qj), m_qk(qk)
|
||||
{}
|
||||
|
||||
inline Point1 const& pi() const { return m_pi; }
|
||||
inline Point1 const& pj() const { return m_pj; }
|
||||
inline Point1 const& pk() const { return m_pk; }
|
||||
|
||||
inline Point2 const& qi() const { return m_qi; }
|
||||
inline Point2 const& qj() const { return m_qj; }
|
||||
inline Point2 const& qk() const { return m_qk; }
|
||||
|
||||
inline robust_point1_type const& rpi() const { return base_t::m_rpi; }
|
||||
inline robust_point1_type const& rpj() const { return base_t::m_rpj; }
|
||||
inline robust_point1_type const& rpk() const { return base_t::m_rpk; }
|
||||
|
||||
inline robust_point2_type const& rqi() const { return base_t::m_rqi; }
|
||||
inline robust_point2_type const& rqj() const { return base_t::m_rqj; }
|
||||
inline robust_point2_type const& rqk() const { return base_t::m_rqk; }
|
||||
|
||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||
|
||||
private:
|
||||
side_calculator_type m_side_calc;
|
||||
|
||||
point1_type const& m_pi;
|
||||
point1_type const& m_pj;
|
||||
point1_type const& m_pk;
|
||||
point2_type const& m_qi;
|
||||
point2_type const& m_qj;
|
||||
point2_type const& m_qk;
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
class intersection_info_base<Point1, Point2, detail::no_rescale_policy>
|
||||
{
|
||||
public:
|
||||
typedef Point1 point1_type;
|
||||
typedef Point2 point2_type;
|
||||
|
||||
typedef Point1 robust_point1_type;
|
||||
typedef Point2 robust_point2_type;
|
||||
|
||||
typedef side_calculator<Point1, Point2> side_calculator_type;
|
||||
|
||||
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
no_rescale_policy const& robust_policy)
|
||||
: m_side_calc(pi, pj, pk, qi, qj, qk)
|
||||
{}
|
||||
|
||||
inline Point1 const& pi() const { return m_side_calc.m_pi; }
|
||||
inline Point1 const& pj() const { return m_side_calc.m_pj; }
|
||||
inline Point1 const& pk() const { return m_side_calc.m_pk; }
|
||||
|
||||
inline Point2 const& qi() const { return m_side_calc.m_qi; }
|
||||
inline Point2 const& qj() const { return m_side_calc.m_qj; }
|
||||
inline Point2 const& qk() const { return m_side_calc.m_qk; }
|
||||
|
||||
inline Point1 const& rpi() const { return pi(); }
|
||||
inline Point1 const& rpj() const { return pj(); }
|
||||
inline Point1 const& rpk() const { return pk(); }
|
||||
|
||||
inline Point2 const& rqi() const { return qi(); }
|
||||
inline Point2 const& rqj() const { return qj(); }
|
||||
inline Point2 const& rqk() const { return qk(); }
|
||||
|
||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||
|
||||
private:
|
||||
side_calculator_type m_side_calc;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
|
||||
class intersection_info
|
||||
: public intersection_info_base<Point1, Point2, RobustPolicy>
|
||||
{
|
||||
typedef intersection_info_base<Point1, Point2, RobustPolicy> base_t;
|
||||
|
||||
typedef typename strategy_intersection
|
||||
<
|
||||
typename cs_tag<TurnPoint>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
TurnPoint,
|
||||
RobustPolicy
|
||||
>::segment_intersection_strategy_type strategy;
|
||||
|
||||
public:
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
typedef model::referring_segment<Point2 const> segment_type2;
|
||||
typedef typename base_t::side_calculator_type side_calculator_type;
|
||||
|
||||
typedef typename strategy::return_type result_type;
|
||||
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
|
||||
typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info
|
||||
|
||||
intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
RobustPolicy const& robust_policy)
|
||||
: base_t(pi, pj, pk, qi, qj, qk, robust_policy)
|
||||
, m_result(strategy::apply(segment_type1(pi, pj),
|
||||
segment_type2(qi, qj),
|
||||
robust_policy))
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
inline result_type const& result() const { return m_result; }
|
||||
inline i_info_type const& i_info() const { return m_result.template get<0>(); }
|
||||
inline d_info_type const& d_info() const { return m_result.template get<1>(); }
|
||||
|
||||
// TODO: it's more like is_spike_ip_p
|
||||
inline bool is_spike_p() const
|
||||
{
|
||||
if ( base_t::sides().pk_wrt_p1() == 0 )
|
||||
{
|
||||
if ( ! is_ip_j<0>() )
|
||||
return false;
|
||||
|
||||
int const qk_p1 = base_t::sides().qk_wrt_p1();
|
||||
int const qk_p2 = base_t::sides().qk_wrt_p2();
|
||||
|
||||
if ( qk_p1 == -qk_p2 )
|
||||
{
|
||||
if ( qk_p1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(base_t::pi(), base_t::pj(), base_t::pk());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: it's more like is_spike_ip_q
|
||||
inline bool is_spike_q() const
|
||||
{
|
||||
if ( base_t::sides().qk_wrt_q1() == 0 )
|
||||
{
|
||||
if ( ! is_ip_j<1>() )
|
||||
return false;
|
||||
|
||||
int const pk_q1 = base_t::sides().pk_wrt_q1();
|
||||
int const pk_q2 = base_t::sides().pk_wrt_q2();
|
||||
|
||||
if ( pk_q1 == -pk_q2 )
|
||||
{
|
||||
if ( pk_q1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(base_t::qi(), base_t::qj(), base_t::qk());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Point>
|
||||
inline bool is_spike_of_collinear(Point const& i, Point const& j, Point const& k) const
|
||||
{
|
||||
typedef model::referring_segment<Point const> seg_t;
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<Point>::type, Point, Point, Point, RobustPolicy
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
typename strategy::return_type result
|
||||
= strategy::apply(seg_t(i, j), seg_t(j, k), m_robust_policy);
|
||||
|
||||
return result.template get<0>().count == 2;
|
||||
}
|
||||
|
||||
template <std::size_t OpId>
|
||||
bool is_ip_j() const
|
||||
{
|
||||
int arrival = d_info().arrival[OpId];
|
||||
bool same_dirs = d_info().dir_a == 0 && d_info().dir_b == 0;
|
||||
|
||||
if ( same_dirs )
|
||||
{
|
||||
if ( i_info().count == 2 )
|
||||
{
|
||||
if ( ! d_info().opposite )
|
||||
{
|
||||
return arrival != -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return arrival != -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return arrival == 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return arrival == 1;
|
||||
}
|
||||
}
|
||||
|
||||
result_type m_result;
|
||||
RobustPolicy const& m_robust_policy;
|
||||
};
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
|
||||
@@ -47,8 +47,10 @@ struct get_turn_info_linear_areal
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out)
|
||||
{
|
||||
intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
|
||||
inters(pi, pj, pk, qi, qj, qk, robust_policy);
|
||||
typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
|
||||
inters_info;
|
||||
|
||||
inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
|
||||
|
||||
char const method = inters.d_info().how;
|
||||
|
||||
@@ -64,7 +66,7 @@ struct get_turn_info_linear_areal
|
||||
get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, inters.result(), method_none, out);
|
||||
tp_model, inters, method_none, out);
|
||||
break;
|
||||
|
||||
case 'd' : // disjoint: never do anything
|
||||
@@ -75,7 +77,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<false, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, inters.result(), method_touch_interior, out) )
|
||||
tp_model, inters, method_touch_interior, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -96,7 +98,12 @@ struct get_turn_info_linear_areal
|
||||
else
|
||||
{
|
||||
// Swap p/q
|
||||
side_calculator<Point2, Point1> swapped_side_calc(qi, qj, qk, pi, pj, pk);
|
||||
side_calculator
|
||||
<
|
||||
typename inters_info::robust_point2_type,
|
||||
typename inters_info::robust_point1_type
|
||||
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
|
||||
inters.rpi(), inters.rpj(), inters.rpk());
|
||||
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
swapped_side_calc);
|
||||
@@ -138,7 +145,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<false, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, inters.result(), method_touch, out) )
|
||||
tp_model, inters, method_touch, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -152,11 +159,62 @@ struct get_turn_info_linear_areal
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
|
||||
// workarounds for touch<> not taking spikes into account starts here
|
||||
// those was discovered empirically
|
||||
// touch<> is not symmetrical!
|
||||
// P spikes and Q spikes may produce various operations!
|
||||
// Only P spikes are valid for L/A
|
||||
// TODO: this is not optimal solution - think about rewriting touch<>
|
||||
|
||||
if ( tp.operations[0].operation == operation_blocked )
|
||||
{
|
||||
// a spike on P on the same line with Q1
|
||||
if ( inters.is_spike_p() )
|
||||
{
|
||||
if ( inters.sides().qk_wrt_p1() == 0 )
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.operations[0].operation = operation_union;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( tp.operations[0].operation == operation_continue
|
||||
&& tp.operations[1].operation == operation_continue )
|
||||
{
|
||||
// P spike on the same line with Q2 (opposite)
|
||||
if ( inters.sides().pk_wrt_q1() == -inters.sides().qk_wrt_q1()
|
||||
&& inters.is_spike_p() )
|
||||
{
|
||||
tp.operations[0].operation = operation_union;
|
||||
tp.operations[1].operation = operation_union;
|
||||
}
|
||||
}
|
||||
else if ( tp.operations[0].operation == operation_none
|
||||
&& tp.operations[1].operation == operation_none )
|
||||
{
|
||||
// spike not handled by touch<>
|
||||
if ( inters.is_spike_p() )
|
||||
{
|
||||
tp.operations[0].operation = operation_intersection;
|
||||
tp.operations[1].operation = operation_union;
|
||||
|
||||
if ( inters.sides().pk_wrt_q2() == 0 )
|
||||
{
|
||||
tp.operations[0].operation = operation_continue; // will be converted to i
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// workarounds for touch<> not taking spikes into account ends here
|
||||
|
||||
replace_method_and_operations_tm(tp.method,
|
||||
tp.operations[0].operation,
|
||||
tp.operations[1].operation);
|
||||
|
||||
// this function assumes that 'u' must be set for a spike
|
||||
bool ignore_spike
|
||||
= calculate_spike_operation(tp.operations[0].operation,
|
||||
inters, is_p_last);
|
||||
@@ -166,7 +224,7 @@ struct get_turn_info_linear_areal
|
||||
|
||||
if ( ! handle_spikes
|
||||
|| ignore_spike
|
||||
|| ! append_opposite_spikes<append_touches>( // for 'i' or 'c'
|
||||
|| ! append_opposite_spikes<append_touches>( // for 'i' or 'c' i???
|
||||
tp, inters, is_p_last, is_q_last, out) )
|
||||
{
|
||||
*out++ = tp;
|
||||
@@ -179,7 +237,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, inters.result(), method_equal, out) )
|
||||
tp_model, inters, method_equal, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -194,8 +252,8 @@ struct get_turn_info_linear_areal
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
turn_transformer_ec<false> 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());
|
||||
@@ -226,7 +284,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, inters.result(), method_collinear, out) )
|
||||
tp_model, inters, method_collinear, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -257,8 +315,8 @@ struct get_turn_info_linear_areal
|
||||
//version = append_collinear;
|
||||
}
|
||||
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_replace);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
turn_transformer_ec<false> transformer(method_replace);
|
||||
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());
|
||||
@@ -275,7 +333,7 @@ struct get_turn_info_linear_areal
|
||||
else
|
||||
{
|
||||
// Is this always 'm' ?
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch_interior);
|
||||
turn_transformer_ec<false> transformer(method_touch_interior);
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( handle_spikes )
|
||||
@@ -294,7 +352,7 @@ struct get_turn_info_linear_areal
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, inters.i_info(), inters.d_info(),
|
||||
inters.sides(), replacer);
|
||||
inters.sides(), transformer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,18 +402,38 @@ struct get_turn_info_linear_areal
|
||||
IntersectionInfo const& inters,
|
||||
bool is_p_last)
|
||||
{
|
||||
bool is_p_spike = op == operation_union
|
||||
bool is_p_spike = ( op == operation_union || op == operation_intersection )
|
||||
&& ! is_p_last
|
||||
&& inters.is_spike_p();
|
||||
|
||||
// we don't know where the spike is going since for both directions 'u' is set
|
||||
if ( is_p_spike )
|
||||
{
|
||||
if ( inters.sides().pk_wrt_q1() < 0 && inters.sides().pk_wrt_q2() < 0 )
|
||||
bool going_in = false, going_out = false;
|
||||
|
||||
int const pk_q1 = inters.sides().pk_wrt_q1();
|
||||
int const pk_q2 = inters.sides().pk_wrt_q2();
|
||||
|
||||
if ( inters.sides().qk_wrt_q1() <= 0 ) // Q turning R or C
|
||||
{
|
||||
going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both
|
||||
going_out = pk_q1 > 0 || pk_q2 > 0; // Pk on the left of one of them
|
||||
}
|
||||
else
|
||||
{
|
||||
going_in = pk_q1 < 0 || pk_q2 < 0; // Pk on the right of one of them
|
||||
going_out = pk_q1 > 0 && pk_q2 > 0; // Pk on the left of both
|
||||
}
|
||||
|
||||
if ( going_in )
|
||||
{
|
||||
op = operation_intersection;
|
||||
return true;
|
||||
}
|
||||
else if ( going_out )
|
||||
{
|
||||
op = operation_union;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -416,7 +494,7 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
bool is_p_spike = ( Version == append_touches ?
|
||||
( tp.operations[0].operation == operation_continue
|
||||
|| tp.operations[0].operation == operation_intersection ) :
|
||||
|| tp.operations[0].operation == operation_intersection ) : // i ???
|
||||
true )
|
||||
&& ! is_p_last
|
||||
&& inters.is_spike_p();
|
||||
@@ -433,13 +511,13 @@ struct get_turn_info_linear_areal
|
||||
if ( Version == append_touches )
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = ???
|
||||
//tp.operations[1].is_collinear = false;
|
||||
tp.method = method_touch;
|
||||
}
|
||||
else
|
||||
{
|
||||
//tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = true;
|
||||
tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = false;
|
||||
|
||||
BOOST_ASSERT(inters.i_info().count > 1);
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1);
|
||||
@@ -495,25 +573,29 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
|
||||
template <bool IsFront>
|
||||
class replacer_of_method_and_operations_ec
|
||||
class turn_transformer_ec
|
||||
{
|
||||
public:
|
||||
explicit replacer_of_method_and_operations_ec(method_type method_t_or_m)
|
||||
explicit turn_transformer_ec(method_type method_t_or_m)
|
||||
: m_method(method_t_or_m)
|
||||
{}
|
||||
|
||||
void operator()(method_type & method,
|
||||
operation_type & op0,
|
||||
operation_type & op1) const
|
||||
template <typename Turn>
|
||||
void operator()(Turn & turn) const
|
||||
{
|
||||
operation_type & op0 = turn.operations[0].operation;
|
||||
operation_type & op1 = turn.operations[1].operation;
|
||||
|
||||
// NOTE: probably only if methods are WRT IPs, not segments!
|
||||
if ( IsFront
|
||||
|| op0 == operation_intersection || op0 == operation_union
|
||||
|| op1 == operation_intersection || op1 == operation_union )
|
||||
{
|
||||
method = m_method;
|
||||
turn.method = m_method;
|
||||
}
|
||||
|
||||
turn.operations[0].is_collinear = op0 != operation_blocked;
|
||||
|
||||
// Assuming G1 is always Linear
|
||||
if ( op0 == operation_blocked )
|
||||
{
|
||||
@@ -550,7 +632,7 @@ struct get_turn_info_linear_areal
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename TurnInfo,
|
||||
typename IntersectionResult,
|
||||
typename IntersectionInfo,
|
||||
typename OutputIterator>
|
||||
static inline bool get_turn_info_for_endpoint(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
@@ -558,14 +640,14 @@ struct get_turn_info_linear_areal
|
||||
bool is_p_first, bool is_p_last,
|
||||
bool is_q_first, bool is_q_last,
|
||||
TurnInfo const& tp_model,
|
||||
IntersectionResult const& result,
|
||||
IntersectionInfo const& inters,
|
||||
method_type /*method*/,
|
||||
OutputIterator out)
|
||||
{
|
||||
namespace ov = overlay;
|
||||
typedef ov::get_turn_info_for_endpoint<AssignPolicy, EnableFirst, EnableLast> get_info_e;
|
||||
|
||||
const std::size_t ip_count = result.template get<0>().count;
|
||||
const std::size_t ip_count = inters.i_info().count;
|
||||
// no intersection points
|
||||
if ( ip_count == 0 )
|
||||
return false;
|
||||
@@ -577,11 +659,11 @@ struct get_turn_info_linear_areal
|
||||
if ( !is_p_first && !is_p_last )
|
||||
return false;
|
||||
|
||||
linear_intersections intersections(pi, qi, result, is_p_last, is_q_last);
|
||||
linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last);
|
||||
linear_intersections::ip_info const& ip0 = intersections.template get<0>();
|
||||
linear_intersections::ip_info const& ip1 = intersections.template get<1>();
|
||||
|
||||
const bool opposite = result.template get<1>().opposite;
|
||||
const bool opposite = inters.d_info().opposite;
|
||||
|
||||
// ANALYSE AND ASSIGN FIRST
|
||||
|
||||
@@ -604,7 +686,13 @@ struct get_turn_info_linear_areal
|
||||
|
||||
if ( ip0.is_qj )
|
||||
{
|
||||
side_calculator<Point1, Point2, Point2> side_calc(qi, pi, pj, qi, qj, qk);
|
||||
side_calculator
|
||||
<
|
||||
typename IntersectionInfo::robust_point1_type,
|
||||
typename IntersectionInfo::robust_point2_type,
|
||||
typename IntersectionInfo::robust_point2_type
|
||||
> side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
|
||||
inters.rqi(), inters.rqj(), inters.rqk());
|
||||
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = get_info_e::operations_of_equal(side_calc);
|
||||
@@ -616,9 +704,18 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
else
|
||||
{
|
||||
side_calculator<Point1, Point2,
|
||||
Point2, Point1, Point1,
|
||||
Point2, Point1, Point2> side_calc(qi, pi, pj, qi, pi, qj);
|
||||
side_calculator
|
||||
<
|
||||
typename IntersectionInfo::robust_point1_type,
|
||||
typename IntersectionInfo::robust_point2_type,
|
||||
typename IntersectionInfo::robust_point2_type,
|
||||
typename IntersectionInfo::robust_point1_type,
|
||||
typename IntersectionInfo::robust_point1_type,
|
||||
typename IntersectionInfo::robust_point2_type,
|
||||
typename IntersectionInfo::robust_point1_type,
|
||||
typename IntersectionInfo::robust_point2_type
|
||||
> side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
|
||||
inters.rqi(), inters.rpi(), inters.rqj());
|
||||
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = get_info_e::operations_of_equal(side_calc);
|
||||
@@ -627,23 +724,20 @@ struct get_turn_info_linear_areal
|
||||
tp.operations[1].operation = operations.second;
|
||||
}
|
||||
|
||||
replacer_of_method_and_operations_ec<true> replacer(replaced_method);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
turn_transformer_ec<true> transformer(replaced_method);
|
||||
transformer(tp);
|
||||
}
|
||||
|
||||
// equals<> or collinear<> will assign the second point,
|
||||
// we'd like to assign the first one
|
||||
base_turn_handler::assign_point(tp, tp.method, result.template get<0>(), 0);
|
||||
base_turn_handler::assign_point(tp, tp.method, inters.i_info(), 0);
|
||||
|
||||
// NOTE: not really needed especially for the first point
|
||||
// for which there is no preceding segment (but consistent with the L/L)
|
||||
if ( result.template get<0>().count > 1 )
|
||||
{
|
||||
//BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
// NOTE: is_collinear is not set for the first endpoint of L
|
||||
// for which there is no preceding segment
|
||||
// here is_p_first_ip == true
|
||||
tp.operations[0].is_collinear = false;
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
@@ -656,7 +750,7 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
TurnInfo tp = tp_model;
|
||||
|
||||
if ( result.template get<0>().count > 1 )
|
||||
if ( inters.i_info().count > 1 )
|
||||
{
|
||||
//BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
|
||||
tp.operations[0].is_collinear = true;
|
||||
@@ -664,7 +758,13 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
else //if ( result.template get<0>().count == 1 )
|
||||
{
|
||||
side_calculator<Point1, Point2, Point2> side_calc(qi, pj, pi, qi, qj, qk);
|
||||
side_calculator
|
||||
<
|
||||
typename IntersectionInfo::robust_point1_type,
|
||||
typename IntersectionInfo::robust_point2_type,
|
||||
typename IntersectionInfo::robust_point2_type
|
||||
> side_calc(inters.rqi(), inters.rpj(), inters.rpi(),
|
||||
inters.rqi(), inters.rqj(), inters.rqk());
|
||||
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = get_info_e::operations_of_equal(side_calc);
|
||||
@@ -672,13 +772,10 @@ struct get_turn_info_linear_areal
|
||||
tp.operations[0].operation = operations.first;
|
||||
tp.operations[1].operation = operations.second;
|
||||
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_none);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
turn_transformer_ec<false> transformer(method_none);
|
||||
transformer(tp);
|
||||
|
||||
if ( tp.both(operation_continue) )
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
tp.operations[0].is_collinear = tp.both(operation_continue);
|
||||
}
|
||||
|
||||
tp.method = ( ip_count > 1 ? ip1.is_qj : ip0.is_qj ) ? method_touch : method_touch_interior;
|
||||
@@ -689,9 +786,9 @@ struct get_turn_info_linear_areal
|
||||
// equals<> or collinear<> will assign the second point,
|
||||
// we'd like to assign the first one
|
||||
std::size_t ip_index = ip_count > 1 ? 1 : 0;
|
||||
base_turn_handler::assign_point(tp, tp.method, result.template get<0>(), ip_index);
|
||||
base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -44,8 +44,10 @@ struct get_turn_info_linear_linear
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out)
|
||||
{
|
||||
intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
|
||||
inters(pi, pj, pk, qi, qj, qk, robust_policy);
|
||||
typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
|
||||
inters_info;
|
||||
|
||||
inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
|
||||
|
||||
char const method = inters.d_info().how;
|
||||
|
||||
@@ -93,7 +95,13 @@ struct get_turn_info_linear_linear
|
||||
else
|
||||
{
|
||||
// Swap p/q
|
||||
side_calculator<Point2, Point1> swapped_side_calc(qi, qj, qk, pi, pj, pk);
|
||||
side_calculator
|
||||
<
|
||||
typename inters_info::robust_point2_type,
|
||||
typename inters_info::robust_point1_type
|
||||
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
|
||||
inters.rpi(), inters.rpj(), inters.rpk());
|
||||
|
||||
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
swapped_side_calc);
|
||||
@@ -143,14 +151,109 @@ struct get_turn_info_linear_linear
|
||||
touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
if ( tp.operations[0].operation == operation_blocked )
|
||||
// workarounds for touch<> not taking spikes into account starts here
|
||||
// those was discovered empirically
|
||||
// touch<> is not symmetrical!
|
||||
// P spikes and Q spikes may produce various operations!
|
||||
// TODO: this is not optimal solution - think about rewriting touch<>
|
||||
|
||||
if ( tp.operations[0].operation == operation_blocked
|
||||
&& tp.operations[1].operation == operation_blocked )
|
||||
{
|
||||
tp.operations[1].is_collinear = true;
|
||||
// two touching spikes on the same line
|
||||
if ( inters.is_spike_p() && inters.is_spike_q() )
|
||||
{
|
||||
tp.operations[0].operation = operation_union;
|
||||
tp.operations[1].operation = operation_union;
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
tp.operations[1].is_collinear = true;
|
||||
}
|
||||
}
|
||||
if ( tp.operations[1].operation == operation_blocked )
|
||||
else if ( tp.operations[0].operation == operation_blocked )
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
// a spike on P on the same line with Q1
|
||||
if ( inters.is_spike_p() )
|
||||
{
|
||||
if ( inters.sides().qk_wrt_p1() == 0 )
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.operations[0].operation = operation_union;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.operations[1].is_collinear = true;
|
||||
}
|
||||
}
|
||||
else if ( tp.operations[1].operation == operation_blocked )
|
||||
{
|
||||
// a spike on Q on the same line with P1
|
||||
if ( inters.is_spike_q() )
|
||||
{
|
||||
if ( inters.sides().pk_wrt_q1() == 0 )
|
||||
{
|
||||
tp.operations[1].is_collinear = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.operations[1].operation = operation_union;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
}
|
||||
else if ( tp.operations[0].operation == operation_continue
|
||||
&& tp.operations[1].operation == operation_continue )
|
||||
{
|
||||
// P spike on the same line with Q2 (opposite)
|
||||
if ( inters.sides().pk_wrt_q1() == -inters.sides().qk_wrt_q1()
|
||||
&& inters.is_spike_p() )
|
||||
{
|
||||
tp.operations[0].operation = operation_union;
|
||||
tp.operations[1].operation = operation_union;
|
||||
}
|
||||
}
|
||||
else if ( tp.operations[0].operation == operation_none
|
||||
&& tp.operations[1].operation == operation_none )
|
||||
{
|
||||
// spike not handled by touch<>
|
||||
bool const is_p = inters.is_spike_p();
|
||||
bool const is_q = inters.is_spike_q();
|
||||
|
||||
if ( is_p || is_q )
|
||||
{
|
||||
tp.operations[0].operation = operation_union;
|
||||
tp.operations[1].operation = operation_union;
|
||||
|
||||
if ( inters.sides().pk_wrt_q2() == 0 )
|
||||
{
|
||||
tp.operations[0].operation = operation_continue; // will be converted to i
|
||||
if ( is_p )
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( inters.sides().qk_wrt_p2() == 0 )
|
||||
{
|
||||
tp.operations[1].operation = operation_continue; // will be converted to i
|
||||
if ( is_q )
|
||||
{
|
||||
tp.operations[1].is_collinear = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// workarounds for touch<> not taking spikes into account ends here
|
||||
|
||||
replace_method_and_operations_tm(tp.method,
|
||||
tp.operations[0].operation,
|
||||
@@ -190,8 +293,9 @@ struct get_turn_info_linear_linear
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
// 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());
|
||||
@@ -231,6 +335,7 @@ struct get_turn_info_linear_linear
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this is for spikes since those are set in the turn_transformer_ec
|
||||
tp.operations[0].is_collinear = true;
|
||||
tp.operations[1].is_collinear = true;
|
||||
|
||||
@@ -257,8 +362,9 @@ struct get_turn_info_linear_linear
|
||||
//spike_op = operation_continue;
|
||||
}
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_replace);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
// transform turn
|
||||
turn_transformer_ec transformer(method_replace);
|
||||
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());
|
||||
@@ -277,7 +383,7 @@ struct get_turn_info_linear_linear
|
||||
else
|
||||
{
|
||||
// If this always 'm' ?
|
||||
replacer_of_method_and_operations_ec replacer(method_touch_interior);
|
||||
turn_transformer_ec transformer(method_touch_interior);
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( handle_spikes )
|
||||
@@ -297,7 +403,7 @@ struct get_turn_info_linear_linear
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, inters.i_info(), inters.d_info(), inters.sides(),
|
||||
replacer, !is_p_last, !is_q_last);
|
||||
transformer, !is_p_last, !is_q_last);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,13 +547,13 @@ struct get_turn_info_linear_linear
|
||||
if ( Version == append_touches )
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = ???
|
||||
tp.operations[1].is_collinear = false;
|
||||
tp.method = method_touch;
|
||||
}
|
||||
else
|
||||
else // Version == append_collinear_opposite
|
||||
{
|
||||
//tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = true;
|
||||
tp.operations[0].is_collinear = true;
|
||||
tp.operations[1].is_collinear = false;
|
||||
|
||||
BOOST_ASSERT(inters.i_info().count > 1);
|
||||
|
||||
@@ -472,14 +578,14 @@ struct get_turn_info_linear_linear
|
||||
{
|
||||
if ( Version == append_touches )
|
||||
{
|
||||
//tp.operations[0].is_collinear = ???
|
||||
tp.operations[0].is_collinear = false;
|
||||
tp.operations[1].is_collinear = true;
|
||||
tp.method = method_touch;
|
||||
}
|
||||
else
|
||||
else // Version == append_collinear_opposite
|
||||
{
|
||||
//tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = true;
|
||||
tp.operations[0].is_collinear = false;
|
||||
tp.operations[1].is_collinear = true;
|
||||
|
||||
BOOST_ASSERT(inters.i_info().count > 0);
|
||||
|
||||
@@ -543,17 +649,19 @@ struct get_turn_info_linear_linear
|
||||
}
|
||||
}
|
||||
|
||||
class replacer_of_method_and_operations_ec
|
||||
class turn_transformer_ec
|
||||
{
|
||||
public:
|
||||
explicit replacer_of_method_and_operations_ec(method_type method_t_or_m)
|
||||
explicit turn_transformer_ec(method_type method_t_or_m)
|
||||
: m_method(method_t_or_m)
|
||||
{}
|
||||
|
||||
void operator()(method_type & method,
|
||||
operation_type & op0,
|
||||
operation_type & op1) const
|
||||
template <typename Turn>
|
||||
void operator()(Turn & turn) const
|
||||
{
|
||||
operation_type & op0 = turn.operations[0].operation;
|
||||
operation_type & op1 = turn.operations[1].operation;
|
||||
|
||||
BOOST_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
|
||||
|
||||
if ( op0 == operation_blocked )
|
||||
@@ -577,8 +685,13 @@ struct get_turn_info_linear_linear
|
||||
if ( op0 == operation_intersection || op0 == operation_union
|
||||
|| op1 == operation_intersection || op1 == operation_union )
|
||||
{
|
||||
method = m_method;
|
||||
turn.method = m_method;
|
||||
}
|
||||
|
||||
// TODO: is this correct?
|
||||
// it's equivalent to comparing to operation_blocked at the beginning of the function
|
||||
turn.operations[0].is_collinear = op0 != operation_intersection;
|
||||
turn.operations[1].is_collinear = op1 != operation_intersection;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -38,7 +38,7 @@ struct points_end
|
||||
|
||||
|
||||
|
||||
} // namespace core_dispatch
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
@@ -99,6 +99,24 @@ struct segments_intersection_ratios
|
||||
{
|
||||
return return_type();
|
||||
}
|
||||
|
||||
template <typename Segment, typename Ratio>
|
||||
static inline return_type one_degenerate(Segment const& ,
|
||||
Ratio const& ratio, bool a_degenerate)
|
||||
{
|
||||
return_type result;
|
||||
if (a_degenerate)
|
||||
{
|
||||
// IP lies on ratio w.r.t. segment b
|
||||
result.assign(Ratio::zero(), ratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.assign(ratio, Ratio::zero());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,106 +31,132 @@ void test_all()
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(15 5,24 5,20 2,19 0,13 -4,1 0,10 0,13 3,15 7,16 10,10 10,8 10,4 6,2 8,1 10)",
|
||||
"POLYGON((0 0,5 5,0 10,20 10,20 2,19 0,0 0)(10 3,15 3,15 7,10 7,10 3))",
|
||||
expected("miu")("iuu")("tcc")("tuu")("mcu")("mic")("muu")("tiu")("mcu")("mic")("mcc")("miu")("mxu").vec);
|
||||
expected("miu+")("iuu+")("tcc+")("tuu=")("mcu+")("mic=")("muu+")
|
||||
("tiu+")("mcu+")("mic=")("mcc+")("miu=")("mxu+"));
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(5 0,5 5,10 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"miu", "mxu");
|
||||
"miu+", "mxu+");
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,5 5,10 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"tiu", "txu");
|
||||
"tiu+", "txu+");
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,5 0,5 5,10 5,10 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
expected("tcu")("mic")("mcc")("txu").vec);
|
||||
expected("tcu+")("mic=")("mcc+")("txu="));
|
||||
test_geometry<ls, poly>("LINESTRING(10 0,5 0,5 5,10 5,10 10)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
expected("tcc")("miu")("mcu")("txc").vec);
|
||||
expected("tcc+")("miu=")("mcu+")("txc="));
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,10 0,10 10)",
|
||||
"POLYGON((0 0,5 5,0 10,20 10,20 2,19 0,0 0)(10 3,15 3,15 7,10 7,10 3))",
|
||||
expected("tcu")("mic")("mcu")("mic")("mxu").vec);
|
||||
expected("tcu+")("mic=")("mcu+")("mic=")("mxu+"));
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(11 1,10 0,0 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"tcc", "txu");
|
||||
"tcc+", "txu=");
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,10 0,11 1)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"tcu", "tuc");
|
||||
"tcu+", "tuc=");
|
||||
test_geometry<ls, poly>("LINESTRING(10 0,0 0,-1 1)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"tcc", "tuu");
|
||||
"tcc+", "tuu=");
|
||||
|
||||
// true hole
|
||||
test_geometry<ls, poly>("LINESTRING(9 1,10 5,9 9)",
|
||||
"POLYGON((0 0,0 10,10 10,10 5,10 0,0 0)(2 2,10 5,2 8,2 2))",
|
||||
expected("tiu")("tiu").vec);
|
||||
expected("tiu+")("tiu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(10 1,10 5,10 9)",
|
||||
"POLYGON((0 0,0 10,10 10,10 5,10 0,0 0)(2 2,10 5,2 8,2 2))",
|
||||
expected("mcu")("ecc")("tiu")("mxc").vec);
|
||||
expected("mcu+")("ecc=")("tiu+")("mxc="));
|
||||
|
||||
// fake hole
|
||||
test_geometry<ls, poly>("LINESTRING(9 1,10 5,9 9)",
|
||||
"POLYGON((0 0,0 10,10 10,10 5,2 8,2 2,10 5,10 0,0 0))",
|
||||
expected("tuu")("tiu").vec);
|
||||
expected("tuu+")("tiu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(10 1,10 5,10 9)",
|
||||
"POLYGON((0 0,0 10,10 10,10 5,2 8,2 2,10 5,10 0,0 0))",
|
||||
expected("mcu")("tuc")("tcu")("mxc").vec);
|
||||
expected("mcu+")("tuc=")("tcu+")("mxc="));
|
||||
|
||||
// true hole
|
||||
test_geometry<ls, poly>("LINESTRING(10 1,10 5,2 2)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0),(10 5,2 8,2 2,10 5))",
|
||||
expected("mcu")("mic")("tcu")("txc"));
|
||||
expected("mcu+")("mic=")("tcu+")("txc="));
|
||||
test_geometry<ls, poly>("LINESTRING(10 1,10 5,2 8)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0),(10 5,2 8,2 2,10 5))",
|
||||
expected("mcu")("mic")("tcc")("txu"));
|
||||
expected("mcu+")("mic=")("tcc+")("txu="));
|
||||
|
||||
// SPIKE - NON-ENDPOINT - NON-OPPOSITE
|
||||
|
||||
// spike - neq eq
|
||||
test_geometry<ls, poly>("LINESTRING(2 2,4 4,1 1)", "POLYGON((0 0,4 4,6 3,6 0,0 0))",
|
||||
expected("mcc")("txu")("tcu")("mxc"));
|
||||
expected("mcc+")("txu=")("tcu=")("mxc="));
|
||||
// spike - eq eq
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,4 4,1 1)", "POLYGON((0 0,4 4,6 3,6 0,0 0))",
|
||||
expected("tcc")("txu")("tcu")("mxc"));
|
||||
expected("tcc+")("txu=")("tcu=")("mxc="));
|
||||
// spike - eq neq
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,3 3,1 1)", "POLYGON((0 0,4 4,6 3,6 0,0 0))",
|
||||
expected("tcc")("mxu")("mcu")("mxc"));
|
||||
expected("tcc+")("mxu=")("mcu=")("mxc="));
|
||||
// spike - neq neq
|
||||
test_geometry<ls, poly>("LINESTRING(1 1,3 3,2 2)", "POLYGON((0 0,4 4,6 3,6 0,0 0))",
|
||||
expected("mcc")("mxu")("mcu")("mxc"));
|
||||
expected("mcc+")("mxu=")("mcu=")("mxc="));
|
||||
// spike - out neq
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,3 3,2 2)", "POLYGON((1 1,4 4,6 3,6 0,1 1))",
|
||||
expected("mcc")("mxu")("mcu")("mxc"));
|
||||
expected("mcc+")("mxu=")("mcu=")("mxc="));
|
||||
// spike - out eq
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,4 4,2 2)", "POLYGON((1 1,4 4,6 3,6 0,1 1))",
|
||||
expected("mcc")("txu")("tcu")("mxc"));
|
||||
expected("mcc+")("txu=")("tcu=")("mxc="));
|
||||
// spike - out out/eq
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,4 4,2 2)", "POLYGON((1 0,4 4,6 3,1 0))",
|
||||
expected("tuu"));
|
||||
expected("tuu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,4 4,2 2)", "POLYGON((0 1,4 4,6 3,6 0,-1 -1,0 1))",
|
||||
expected("tiu"));
|
||||
expected("tiu+"));
|
||||
// spike - out out/neq
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,4 4,2 2)", "POLYGON((4 0,4 5,6 3,4 0))",
|
||||
expected("muu"));
|
||||
expected("muu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,4 4,2 2)", "POLYGON((0 4,5 4,6 3,6 0,-1 -1,0 4))",
|
||||
expected("miu"));
|
||||
expected("miu+"));
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(0 1,1 1,0 1)", "POLYGON((0 0,3 3,3 0,0 0))",
|
||||
expected("muu"));
|
||||
expected("muu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(0 1,3 3,0 1)", "POLYGON((0 0,3 3,3 0,0 0))",
|
||||
expected("tuu"));
|
||||
expected("tuu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(0 1,0 0,0 1)", "POLYGON((0 0,3 3,3 0,0 0))",
|
||||
expected("tuu"));
|
||||
expected("tuu+"));
|
||||
|
||||
// SPIKE - NON-ENDPOINT - OPPOSITE
|
||||
|
||||
// opposite - eq eq
|
||||
test_geometry<ls, poly>("LINESTRING(6 6,4 4,0 0,2 2)", "POLYGON((-1 -1,0 0,4 4,6 3,-1 -1))",
|
||||
expected("tcu")("txc")("tcc")("mxu"));
|
||||
expected("tcu+")("txc=")("tcc=")("mxu="));
|
||||
// opposite - neq eq
|
||||
test_geometry<ls, poly>("LINESTRING(6 6,4 4,0 0,2 2)", "POLYGON((-1 -1,0 0,5 5,6 3,-1 -1))",
|
||||
expected("mcu")("txc")("tcc")("mxu"));
|
||||
expected("mcu+")("txc=")("tcc=")("mxu="));
|
||||
// opposite - eq, neq
|
||||
test_geometry<ls, poly>("LINESTRING(6 6,4 4,0 0,2 2)", "POLYGON((-2 -2,-1 -1,4 4,6 3,-2 -2))",
|
||||
expected("tcu")("mxc")("mcc")("mxu"));
|
||||
expected("tcu+")("mxc=")("mcc=")("mxu="));
|
||||
// opposite - neq neq
|
||||
test_geometry<ls, poly>("LINESTRING(6 6,4 4,0 0,2 2)", "POLYGON((-2 -2,-1 -1,3 3,6 3,-2 -2))",
|
||||
expected("mcu")("mxc")("mcc")("mxu"));
|
||||
expected("mcu+")("mxc=")("mcc=")("mxu="));
|
||||
// opposite - neq neq
|
||||
test_geometry<ls, poly>("LINESTRING(6 6,4 4,0 0,2 2)", "POLYGON((-2 -2,-1 -1,3 3,5 5,6 3,-2 -2))",
|
||||
expected("mcu")("mxc")("mcc")("mxu"));
|
||||
expected("mcu+")("mxc=")("mcc=")("mxu="));
|
||||
|
||||
// spike vs internal
|
||||
test_geometry<ls, poly>("LINESTRING(0 1,1 1,0 1)", // --
|
||||
"POLYGON((1 0,1 1,2 1,1 0))",
|
||||
expected("tuu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(1 2,1 1,1 2)", // |
|
||||
"POLYGON((1 0,1 1,2 1,1 0))",
|
||||
expected("tuu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(0 2,1 1,0 2)",
|
||||
"POLYGON((1 0,1 1,2 1,1 0))",
|
||||
expected("tuu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(2 0,1 1,2 0)",
|
||||
"POLYGON((1 0,1 1,2 1,2 0,1 0))",
|
||||
expected("tiu+")("tiu+")("txu+")); // TODO: should spike point be duplicated?
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,1 1,0 0)", // /
|
||||
"POLYGON((1 0,1 1,2 1,1 0))",
|
||||
expected("tuu+"));
|
||||
test_geometry<ls, poly>("LINESTRING(2 2,1 1,2 2)", // /
|
||||
"POLYGON((1 0,1 1,2 1,1 0))",
|
||||
expected("tuu+"));
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(2 1,1 1,2 1)",
|
||||
"POLYGON((1 0,1 1,2 1,1 0))",
|
||||
expected("tcu+")("txc=")("tcc=")("txu="));
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
|
||||
@@ -32,179 +32,189 @@ void test_all()
|
||||
typedef bg::model::linestring<pt> ls;
|
||||
typedef bg::model::multi_linestring<ls> mls;
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0)", "LINESTRING(0 0,2 0)", "tii", "txx");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0)", "LINESTRING(2 0,0 0)", "tix", "txi");
|
||||
// NOTE: currently for the first endpoint of the Linestring on collinear segment
|
||||
// is_collinear flags are set to FALSE!
|
||||
// E.g. in the first test tii++, NOT tii==
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0)", "LINESTRING(0 0,2 0)", "tii++", "txx==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0)", "LINESTRING(2 0,0 0)", "tix+=", "txi=+");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 1)", "LINESTRING(0 0,1 0,2 0)", "tuu");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,0 0)", "LINESTRING(0 0,1 0,2 0)", "txi", "tiu");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,2 0)", "LINESTRING(0 0,1 0,2 0)", "tii", "txx");
|
||||
test_geometry<ls, ls>("LINESTRING(1 1,1 0)", "LINESTRING(0 0,1 0,2 0)", "txu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0)", "LINESTRING(0 0,1 0,2 0)", "tii", "txu");
|
||||
test_geometry<ls, ls>("LINESTRING(2 0,1 0)", "LINESTRING(0 0,1 0,2 0)", "txi", "tix");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 1)", "LINESTRING(0 0,1 0,2 0)", "tuu++");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,0 0)", "LINESTRING(0 0,1 0,2 0)", "txi=+", "tiu+=");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,2 0)", "LINESTRING(0 0,1 0,2 0)", "tii++", "txx==");
|
||||
test_geometry<ls, ls>("LINESTRING(1 1,1 0)", "LINESTRING(0 0,1 0,2 0)", "txu++");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0)", "LINESTRING(0 0,1 0,2 0)", "tii++", "txu==");
|
||||
test_geometry<ls, ls>("LINESTRING(2 0,1 0)", "LINESTRING(0 0,1 0,2 0)", "txi=+", "tix+=");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 0,1 1)", "tuu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 0,0 0)", "tix", "tui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 0,2 0)", "tii", "txx");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 1,1 0)", "tux");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(0 0,1 0)", "tii", "tux");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(2 0,1 0)", "tix", "txi");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 0,1 1)", "tuu++");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 0,0 0)", "tix+=", "tui=+");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 0,2 0)", "tii++", "txx==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(1 1,1 0)", "tux++");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(0 0,1 0)", "tii++", "tux==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 0)", "LINESTRING(2 0,1 0)", "tix+=", "txi=+");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(1 1,1 0,3 0,3 1)", "mii", "ccc", "muu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(1 -1,1 0,3 0,3 -1)", "mii", "ccc", "muu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(3 1,3 0,1 0,1 1)", "miu", "mui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(3 -1,3 0,1 0,1 -1)", "miu", "mui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(2 1,2 0,4 0,4 1)", "tii", "ccc", "tuu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(2 -1,2 0,4 0,4 -1)", "tii", "ccc", "tuu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(4 1,4 0,2 0,2 1)", "tiu", "tui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(4 -1,4 0,2 0,2 -1)", "tiu", "tui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(1 1,1 0,3 0,3 1)", "mii++", "ccc==", "muu==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(1 -1,1 0,3 0,3 -1)", "mii++", "ccc==", "muu==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(3 1,3 0,1 0,1 1)", "miu+=", "mui=+");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(3 -1,3 0,1 0,1 -1)", "miu+=", "mui=+");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(2 1,2 0,4 0,4 1)", "tii++", "ccc==", "tuu==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(2 -1,2 0,4 0,4 -1)", "tii++", "ccc==", "tuu==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(4 1,4 0,2 0,2 1)", "tiu+=", "tui=+");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(4 -1,4 0,2 0,2 -1)", "tiu+=", "tui=+");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(1 1,1 0,2 0,3 0,3 1)", "mii", "ecc", "muu");
|
||||
// same as above - TODO: reverse manually or automatically for all tests
|
||||
/*test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(1 1,1 0,2 0,3 0,3 1)", "mii", "ecc", "muu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(1 -1,1 0,2 0,3 0,3 -1)", "mii", "ecc", "muu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(3 1,3 0,2 0,1 0,1 1)", "miu", "ecc", "mui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,4 0)", "LINESTRING(3 -1,3 0,2 0,1 0,1 -1)", "miu", "ecc", "mui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(2 1,2 0,3 0,4 0,4 1)", "tii", "ecc", "tuu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(2 -1,2 0,3 0,4 0,4 -1)", "tii", "ecc", "tuu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(4 1,4 0,3 0,2 0,2 1)", "tiu", "ecc", "tui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(4 -1,4 0,3 0,2 0,2 -1)", "tiu", "ecc", "tui");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 0,3 0,4 0,6 0)", "LINESTRING(4 -1,4 0,3 0,2 0,2 -1)", "tiu", "ecc", "tui");*/
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 1,3 5,4 0)", "LINESTRING(1 0,2 1,3 5)", "tii", "ecc", "tux");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 1,3 5,4 0)", "LINESTRING(3 5,2 1,1 0)", "tix", "ecc", "tui");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,2 1,3 5)", "LINESTRING(0 0,1 0,2 1,3 5,4 0)", "txu", "ecc", "tii");
|
||||
test_geometry<ls, ls>("LINESTRING(3 5,2 1,1 0)", "LINESTRING(0 0,1 0,2 1,3 5,4 0)", "tiu", "ecc", "txi");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 1,3 5,4 0)", "LINESTRING(1 0,2 1,3 5)", "tii++", "ecc==", "tux==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 1,3 5,4 0)", "LINESTRING(3 5,2 1,1 0)", "tix+=", "ecc==", "tui=+");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,2 1,3 5)", "LINESTRING(0 0,1 0,2 1,3 5,4 0)", "txu==", "ecc==", "tii++");
|
||||
test_geometry<ls, ls>("LINESTRING(3 5,2 1,1 0)", "LINESTRING(0 0,1 0,2 1,3 5,4 0)", "tiu+=", "ecc==", "txi=+");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(-1 -1,1 0,10 0,20 -1)", "mii", "txu");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(20 -1,10 0,1 0,-1 -1)", "miu", "txi");
|
||||
test_geometry<ls, ls>("LINESTRING(-1 -1,1 0,10 0,20 -1)", "LINESTRING(0 0,10 0)", "mii", "tux");
|
||||
test_geometry<ls, ls>("LINESTRING(20 -1,10 0,1 0,-1 -1)", "LINESTRING(0 0,10 0)", "mui", "tix");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(-1 -1,1 0,10 0,20 -1)", "mii++", "txu==");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(20 -1,10 0,1 0,-1 -1)", "miu+=", "txi=+");
|
||||
test_geometry<ls, ls>("LINESTRING(-1 -1,1 0,10 0,20 -1)", "LINESTRING(0 0,10 0)", "mii++", "tux==");
|
||||
test_geometry<ls, ls>("LINESTRING(20 -1,10 0,1 0,-1 -1)", "LINESTRING(0 0,10 0)", "mui=+", "tix+=");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0)",
|
||||
"LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)",
|
||||
expected("tii")("ecc")("muu")("mii")("muu")("mii")("mux"));
|
||||
expected("tii++")("ecc==")("muu==")("mii++")("muu==")("mii++")("mux=="));
|
||||
test_geometry<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0)",
|
||||
"LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)",
|
||||
expected("tiu")("ecc")("mui")("miu")("mui")("miu")("mui"));
|
||||
expected("tiu+=")("ecc==")("mui=+")("miu+=")("mui=+")("miu+=")("mui=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)",
|
||||
"LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)",
|
||||
expected("tui")("ecc")("miu")("mui")("miu")("mui")("mix"));
|
||||
expected("tui=+")("ecc==")("miu+=")("mui=+")("miu+=")("mui=+")("mix+="));
|
||||
test_geometry<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)",
|
||||
"LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)",
|
||||
expected("tuu")("ecc")("mii")("muu")("mii")("muu")("mii"));
|
||||
expected("tuu==")("ecc==")("mii++")("muu==")("mii++")("muu==")("mii++"));
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(-1 0,1 0,2 1,3 2)", "LINESTRING(4 5,3 2,1 0,0 0)", "mix", "txi", "ecc");
|
||||
test_geometry<ls, ls>("LINESTRING(4 5,3 2,1 0,0 0)", "LINESTRING(-1 0,1 0,2 1,3 2)", "mxi", "tix", "ecc");
|
||||
test_geometry<ls, ls>("LINESTRING(-1 0,1 0,2 1,3 2)", "LINESTRING(4 5,3 2,1 0,0 0)", "mix+=", "txi=+", "ecc==");
|
||||
test_geometry<ls, ls>("LINESTRING(4 5,3 2,1 0,0 0)", "LINESTRING(-1 0,1 0,2 1,3 2)", "mxi=+", "tix+=", "ecc==");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(30 1,20 1,10 0,0 0)", "LINESTRING(1 1,2 0,3 1,20 1,25 1)", "mix", "tui", "muu");
|
||||
test_geometry<ls, ls>("LINESTRING(1 1,2 0,3 1,20 1,25 1)", "LINESTRING(30 1,20 1,10 0,0 0)", "mxi", "tiu", "muu");
|
||||
test_geometry<ls, ls>("LINESTRING(30 1,20 1,10 0,0 0)", "LINESTRING(1 1,2 0,3 1,20 1,25 1)", "mix+=", "tui=+", "muu++");
|
||||
test_geometry<ls, ls>("LINESTRING(1 1,2 0,3 1,20 1,25 1)", "LINESTRING(30 1,20 1,10 0,0 0)", "mxi=+", "tiu+=", "muu++");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,30 0)", "LINESTRING(4 0,4 1,20 1,5 0,1 0)", "muu", "mui", "mix");
|
||||
test_geometry<ls, ls>("LINESTRING(4 0,4 1,20 1,5 0,1 0)", "LINESTRING(0 0,30 0)", "muu", "miu", "mxi");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,30 0)", "LINESTRING(4 0,4 1,20 1,5 0,1 0)", "muu++", "mui=+", "mix+=");
|
||||
test_geometry<ls, ls>("LINESTRING(4 0,4 1,20 1,5 0,1 0)", "LINESTRING(0 0,30 0)", "muu++", "miu+=", "mxi=+");
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(30 0,0 0)", "LINESTRING(1 0,5 0,20 1,4 1,4 0,5 0)",
|
||||
expected("mui")("miu")("mui")("mix"));
|
||||
expected("mui=+")("miu+=")("mui=+")("mix+="));
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,5 0,20 1,4 1,4 0,5 0)", "LINESTRING(30 0,0 0)",
|
||||
expected("miu")("mui")("miu")("mxi"));
|
||||
expected("miu+=")("mui=+")("miu+=")("mxi=+"));
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,7 0,8 1)", "LINESTRING(0 0,10 0,10 10,4 -1)",
|
||||
expected("mii")("iuu")("muu"));
|
||||
expected("mii++")("iuu++")("muu=="));
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,7 0,8 1)", "LINESTRING(0 0,10 0,10 10,5 0,4 1)",
|
||||
expected("mii")("muu")("muu"));
|
||||
expected("mii++")("muu++")("muu=="));
|
||||
|
||||
// non-collinear
|
||||
test_geometry<ls, ls>("LINESTRING(0 1,0 0)", "LINESTRING(0 0,1 0,2 0)", "txu++");
|
||||
test_geometry<ls, ls>("LINESTRING(0 1,0 0,1 1)", "LINESTRING(0 0,1 0,2 0)", "tuu++");
|
||||
test_geometry<ls, ls>("LINESTRING(0 1,1 0,2 1)", "LINESTRING(0 0,1 0,2 0)", "tuu++");
|
||||
|
||||
// SPIKE - NON-ENDPOINT - NON-OPPOSITE
|
||||
|
||||
// spike - neq eq
|
||||
test_geometry<ls, ls>("LINESTRING(2 2,4 4,1 1)", "LINESTRING(0 0,4 4,6 3)",
|
||||
expected("mii")("txu")("tiu")("mxi"));
|
||||
expected("mii++")("txu==")("tiu==")("mxi=+"));
|
||||
// spike - eq eq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,1 1)", "LINESTRING(0 0,4 4,6 3)",
|
||||
expected("tii")("txu")("tiu")("mxi"));
|
||||
expected("tii++")("txu==")("tiu==")("mxi=+"));
|
||||
// spike - eq neq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,3 3,1 1)", "LINESTRING(0 0,4 4,6 3)",
|
||||
expected("tii")("mxu")("miu")("mxi"));
|
||||
expected("tii++")("mxu==")("miu==")("mxi=+"));
|
||||
// spike - neq neq
|
||||
test_geometry<ls, ls>("LINESTRING(1 1,3 3,2 2)", "LINESTRING(0 0,4 4,6 3)",
|
||||
expected("mii")("mxu")("miu")("mxi"));
|
||||
expected("mii++")("mxu==")("miu==")("mxi=+"));
|
||||
// spike - out neq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,3 3,2 2)", "LINESTRING(1 1,4 4,6 3)",
|
||||
expected("mii")("mxu")("miu")("mxi"));
|
||||
expected("mii++")("mxu==")("miu==")("mxi=+"));
|
||||
// spike - out eq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(1 1,4 4,6 3)",
|
||||
expected("mii")("txu")("tiu")("mxi"));
|
||||
expected("mii++")("txu==")("tiu==")("mxi=+"));
|
||||
// spike - out out/eq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(1 0,4 4,6 3)",
|
||||
expected("tuu"));
|
||||
expected("tuu++"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(0 1,4 4,6 3)",
|
||||
expected("tuu"));
|
||||
expected("tuu++"));
|
||||
// spike - out out/neq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(4 0,4 5,6 3)",
|
||||
expected("muu"));
|
||||
expected("muu++"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(0 4,5 4,6 3)",
|
||||
expected("muu"));
|
||||
expected("muu++"));
|
||||
|
||||
// SPIKE - NON-ENDPOINT - OPPOSITE
|
||||
|
||||
// opposite - eq eq
|
||||
test_geometry<ls, ls>("LINESTRING(6 6,4 4,0 0,2 2)", "LINESTRING(-1 -1,0 0,4 4,6 3)",
|
||||
expected("tiu")("txi")("tii")("mxu"));
|
||||
expected("tiu+=")("txi=+")("tii=+")("mxu=="));
|
||||
test_geometry<ls, ls>("LINESTRING(-1 -1,0 0,4 4,6 3)", "LINESTRING(6 6,4 4,0 0,2 2)",
|
||||
expected("tui")("tix")("tii")("mux"));
|
||||
expected("tui=+")("tix+=")("tii+=")("mux=="));
|
||||
// opposite - neq eq
|
||||
test_geometry<ls, ls>("LINESTRING(6 6,4 4,0 0,2 2)", "LINESTRING(-1 -1,0 0,5 5,6 3)",
|
||||
expected("miu")("txi")("tii")("mxu"));
|
||||
expected("miu+=")("txi=+")("tii=+")("mxu=="));
|
||||
// opposite - eq neq
|
||||
test_geometry<ls, ls>("LINESTRING(6 6,4 4,0 0,2 2)", "LINESTRING(-2 -2,-1 -1,4 4,6 3)",
|
||||
expected("tiu")("mxi")("mii")("mxu"));
|
||||
expected("tiu+=")("mxi=+")("mii=+")("mxu=="));
|
||||
// opposite - neq neq
|
||||
test_geometry<ls, ls>("LINESTRING(6 6,4 4,0 0,2 2)", "LINESTRING(-2 -2,-1 -1,3 3,6 3)",
|
||||
expected("miu")("mxi")("mii")("mxu"));
|
||||
expected("miu+=")("mxi=+")("mii=+")("mxu=="));
|
||||
// opposite - neq neq
|
||||
test_geometry<ls, ls>("LINESTRING(6 6,4 4,0 0,2 2)", "LINESTRING(-2 -2,-1 -1,3 3,5 5,6 3)",
|
||||
expected("miu")("mxi")("mii")("mxu"));
|
||||
expected("miu+=")("mxi=+")("mii=+")("mxu=="));
|
||||
// opposite - neq eq
|
||||
test_geometry<ls, ls>("LINESTRING(6 3,3 3,0 0)", "LINESTRING(0 0,2 2,3 3,1 1)",
|
||||
expected("txi")("tix")("tii")("mux"));
|
||||
expected("txi=+")("tix+=")("tii+=")("mux=="));
|
||||
|
||||
// SPIKE - ENDPOINT - NON-OPPOSITE
|
||||
|
||||
// spike - neq eq
|
||||
test_geometry<ls, ls>("LINESTRING(2 2,4 4,1 1)", "LINESTRING(0 0,4 4)",
|
||||
expected("mii")("txx")("tix")("mxi"));
|
||||
expected("mii++")("txx==")("tix==")("mxi=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(2 2,4 4,1 1)", "LINESTRING(4 4,0 0)",
|
||||
expected("miu")("txi")("tii")("mxu"));
|
||||
expected("miu+=")("txi=+")("tii=+")("mxu=="));
|
||||
// spike - eq eq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,1 1)", "LINESTRING(0 0,4 4)",
|
||||
expected("tii")("txx")("tix")("mxi"));
|
||||
expected("tii++")("txx==")("tix==")("mxi=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,1 1)", "LINESTRING(4 4,0 0)",
|
||||
expected("tix")("txi")("tii")("mxu"));
|
||||
expected("tix+=")("txi=+")("tii=+")("mxu=="));
|
||||
// spike - eq neq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,3 3,1 1)", "LINESTRING(0 0,4 4)",
|
||||
expected("tii")("mxu")("miu")("mxi"));
|
||||
expected("tii++")("mxu==")("miu==")("mxi=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,3 3,1 1)", "LINESTRING(4 4,0 0)",
|
||||
expected("tix")("mxi")("mii")("mxu"));
|
||||
expected("tix+=")("mxi=+")("mii=+")("mxu=="));
|
||||
// spike - neq neq
|
||||
test_geometry<ls, ls>("LINESTRING(1 1,3 3,2 2)", "LINESTRING(0 0,4 4)",
|
||||
expected("mii")("mxu")("miu")("mxi"));
|
||||
expected("mii++")("mxu==")("miu==")("mxi=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(1 1,3 3,2 2)", "LINESTRING(4 4,0 0)",
|
||||
expected("miu")("mxi")("mii")("mxu"));
|
||||
expected("miu+=")("mxi=+")("mii=+")("mxu=="));
|
||||
// spike - out neq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,3 3,2 2)", "LINESTRING(1 1,4 4)",
|
||||
expected("mii")("mxu")("miu")("mxi"));
|
||||
expected("mii++")("mxu==")("miu==")("mxi=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,3 3,2 2)", "LINESTRING(4 4,1 1)",
|
||||
expected("mix")("mxi")("mii")("mxu"));
|
||||
expected("mix+=")("mxi=+")("mii=+")("mxu=="));
|
||||
// spike - out eq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(1 1,4 4)",
|
||||
expected("mii")("txx")("tix")("mxi"));
|
||||
expected("mii++")("txx==")("tix==")("mxi=+"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(4 4,1 1)",
|
||||
expected("mix")("txi")("tii")("mxu"));
|
||||
expected("mix+=")("txi=+")("tii=+")("mxu=="));
|
||||
// spike - out out/eq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(1 0,4 4)",
|
||||
expected("tux"));
|
||||
expected("tux++"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(0 1,4 4)",
|
||||
expected("tux"));
|
||||
expected("tux++"));
|
||||
// spike - out out/neq
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(4 0,4 5)",
|
||||
expected("muu"));
|
||||
expected("muu++"));
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,2 2)", "LINESTRING(0 4,5 4)",
|
||||
expected("muu"));
|
||||
expected("muu++"));
|
||||
|
||||
// TODO:
|
||||
//test_geometry<ls, ls>("LINESTRING(0 0,2 0,1 0)", "LINESTRING(0 1,0 0,2 0)", "1FF00F102");
|
||||
@@ -233,16 +243,16 @@ void test_all()
|
||||
// duplicated
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0,30 0))",
|
||||
"MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(2 0,2 0),(3 0,3 0,3 0))",
|
||||
expected("mii")("ccc")("ccc")("txx"));
|
||||
expected("mii++")("ccc==")("ccc==")("txx=="));
|
||||
|
||||
// spike
|
||||
test_geometry<ls, ls>("LINESTRING(2 2,5 -1,15 2,18 0,20 0)",
|
||||
"LINESTRING(30 0,19 0,18 0,0 0)",
|
||||
expected("iuu")("iuu")("tiu")("mxi"));
|
||||
expected("iuu++")("iuu++")("tiu+=")("mxi=+"));
|
||||
// spike
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0,5 0))",
|
||||
"MULTILINESTRING((1 0,8 0,4 0))",
|
||||
expected("mii")("mix")("mux")("mui")("mix")("mii")("mxu")("mxi"));
|
||||
expected("mii++")("mix+=")("mux==")("mui==")("mix+=")("mii+=")("mxu==")("mxi=+"));
|
||||
|
||||
/*test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0,5 0))",
|
||||
"MULTILINESTRING((1 0,8 0,4 0),(2 0,9 0,5 0))",
|
||||
@@ -251,20 +261,120 @@ void test_all()
|
||||
// spike vs endpoint
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((-1 0,0 0,-2 0),(11 0,10 0,12 0))",
|
||||
expected("tuu")("txu"));
|
||||
expected("tuu++")("txu++"));
|
||||
// internal turning R vs spike
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,2 1))",
|
||||
"MULTILINESTRING((0 1,1 1,0 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,2 1))",
|
||||
"MULTILINESTRING((1 2,1 1,1 2))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 0,0 0))",
|
||||
"MULTILINESTRING((2 0,1 0,2 0))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,2 1))",
|
||||
"MULTILINESTRING((0 2,1 1,0 2))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,2 1))",
|
||||
"MULTILINESTRING((2 0,1 1,2 0))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,2 1))",
|
||||
"MULTILINESTRING((2 1,1 1,2 1))",
|
||||
expected("txi=+")("tix+=")("tii+=")("txx=="));
|
||||
// internal turning L vs spike
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,0 1))",
|
||||
"MULTILINESTRING((2 1,1 1,2 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,0 1))",
|
||||
"MULTILINESTRING((1 2,1 1,1 2))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,0 1))",
|
||||
"MULTILINESTRING((2 2,1 1,2 2))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,0 1))",
|
||||
"MULTILINESTRING((0 0,1 1,0 0))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 0,1 1,0 1))",
|
||||
"MULTILINESTRING((0 1,1 1,0 1))",
|
||||
expected("txi=+")("tix+=")("tii+=")("txx=="));
|
||||
// spike vs internal turning R
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 1,1 1,0 1))",
|
||||
"MULTILINESTRING((1 0,1 1,2 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 2,1 1,1 2))",
|
||||
"MULTILINESTRING((1 0,1 1,2 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((2 0,1 0,2 0))",
|
||||
"MULTILINESTRING((0 0,1 0,0 0))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 2,1 1,0 2))",
|
||||
"MULTILINESTRING((1 0,1 1,2 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((2 0,1 1,2 0))",
|
||||
"MULTILINESTRING((1 0,1 1,2 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((2 1,1 1,2 1))",
|
||||
"MULTILINESTRING((1 0,1 1,2 1))",
|
||||
expected("tix+=")("txi=+")("tii=+")("txx=="));
|
||||
// spike vs internal turning L
|
||||
test_geometry<mls, mls>("MULTILINESTRING((2 1,1 1,2 1))",
|
||||
"MULTILINESTRING((1 0,1 1,0 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((1 2,1 1,1 2))",
|
||||
"MULTILINESTRING((1 0,1 1,0 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((2 2,1 1,2 2))",
|
||||
"MULTILINESTRING((1 0,1 1,0 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 1,0 0))",
|
||||
"MULTILINESTRING((1 0,1 1,0 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 1,1 1,0 1))",
|
||||
"MULTILINESTRING((1 0,1 1,0 1))",
|
||||
expected("tix+=")("txi=+")("tii=+")("txx=="));
|
||||
// spike vs internal collinear
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 1,1 1,0 1))",
|
||||
"MULTILINESTRING((2 1,1 1,0 1))",
|
||||
expected("tix+=")("txi=+")("tii=+")("txx=="));
|
||||
// internal collinear vs spike
|
||||
test_geometry<mls, mls>("MULTILINESTRING((2 1,1 1,0 1))",
|
||||
"MULTILINESTRING((0 1,1 1,0 1))",
|
||||
expected("txi=+")("tix+=")("tii+=")("txx=="));
|
||||
// spike vs spike
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 1,0 0))",
|
||||
"MULTILINESTRING((2 2,1 1,2 2))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 1,0 0))",
|
||||
"MULTILINESTRING((2 0,1 1,2 0))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 1,0 0))",
|
||||
"MULTILINESTRING((2 1,1 1,2 1))",
|
||||
expected("tuu++"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 1,0 0))",
|
||||
"MULTILINESTRING((0 1,1 1,0 1))",
|
||||
expected("tuu++"));
|
||||
// collinear spikes
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 1,0 0))",
|
||||
"MULTILINESTRING((0 0,1 1,0 0))",
|
||||
expected("tii++")("tix+=")("txi=+")("txx==")
|
||||
("ecc=="));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,1 1,0 0))",
|
||||
"MULTILINESTRING((1 1,0 0,1 1))",
|
||||
expected("tix+=")("tii+=")("txx==")("txi==")
|
||||
("txi=+")("tii=+")("txx==")("tix=="));
|
||||
// non-spike similar
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((-1 0,0 0,2 0))",
|
||||
expected("tii")("mux"));
|
||||
expected("tii++")("mux=="));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((-1 -1,0 0,2 0))",
|
||||
expected("tii")("mux"));
|
||||
expected("tii++")("mux=="));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((2 0,0 0,-1 0))",
|
||||
expected("tiu")("mui"));
|
||||
expected("tiu+=")("mui=+"));
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((2 0,0 0,-1 -1))",
|
||||
expected("tiu")("mui"));
|
||||
expected("tiu+=")("mui=+"));
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
|
||||
@@ -33,6 +33,36 @@
|
||||
#include <boost/geometry/io/wkt/read.hpp>
|
||||
#include <boost/geometry/io/wkt/write.hpp>
|
||||
|
||||
template <int Version = 0>
|
||||
struct expected_pusher
|
||||
{
|
||||
static const int version = Version;
|
||||
|
||||
void push_back(std::string const& ex) { vec.push_back(ex); }
|
||||
expected_pusher & operator()(std::string const& ex)
|
||||
{
|
||||
push_back(ex);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef std::vector<std::string>::iterator iterator;
|
||||
typedef std::vector<std::string>::const_iterator const_iterator;
|
||||
|
||||
iterator begin() { return vec.begin(); }
|
||||
iterator end() { return vec.end(); }
|
||||
const_iterator begin() const { return vec.begin(); }
|
||||
const_iterator end() const { return vec.end(); }
|
||||
|
||||
std::vector<std::string> vec;
|
||||
};
|
||||
|
||||
expected_pusher<1> expected(std::string const& ex)
|
||||
{
|
||||
expected_pusher<1> res;
|
||||
return res(ex);
|
||||
}
|
||||
|
||||
template <int Version>
|
||||
struct equal_turn
|
||||
{
|
||||
equal_turn(std::string const& s) : turn_ptr(&s) {}
|
||||
@@ -49,13 +79,46 @@ struct equal_turn
|
||||
const std::string * turn_ptr;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Range>
|
||||
template <>
|
||||
struct equal_turn<1>
|
||||
{
|
||||
equal_turn(std::string const& s) : turn_ptr(&s) {}
|
||||
|
||||
template <typename T>
|
||||
bool operator()(T const& t) const
|
||||
{
|
||||
unsigned count = turn_ptr->size();
|
||||
BOOST_ASSERT(turn_ptr && count >= 1);
|
||||
return bg::method_char(t.method) == (*turn_ptr)[0]
|
||||
&& ( count > 1
|
||||
? bg::operation_char(t.operations[0].operation) == (*turn_ptr)[1]
|
||||
: true )
|
||||
&& ( count > 2
|
||||
? bg::operation_char(t.operations[1].operation) == (*turn_ptr)[2]
|
||||
: true )
|
||||
&& ( count > 3
|
||||
? is_colinear_char(t.operations[0].is_collinear) == (*turn_ptr)[3]
|
||||
: true )
|
||||
&& ( count > 4
|
||||
? is_colinear_char(t.operations[1].is_collinear) == (*turn_ptr)[4]
|
||||
: true );
|
||||
}
|
||||
|
||||
static inline char is_colinear_char(bool is_collinear)
|
||||
{
|
||||
return is_collinear ? '=' : '+';
|
||||
}
|
||||
|
||||
const std::string * turn_ptr;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Expected>
|
||||
void check_geometry_range(
|
||||
Geometry1 const& g1,
|
||||
Geometry2 const& g2,
|
||||
std::string const& wkt1,
|
||||
std::string const& wkt2,
|
||||
Range const& expected)
|
||||
Expected const& expected)
|
||||
{
|
||||
typedef bg::detail::no_rescale_policy robust_policy_type;
|
||||
typedef typename bg::point_type<Geometry2>::type point_type;
|
||||
@@ -95,11 +158,11 @@ void check_geometry_range(
|
||||
"get_turns: " << wkt1 << " and " << wkt2
|
||||
<< " -> Expected turns #: " << boost::size(expected) << " detected turns #: " << turns.size());
|
||||
|
||||
for ( typename boost::range_iterator<Range const>::type sit = boost::begin(expected) ;
|
||||
for ( typename boost::range_iterator<Expected const>::type sit = boost::begin(expected) ;
|
||||
sit != boost::end(expected) ; ++sit)
|
||||
{
|
||||
typename std::vector<turn_info>::iterator
|
||||
it = std::find_if(turns.begin(), turns.end(), equal_turn(*sit));
|
||||
it = std::find_if(turns.begin(), turns.end(), equal_turn<Expected::version>(*sit));
|
||||
|
||||
if ( it != turns.end() )
|
||||
turns.erase(it);
|
||||
@@ -112,9 +175,9 @@ void check_geometry_range(
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Range>
|
||||
template <typename Geometry1, typename Geometry2, typename Expected>
|
||||
void test_geometry_range(std::string const& wkt1, std::string const& wkt2,
|
||||
Range const& expected)
|
||||
Expected const& expected)
|
||||
{
|
||||
Geometry1 geometry1;
|
||||
Geometry2 geometry2;
|
||||
@@ -127,67 +190,26 @@ template <typename G1, typename G2>
|
||||
void test_geometry(std::string const& wkt1, std::string const& wkt2,
|
||||
std::string const& ex0)
|
||||
{
|
||||
std::vector<std::string> expected;
|
||||
expected.push_back(ex0);
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected);
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected(ex0));
|
||||
}
|
||||
|
||||
template <typename G1, typename G2>
|
||||
void test_geometry(std::string const& wkt1, std::string const& wkt2,
|
||||
std::string const& ex0, std::string const& ex1)
|
||||
{
|
||||
std::vector<std::string> expected;
|
||||
expected.push_back(ex0);
|
||||
expected.push_back(ex1);
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected);
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected(ex0)(ex1));
|
||||
}
|
||||
|
||||
template <typename G1, typename G2>
|
||||
void test_geometry(std::string const& wkt1, std::string const& wkt2,
|
||||
std::string const& ex0, std::string const& ex1, std::string const& ex2)
|
||||
{
|
||||
std::vector<std::string> expected;
|
||||
expected.push_back(ex0);
|
||||
expected.push_back(ex1);
|
||||
expected.push_back(ex2);
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected);
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected(ex0)(ex1)(ex2));
|
||||
}
|
||||
|
||||
struct expected_pusher
|
||||
{
|
||||
expected_pusher & operator()(std::string const& ex)
|
||||
{
|
||||
vec.push_back(ex);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef std::vector<std::string>::iterator iterator;
|
||||
typedef std::vector<std::string>::const_iterator const_iterator;
|
||||
|
||||
iterator begin() { return vec.begin(); }
|
||||
iterator end() { return vec.end(); }
|
||||
const_iterator begin() const { return vec.begin(); }
|
||||
const_iterator end() const { return vec.end(); }
|
||||
|
||||
std::vector<std::string> vec;
|
||||
};
|
||||
|
||||
expected_pusher expected(std::string const& ex)
|
||||
{
|
||||
expected_pusher res;
|
||||
return res(ex);
|
||||
}
|
||||
|
||||
template <typename G1, typename G2>
|
||||
template <typename G1, typename G2, int Version>
|
||||
void test_geometry(std::string const& wkt1, std::string const& wkt2,
|
||||
std::vector<std::string> const& expected)
|
||||
{
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected);
|
||||
}
|
||||
|
||||
template <typename G1, typename G2>
|
||||
void test_geometry(std::string const& wkt1, std::string const& wkt2,
|
||||
expected_pusher const& expected)
|
||||
expected_pusher<Version> const& expected)
|
||||
{
|
||||
test_geometry_range<G1, G2>(wkt1, wkt2, expected);
|
||||
}
|
||||
|
||||
@@ -172,12 +172,11 @@ void test_linestring_linestring()
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 6)", "LINESTRING(0 0,5 0,5 5,0 5)", "0F10F0102");
|
||||
|
||||
// point-size Linestring
|
||||
// FOR NOW DISABLED, THE ROBUSTNESS UPGRADES BROKE POINT-SIZED LINESTRINGS
|
||||
/*test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,5 0)", "0FFFFF102");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,5 0)", "0FFFFF102");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(1 0,5 0)", "F0FFFF102");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,1 0)", "F0FFFF102");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(1 0,1 0)", "0FFFFFFF2");
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,0 0)", "FF0FFF0F2");*/
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,0 0)", "FF0FFF0F2");
|
||||
|
||||
//to_svg<ls, ls>("LINESTRING(0 0,5 0)", "LINESTRING(5 0,10 0,5 5,5 0)", "test_relate_00.svg");
|
||||
|
||||
@@ -238,32 +237,31 @@ void test_linestring_multi_linestring()
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,9 0),(2 0,2 0,2 0))", "101FF0FF2");
|
||||
|
||||
// point-like
|
||||
// FOR NOW DISABLED, THE ROBUSTNESS UPGRADES BROKE POINT-SIZED LINESTRINGS
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((0 0, 1 0),(2 0, 2 0))", // |------| *
|
||||
// "101F00FF2");
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((0 0, 1 0),(1 0, 1 0))", // |------*
|
||||
// "101F00FF2");
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((5 0, 1 0),(1 0, 1 0))", // *-------|
|
||||
// "101F00FF2");
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((0 0, 1 0),(5 0, 5 0))", // |------| *
|
||||
// "10100FFF2");
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((0 0, 1 0),(0 0, 0 0))", // *------|
|
||||
// "101000FF2");
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((4 0, 5 0),(5 0, 5 0))", // |------*
|
||||
// "101000FF2");
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((1 0, 2 0),(0 0, 0 0))", // * |------|
|
||||
// "1010F0FF2");
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((0 0, 1 0),(2 0, 2 0))", // |------| *
|
||||
"101F00FF2");
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((0 0, 1 0),(1 0, 1 0))", // |------*
|
||||
"101F00FF2");
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((5 0, 1 0),(1 0, 1 0))", // *-------|
|
||||
"101F00FF2");
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((0 0, 1 0),(5 0, 5 0))", // |------| *
|
||||
"10100FFF2");
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((0 0, 1 0),(0 0, 0 0))", // *------|
|
||||
"101000FF2");
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((4 0, 5 0),(5 0, 5 0))", // |------*
|
||||
"101000FF2");
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((1 0, 2 0),(0 0, 0 0))", // * |------|
|
||||
"1010F0FF2");
|
||||
|
||||
//test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
// "MULTILINESTRING((2 0, 2 0),(2 0, 2 2))", // *
|
||||
// "001FF0102"); // |
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
"MULTILINESTRING((2 0, 2 0),(2 0, 2 2))", // *
|
||||
"001FF0102"); // |
|
||||
|
||||
// for consistency
|
||||
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
|
||||
@@ -318,8 +316,7 @@ void test_multi_linestring_multi_linestring()
|
||||
"1F1F0F1F2");
|
||||
|
||||
// point-like
|
||||
// FOR NOW DISABLED, THE ROBUSTNESS UPGRADES BROKE POINT-SIZED LINESTRINGS
|
||||
/*test_geometry<mls, mls>("MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
|
||||
"MULTILINESTRING((0 0, 0 0))",
|
||||
"0F0FFFFF2");
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
|
||||
@@ -327,7 +324,7 @@ void test_multi_linestring_multi_linestring()
|
||||
"0FFFFFFF2");
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
|
||||
"MULTILINESTRING((2 2, 2 2),(3 3, 3 3))",
|
||||
"FF0FFF0F2");*/
|
||||
"FF0FFF0F2");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
Reference in New Issue
Block a user