Distance strategies no longer need to be parameterized with the point type(s).

[SVN r85040]
This commit is contained in:
Bruno Lalande 2013-07-14 22:54:43 +00:00
parent 23612b0b6b
commit 4246ea4217
22 changed files with 460 additions and 791 deletions

View File

@ -40,7 +40,8 @@ struct enrichment_info
point_tag,
P
>::type
>::type
>::type,
P, P
>::type distance_type;
inline enrichment_info()

View File

@ -53,8 +53,8 @@ using strategy::distance::services::return_type;
template <typename P1, typename P2, typename Strategy>
struct point_to_point
{
static inline typename return_type<Strategy>::type apply(P1 const& p1,
P2 const& p2, Strategy const& strategy)
static inline typename return_type<Strategy, P1, P2>::type
apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
{
boost::ignore_unused_variable_warning(strategy);
return strategy.apply(p1, p2);
@ -65,8 +65,8 @@ struct point_to_point
template<typename Point, typename Segment, typename Strategy>
struct point_to_segment
{
static inline typename return_type<Strategy>::type apply(Point const& point,
Segment const& segment, Strategy const& )
static inline typename return_type<Strategy, Point, typename point_type<Segment>::type>::type
apply(Point const& point, Segment const& segment, Strategy const& )
{
typename strategy::distance::services::default_strategy
<
@ -96,7 +96,7 @@ template
>
struct point_to_range
{
typedef typename return_type<PSStrategy>::type return_type;
typedef typename return_type<PSStrategy, Point, typename point_type<Range>::type>::type return_type;
static inline return_type apply(Point const& point, Range const& range,
PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
@ -161,7 +161,7 @@ struct point_to_ring
{
typedef std::pair
<
typename return_type<PPStrategy>::type, bool
typename return_type<PPStrategy, Point, typename point_type<Ring>::type>::type, bool
> distance_containment;
static inline distance_containment apply(Point const& point,
@ -195,7 +195,7 @@ template
>
struct point_to_polygon
{
typedef typename return_type<PPStrategy>::type return_type;
typedef typename return_type<PPStrategy, 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,
@ -288,7 +288,14 @@ struct distance
>
: distance<Geometry2, Geometry1, Strategy, Tag2, Tag1, StrategyTag, false>
{
static inline typename return_type<Strategy>::type apply(
typedef typename return_type
<
Strategy,
typename point_type<Geometry2>::type,
typename point_type<Geometry1>::type
>::type return_type;
static inline return_type apply(
Geometry1 const& g1,
Geometry2 const& g2,
Strategy const& strategy)
@ -302,44 +309,6 @@ struct distance
}
};
// If reversal is needed and we got the strategy by default, invert it before
// proceeding to the reversal.
template
<
typename Geometry1, typename Geometry2,
typename Tag1, typename Tag2, typename StrategyTag
>
struct distance
<
Geometry1, Geometry2,
typename detail::distance::default_strategy<Geometry1, Geometry2>::type,
Tag1, Tag2, StrategyTag,
true
>
: distance
<
Geometry2, Geometry1,
typename detail::distance::default_strategy<Geometry2, Geometry1>::type,
Tag2, Tag1, StrategyTag,
false
>
{
typedef typename detail::distance::default_strategy<Geometry2, Geometry1>::type reversed_strategy;
static inline typename strategy::distance::services::return_type<reversed_strategy>::type apply(
Geometry1 const& g1,
Geometry2 const& g2,
typename detail::distance::default_strategy<Geometry1, Geometry2>::type const&)
{
return distance
<
Geometry2, Geometry1, reversed_strategy,
Tag2, Tag1, StrategyTag,
false
>::apply(g2, g1, reversed_strategy());
}
};
// Point-point
template <typename P1, typename P2, typename Strategy>
@ -363,9 +332,10 @@ struct distance
>
{
static inline typename return_type<Strategy>::type apply(Point const& point,
Linestring const& linestring,
Strategy const& strategy)
static inline typename return_type<Strategy, Point, typename point_type<Linestring>::type>::type
apply(Point const& point,
Linestring const& linestring,
Strategy const& strategy)
{
typedef typename strategy::distance::services::default_strategy
<
@ -394,9 +364,10 @@ struct distance
false
>
{
static inline typename return_type<Strategy>::type apply(Point const& point,
Linestring const& linestring,
Strategy const& strategy)
static inline typename return_type<Strategy, Point, typename point_type<Linestring>::type>::type
apply(Point const& point,
Linestring const& linestring,
Strategy const& strategy)
{
typedef typename Strategy::point_strategy_type pp_strategy_type;
return detail::distance::point_to_range
@ -415,7 +386,7 @@ struct distance
false
>
{
typedef typename return_type<Strategy>::type return_type;
typedef typename return_type<Strategy, Point, typename point_type<Ring>::type>::type return_type;
static inline return_type apply(Point const& point,
Ring const& ring,
@ -450,7 +421,7 @@ struct distance
false
>
{
typedef typename return_type<Strategy>::type return_type;
typedef typename return_type<Strategy, Point, typename point_type<Polygon>::type>::type return_type;
static inline return_type apply(Point const& point,
Polygon const& polygon,
@ -496,8 +467,10 @@ struct distance
false
>
{
static inline typename return_type<Strategy>::type apply(Point const& point,
Segment const& segment, Strategy const& strategy)
static inline typename return_type<Strategy, Point, typename point_type<Segment>::type>::type
apply(Point const& point,
Segment const& segment,
Strategy const& strategy)
{
typename point_type<Segment>::type p[2];
@ -549,9 +522,15 @@ for distance, it is probably so that there is no specialization
for return_type<...> for your strategy.
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline typename strategy::distance::services::return_type<Strategy>::type distance(
Geometry1 const& geometry1, Geometry2 const& geometry2,
Strategy const& strategy)
inline typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type
>::type
distance(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();

View File

@ -252,7 +252,9 @@ inline void simplify(Geometry const& geometry, Geometry& out,
{
concept::check<Geometry>();
BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
BOOST_CONCEPT_ASSERT(
(concept::SimplifyStrategy<Strategy, typename point_type<Geometry>::type>)
);
geometry::clear(out);
@ -322,7 +324,9 @@ inline void simplify_insert(Geometry const& geometry, OutputIterator out,
Distance const& max_distance, Strategy const& strategy)
{
concept::check<Geometry const>();
BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
BOOST_CONCEPT_ASSERT(
(concept::SimplifyStrategy<Strategy, typename point_type<Geometry>::type>)
);
dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy);
}

View File

@ -45,7 +45,12 @@ struct distance_single_to_multi
Strategy
>
{
typedef typename strategy::distance::services::return_type<Strategy>::type return_type;
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,
@ -84,7 +89,12 @@ struct distance_multi_to_multi
Strategy
>
{
typedef typename strategy::distance::services::return_type<Strategy>::type return_type;
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)

View File

@ -99,7 +99,11 @@ public :
typedef PointDistanceStrategy distance_strategy_type;
// typedef typename strategy::distance::services::comparable_type<PointDistanceStrategy>::type distance_strategy_type;
typedef typename strategy::distance::services::return_type<distance_strategy_type>::type return_type;
typedef typename strategy::distance::services::return_type
<
distance_strategy_type,
Point, Point
>::type return_type;
private :
typedef detail::douglas_peucker_point<Point> dp_point_type;
@ -197,7 +201,11 @@ public :
// Get points, recursively, including them if they are further away
// than the specified distance
typedef typename strategy::distance::services::return_type<distance_strategy_type>::type return_type;
typedef typename strategy::distance::services::return_type
<
distance_strategy_type,
dp_point_type, dp_point_type
>::type return_type;
consider(boost::begin(ref_candidates), boost::end(ref_candidates), max_distance, n, strategy);
@ -224,6 +232,17 @@ public :
}} // namespace strategy::simplify
namespace traits {
template <typename P>
struct point_type<strategy::simplify::detail::douglas_peucker_point<P> >
{
typedef P type;
};
} // namespace traits
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP

View File

@ -67,10 +67,8 @@ namespace strategy { namespace distance
*/
template
<
typename Point,
typename PointOfSegment = Point,
typename CalculationType = void,
typename Strategy = pythagoras<Point, PointOfSegment, CalculationType>
typename Strategy = pythagoras<CalculationType>
>
class projected_point
{
@ -81,45 +79,41 @@ public :
// Integer coordinates can still result in FP distances.
// There is a division, which must be represented in FP.
// So promote.
typedef typename promote_floating_point
<
typename strategy::distance::services::return_type
<
Strategy
>::type
>::type calculation_type;
private :
// A projected point of points in Integer coordinates must be able to be
// represented in FP.
typedef model::point
<
calculation_type,
dimension<PointOfSegment>::value,
typename coordinate_system<PointOfSegment>::type
> fp_point_type;
// For convenience
typedef fp_point_type fp_vector_type;
// We have to use a strategy using FP coordinates (fp-type) which is
// not always the same as Strategy (defined as point_strategy_type)
// So we create a "similar" one
typedef typename strategy::distance::services::similar_type
<
Strategy,
Point,
fp_point_type
>::type fp_strategy_type;
template <typename Point, typename PointOfSegment>
struct calculation_type
: promote_floating_point
<
typename strategy::distance::services::return_type
<
Strategy,
Point,
PointOfSegment
>::type
>
{};
public :
inline calculation_type apply(Point const& p,
PointOfSegment const& p1, PointOfSegment const& p2) const
template <typename Point, typename PointOfSegment>
inline typename calculation_type<Point, PointOfSegment>::type
apply(Point const& p, PointOfSegment const& p1, PointOfSegment const& p2) const
{
assert_dimension_equal<Point, PointOfSegment>();
typedef typename calculation_type<Point, PointOfSegment>::type calculation_type;
// A projected point of points in Integer coordinates must be able to be
// represented in FP.
typedef model::point
<
calculation_type,
dimension<PointOfSegment>::value,
typename coordinate_system<PointOfSegment>::type
> fp_point_type;
// For convenience
typedef fp_point_type fp_vector_type;
/*
Algorithm [p1: (x1,y1), p2: (x2,y2), p: (px,py)]
VECTOR v(x2 - x1, y2 - y1)
@ -157,21 +151,12 @@ public :
// See above, c1 > 0 AND c2 > c1 so: c2 != 0
calculation_type const b = c1 / c2;
fp_strategy_type fp_strategy
= strategy::distance::services::get_similar
<
Strategy, Point, fp_point_type
>::apply(strategy);
boost::ignore_unused_variable_warning(fp_strategy);
fp_point_type projected;
geometry::convert(p1, projected);
multiply_value(v, b);
add_point(projected, v);
//std::cout << "distance " << dsv(p) << " .. " << dsv(projected) << std::endl;
return fp_strategy.apply(p, projected);
return strategy.apply(p, projected);
}
};
@ -179,103 +164,64 @@ public :
namespace services
{
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct tag<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
template <typename CalculationType, typename Strategy>
struct tag<projected_point<CalculationType, Strategy> >
{
typedef strategy_tag_distance_point_segment type;
};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct return_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
{
typedef typename projected_point<Point, PointOfSegment, CalculationType, Strategy>::calculation_type type;
};
template <typename CalculationType, typename Strategy, typename P, typename PS>
struct return_type<projected_point<CalculationType, Strategy>, P, PS>
: projected_point<CalculationType, Strategy>::template calculation_type<P, PS>
{};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct strategy_point_point<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
template <typename CalculationType, typename Strategy>
struct strategy_point_point<projected_point<CalculationType, Strategy> >
{
typedef Strategy type;
};
template
<
typename Point,
typename PointOfSegment,
typename CalculationType,
typename Strategy,
typename P1,
typename P2
>
struct similar_type<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
{
typedef projected_point<P1, P2, CalculationType, Strategy> type;
};
template
<
typename Point,
typename PointOfSegment,
typename CalculationType,
typename Strategy,
typename P1,
typename P2
>
struct get_similar<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
{
static inline typename similar_type
<
projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2
>::type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
{
return projected_point<P1, P2, CalculationType, Strategy>();
}
};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct comparable_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
template <typename CalculationType, typename Strategy>
struct comparable_type<projected_point<CalculationType, Strategy> >
{
// Define a projected_point strategy with its underlying point-point-strategy
// being comparable
typedef projected_point
<
Point,
PointOfSegment,
CalculationType,
typename comparable_type<Strategy>::type
> type;
};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct get_comparable<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
template <typename CalculationType, typename Strategy>
struct get_comparable<projected_point<CalculationType, Strategy> >
{
typedef typename comparable_type
<
projected_point<Point, PointOfSegment, CalculationType, Strategy>
projected_point<CalculationType, Strategy>
>::type comparable_type;
public :
static inline comparable_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
static inline comparable_type apply(projected_point<CalculationType, Strategy> const& )
{
return comparable_type();
}
};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct result_from_distance<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
template <typename CalculationType, typename Strategy, typename P, typename PS>
struct result_from_distance<projected_point<CalculationType, Strategy>, P, PS>
{
private :
typedef typename return_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >::type return_type;
typedef typename return_type<projected_point<CalculationType, Strategy>, P, PS>::type return_type;
public :
template <typename T>
static inline return_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& , T const& value)
static inline return_type apply(projected_point<CalculationType, Strategy> const& , T const& value)
{
Strategy s;
return result_from_distance<Strategy>::apply(s, value);
return result_from_distance<Strategy, P, PS>::apply(s, value);
}
};
@ -290,8 +236,6 @@ struct default_strategy<segment_tag, Point, PointOfSegment, cartesian_tag, carte
{
typedef strategy::distance::projected_point
<
Point,
PointOfSegment,
void,
typename boost::mpl::if_
<

View File

@ -37,21 +37,23 @@ namespace strategy { namespace distance
namespace detail
{
template <typename Point1, typename Point2, size_t I, typename T>
template <size_t I, typename T>
struct compute_pythagoras
{
template <typename Point1, typename Point2>
static inline T apply(Point1 const& p1, Point2 const& p2)
{
T const c1 = boost::numeric_cast<T>(get<I-1>(p1));
T const c2 = boost::numeric_cast<T>(get<I-1>(p2));
T const d = c1 - c2;
return d * d + compute_pythagoras<Point1, Point2, I-1, T>::apply(p1, p2);
return d * d + compute_pythagoras<I-1, T>::apply(p1, p2);
}
};
template <typename Point1, typename Point2, typename T>
struct compute_pythagoras<Point1, Point2, 0, T>
template <typename T>
struct compute_pythagoras<0, T>
{
template <typename Point1, typename Point2>
static inline T apply(Point1 const&, Point2 const&)
{
return boost::numeric_cast<T>(0);
@ -72,24 +74,24 @@ namespace comparable
\tparam Point2 \tparam_second_point
\tparam CalculationType \tparam_calculation
*/
template
<
typename Point1,
typename Point2 = Point1,
typename CalculationType = void
>
template <typename CalculationType = void>
class pythagoras
{
public :
typedef typename util::calculation_type::geometric::binary
<
Point1,
Point2,
CalculationType
>::type calculation_type;
template <typename Point1, typename Point2>
struct calculation_type
: util::calculation_type::geometric::binary
<
Point1,
Point2,
CalculationType
>
{};
static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
template <typename Point1, typename Point2>
static inline typename calculation_type<Point1, Point2>::type
apply(Point1 const& p1, Point2 const& p2)
{
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point1>) );
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
@ -101,9 +103,8 @@ public :
return detail::compute_pythagoras
<
Point1, Point2,
dimension<Point1>::value,
calculation_type
typename calculation_type<Point1, Point2>::type
>::apply(p1, p2);
}
};
@ -128,22 +129,21 @@ public :
*/
template
<
typename Point1,
typename Point2 = Point1,
typename CalculationType = void
>
class pythagoras
struct pythagoras
{
typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
public :
typedef typename util::calculation_type::geometric::binary
<
Point1,
Point2,
CalculationType,
double,
double // promote integer to double
>::type calculation_type;
template <typename P1, typename P2>
struct calculation_type
: util::calculation_type::geometric::binary
<
P1,
P2,
CalculationType,
double,
double // promote integer to double
>
{};
/*!
\brief applies the distance calculation using pythagoras
@ -151,10 +151,11 @@ public :
\param p1 first point
\param p2 second point
*/
static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
template <typename P1, typename P2>
static inline typename calculation_type<P1, P2>::type
apply(P1 const& p1, P2 const& p2)
{
calculation_type const t = comparable_type::apply(p1, p2);
return sqrt(t);
return sqrt(comparable::pythagoras<CalculationType>::apply(p1, p2));
}
};
@ -163,81 +164,46 @@ public :
namespace services
{
template <typename Point1, typename Point2, typename CalculationType>
struct tag<pythagoras<Point1, Point2, CalculationType> >
template <typename CalculationType>
struct tag<pythagoras<CalculationType> >
{
typedef strategy_tag_distance_point_point type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct return_type<pythagoras<Point1, Point2, CalculationType> >
template <typename CalculationType, typename P1, typename P2>
struct return_type<distance::pythagoras<CalculationType>, P1, P2>
: pythagoras<CalculationType>::template calculation_type<P1, P2>
{};
template <typename CalculationType>
struct comparable_type<pythagoras<CalculationType> >
{
typedef typename pythagoras<Point1, Point2, CalculationType>::calculation_type type;
typedef comparable::pythagoras<CalculationType> type;
};
template
<
typename Point1,
typename Point2,
typename CalculationType,
typename P1,
typename P2
>
struct similar_type<pythagoras<Point1, Point2, CalculationType>, P1, P2>
template <typename CalculationType>
struct get_comparable<pythagoras<CalculationType> >
{
typedef pythagoras<P1, P2, CalculationType> type;
};
template
<
typename Point1,
typename Point2,
typename CalculationType,
typename P1,
typename P2
>
struct get_similar<pythagoras<Point1, Point2, CalculationType>, P1, P2>
{
static inline typename similar_type
<
pythagoras<Point1, Point2, CalculationType>, P1, P2
>::type apply(pythagoras<Point1, Point2, CalculationType> const& )
{
return pythagoras<P1, P2, CalculationType>();
}
};
template <typename Point1, typename Point2, typename CalculationType>
struct comparable_type<pythagoras<Point1, Point2, CalculationType> >
{
typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct get_comparable<pythagoras<Point1, Point2, CalculationType> >
{
typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
typedef comparable::pythagoras<CalculationType> comparable_type;
public :
static inline comparable_type apply(pythagoras<Point1, Point2, CalculationType> const& )
static inline comparable_type apply(pythagoras<CalculationType> const& )
{
return comparable_type();
}
};
template <typename Point1, typename Point2, typename CalculationType>
struct result_from_distance<pythagoras<Point1, Point2, CalculationType> >
template <typename CalculationType, typename Point1, typename Point2>
struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
{
private :
typedef typename return_type<pythagoras<Point1, Point2, CalculationType> >::type return_type;
typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
public :
template <typename T>
static inline return_type apply(pythagoras<Point1, Point2, CalculationType> const& , T const& value)
static inline return_type apply(pythagoras<CalculationType> const& , T const& value)
{
return return_type(value);
}
@ -245,83 +211,48 @@ public :
// Specializations for comparable::pythagoras
template <typename Point1, typename Point2, typename CalculationType>
struct tag<comparable::pythagoras<Point1, Point2, CalculationType> >
template <typename CalculationType>
struct tag<comparable::pythagoras<CalculationType> >
{
typedef strategy_tag_distance_point_point type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct return_type<comparable::pythagoras<Point1, Point2, CalculationType> >
template <typename CalculationType, typename P1, typename P2>
struct return_type<comparable::pythagoras<CalculationType>, P1, P2>
: comparable::pythagoras<CalculationType>::template calculation_type<P1, P2>
{};
template <typename CalculationType>
struct comparable_type<comparable::pythagoras<CalculationType> >
{
typedef typename comparable::pythagoras<Point1, Point2, CalculationType>::calculation_type type;
typedef comparable::pythagoras<CalculationType> type;
};
template
<
typename Point1,
typename Point2,
typename CalculationType,
typename P1,
typename P2
>
struct similar_type<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
template <typename CalculationType>
struct get_comparable<comparable::pythagoras<CalculationType> >
{
typedef comparable::pythagoras<P1, P2, CalculationType> type;
};
template
<
typename Point1,
typename Point2,
typename CalculationType,
typename P1,
typename P2
>
struct get_similar<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
{
static inline typename similar_type
<
comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2
>::type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& )
{
return comparable::pythagoras<P1, P2, CalculationType>();
}
};
template <typename Point1, typename Point2, typename CalculationType>
struct comparable_type<comparable::pythagoras<Point1, Point2, CalculationType> >
{
typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct get_comparable<comparable::pythagoras<Point1, Point2, CalculationType> >
{
typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
typedef comparable::pythagoras<CalculationType> comparable_type;
public :
static inline comparable_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& )
static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
{
return comparable_type();
}
};
template <typename Point1, typename Point2, typename CalculationType>
struct result_from_distance<comparable::pythagoras<Point1, Point2, CalculationType> >
template <typename CalculationType, typename Point1, typename Point2>
struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
{
private :
typedef typename return_type<comparable::pythagoras<Point1, Point2, CalculationType> >::type return_type;
typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
public :
template <typename T>
static inline return_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& , T const& value)
static inline return_type apply(comparable::pythagoras<CalculationType> const& , T const& value)
{
return_type const v = value;
return v * v;
@ -332,7 +263,7 @@ public :
template <typename Point1, typename Point2>
struct default_strategy<point_tag, Point1, Point2, cartesian_tag, cartesian_tag, void>
{
typedef pythagoras<Point1, Point2> type;
typedef pythagoras<> type;
};

View File

@ -23,6 +23,7 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/point.hpp>
namespace boost { namespace geometry { namespace concept
@ -33,7 +34,7 @@ namespace boost { namespace geometry { namespace concept
\brief Checks strategy for point-segment-distance
\ingroup distance
*/
template <typename Strategy>
template <typename Strategy, typename Point1, typename Point2>
struct PointDistanceStrategy
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
@ -55,66 +56,44 @@ private :
ApplyMethod, 1
>::type ptype2;
// 2) check if apply-arguments fulfill point concept
BOOST_CONCEPT_ASSERT
(
(concept::ConstPoint<ptype1>)
);
BOOST_CONCEPT_ASSERT
(
(concept::ConstPoint<ptype2>)
);
// 3) must define meta-function return_type
typedef typename strategy::distance::services::return_type<Strategy>::type rtype;
// 4) must define meta-function "similar_type"
typedef typename strategy::distance::services::similar_type
// 2) must define meta-function return_type
typedef typename strategy::distance::services::return_type
<
Strategy, ptype2, ptype1
>::type stype;
Strategy, ptype1, ptype2
>::type rtype;
// 5) must define meta-function "comparable_type"
// 3) must define meta-function "comparable_type"
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type ctype;
// 6) must define meta-function "tag"
// 4) must define meta-function "tag"
typedef typename strategy::distance::services::tag
<
Strategy
>::type tag;
// 7) must implement apply with arguments
// 5) must implement apply with arguments
Strategy* str = 0;
ptype1 *p1 = 0;
ptype2 *p2 = 0;
rtype r = str->apply(*p1, *p2);
// 8) must define (meta)struct "get_similar" with apply
stype s = strategy::distance::services::get_similar
<
Strategy,
ptype2, ptype1
>::apply(*str);
// 9) must define (meta)struct "get_comparable" with apply
// 6) must define (meta)struct "get_comparable" with apply
ctype c = strategy::distance::services::get_comparable
<
Strategy
>::apply(*str);
// 10) must define (meta)struct "result_from_distance" with apply
// 7) must define (meta)struct "result_from_distance" with apply
r = strategy::distance::services::result_from_distance
<
Strategy
Strategy,
ptype1, ptype2
>::apply(*str, 1.0);
boost::ignore_unused_variable_warning(str);
boost::ignore_unused_variable_warning(s);
boost::ignore_unused_variable_warning(c);
boost::ignore_unused_variable_warning(r);
}
@ -125,7 +104,7 @@ private :
public :
BOOST_CONCEPT_USAGE(PointDistanceStrategy)
{
checker::apply(&Strategy::apply);
checker::apply(&Strategy::template apply<Point1, Point2>);
}
#endif
};
@ -135,7 +114,7 @@ public :
\brief Checks strategy for point-segment-distance
\ingroup strategy_concepts
*/
template <typename Strategy>
template <typename Strategy, typename Point, typename PointOfSegment>
struct PointSegmentDistanceStrategy
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
@ -156,26 +135,14 @@ private :
ApplyMethod, 1
>::type sptype;
// 2) check if apply-arguments fulfill point concept
BOOST_CONCEPT_ASSERT
(
(concept::ConstPoint<ptype>)
);
// 1) must define meta-function return_type
typedef typename strategy::distance::services::return_type<Strategy, ptype, sptype>::type rtype;
BOOST_CONCEPT_ASSERT
(
(concept::ConstPoint<sptype>)
);
// 3) must define meta-function return_type
typedef typename strategy::distance::services::return_type<Strategy>::type rtype;
// 4) must define underlying point-distance-strategy
// 2) must define underlying point-distance-strategy
typedef typename strategy::distance::services::strategy_point_point<Strategy>::type stype;
BOOST_CONCEPT_ASSERT
(
(concept::PointDistanceStrategy<stype>)
(concept::PointDistanceStrategy<stype, Point, PointOfSegment>)
);
@ -194,7 +161,7 @@ private :
public :
BOOST_CONCEPT_USAGE(PointSegmentDistanceStrategy)
{
checker::apply(&Strategy::apply);
checker::apply(&Strategy::template apply<Point, PointOfSegment>);
}
#endif
};

View File

@ -19,6 +19,7 @@
#include <boost/concept_check.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
@ -30,7 +31,7 @@ namespace boost { namespace geometry { namespace concept
\brief Checks strategy for simplify
\ingroup simplify
*/
template <typename Strategy>
template <typename Strategy, typename Point>
struct SimplifyStrategy
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
@ -59,29 +60,14 @@ private :
boost::mpl::int_<0>
>::type base_index;
// 1: inspect and define both arguments of apply
typedef typename boost::remove_const
<
typename boost::remove_reference
<
typename boost::mpl::at
<
parameter_types,
base_index
>::type
>::type
>::type point_type;
BOOST_CONCEPT_ASSERT
(
(concept::PointSegmentDistanceStrategy<ds_type>)
(concept::PointSegmentDistanceStrategy<ds_type, Point, Point>)
);
Strategy *str = 0;
std::vector<point_type> const* v1 = 0;
std::vector<point_type> * v2 = 0;
std::vector<Point> const* v1 = 0;
std::vector<Point> * v2 = 0;
// 2) must implement method apply with arguments
// - Range
@ -96,8 +82,7 @@ private :
public :
BOOST_CONCEPT_USAGE(SimplifyStrategy)
{
checker::apply(&ds_type::apply);
checker::apply(&ds_type::template apply<Point, Point>);
}
#endif
};

View File

@ -39,7 +39,9 @@ struct default_distance_result
point_tag,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type
>::type
>::type,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type
>::type type;
};

View File

@ -30,48 +30,17 @@ namespace strategy { namespace distance { namespace services
template <typename Strategy> struct tag {};
template <typename Strategy> struct return_type
template <typename Strategy, typename P1, typename P2>
struct return_type
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy>)
false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy, P1, P2>)
);
};
/*!
\brief Metafunction delivering a similar strategy with other input point types
*/
template
<
typename Strategy,
typename Point1,
typename Point2
>
struct similar_type
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY
, (types<Strategy, Point1, Point2>)
);
};
template
<
typename Strategy,
typename Point1,
typename Point2
>
struct get_similar
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY
, (types<Strategy, Point1, Point2>)
);
};
template <typename Strategy> struct comparable_type
{
BOOST_MPL_ASSERT_MSG
@ -88,7 +57,8 @@ template <typename Strategy> struct get_comparable
);
};
template <typename Strategy> struct result_from_distance {};
template <typename Strategy, typename P1, typename P2>
struct result_from_distance {};
// For point-segment only:

View File

@ -82,8 +82,7 @@ protected :
calculation_type sum;
// Distances are calculated on unit sphere here
strategy::distance::haversine<PointOfSegment, PointOfSegment>
distance_over_unit_sphere;
strategy::distance::haversine<calculation_type> distance_over_unit_sphere;
inline excess_sum()

View File

@ -21,6 +21,7 @@
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/math.hpp>
@ -55,40 +56,35 @@ namespace strategy { namespace distance
*/
template
<
typename Point,
typename PointOfSegment = Point,
typename CalculationType = void,
typename Strategy = typename services::default_strategy<point_tag, Point>::type
typename Strategy = haversine<double, CalculationType>
>
class cross_track
{
public :
typedef typename promote_floating_point
<
typename select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>::type
>::type return_type;
template <typename Point, typename PointOfSegment>
struct return_type
: promote_floating_point
<
typename select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>::type
>
{};
inline cross_track()
{
m_strategy = Strategy();
m_radius = m_strategy.radius();
}
{}
inline cross_track(return_type const& r)
: m_radius(r)
, m_strategy(r)
explicit inline cross_track(typename Strategy::radius_type const& r)
: m_strategy(r)
{}
inline cross_track(Strategy const& s)
: m_strategy(s)
{
m_radius = m_strategy.radius();
}
{}
// It might be useful in the future
@ -96,9 +92,16 @@ public :
// crosstrack(...) {}
inline return_type apply(Point const& p,
PointOfSegment const& sp1, PointOfSegment const& sp2) const
template <typename Point, typename PointOfSegment>
inline typename return_type<Point, PointOfSegment>::type
apply(Point const& p, PointOfSegment const& sp1, PointOfSegment const& sp2) const
{
BOOST_CONCEPT_ASSERT(
(concept::PointDistanceStrategy<Strategy, Point, PointOfSegment>)
);
typedef typename return_type<Point, PointOfSegment>::type return_type;
// http://williams.best.vwh.net/avform.htm#XTE
return_type d1 = m_strategy.apply(sp1, p);
return_type d3 = m_strategy.apply(sp1, sp2);
@ -132,7 +135,7 @@ public :
if(projection1 > 0.0 && projection2 > 0.0)
{
return_type XTD = m_radius * geometry::math::abs( asin( sin( d1 / m_radius ) * sin( d_crs1 ) ));
return_type XTD = radius() * geometry::math::abs( asin( sin( d1 / radius() ) * sin( d_crs1 ) ));
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Projection ON the segment" << std::endl;
@ -153,23 +156,20 @@ public :
}
}
inline return_type radius() const { return m_radius; }
inline typename Strategy::radius_type radius() const
{ return m_strategy.radius(); }
private :
BOOST_CONCEPT_ASSERT
(
(geometry::concept::PointDistanceStrategy<Strategy >)
);
return_type m_radius;
// Point-point distances are calculated in radians, on the unit sphere
Strategy m_strategy;
/// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
inline return_type course(Point const& p1, Point const& p2) const
template <typename Point>
inline typename return_type<Point, Point>::type
course(Point const& p1, Point const& p2) const
{
typedef typename return_type<Point, Point>::type return_type;
// http://williams.best.vwh.net/avform.htm#Crs
return_type dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
return_type cos_p2lat = cos(get_as_radian<1>(p2));
@ -188,84 +188,32 @@ private :
namespace services
{
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct tag<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
template <typename CalculationType, typename Strategy>
struct tag<cross_track<CalculationType, Strategy> >
{
typedef strategy_tag_distance_point_segment type;
};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct return_type<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
{
typedef typename cross_track<Point, PointOfSegment, CalculationType, Strategy>::return_type type;
};
template
<
typename Point,
typename PointOfSegment,
typename CalculationType,
typename Strategy,
typename P,
typename PS
>
struct similar_type<cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS>
{
typedef cross_track<Point, PointOfSegment, CalculationType, Strategy> type;
};
template
<
typename Point,
typename PointOfSegment,
typename CalculationType,
typename Strategy,
typename P,
typename PS
>
struct get_similar<cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS>
{
static inline typename similar_type
<
cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS
>::type apply(cross_track<Point, PointOfSegment, CalculationType, Strategy> const& strategy)
{
return cross_track<P, PS, CalculationType, Strategy>(strategy.radius());
}
};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct comparable_type<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
{
// Comparable type is here just the strategy
typedef typename similar_type
<
cross_track
<
Point, PointOfSegment, CalculationType, Strategy
>, Point, PointOfSegment
>::type type;
};
template <typename CalculationType, typename Strategy, typename P, typename PS>
struct return_type<cross_track<CalculationType, Strategy>, P, PS>
: cross_track<CalculationType, Strategy>::template return_type<P, PS>
{};
template
<
typename Point, typename PointOfSegment,
typename CalculationType,
typename Strategy
>
struct get_comparable<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
struct get_comparable<cross_track<CalculationType, Strategy> >
{
typedef typename comparable_type
<
cross_track<Point, PointOfSegment, CalculationType, Strategy>
cross_track<CalculationType, Strategy>
>::type comparable_type;
public :
static inline comparable_type apply(cross_track<Point, PointOfSegment, CalculationType, Strategy> const& strategy)
static inline comparable_type apply(cross_track<CalculationType, Strategy> const& strategy)
{
return comparable_type(strategy.radius());
}
@ -274,30 +222,29 @@ public :
template
<
typename Point, typename PointOfSegment,
typename CalculationType,
typename Strategy
typename Strategy,
typename P, typename PS
>
struct result_from_distance<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
struct result_from_distance<cross_track<CalculationType, Strategy>, P, PS>
{
private :
typedef typename cross_track<Point, PointOfSegment, CalculationType, Strategy>::return_type return_type;
typedef typename cross_track<CalculationType, Strategy>::template return_type<P, PS> return_type;
public :
template <typename T>
static inline return_type apply(cross_track<Point, PointOfSegment, CalculationType, Strategy> const& , T const& distance)
static inline return_type apply(cross_track<CalculationType, Strategy> const& , T const& distance)
{
return distance;
}
};
template
template
<
typename Point, typename PointOfSegment,
typename CalculationType,
typename Strategy
>
struct strategy_point_point<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
struct strategy_point_point<cross_track<CalculationType, Strategy> >
{
typedef Strategy type;
};
@ -318,8 +265,6 @@ struct default_strategy
{
typedef cross_track
<
Point,
PointOfSegment,
void,
typename boost::mpl::if_
<
@ -345,8 +290,6 @@ struct default_strategy
{
typedef cross_track
<
Point,
PointOfSegment,
void,
typename boost::mpl::if_
<

View File

@ -39,52 +39,57 @@ namespace comparable
// - applying asin (which is strictly (monotone) increasing)
template
<
typename Point1,
typename Point2 = Point1,
typename RadiusType,
typename CalculationType = void
>
class haversine
{
public :
typedef typename promote_floating_point
<
typename select_calculation_type
<
Point1,
Point2,
CalculationType
>::type
>::type calculation_type;
template <typename Point1, typename Point2>
struct calculation_type
: promote_floating_point
<
typename select_calculation_type
<
Point1,
Point2,
CalculationType
>::type
>
{};
inline haversine(calculation_type const& r = 1.0)
typedef RadiusType radius_type;
explicit inline haversine(RadiusType const& r = 1.0)
: m_radius(r)
{}
static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
template <typename Point1, typename Point2>
static inline typename calculation_type<Point1, Point2>::type
apply(Point1 const& p1, Point2 const& p2)
{
return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
get_as_radian<0>(p2), get_as_radian<1>(p2));
return calculate<typename calculation_type<Point1, Point2>::type>(
get_as_radian<0>(p1), get_as_radian<1>(p1),
get_as_radian<0>(p2), get_as_radian<1>(p2)
);
}
inline calculation_type radius() const
inline RadiusType radius() const
{
return m_radius;
}
private :
static inline calculation_type calculate(calculation_type const& lon1,
calculation_type const& lat1,
calculation_type const& lon2,
calculation_type const& lat2)
template <typename R, typename T1, typename T2>
static inline R calculate(T1 const& lon1, T1 const& lat1,
T2 const& lon2, T2 const& lat2)
{
return math::hav(lat2 - lat1)
+ cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
}
calculation_type m_radius;
RadiusType m_radius;
};
@ -117,23 +122,26 @@ A mathematically equivalent formula, which is less subject
*/
template
<
typename Point1,
typename Point2 = Point1,
typename RadiusType,
typename CalculationType = void
>
class haversine
{
typedef comparable::haversine<Point1, Point2, CalculationType> comparable_type;
typedef comparable::haversine<RadiusType, CalculationType> comparable_type;
public :
template <typename Point1, typename Point2>
struct calculation_type
: services::return_type<comparable_type, Point1, Point2>
{};
typedef typename services::return_type<comparable_type>::type calculation_type;
typedef RadiusType radius_type;
/*!
\brief Constructor
\param radius radius of the sphere, defaults to 1.0 for the unit sphere
*/
inline haversine(calculation_type const& radius = 1.0)
inline haversine(RadiusType const& radius = 1.0)
: m_radius(radius)
{}
@ -143,8 +151,11 @@ public :
\param p1 first point
\param p2 second point
*/
inline calculation_type apply(Point1 const& p1, Point2 const& p2) const
template <typename Point1, typename Point2>
inline typename calculation_type<Point1, Point2>::type
apply(Point1 const& p1, Point2 const& p2) const
{
typedef typename calculation_type<Point1, Point2>::type calculation_type;
calculation_type const a = comparable_type::apply(p1, p2);
calculation_type const c = calculation_type(2.0) * asin(sqrt(a));
return m_radius * c;
@ -154,13 +165,13 @@ public :
\brief access to radius value
\return the radius
*/
inline calculation_type radius() const
inline RadiusType radius() const
{
return m_radius;
}
private :
calculation_type m_radius;
RadiusType m_radius;
};
@ -168,52 +179,32 @@ private :
namespace services
{
template <typename Point1, typename Point2, typename CalculationType>
struct tag<haversine<Point1, Point2, CalculationType> >
template <typename RadiusType, typename CalculationType>
struct tag<haversine<RadiusType, CalculationType> >
{
typedef strategy_tag_distance_point_point type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct return_type<haversine<Point1, Point2, CalculationType> >
template <typename RadiusType, typename CalculationType, typename P1, typename P2>
struct return_type<haversine<RadiusType, CalculationType>, P1, P2>
: haversine<RadiusType, CalculationType>::template calculation_type<P1, P2>
{};
template <typename RadiusType, typename CalculationType>
struct comparable_type<haversine<RadiusType, CalculationType> >
{
typedef typename haversine<Point1, Point2, CalculationType>::calculation_type type;
typedef comparable::haversine<RadiusType, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
struct similar_type<haversine<Point1, Point2, CalculationType>, P1, P2>
{
typedef haversine<P1, P2, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
struct get_similar<haversine<Point1, Point2, CalculationType>, P1, P2>
template <typename RadiusType, typename CalculationType>
struct get_comparable<haversine<RadiusType, CalculationType> >
{
private :
typedef haversine<Point1, Point2, CalculationType> this_type;
public :
static inline typename similar_type<this_type, P1, P2>::type apply(this_type const& input)
{
return haversine<P1, P2, CalculationType>(input.radius());
}
};
template <typename Point1, typename Point2, typename CalculationType>
struct comparable_type<haversine<Point1, Point2, CalculationType> >
{
typedef comparable::haversine<Point1, Point2, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct get_comparable<haversine<Point1, Point2, CalculationType> >
{
private :
typedef haversine<Point1, Point2, CalculationType> this_type;
typedef comparable::haversine<Point1, Point2, CalculationType> comparable_type;
typedef haversine<RadiusType, CalculationType> this_type;
typedef comparable::haversine<RadiusType, CalculationType> comparable_type;
public :
static inline comparable_type apply(this_type const& input)
{
@ -221,12 +212,12 @@ public :
}
};
template <typename Point1, typename Point2, typename CalculationType>
struct result_from_distance<haversine<Point1, Point2, CalculationType> >
template <typename RadiusType, typename CalculationType, typename P1, typename P2>
struct result_from_distance<haversine<RadiusType, CalculationType>, P1, P2>
{
private :
typedef haversine<Point1, Point2, CalculationType> this_type;
typedef typename return_type<this_type>::type return_type;
typedef haversine<RadiusType, CalculationType> this_type;
typedef typename return_type<this_type, P1, P2>::type return_type;
public :
template <typename T>
static inline return_type apply(this_type const& , T const& value)
@ -237,51 +228,31 @@ public :
// Specializations for comparable::haversine
template <typename Point1, typename Point2, typename CalculationType>
struct tag<comparable::haversine<Point1, Point2, CalculationType> >
template <typename RadiusType, typename CalculationType>
struct tag<comparable::haversine<RadiusType, CalculationType> >
{
typedef strategy_tag_distance_point_point type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct return_type<comparable::haversine<Point1, Point2, CalculationType> >
template <typename RadiusType, typename CalculationType, typename P1, typename P2>
struct return_type<comparable::haversine<RadiusType, CalculationType>, P1, P2>
: comparable::haversine<RadiusType, CalculationType>::template calculation_type<P1, P2>
{};
template <typename RadiusType, typename CalculationType>
struct comparable_type<comparable::haversine<RadiusType, CalculationType> >
{
typedef typename comparable::haversine<Point1, Point2, CalculationType>::calculation_type type;
typedef comparable::haversine<RadiusType, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
struct similar_type<comparable::haversine<Point1, Point2, CalculationType>, P1, P2>
{
typedef comparable::haversine<P1, P2, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
struct get_similar<comparable::haversine<Point1, Point2, CalculationType>, P1, P2>
template <typename RadiusType, typename CalculationType>
struct get_comparable<comparable::haversine<RadiusType, CalculationType> >
{
private :
typedef comparable::haversine<Point1, Point2, CalculationType> this_type;
public :
static inline typename similar_type<this_type, P1, P2>::type apply(this_type const& input)
{
return comparable::haversine<P1, P2, CalculationType>(input.radius());
}
};
template <typename Point1, typename Point2, typename CalculationType>
struct comparable_type<comparable::haversine<Point1, Point2, CalculationType> >
{
typedef comparable::haversine<Point1, Point2, CalculationType> type;
};
template <typename Point1, typename Point2, typename CalculationType>
struct get_comparable<comparable::haversine<Point1, Point2, CalculationType> >
{
private :
typedef comparable::haversine<Point1, Point2, CalculationType> this_type;
typedef comparable::haversine<RadiusType, CalculationType> this_type;
public :
static inline this_type apply(this_type const& input)
{
@ -290,12 +261,12 @@ public :
};
template <typename Point1, typename Point2, typename CalculationType>
struct result_from_distance<comparable::haversine<Point1, Point2, CalculationType> >
template <typename RadiusType, typename CalculationType, typename P1, typename P2>
struct result_from_distance<comparable::haversine<RadiusType, CalculationType>, P1, P2>
{
private :
typedef comparable::haversine<Point1, Point2, CalculationType> strategy_type;
typedef typename return_type<strategy_type>::type return_type;
typedef comparable::haversine<RadiusType, CalculationType> strategy_type;
typedef typename return_type<strategy_type, P1, P2>::type return_type;
public :
template <typename T>
static inline return_type apply(strategy_type const& strategy, T const& distance)
@ -311,7 +282,7 @@ public :
template <typename Point1, typename Point2>
struct default_strategy<point_tag, Point1, Point2, spherical_equatorial_tag, spherical_equatorial_tag>
{
typedef strategy::distance::haversine<Point1, Point2> type;
typedef strategy::distance::haversine<typename select_coordinate_type<Point1, Point2>::type> type;
};
// Note: spherical polar coordinate system requires "get_as_radian_equatorial"

View File

@ -71,12 +71,12 @@ void test_distance_point()
{
// Test custom strategy
BOOST_CONCEPT_ASSERT( (bg::concept::PointDistanceStrategy<taxicab_distance<P> >) );
BOOST_CONCEPT_ASSERT( (bg::concept::PointDistanceStrategy<taxicab_distance, P, P>) );
typedef typename services::return_type<taxicab_distance<P> >::type cab_return_type;
typedef typename services::return_type<taxicab_distance, P, P>::type cab_return_type;
BOOST_MPL_ASSERT((boost::is_same<cab_return_type, typename bg::coordinate_type<P>::type>));
taxicab_distance<P> tcd;
taxicab_distance tcd;
cab_return_type d = bg::distance(p1, p2, tcd);
BOOST_CHECK( bg::math::abs(d - cab_return_type(2)) <= cab_return_type(0.01) );
@ -90,7 +90,7 @@ void test_distance_point()
strategy_type strategy;
comparable_strategy_type comparable_strategy = services::get_comparable<strategy_type>::apply(strategy);
return_type comparable = services::result_from_distance<comparable_strategy_type>::apply(comparable_strategy, 3);
return_type comparable = services::result_from_distance<comparable_strategy_type, P, P>::apply(comparable_strategy, 3);
BOOST_CHECK_CLOSE(comparable, return_type(9), 0.001);
}
@ -145,7 +145,7 @@ void test_distance_segment()
BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);
// 3) custom point strategy
taxicab_distance<P> tcd;
taxicab_distance tcd;
d1 = bg::distance(p1, seg, tcd);
BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);
}

View File

@ -24,9 +24,9 @@
// For a point-segment-distance operation, there is some magic inside
// using another point type and casting if necessary. Therefore,
// two point-types are necessary.
template <typename P1, typename P2 = P1>
struct taxicab_distance
{
template <typename P1, typename P2>
static inline typename bg::coordinate_type<P1>::type apply(
P1 const& p1, P2 const& p2)
{
@ -42,59 +42,40 @@ struct taxicab_distance
namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
{
template <typename P1, typename P2>
struct tag<taxicab_distance<P1, P2> >
template <>
struct tag<taxicab_distance>
{
typedef strategy_tag_distance_point_point type;
};
template <typename P1, typename P2>
struct return_type<taxicab_distance<P1, P2> >
struct return_type<taxicab_distance, P1, P2>
{
typedef typename coordinate_type<P1>::type type;
};
template<typename P1, typename P2, typename PN1, typename PN2>
struct similar_type<taxicab_distance<P1, P2>, PN1, PN2>
template <>
struct comparable_type<taxicab_distance>
{
typedef taxicab_distance<PN1, PN2> type;
typedef taxicab_distance type;
};
template<typename P1, typename P2, typename PN1, typename PN2>
struct get_similar<taxicab_distance<P1, P2>, PN1, PN2>
template <>
struct get_comparable<taxicab_distance>
{
static inline typename similar_type
<
taxicab_distance<P1, P2>, PN1, PN2
>::type apply(taxicab_distance<P1, P2> const& )
{
return taxicab_distance<PN1, PN2>();
}
};
template <typename P1, typename P2>
struct comparable_type<taxicab_distance<P1, P2> >
{
typedef taxicab_distance<P1, P2> type;
};
template <typename P1, typename P2>
struct get_comparable<taxicab_distance<P1, P2> >
{
static inline taxicab_distance<P1, P2> apply(taxicab_distance<P1, P2> const& input)
static inline taxicab_distance apply(taxicab_distance const& input)
{
return input;
}
};
template <typename P1, typename P2>
struct result_from_distance<taxicab_distance<P1, P2> >
struct result_from_distance<taxicab_distance, P1, P2>
{
template <typename T>
static inline typename coordinate_type<P1>::type apply(taxicab_distance<P1, P2> const& , T const& value)
static inline typename coordinate_type<P1>::type apply(taxicab_distance const& , T const& value)
{
return value;
}

View File

@ -64,18 +64,14 @@ void test_geometry(std::string const& wkt, std::string const& expected, double d
// Check using user-specified strategy
typedef typename bg::point_type<Geometry>::type point_type;
typedef typename bg::cs_tag<point_type>::type tag;
typedef bg::strategy::distance::projected_point
<
point_type,
point_type
> strategy;
typedef bg::strategy::distance::projected_point<double> strategy;
typedef bg::strategy::simplify::douglas_peucker
<
point_type,
strategy
> simplify_strategy_type;
BOOST_CONCEPT_ASSERT( (bg::concept::SimplifyStrategy<simplify_strategy_type>) );
BOOST_CONCEPT_ASSERT( (bg::concept::SimplifyStrategy<simplify_strategy_type, point_type>) );
bg::simplify(geometry, simplified, distance, simplify_strategy_type());
{

View File

@ -74,7 +74,7 @@ void test_2d()
test_distance<ml, mp>("MULTILINESTRING((1 1,2 2),(1 0,2 0),(0 2,0 3))", "MULTIPOINT((0 0),(1 1))", 0.0);
// Test with a strategy
bg::strategy::distance::pythagoras<P, P> pyth;
bg::strategy::distance::pythagoras<> pyth;
test_distance<P, P>(pyth, "POINT(0 0)", "POINT(1 1)", sqrt(2.0));
test_distance<P, mp>(pyth, "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<mp, P>(pyth, "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
@ -116,18 +116,18 @@ void test_mixed()
// Test with a strategy
using namespace bg::strategy::distance;
test_distance<P1, P2>(pythagoras<P1, P2>(), "POINT(0 0)", "POINT(1 1)", sqrt(2.0));
test_distance<P1, P2>(pythagoras<>(), "POINT(0 0)", "POINT(1 1)", sqrt(2.0));
test_distance<P1, mp1>(pythagoras<P1, P1>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<P1, mp2>(pythagoras<P1, P2>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<P2, mp1>(pythagoras<P2, P1>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<P2, mp2>(pythagoras<P2, P2>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<P1, mp1>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<P1, mp2>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<P2, mp1>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
test_distance<P2, mp2>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
// Most interesting: reversal AND a strategy (note that the stategy must be reversed automatically
test_distance<mp1, P1>(pythagoras<P1, P1>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
test_distance<mp1, P2>(pythagoras<P1, P2>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
test_distance<mp2, P1>(pythagoras<P2, P1>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
test_distance<mp2, P2>(pythagoras<P2, P2>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
test_distance<mp1, P1>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
test_distance<mp1, P2>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
test_distance<mp2, P1>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
test_distance<mp2, P2>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
}
template <typename P>

View File

@ -46,18 +46,20 @@ void test_distance(
{
typedef bg::strategy::distance::cross_track
<
Point,
Point
typename bg::coordinate_type<Point>::type
> strategy_type;
typedef typename bg::strategy::distance::services::return_type
<
strategy_type
strategy_type,
Point,
Point
>::type return_type;
BOOST_CONCEPT_ASSERT
(
(bg::concept::PointSegmentDistanceStrategy<strategy_type>)
(bg::concept::PointSegmentDistanceStrategy<strategy_type, Point, Point>)
);
@ -72,6 +74,10 @@ void test_distance(
BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
// The strategy should return the same result if we reverse the parameters
d = strategy.apply(p1, p3, p2);
BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
// Test specifying radius explicitly
strategy_type strategy_radius(radius);
d = strategy_radius.apply(p1, p2, p3);

View File

@ -37,25 +37,17 @@ double const average_earth_radius = 6372795.0;
template <typename Point, typename LatitudePolicy>
struct test_distance
{
typedef bg::strategy::distance::haversine
<
Point,
Point
> haversine_type;
BOOST_CONCEPT_ASSERT( (bg::concept::PointDistanceStrategy<haversine_type>) );
typedef typename bg::strategy::distance::services::return_type<haversine_type>::type return_type;
typedef bg::strategy::distance::haversine<double> haversine_type;
typedef typename bg::strategy::distance::services::return_type<haversine_type, Point, Point>::type return_type;
BOOST_CONCEPT_ASSERT
(
(bg::concept::PointDistanceStrategy<haversine_type>)
(bg::concept::PointDistanceStrategy<haversine_type, Point, Point>)
);
static void test(double lon1, double lat1, double lon2, double lat2,
double radius, return_type expected, double tolerance)
double radius, double expected, double tolerance)
{
haversine_type strategy(radius);
@ -117,21 +109,15 @@ void test_services()
// 1: normal, calculate distance:
typedef bgsd::haversine<P1, P2, CalculationType> strategy_type;
typedef typename bgsd::services::return_type<strategy_type>::type return_type;
typedef bgsd::haversine<double, CalculationType> strategy_type;
typedef typename bgsd::services::return_type<strategy_type, P1, P2>::type return_type;
strategy_type strategy(average_earth_radius);
return_type result = strategy.apply(p1, p2);
BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
// 2: "similar" to construct a similar strategy (similar but with other template-parameters) for, e.g., the reverse P2/P1
// 2a: similar_type:
typedef typename services::similar_type<strategy_type, P2, P1>::type similar_type;
// 2b: get_similar
similar_type similar = services::get_similar<strategy_type, P2, P1>::apply(strategy);
//result = similar.apply(p1, p2); // should NOT compile because p1/p2 should also be reversed here
result = similar.apply(p2, p1);
// 2: the strategy should return the same result if we reverse parameters
result = strategy.apply(p2, p1);
BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
@ -149,14 +135,14 @@ void test_services()
// First the result of the comparable strategy
return_type c_result = comparable.apply(p1, p2);
// Second the comparable result of the expected distance
return_type c_expected = services::result_from_distance<comparable_type>::apply(comparable, expected);
return_type c_expected = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, expected);
// And that one should be equa.
BOOST_CHECK_CLOSE(c_result, return_type(c_expected), 0.001);
// 4: the comparable_type should have a distance_strategy_constructor as well,
// knowing how to compare something with a fixed distance
return_type c_dist_lower = services::result_from_distance<comparable_type>::apply(comparable, expected_lower);
return_type c_dist_higher = services::result_from_distance<comparable_type>::apply(comparable, expected_higher);
return_type c_dist_lower = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, expected_lower);
return_type c_dist_higher = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, expected_higher);
// If this is the case:
BOOST_CHECK(c_dist_lower < c_result && c_result < c_dist_higher);
@ -166,8 +152,8 @@ void test_services()
BOOST_CHECK_CLOSE(c_check, expected, 0.001);
// This should also be the case
return_type dist_lower = services::result_from_distance<strategy_type>::apply(strategy, expected_lower);
return_type dist_higher = services::result_from_distance<strategy_type>::apply(strategy, expected_higher);
return_type dist_lower = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, expected_lower);
return_type dist_higher = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, expected_higher);
BOOST_CHECK(dist_lower < result && result < dist_higher);
}
@ -194,8 +180,8 @@ void time_compare_s(int const n)
template <typename P>
void time_compare(int const n)
{
time_compare_s<P, bg::strategy::distance::haversine<P> >(n);
time_compare_s<P, bg::strategy::distance::comparable::haversine<P> >(n);
time_compare_s<P, bg::strategy::distance::haversine<double> >(n);
time_compare_s<P, bg::strategy::distance::comparable::haversine<double> >(n);
}
#include <time.h>

View File

@ -52,23 +52,18 @@ void test_services()
namespace services = bg::strategy::distance::services;
// 1: normal, calculate distance:
typedef bgsd::projected_point<P, PS, CalculationType> strategy_type;
typedef bgsd::projected_point<CalculationType> strategy_type;
BOOST_CONCEPT_ASSERT( (bg::concept::PointSegmentDistanceStrategy<strategy_type>) );
BOOST_CONCEPT_ASSERT( (bg::concept::PointSegmentDistanceStrategy<strategy_type, P, PS>) );
typedef typename services::return_type<strategy_type>::type return_type;
typedef typename services::return_type<strategy_type, P, PS>::type return_type;
strategy_type strategy;
return_type result = strategy.apply(p, p1, p2);
BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
// 2: "similar" to construct a similar strategy (similar but with other template-parameters) for, e.g., the reverse P2/P1
// 2a: similar_type:
typedef typename services::similar_type<strategy_type, P, PS>::type similar_type;
// 2b: get_similar
similar_type similar = services::get_similar<strategy_type, P, PS>::apply(strategy);
result = similar.apply(p, p1, p2);
// 2: the strategy should return the same result if we reverse parameters
result = strategy.apply(p, p1, p2);
BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
@ -100,19 +95,15 @@ void test_all_2d(std::string const& wkt_p,
bg::read_wkt(wkt_sp2, sp2);
{
typedef bg::strategy::distance::projected_point
<
P1,
P2
> strategy_type;
typedef bg::strategy::distance::projected_point<> strategy_type;
BOOST_CONCEPT_ASSERT
(
(bg::concept::PointSegmentDistanceStrategy<strategy_type>)
(bg::concept::PointSegmentDistanceStrategy<strategy_type, P1, P2>)
);
strategy_type strategy;
typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
typedef typename bg::strategy::distance::services::return_type<strategy_type, P1, P2>::type return_type;
return_type d = strategy.apply(p, sp1, sp2);
BOOST_CHECK_CLOSE(d, expected_distance, 0.001);
}
@ -121,13 +112,11 @@ void test_all_2d(std::string const& wkt_p,
{
typedef bg::strategy::distance::projected_point
<
P1,
P2,
void,
bg::strategy::distance::comparable::pythagoras<P1, P2>
bg::strategy::distance::comparable::pythagoras<>
> strategy_type;
strategy_type strategy;
typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
typedef typename bg::strategy::distance::services::return_type<strategy_type, P1, P2>::type return_type;
return_type d = strategy.apply(p, sp1, sp2);
T expected_squared_distance = expected_distance * expected_distance;
BOOST_CHECK_CLOSE(d, expected_squared_distance, 0.01);

View File

@ -51,8 +51,8 @@ void test_null_distance_3d()
P2 p2;
bg::assign_values(p2, 1, 2, 3);
typedef bg::strategy::distance::pythagoras<P1, P2> pythagoras_type;
typedef typename bg::strategy::distance::services::return_type<pythagoras_type>::type return_type;
typedef bg::strategy::distance::pythagoras<> pythagoras_type;
typedef typename bg::strategy::distance::services::return_type<pythagoras_type, P1, P2>::type return_type;
pythagoras_type pythagoras;
return_type result = pythagoras.apply(p1, p2);
@ -68,8 +68,8 @@ void test_axis_3d()
P2 p2;
bg::assign_values(p2, 1, 0, 0);
typedef bg::strategy::distance::pythagoras<P1, P2> pythagoras_type;
typedef typename bg::strategy::distance::services::return_type<pythagoras_type>::type return_type;
typedef bg::strategy::distance::pythagoras<> pythagoras_type;
typedef typename bg::strategy::distance::services::return_type<pythagoras_type, P1, P2>::type return_type;
pythagoras_type pythagoras;
@ -94,8 +94,8 @@ void test_arbitrary_3d()
bg::assign_values(p2, 9, 8, 7);
{
typedef bg::strategy::distance::pythagoras<P1, P2> strategy_type;
typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
typedef bg::strategy::distance::pythagoras<> strategy_type;
typedef typename bg::strategy::distance::services::return_type<strategy_type, P1, P2>::type return_type;
strategy_type strategy;
return_type result = strategy.apply(p1, p2);
@ -104,8 +104,8 @@ void test_arbitrary_3d()
{
// Check comparable distance
typedef bg::strategy::distance::comparable::pythagoras<P1, P2> strategy_type;
typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
typedef bg::strategy::distance::comparable::pythagoras<> strategy_type;
typedef typename bg::strategy::distance::services::return_type<strategy_type, P1, P2>::type return_type;
strategy_type strategy;
return_type result = strategy.apply(p1, p2);
@ -137,24 +137,18 @@ void test_services()
// 1: normal, calculate distance:
typedef bgsd::pythagoras<P1, P2, CalculationType> strategy_type;
typedef bgsd::pythagoras<CalculationType> strategy_type;
BOOST_CONCEPT_ASSERT( (bg::concept::PointDistanceStrategy<strategy_type>) );
BOOST_CONCEPT_ASSERT( (bg::concept::PointDistanceStrategy<strategy_type, P1, P2>) );
typedef typename bgsd::services::return_type<strategy_type>::type return_type;
typedef typename bgsd::services::return_type<strategy_type, P1, P2>::type return_type;
strategy_type strategy;
return_type result = strategy.apply(p1, p2);
BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
// 2: "similar" to construct a similar strategy (similar but with other template-parameters) for, e.g., the reverse P2/P1
// 2a: similar_type:
typedef typename services::similar_type<strategy_type, P2, P1>::type similar_type;
// 2b: get_similar
similar_type similar = services::get_similar<strategy_type, P2, P1>::apply(strategy);
//result = similar.apply(p1, p2); // should NOT compile because p1/p2 should also be reversed here
result = similar.apply(p2, p1);
// 2: the strategy should return the same result if we reverse parameters
result = strategy.apply(p2, p1);
BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
@ -173,15 +167,15 @@ void test_services()
// 4: the comparable_type should have a distance_strategy_constructor as well,
// knowing how to compare something with a fixed distance
return_type c_dist5 = services::result_from_distance<comparable_type>::apply(comparable, 5.0);
return_type c_dist6 = services::result_from_distance<comparable_type>::apply(comparable, 6.0);
return_type c_dist5 = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, 5.0);
return_type c_dist6 = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, 6.0);
// If this is the case:
BOOST_CHECK(c_dist5 < c_result && c_result < c_dist6);
// This should also be the case
return_type dist5 = services::result_from_distance<strategy_type>::apply(strategy, 5.0);
return_type dist6 = services::result_from_distance<strategy_type>::apply(strategy, 6.0);
return_type dist5 = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, 5.0);
return_type dist6 = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, 6.0);
BOOST_CHECK(dist5 < result && result < dist6);
}
@ -191,15 +185,10 @@ void test_big_2d_with(AssignType const& x1, AssignType const& y1,
AssignType const& x2, AssignType const& y2)
{
typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
typedef bg::strategy::distance::pythagoras
<
point_type,
point_type,
CalculationType
> pythagoras_type;
typedef bg::strategy::distance::pythagoras<CalculationType> pythagoras_type;
pythagoras_type pythagoras;
typedef typename bg::strategy::distance::services::return_type<pythagoras_type>::type return_type;
typedef typename bg::strategy::distance::services::return_type<pythagoras_type, point_type, point_type>::type return_type;
point_type p1, p2;
@ -242,10 +231,7 @@ void test_integer(bool check_types)
bg::assign_values(p1, 12345678, 23456789);
bg::assign_values(p2, 98765432, 87654321);
typedef bg::strategy::distance::pythagoras
<
point_type
> pythagoras_type;
typedef bg::strategy::distance::pythagoras<> pythagoras_type;
pythagoras_type pythagoras;
BOOST_AUTO(distance, pythagoras.apply(p1, p2));
BOOST_CHECK_CLOSE(distance, 107655455.02347542, 0.001);
@ -300,7 +286,7 @@ void time_compare_s(int const n)
bg::assign_values(p1, 1, 1);
bg::assign_values(p2, 2, 2);
Strategy strategy;
typename bg::strategy::distance::services::return_type<Strategy>::type s = 0;
typename bg::strategy::distance::services::return_type<Strategy, P, P>::type s = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
@ -315,8 +301,8 @@ void time_compare_s(int const n)
template <typename P>
void time_compare(int const n)
{
time_compare_s<P, bg::strategy::distance::pythagoras<P> >(n);
time_compare_s<P, bg::strategy::distance::comparable::pythagoras<P> >(n);
time_compare_s<P, bg::strategy::distance::pythagoras<> >(n);
time_compare_s<P, bg::strategy::distance::comparable::pythagoras<> >(n);
}
int test_main(int, char* [])