mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-02 21:02:13 +00:00
[algorithms][distance] modify the various classes to do not inherit
from closest feature classes, but rather call their public (instead of protected) interface; optimize the computation of comparable distances by not re-computing them from closest features
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
@@ -30,6 +31,7 @@
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
|
||||
|
||||
|
||||
@@ -45,44 +47,36 @@ namespace detail { namespace distance
|
||||
|
||||
template
|
||||
<
|
||||
typename PointOrSegmentIterator,
|
||||
typename Geometry,
|
||||
typename Strategy
|
||||
>
|
||||
class point_or_segment_range_to_geometry_rtree
|
||||
{
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
typedef typename std::iterator_traits
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
PointOrSegmentIterator
|
||||
>::value_type point_or_segment_type;
|
||||
|
||||
typedef iterator_selector<Geometry const> selector_type;
|
||||
|
||||
typedef detail::closest_feature::range_to_range_rtree range_to_range;
|
||||
|
||||
public:
|
||||
template <typename PointOrSegmentIterator>
|
||||
static inline
|
||||
typename strategy::distance::services::return_type
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type
|
||||
<
|
||||
typename std::iterator_traits
|
||||
<
|
||||
PointOrSegmentIterator
|
||||
>::value_type
|
||||
>::type,
|
||||
typename point_type<point_or_segment_type>::type,
|
||||
typename point_type<Geometry>::type
|
||||
>::type
|
||||
apply(PointOrSegmentIterator first,
|
||||
PointOrSegmentIterator beyond,
|
||||
Geometry const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef iterator_selector<Geometry const> selector_type;
|
||||
>::type return_type;
|
||||
|
||||
typedef detail::closest_feature::range_to_range_rtree
|
||||
<
|
||||
PointOrSegmentIterator,
|
||||
typename selector_type::iterator_type
|
||||
> closest_features_type;
|
||||
static inline return_type apply(PointOrSegmentIterator first,
|
||||
PointOrSegmentIterator beyond,
|
||||
Geometry const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
namespace sds = strategy::distance::services;
|
||||
|
||||
BOOST_ASSERT( first != beyond );
|
||||
|
||||
@@ -90,38 +84,47 @@ public:
|
||||
{
|
||||
return dispatch::distance
|
||||
<
|
||||
typename std::iterator_traits
|
||||
<
|
||||
PointOrSegmentIterator
|
||||
>::value_type,
|
||||
Geometry,
|
||||
Strategy
|
||||
point_or_segment_type, Geometry, Strategy
|
||||
>::apply(*first, geometry, strategy);
|
||||
}
|
||||
|
||||
comparable_strategy cstrategy
|
||||
= strategy::distance::services::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
|
||||
typename closest_features_type::return_type cf
|
||||
= closest_features_type::apply(first,
|
||||
beyond,
|
||||
selector_type::begin(geometry),
|
||||
selector_type::end(geometry),
|
||||
cstrategy);
|
||||
|
||||
|
||||
return dispatch::distance
|
||||
point_or_segment_type rtree_value_min;
|
||||
typename selector_type::iterator_type qit_min;
|
||||
typename sds::return_type
|
||||
<
|
||||
typename closest_features_type::return_type::first_type,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename closest_features_type::return_type::second_type
|
||||
>::value_type,
|
||||
Strategy
|
||||
>::apply(cf.first, *cf.second, strategy);
|
||||
typename sds::comparable_type<Strategy>::type,
|
||||
typename point_type<point_or_segment_type>::type,
|
||||
typename point_type<Geometry>::type
|
||||
>::type cd_min;
|
||||
|
||||
std::pair
|
||||
<
|
||||
point_or_segment_type,
|
||||
typename selector_type::iterator_type
|
||||
> cf = range_to_range::apply(first,
|
||||
beyond,
|
||||
selector_type::begin(geometry),
|
||||
selector_type::end(geometry),
|
||||
sds::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy),
|
||||
cd_min);
|
||||
|
||||
return
|
||||
is_comparable<Strategy>::value
|
||||
?
|
||||
cd_min
|
||||
:
|
||||
dispatch::distance
|
||||
<
|
||||
point_or_segment_type,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename selector_type::iterator_type
|
||||
>::value_type,
|
||||
Strategy
|
||||
>::apply(cf.first, *cf.second, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -148,6 +151,15 @@ private:
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy,
|
||||
typename point_type<Geometry1>::type,
|
||||
typename point_type<Geometry2>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
typedef detail::closest_feature::range_to_range_rtree range_to_range;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
@@ -164,22 +176,6 @@ public:
|
||||
typedef geometry::point_iterator<Geometry1 const> const_point_iterator1;
|
||||
typedef geometry::point_iterator<Geometry2 const> const_point_iterator2;
|
||||
|
||||
typedef detail::closest_feature::range_to_range_rtree
|
||||
<
|
||||
const_point_iterator1,
|
||||
geometry::segment_iterator<Geometry2 const>
|
||||
> closest_features_type12;
|
||||
|
||||
typedef typename closest_features_type12::return_type return_type12;
|
||||
|
||||
typedef detail::closest_feature::range_to_range_rtree
|
||||
<
|
||||
const_point_iterator2,
|
||||
geometry::segment_iterator<Geometry1 const>
|
||||
> closest_features_type21;
|
||||
|
||||
typedef typename closest_features_type21::return_type return_type21;
|
||||
|
||||
const_point_iterator1 first1 = points_begin(geometry1);
|
||||
const_point_iterator1 beyond1 = points_end(geometry1);
|
||||
const_point_iterator2 first2 = points_begin(geometry2);
|
||||
@@ -216,41 +212,57 @@ public:
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
|
||||
return_type12 cf12
|
||||
= closest_features_type12::apply(first1,
|
||||
beyond1,
|
||||
segments_begin(geometry2),
|
||||
segments_end(geometry2),
|
||||
cstrategy);
|
||||
|
||||
return_type21 cf21
|
||||
= closest_features_type21::apply(first2,
|
||||
beyond2,
|
||||
segments_begin(geometry1),
|
||||
segments_end(geometry1),
|
||||
cstrategy);
|
||||
|
||||
return_type dist1 = dispatch::distance
|
||||
comparable_return_type cdist12;
|
||||
std::pair
|
||||
<
|
||||
typename point_type<Geometry1>::type,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename return_type12::second_type
|
||||
>::value_type,
|
||||
Strategy
|
||||
>::apply(cf12.first, *cf12.second, strategy);
|
||||
geometry::segment_iterator<Geometry2 const>
|
||||
> cf12 = range_to_range::apply(first1,
|
||||
beyond1,
|
||||
segments_begin(geometry2),
|
||||
segments_end(geometry2),
|
||||
cstrategy,
|
||||
cdist12);
|
||||
|
||||
return_type dist2 = dispatch::distance
|
||||
comparable_return_type cdist21;
|
||||
std::pair
|
||||
<
|
||||
typename point_type<Geometry2>::type,
|
||||
geometry::segment_iterator<Geometry1 const>
|
||||
> cf21 = range_to_range::apply(first2,
|
||||
beyond2,
|
||||
segments_begin(geometry1),
|
||||
segments_end(geometry1),
|
||||
cstrategy,
|
||||
cdist21);
|
||||
|
||||
if ( is_comparable<Strategy>::value )
|
||||
{
|
||||
return (std::min)(cdist12, cdist21);
|
||||
}
|
||||
|
||||
if ( cdist12 < cdist21 )
|
||||
{
|
||||
return dispatch::distance
|
||||
<
|
||||
typename point_type<Geometry1>::type,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
geometry::segment_iterator<Geometry2 const>
|
||||
>::value_type,
|
||||
Strategy
|
||||
>::apply(cf12.first, *cf12.second, strategy);
|
||||
}
|
||||
|
||||
return dispatch::distance
|
||||
<
|
||||
typename point_type<Geometry2>::type,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename return_type21::second_type
|
||||
geometry::segment_iterator<Geometry1 const>
|
||||
>::value_type,
|
||||
Strategy
|
||||
>::apply(cf21.first, *cf21.second, strategy);
|
||||
|
||||
return (std::min)(dist1, dist2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -74,17 +76,6 @@ template
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
class geometry_to_segment_or_box
|
||||
: detail::closest_feature::point_to_point_range
|
||||
<
|
||||
typename point_type<Geometry>::type,
|
||||
std::vector<typename point_type<SegmentOrBox>::type>,
|
||||
segment_or_box_point_range_closure<SegmentOrBox>::value,
|
||||
typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type
|
||||
>,
|
||||
detail::closest_feature::geometry_to_range
|
||||
{
|
||||
private:
|
||||
typedef typename point_type<SegmentOrBox>::type segment_or_box_point;
|
||||
@@ -100,9 +91,9 @@ private:
|
||||
std::vector<segment_or_box_point>,
|
||||
segment_or_box_point_range_closure<SegmentOrBox>::value,
|
||||
comparable_strategy
|
||||
> base_type1;
|
||||
> point_to_point_range;
|
||||
|
||||
typedef detail::closest_feature::geometry_to_range base_type2;
|
||||
typedef detail::closest_feature::geometry_to_range geometry_to_range;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
@@ -233,22 +224,23 @@ public:
|
||||
for (point_iterator_type pit = points_begin(geometry);
|
||||
pit != points_end(geometry); ++pit, first = false)
|
||||
{
|
||||
seg_or_box_iterator_type it1, it2;
|
||||
comparable_return_type cd;
|
||||
base_type1::apply(*pit,
|
||||
seg_or_box_points.begin(),
|
||||
seg_or_box_points.end(),
|
||||
cstrategy,
|
||||
it1,
|
||||
it2,
|
||||
cd);
|
||||
std::pair
|
||||
<
|
||||
seg_or_box_iterator_type, seg_or_box_iterator_type
|
||||
> it_pair
|
||||
= point_to_point_range::apply(*pit,
|
||||
seg_or_box_points.begin(),
|
||||
seg_or_box_points.end(),
|
||||
cstrategy,
|
||||
cd);
|
||||
|
||||
if ( first || cd < cd_min1 )
|
||||
{
|
||||
cd_min1 = cd;
|
||||
pit_min = pit;
|
||||
assign_new_value::apply(it_min1, it1);
|
||||
assign_new_value::apply(it_min2, it2);
|
||||
assign_new_value::apply(it_min1, it_pair.first);
|
||||
assign_new_value::apply(it_min2, it_pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,14 +255,13 @@ public:
|
||||
= seg_or_box_points.begin();
|
||||
it != seg_or_box_points.end(); ++it, first = false)
|
||||
{
|
||||
segment_iterator_type sit;
|
||||
comparable_return_type cd;
|
||||
base_type2::apply(*it,
|
||||
segments_begin(geometry),
|
||||
segments_end(geometry),
|
||||
cstrategy,
|
||||
sit,
|
||||
cd);
|
||||
segment_iterator_type sit
|
||||
= geometry_to_range::apply(*it,
|
||||
segments_begin(geometry),
|
||||
segments_end(geometry),
|
||||
cstrategy,
|
||||
cd);
|
||||
|
||||
if ( first || cd < cd_min2 )
|
||||
{
|
||||
@@ -280,6 +271,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_comparable<Strategy>::value )
|
||||
{
|
||||
return (std::min)(cd_min1, cd_min2);
|
||||
}
|
||||
|
||||
if ( cd_min1 < cd_min2 )
|
||||
{
|
||||
return strategy.apply(*pit_min, *it_min1, *it_min2);
|
||||
@@ -313,21 +309,18 @@ template <typename MultiPoint, typename SegmentOrBox, typename Strategy>
|
||||
class geometry_to_segment_or_box
|
||||
<
|
||||
MultiPoint, SegmentOrBox, Strategy, multi_point_tag
|
||||
> : detail::closest_feature::geometry_to_range
|
||||
>
|
||||
{
|
||||
private:
|
||||
typedef detail::closest_feature::geometry_to_range base_type;
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
MultiPoint const
|
||||
>::type iterator_type;
|
||||
|
||||
typedef detail::closest_feature::geometry_to_range geometry_to_range;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
@@ -342,18 +335,34 @@ public:
|
||||
{
|
||||
namespace sds = strategy::distance::services;
|
||||
|
||||
iterator_type it_min
|
||||
= base_type::apply(segment_or_box,
|
||||
boost::begin(multipoint),
|
||||
boost::end(multipoint),
|
||||
sds::get_comparable<Strategy>::apply(strategy));
|
||||
|
||||
return dispatch::distance
|
||||
typename sds::return_type
|
||||
<
|
||||
typename point_type<MultiPoint>::type,
|
||||
SegmentOrBox,
|
||||
Strategy
|
||||
>::apply(*it_min, segment_or_box, strategy);
|
||||
typename sds::comparable_type<Strategy>::type,
|
||||
typename point_type<SegmentOrBox>::type,
|
||||
typename point_type<MultiPoint>::type
|
||||
>::type cd_min;
|
||||
|
||||
iterator_type it_min
|
||||
= geometry_to_range::apply(segment_or_box,
|
||||
boost::begin(multipoint),
|
||||
boost::end(multipoint),
|
||||
sds::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy),
|
||||
cd_min);
|
||||
|
||||
return
|
||||
is_comparable<Strategy>::value
|
||||
?
|
||||
cd_min
|
||||
:
|
||||
dispatch::distance
|
||||
<
|
||||
typename point_type<MultiPoint>::type,
|
||||
SegmentOrBox,
|
||||
Strategy
|
||||
>::apply(*it_min, segment_or_box, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +83,9 @@ struct linear_to_linear<Linear1, Linear2, Strategy, true>
|
||||
{
|
||||
return point_or_segment_range_to_geometry_rtree
|
||||
<
|
||||
Linear1, Strategy
|
||||
geometry::segment_iterator<Linear2 const>,
|
||||
Linear1,
|
||||
Strategy
|
||||
>::apply(geometry::segments_begin(linear2),
|
||||
geometry::segments_end(linear2),
|
||||
linear1,
|
||||
@@ -93,7 +95,9 @@ struct linear_to_linear<Linear1, Linear2, Strategy, true>
|
||||
|
||||
return point_or_segment_range_to_geometry_rtree
|
||||
<
|
||||
Linear2, Strategy
|
||||
geometry::segment_iterator<Linear1 const>,
|
||||
Linear2,
|
||||
Strategy
|
||||
>::apply(geometry::segments_begin(linear1),
|
||||
geometry::segments_end(linear1),
|
||||
linear2,
|
||||
|
||||
@@ -53,7 +53,9 @@ struct multipoint_to_multipoint
|
||||
{
|
||||
return point_or_segment_range_to_geometry_rtree
|
||||
<
|
||||
MultiPoint1, Strategy
|
||||
typename boost::range_iterator<MultiPoint2 const>::type,
|
||||
MultiPoint1,
|
||||
Strategy
|
||||
>::apply(boost::begin(multipoint2),
|
||||
boost::end(multipoint2),
|
||||
multipoint1,
|
||||
@@ -62,7 +64,9 @@ struct multipoint_to_multipoint
|
||||
|
||||
return point_or_segment_range_to_geometry_rtree
|
||||
<
|
||||
MultiPoint2, Strategy
|
||||
typename boost::range_iterator<MultiPoint1 const>::type,
|
||||
MultiPoint2,
|
||||
Strategy
|
||||
>::apply(boost::begin(multipoint1),
|
||||
boost::end(multipoint1),
|
||||
multipoint2,
|
||||
@@ -87,7 +91,9 @@ struct multipoint_to_linear
|
||||
{
|
||||
return detail::distance::point_or_segment_range_to_geometry_rtree
|
||||
<
|
||||
Linear, Strategy
|
||||
typename boost::range_iterator<MultiPoint const>::type,
|
||||
Linear,
|
||||
Strategy
|
||||
>::apply(boost::begin(multipoint),
|
||||
boost::end(multipoint),
|
||||
linear,
|
||||
@@ -149,7 +155,9 @@ public:
|
||||
|
||||
return detail::distance::point_or_segment_range_to_geometry_rtree
|
||||
<
|
||||
Areal, Strategy
|
||||
typename boost::range_iterator<MultiPoint const>::type,
|
||||
Areal,
|
||||
Strategy
|
||||
>::apply(boost::begin(multipoint),
|
||||
boost::end(multipoint),
|
||||
areal,
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
@@ -86,7 +87,7 @@ private:
|
||||
typedef detail::closest_feature::point_to_point_range
|
||||
<
|
||||
Point, Range, Closure, comparable_strategy
|
||||
> closest_feature_type;
|
||||
> point_to_point_range;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
@@ -108,15 +109,33 @@ public:
|
||||
|
||||
namespace sds = strategy::distance::services;
|
||||
|
||||
typename closest_feature_type::return_type cf
|
||||
= closest_feature_type::apply(point,
|
||||
range,
|
||||
typename sds::return_type
|
||||
<
|
||||
comparable_strategy,
|
||||
Point,
|
||||
typename point_type<Range>::type
|
||||
>::type cd_min;
|
||||
|
||||
std::pair
|
||||
<
|
||||
typename boost::range_iterator<Range const>::type,
|
||||
typename boost::range_iterator<Range const>::type
|
||||
> it_pair
|
||||
= point_to_point_range::apply(point,
|
||||
boost::begin(range),
|
||||
boost::end(range),
|
||||
sds::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy));
|
||||
>::apply(strategy),
|
||||
cd_min);
|
||||
|
||||
return strategy.apply(point, *cf.first, *cf.second);
|
||||
return
|
||||
is_comparable<Strategy>::value
|
||||
?
|
||||
cd_min
|
||||
:
|
||||
strategy.apply(point, *it_pair.first, *it_pair.second);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,7 +163,7 @@ struct point_to_ring
|
||||
return return_type(0);
|
||||
}
|
||||
|
||||
return detail::distance::point_to_range
|
||||
return point_to_range
|
||||
<
|
||||
Point, Ring, closure<Ring>::value, Strategy
|
||||
>::apply(point, ring, strategy);
|
||||
@@ -237,10 +256,7 @@ template
|
||||
class point_to_multigeometry
|
||||
{
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
typedef detail::closest_feature::geometry_to_range geometry_to_range;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
@@ -256,27 +272,39 @@ public:
|
||||
{
|
||||
typedef iterator_selector<MultiGeometry const> selector_type;
|
||||
|
||||
typedef detail::closest_feature::geometry_to_range point_to_range;
|
||||
|
||||
namespace sds = strategy::distance::services;
|
||||
|
||||
typename selector_type::iterator_type it_min
|
||||
= point_to_range::apply(point,
|
||||
selector_type::begin(multigeometry),
|
||||
selector_type::end(multigeometry),
|
||||
sds::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy));
|
||||
return dispatch::distance
|
||||
typename sds::return_type
|
||||
<
|
||||
typename sds::comparable_type<Strategy>::type,
|
||||
Point,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename selector_type::iterator_type
|
||||
>::value_type,
|
||||
Strategy
|
||||
>::apply(point, *it_min, strategy);
|
||||
typename point_type<MultiGeometry>::type
|
||||
>::type cd;
|
||||
|
||||
typename selector_type::iterator_type it_min
|
||||
= geometry_to_range::apply(point,
|
||||
selector_type::begin(multigeometry),
|
||||
selector_type::end(multigeometry),
|
||||
sds::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy),
|
||||
cd);
|
||||
|
||||
return
|
||||
is_comparable<Strategy>::value
|
||||
?
|
||||
cd
|
||||
:
|
||||
dispatch::distance
|
||||
<
|
||||
Point,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename selector_type::iterator_type
|
||||
>::value_type,
|
||||
Strategy
|
||||
>::apply(point, *it_min, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
|
||||
@@ -65,16 +65,6 @@ template
|
||||
bool UsePointBoxStrategy = false
|
||||
>
|
||||
class segment_to_box_2D_generic
|
||||
: detail::closest_feature::point_to_point_range
|
||||
<
|
||||
typename point_type<Segment>::type,
|
||||
std::vector<typename point_type<Box>::type>,
|
||||
open,
|
||||
typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type
|
||||
>
|
||||
{
|
||||
private:
|
||||
typedef typename point_type<Segment>::type segment_point;
|
||||
@@ -91,18 +81,13 @@ private:
|
||||
std::vector<box_point>,
|
||||
open,
|
||||
comparable_strategy
|
||||
> base_type;
|
||||
> point_to_point_range;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, segment_point, box_point
|
||||
>::type comparable_return_type;
|
||||
|
||||
typedef point_to_range
|
||||
<
|
||||
segment_point, std::vector<box_point>, open, comparable_strategy
|
||||
> point_to_box_boundary;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
@@ -140,19 +125,22 @@ public:
|
||||
cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
|
||||
}
|
||||
|
||||
typename std::vector<box_point>::const_iterator bit_min1[2];
|
||||
typename std::vector<box_point>::const_iterator bit_min2[2];
|
||||
std::pair
|
||||
<
|
||||
typename std::vector<box_point>::const_iterator,
|
||||
typename std::vector<box_point>::const_iterator
|
||||
> bit_min[2];
|
||||
|
||||
base_type::apply(p[0],
|
||||
box_points.begin(), box_points.end(),
|
||||
cstrategy,
|
||||
bit_min1[0], bit_min2[0],
|
||||
cd[4]);
|
||||
base_type::apply(p[1],
|
||||
box_points.begin(), box_points.end(),
|
||||
cstrategy,
|
||||
bit_min1[1], bit_min2[1],
|
||||
cd[5]);
|
||||
bit_min[0] = point_to_point_range::apply(p[0],
|
||||
box_points.begin(),
|
||||
box_points.end(),
|
||||
cstrategy,
|
||||
cd[4]);
|
||||
bit_min[1] = point_to_point_range::apply(p[1],
|
||||
box_points.begin(),
|
||||
box_points.end(),
|
||||
cstrategy,
|
||||
cd[5]);
|
||||
|
||||
unsigned int imin = 0;
|
||||
for (unsigned int i = 1; i < 6; ++i)
|
||||
@@ -163,6 +151,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_comparable<Strategy>::value )
|
||||
{
|
||||
return cd[imin];
|
||||
}
|
||||
|
||||
if ( imin < 4 )
|
||||
{
|
||||
return strategy.apply(box_points[imin], p[0], p[1]);
|
||||
@@ -170,7 +163,9 @@ public:
|
||||
else
|
||||
{
|
||||
unsigned int bimin = imin - 4;
|
||||
return strategy.apply(p[bimin], *bit_min1[bimin], *bit_min2[bimin]);
|
||||
return strategy.apply(p[bimin],
|
||||
*bit_min[bimin].first,
|
||||
*bit_min[bimin].second);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -198,12 +193,14 @@ private:
|
||||
comparable_strategy, segment_point, box_point
|
||||
>::type comparable_return_type;
|
||||
|
||||
typedef typename detail::distance::default_strategy
|
||||
<
|
||||
segment_point, Box
|
||||
>::type point_box_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
typename detail::distance::default_strategy
|
||||
<
|
||||
segment_point, Box
|
||||
>::type
|
||||
point_box_strategy
|
||||
>::type point_box_comparable_strategy;
|
||||
|
||||
public:
|
||||
@@ -258,20 +255,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_comparable<Strategy>::value )
|
||||
{
|
||||
return cd[imin];
|
||||
}
|
||||
|
||||
if ( imin < 4 )
|
||||
{
|
||||
return strategy.apply(box_points[imin], p[0], p[1]);
|
||||
strategy.apply(box_points[imin], p[0], p[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
typename detail::distance::default_strategy
|
||||
<
|
||||
segment_point, Box
|
||||
>::type pb_strategy;
|
||||
|
||||
boost::ignore_unused(pb_strategy);
|
||||
|
||||
return pb_strategy.apply(p[imin - 4], box);
|
||||
return point_box_strategy().apply(p[imin - 4], box);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
|
||||
|
||||
@@ -94,6 +96,11 @@ public:
|
||||
std::size_t imin = std::distance(boost::addressof(d[0]),
|
||||
std::min_element(d, d + 4));
|
||||
|
||||
if ( is_comparable<Strategy>::value )
|
||||
{
|
||||
return d[imin];
|
||||
}
|
||||
|
||||
switch (imin)
|
||||
{
|
||||
case 0:
|
||||
|
||||
Reference in New Issue
Block a user