mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 05:24:02 +00:00
[traverse][robustness] in case of cc, instead of arbitrary candidate,
take candidate with largest remaining distance. This fixes some errors if rescaling is turned off.
This commit is contained in:
parent
74f5465516
commit
533543e86b
@ -585,8 +585,8 @@ struct collinear : public base_turn_handler
|
||||
typename SidePolicy
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& , Point1 const& , Point1 const& ,
|
||||
Point2 const& , Point2 const& , Point2 const& ,
|
||||
Point1 const& , Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& , Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo& ti,
|
||||
IntersectionInfo const& info,
|
||||
DirInfo const& dir_info,
|
||||
@ -623,8 +623,30 @@ struct collinear : public base_turn_handler
|
||||
{
|
||||
ui_else_iu(product == 1, ti);
|
||||
}
|
||||
|
||||
// Calculate remaining distance. If it continues collinearly it is
|
||||
// measured until the end of the next segment
|
||||
ti.operations[0].remaining_distance
|
||||
= side_p == 0
|
||||
? distance_measure(ti.point, pk)
|
||||
: distance_measure(ti.point, pj);
|
||||
ti.operations[1].remaining_distance
|
||||
= side_q == 0
|
||||
? distance_measure(ti.point, qk)
|
||||
: distance_measure(ti.point, qj);
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
static inline typename geometry::coordinate_type<Point1>::type
|
||||
distance_measure(Point1 const& a, Point2 const& b)
|
||||
{
|
||||
// TODO: use comparable distance for point-point instead - but that
|
||||
// causes currently cycling include problems
|
||||
typedef typename geometry::coordinate_type<Point1>::type ctype;
|
||||
ctype const dx = get<0>(a) - get<0>(b);
|
||||
ctype const dy = get<1>(b) - get<1>(b);
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
|
@ -23,9 +23,9 @@ namespace detail { namespace overlay {
|
||||
|
||||
enum turn_position { position_middle, position_front, position_back };
|
||||
|
||||
template <typename SegmentRatio>
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct turn_operation_linear
|
||||
: public turn_operation<SegmentRatio>
|
||||
: public turn_operation<Point, SegmentRatio>
|
||||
{
|
||||
turn_operation_linear()
|
||||
: position(position_middle)
|
||||
|
@ -802,19 +802,19 @@ template <typename Geometry1, typename Geometry2, typename SegmentRatio,
|
||||
typename TagBase1 = typename topological_tag_base<Geometry1>::type, typename TagBase2 = typename topological_tag_base<Geometry2>::type>
|
||||
struct turn_operation_type
|
||||
{
|
||||
typedef overlay::turn_operation<SegmentRatio> type;
|
||||
typedef overlay::turn_operation<typename point_type<Geometry1>::type, SegmentRatio> type;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename SegmentRatio, typename Tag1, typename Tag2>
|
||||
struct turn_operation_type<Geometry1, Geometry2, SegmentRatio, Tag1, Tag2, linear_tag, linear_tag>
|
||||
{
|
||||
typedef overlay::turn_operation_linear<SegmentRatio> type;
|
||||
typedef overlay::turn_operation_linear<typename point_type<Geometry1>::type, SegmentRatio> type;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename SegmentRatio, typename Tag1, typename Tag2>
|
||||
struct turn_operation_type<Geometry1, Geometry2, SegmentRatio, Tag1, Tag2, linear_tag, areal_tag>
|
||||
{
|
||||
typedef overlay::turn_operation_linear<SegmentRatio> type;
|
||||
typedef overlay::turn_operation_linear<typename point_type<Geometry1>::type, SegmentRatio> type;
|
||||
};
|
||||
|
||||
}} // namespace detail::get_turns
|
||||
|
@ -25,7 +25,7 @@ namespace detail { namespace overlay
|
||||
|
||||
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct traversal_turn_operation : public turn_operation<SegmentRatio>
|
||||
struct traversal_turn_operation : public turn_operation<Point, SegmentRatio>
|
||||
{
|
||||
enrichment_info<Point> enriched;
|
||||
visit_info visited;
|
||||
|
@ -174,7 +174,17 @@ inline bool select_next_ip(operation_type operation,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool has_tp = false;
|
||||
|
||||
typedef typename std::iterator_traits
|
||||
<
|
||||
Iterator
|
||||
>::value_type operation_type;
|
||||
|
||||
typename operation_type::comparable_distance_type
|
||||
max_remaining_distance = 0;
|
||||
|
||||
selected = boost::end(turn.operations);
|
||||
for (Iterator it = boost::begin(turn.operations);
|
||||
it != boost::end(turn.operations);
|
||||
@ -206,10 +216,24 @@ inline bool select_next_ip(operation_type operation,
|
||||
)
|
||||
)
|
||||
{
|
||||
if (it->operation == operation_continue)
|
||||
{
|
||||
max_remaining_distance = it->remaining_distance;
|
||||
}
|
||||
selected = it;
|
||||
debug_traverse(turn, *it, " Candidate");
|
||||
has_tp = true;
|
||||
}
|
||||
|
||||
if (it->operation == operation_continue && has_tp)
|
||||
{
|
||||
if (it->remaining_distance > max_remaining_distance)
|
||||
{
|
||||
max_remaining_distance = it->remaining_distance;
|
||||
selected = it;
|
||||
debug_traverse(turn, *it, " Candidate override");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_tp)
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -54,15 +55,19 @@ enum method_type
|
||||
The class is to be included in the turn_info class, either direct
|
||||
or a derived or similar class with more (e.g. enrichment) information.
|
||||
*/
|
||||
template <typename SegmentRatio>
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct turn_operation
|
||||
{
|
||||
operation_type operation;
|
||||
segment_identifier seg_id;
|
||||
SegmentRatio fraction;
|
||||
|
||||
typedef typename coordinate_type<Point>::type comparable_distance_type;
|
||||
comparable_distance_type remaining_distance;
|
||||
|
||||
inline turn_operation()
|
||||
: operation(operation_none)
|
||||
, remaining_distance(0)
|
||||
{}
|
||||
};
|
||||
|
||||
@ -80,7 +85,7 @@ template
|
||||
<
|
||||
typename Point,
|
||||
typename SegmentRatio,
|
||||
typename Operation = turn_operation<SegmentRatio>,
|
||||
typename Operation = turn_operation<Point, SegmentRatio>,
|
||||
typename Container = boost::array<Operation, 2>
|
||||
>
|
||||
struct turn_info
|
||||
|
@ -128,8 +128,8 @@ struct get_turns
|
||||
template <int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0>
|
||||
struct op_to_int
|
||||
{
|
||||
template <typename SegmentRatio>
|
||||
inline int operator()(detail::overlay::turn_operation<SegmentRatio> const& op) const
|
||||
template <typename Operation>
|
||||
inline int operator()(Operation const& op) const
|
||||
{
|
||||
switch(op.operation)
|
||||
{
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
// To test that "get_turns" can be called using additional information
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct my_turn_op : public bg::detail::overlay::turn_operation<SegmentRatio>
|
||||
struct my_turn_op : public bg::detail::overlay::turn_operation<Point, SegmentRatio>
|
||||
{
|
||||
};
|
||||
|
||||
|
@ -248,7 +248,7 @@ void test_areal()
|
||||
1,
|
||||
0,
|
||||
-1,
|
||||
313.36036462, 0.01);
|
||||
313.36036462, 0.1);
|
||||
|
||||
// SQL Server gives: 313.360374193241
|
||||
// PostGIS gives: 313.360364623393
|
||||
@ -319,10 +319,8 @@ void test_areal()
|
||||
1, 0, if_typed<ct, double>(18, 23), 4.60853);
|
||||
#endif
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
|
||||
1, 0, if_typed<ct, float>(18, 17), 16.571);
|
||||
#endif
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_g_rev", buffer_rt_g[1], buffer_rt_g[0],
|
||||
1, 0, if_typed<ct, float>(18, 17), 16.571);
|
||||
|
||||
@ -355,10 +353,8 @@ void test_areal()
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_m2_rev", buffer_rt_m2[1], buffer_rt_m2[0],
|
||||
1, 0, if_typed_tt<ct>(20, 19), 21.4853);
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_q", buffer_rt_q[0], buffer_rt_q[1],
|
||||
1, 0, 18, 18.5710);
|
||||
#endif
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_q_rev", buffer_rt_q[1], buffer_rt_q[0],
|
||||
1, 0, 18, 18.5710);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user