[distance] polish code; make clear when the result of comparable or regular strategy is used;

This commit is contained in:
Menelaos Karavelas
2014-05-11 23:21:22 +03:00
parent 15c711cf53
commit cea8dd1b0d
7 changed files with 174 additions and 101 deletions

View File

@@ -50,24 +50,33 @@ namespace detail { namespace distance
template <typename Multi1, typename Multi2, typename Strategy>
struct distance_multi_to_multi_generic
class distance_multi_to_multi_generic
{
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Multi1>::type,
typename point_type<Multi2>::type
>::type return_type;
<
comparable_strategy,
typename point_type<Multi1>::type,
typename point_type<Multi2>::type
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Multi1>::type,
typename point_type<Multi2>::type
>::type return_type;
static inline return_type apply(Multi1 const& multi1,
Multi2 const& multi2, Strategy const& strategy)
{
return_type min_cdist = return_type();
comparable_return_type min_cdist = comparable_return_type();
bool first = true;
comparable_strategy cstrategy =
@@ -80,7 +89,7 @@ struct distance_multi_to_multi_generic
it != boost::end(multi1);
++it, first = false)
{
return_type cdist =
comparable_return_type cdist =
dispatch::splitted_dispatch::distance_single_to_multi
<
typename range_value<Multi1>::type,

View File

@@ -56,14 +56,11 @@ namespace detail { namespace distance
{
// To avoid spurious namespaces here:
using strategy::distance::services::return_type;
template <typename P1, typename P2, typename Strategy>
struct point_to_point
{
static inline typename return_type<Strategy, P1, P2>::type
static inline
typename strategy::distance::services::return_type<Strategy, P1, P2>::type
apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
{
boost::ignore_unused_variable_warning(strategy);
@@ -79,18 +76,25 @@ template
closure_selector Closure,
typename Strategy
>
struct point_to_range
class point_to_range
{
typedef typename return_type
<
Strategy, Point, typename point_type<Range>::type
>::type return_type;
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
comparable_strategy, Point, typename point_type<Range>::type
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Range>::type
>::type return_type;
static inline return_type apply(Point const& point, Range const& range,
Strategy const& strategy)
{
@@ -100,7 +104,7 @@ struct point_to_range
Strategy
>::apply(strategy);
return_type const zero = return_type(0);
comparable_return_type const zero = comparable_return_type(0);
if (boost::size(range) == 0)
{
@@ -126,26 +130,29 @@ struct point_to_range
}
// start with first segment distance
return_type d = c_strategy.apply(point, *prev, *it);
comparable_return_type cd = c_strategy.apply(point, *prev, *it);
// check if other segments are closer
for (++prev, ++it; it != boost::end(view); ++prev, ++it)
{
return_type const ds = c_strategy.apply(point, *prev, *it);
if (geometry::math::equals(ds, zero))
comparable_return_type cds = c_strategy.apply(point, *prev, *it);
if (geometry::math::equals(cds, zero))
{
return ds;
return strategy::distance::services::comparable_to_regular
<
comparable_strategy, Strategy, Point, Range
>::apply(zero);
}
else if (ds < d)
else if (cds < cd)
{
d = ds;
cd = cds;
}
}
return strategy::distance::services::comparable_to_regular
<
comparable_strategy, Strategy, Point, Range
>::apply(d);
>::apply(cd);
}
};
@@ -161,7 +168,7 @@ struct point_to_ring
{
typedef std::pair
<
typename return_type
typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Ring>::type
>::type,
@@ -195,19 +202,31 @@ template
closure_selector Closure,
typename Strategy
>
struct point_to_polygon
class point_to_polygon
{
typedef typename return_type
<
Strategy, Point, typename point_type<Polygon>::type
>::type return_type;
typedef std::pair<return_type, bool> distance_containment;
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
comparable_strategy, Point, typename point_type<Polygon>::type
>::type comparable_return_type;
typedef std::pair
<
comparable_return_type, bool
> comparable_distance_containment;
public:
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Polygon>::type
>::type return_type;
typedef std::pair<return_type, bool> distance_containment;
static inline distance_containment apply(Point const& point,
Polygon const& polygon,
Strategy const& strategy)
@@ -227,9 +246,8 @@ struct point_to_polygon
comparable_strategy
> per_ring;
distance_containment dc = per_ring::apply(point,
exterior_ring(polygon),
c_strategy);
comparable_distance_containment dc =
per_ring::apply(point, exterior_ring(polygon), c_strategy);
typename interior_return_type<Polygon const>::type rings
= interior_rings(polygon);
@@ -239,7 +257,8 @@ struct point_to_polygon
>::type it = boost::begin(rings);
it != boost::end(rings); ++it)
{
distance_containment dcr = per_ring::apply(point, *it, c_strategy);
comparable_distance_containment dcr =
per_ring::apply(point, *it, c_strategy);
if (dcr.first < dc.first)
{
dc.first = dcr.first;
@@ -305,11 +324,14 @@ struct distance
false
>
{
typedef typename return_type<Strategy, Point, typename point_type<Ring>::type>::type return_type;
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Ring>::type
>::type return_type;
static inline return_type apply(Point const& point,
Ring const& ring,
Strategy const& strategy)
Ring const& ring,
Strategy const& strategy)
{
std::pair<return_type, bool>
dc = detail::distance::point_to_ring
@@ -332,11 +354,14 @@ struct distance
strategy_tag_distance_point_segment, false
>
{
typedef typename return_type<Strategy, Point, typename point_type<Polygon>::type>::type return_type;
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Polygon>::type
>::type return_type;
static inline return_type apply(Point const& point,
Polygon const& polygon,
Strategy const& strategy)
Polygon const& polygon,
Strategy const& strategy)
{
std::pair<return_type, bool>
dc = detail::distance::point_to_polygon

View File

@@ -42,20 +42,29 @@ namespace detail { namespace distance
template <typename Polygon, typename SegmentOrBox, typename Strategy>
struct polygon_to_segment_or_box
class polygon_to_segment_or_box
{
typedef typename return_type
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
comparable_strategy,
typename point_type<Polygon>::type,
typename point_type<SegmentOrBox>::type
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Polygon>::type,
typename point_type<SegmentOrBox>::type
>::type return_type;
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
static inline return_type apply(Polygon const& polygon,
SegmentOrBox const& segment_or_box,
Strategy const& strategy)
@@ -79,7 +88,7 @@ struct polygon_to_segment_or_box
>::apply(strategy);
return_type cd_min = range_to_segment_or_box
comparable_return_type cd_min = range_to_segment_or_box
<
e_ring, SegmentOrBox, comparable_strategy
>::apply(ext_ring, segment_or_box, cstrategy, false);
@@ -88,7 +97,7 @@ struct polygon_to_segment_or_box
for (iterator_type it = boost::begin(int_rings);
it != boost::end(int_rings); ++it)
{
return_type cd = range_to_segment_or_box
comparable_return_type cd = range_to_segment_or_box
<
i_ring, SegmentOrBox, comparable_strategy
>::apply(*it, segment_or_box, cstrategy, false);

View File

@@ -57,18 +57,16 @@ private:
typedef typename point_type<SegmentOrBox>::type segment_or_box_point;
typedef typename point_type<Range>::type range_point;
public:
typedef typename strategy::distance::services::return_type
<
Strategy, range_point, segment_or_box_point
>::type return_type;
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
comparable_strategy, range_point, segment_or_box_point
>::type comparable_return_type;
typedef typename strategy::distance::services::tag
<
comparable_strategy
@@ -79,7 +77,7 @@ private:
segment_or_box_point, Range, comparable_strategy,
point_tag, typename tag<Range>::type,
comparable_strategy_tag, false
> point_to_range;
> comparable_point_to_range;
// compute distance of a point to a segment or a box
template
@@ -89,7 +87,7 @@ private:
typename ComparableStrategy,
typename Tag
>
struct distance_point_to_segment_or_box
struct comparable_distance_point_to_segment_or_box
{};
template
@@ -98,14 +96,15 @@ private:
typename SegmentPoints,
typename ComparableStrategy
>
struct distance_point_to_segment_or_box
struct comparable_distance_point_to_segment_or_box
<
Point, SegmentPoints, ComparableStrategy, segment_tag
>
{
static inline return_type apply(Point const& point,
SegmentPoints const& segment_points,
ComparableStrategy const& strategy)
static inline
comparable_return_type apply(Point const& point,
SegmentPoints const& segment_points,
ComparableStrategy const& strategy)
{
return strategy.apply(point, segment_points[0], segment_points[1]);
}
@@ -117,21 +116,22 @@ private:
typename BoxPoints,
typename ComparableStrategy
>
struct distance_point_to_segment_or_box
struct comparable_distance_point_to_segment_or_box
<
Point, BoxPoints, ComparableStrategy, box_tag
>
{
static inline return_type apply(Point const& point,
BoxPoints const& box_points,
ComparableStrategy const& strategy)
static inline
comparable_return_type apply(Point const& point,
BoxPoints const& box_points,
ComparableStrategy const& strategy)
{
return_type cd_min =
comparable_return_type cd_min =
strategy.apply(point, box_points[0], box_points[3]);
for (unsigned int i = 0; i < 2; ++i)
{
return_type cd =
comparable_return_type cd =
strategy.apply(point, box_points[i], box_points[i+1]);
if ( cd < cd_min )
@@ -177,6 +177,11 @@ private:
public:
typedef typename strategy::distance::services::return_type
<
Strategy, range_point, segment_or_box_point
>::type return_type;
static inline return_type
apply(Range const& range, SegmentOrBox const& segment_or_box,
Strategy const& strategy, bool check_intersection = true)
@@ -208,11 +213,13 @@ public:
// to the range
typename std::vector<segment_or_box_point>::const_iterator it
= segment_or_box_points.begin();
return_type cd_min = point_to_range::apply(*it, range, cstrategy);
comparable_return_type cd_min =
comparable_point_to_range::apply(*it, range, cstrategy);
for (++it; it != segment_or_box_points.end(); ++it)
{
return_type cd = point_to_range::apply(*it, range, cstrategy);
comparable_return_type cd =
comparable_point_to_range::apply(*it, range, cstrategy);
if ( cd < cd_min )
{
cd_min = cd;
@@ -224,13 +231,14 @@ public:
typedef typename range_iterator<Range const>::type iterator_type;
for (iterator_type it = boost::begin(range); it != boost::end(range); ++it)
{
return_type cd = distance_point_to_segment_or_box
<
typename point_type<Range>::type,
std::vector<segment_or_box_point>,
comparable_strategy,
typename tag<SegmentOrBox>::type
>::apply(*it, segment_or_box_points, cstrategy);
comparable_return_type cd =
comparable_distance_point_to_segment_or_box
<
typename point_type<Range>::type,
std::vector<segment_or_box_point>,
comparable_strategy,
typename tag<SegmentOrBox>::type
>::apply(*it, segment_or_box_points, cstrategy);
if ( cd < cd_min )
{

View File

@@ -407,6 +407,10 @@ private:
PSStrategy
>::type ps_comparable_strategy;
typedef typename strategy::distance::services::return_type
<
ps_comparable_strategy, segment_point, box_point
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
@@ -468,11 +472,11 @@ public:
PSStrategy
>::apply(ps_strategy);
return_type d;
comparable_return_type cd;
if ( geometry::less<segment_point>()(p[0], p[1]) )
{
d = segment_to_box_2D
cd = segment_to_box_2D
<
return_type,
segment_point,
@@ -486,7 +490,7 @@ public:
}
else
{
d = segment_to_box_2D
cd = segment_to_box_2D
<
return_type,
segment_point,
@@ -502,7 +506,7 @@ public:
return strategy::distance::services::comparable_to_regular
<
ps_comparable_strategy, PSStrategy, Segment, Box
>::apply( d );
>::apply( cd );
}
};

View File

@@ -37,8 +37,22 @@ namespace detail { namespace distance
// compute segment-segment distance
template<typename Segment1, typename Segment2, typename Strategy>
struct segment_to_segment
class segment_to_segment
{
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
comparable_strategy,
typename point_type<Segment1>::type,
typename point_type<Segment2>::type
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
@@ -46,11 +60,6 @@ struct segment_to_segment
typename point_type<Segment2>::type
>::type return_type;
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
static inline return_type
apply(Segment1 const& segment1, Segment2 const& segment2,
Strategy const& strategy)
@@ -74,7 +83,7 @@ struct segment_to_segment
Strategy
>::apply(strategy);
return_type d[4];
comparable_return_type d[4];
d[0] = cstrategy.apply(q[0], p[0], p[1]);
d[1] = cstrategy.apply(q[1], p[0], p[1]);
d[2] = cstrategy.apply(p[0], q[0], q[1]);

View File

@@ -67,25 +67,34 @@ namespace detail { namespace distance
template<typename Geometry, typename MultiGeometry, typename Strategy>
struct distance_single_to_multi_generic
class distance_single_to_multi_generic
{
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Geometry>::type,
typename point_type<MultiGeometry>::type
>::type return_type;
<
comparable_strategy,
typename point_type<Geometry>::type,
typename point_type<MultiGeometry>::type
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Geometry>::type,
typename point_type<MultiGeometry>::type
>::type return_type;
static inline return_type apply(Geometry const& geometry,
MultiGeometry const& multi,
Strategy const& strategy)
{
return_type min_cdist = return_type();
comparable_return_type min_cdist = comparable_return_type();
bool first = true;
comparable_strategy cstrategy =
@@ -98,7 +107,7 @@ struct distance_single_to_multi_generic
it != boost::end(multi);
++it, first = false)
{
return_type cdist = dispatch::distance
comparable_return_type cdist = dispatch::distance
<
Geometry,
typename range_value<MultiGeometry>::type,