summaryrefslogtreecommitdiff
path: root/boost/geometry/strategies/spherical/distance_cross_track.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/strategies/spherical/distance_cross_track.hpp')
-rw-r--r--boost/geometry/strategies/spherical/distance_cross_track.hpp219
1 files changed, 81 insertions, 138 deletions
diff --git a/boost/geometry/strategies/spherical/distance_cross_track.hpp b/boost/geometry/strategies/spherical/distance_cross_track.hpp
index 7b353020eb..a40f03dbaf 100644
--- a/boost/geometry/strategies/spherical/distance_cross_track.hpp
+++ b/boost/geometry/strategies/spherical/distance_cross_track.hpp
@@ -10,6 +10,7 @@
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+#include <boost/config.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits.hpp>
@@ -18,9 +19,11 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/algorithms/detail/course.hpp>
#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>
@@ -40,10 +43,8 @@ namespace strategy { namespace distance
/*!
\brief Strategy functor for distance point to segment calculation
\ingroup strategies
-\details Class which calculates the distance of a point to a segment, using latlong points
+\details Class which calculates the distance of a point to a segment, for points on a sphere or globe
\see http://williams.best.vwh.net/avform.htm
-\tparam Point point type
-\tparam PointOfSegment \tparam_segment_point
\tparam CalculationType \tparam_calculation
\tparam Strategy underlying point-point distance strategy, defaults to haversine
@@ -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,20 @@ 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
{
+
+#if !defined(BOOST_MSVC)
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::PointDistanceStrategy<Strategy, Point, PointOfSegment>)
+ );
+#endif
+
+ 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);
@@ -111,10 +118,10 @@ public :
return_type d2 = m_strategy.apply(sp2, p);
- return_type crs_AD = course(sp1, p);
- return_type crs_AB = course(sp1, sp2);
+ return_type crs_AD = geometry::detail::course<return_type>(sp1, p);
+ return_type crs_AB = geometry::detail::course<return_type>(sp1, sp2);
return_type crs_BA = crs_AB - geometry::math::pi<return_type>();
- return_type crs_BD = course(sp2, p);
+ return_type crs_BD = geometry::detail::course<return_type>(sp2, p);
return_type d_crs1 = crs_AD - crs_AB;
return_type d_crs2 = crs_BD - crs_BA;
@@ -132,7 +139,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,33 +160,12 @@ 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
- {
- // 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));
-
- // "An alternative formula, not requiring the pre-computation of d"
- return atan2(sin(dlon) * cos_p2lat,
- cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
- - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
- }
-
};
@@ -188,120 +174,65 @@ 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 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,
- typename P,
- typename PS
->
-struct similar_type<cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS>
+template <typename CalculationType, typename Strategy>
+struct comparable_type<cross_track<CalculationType, Strategy> >
{
- typedef cross_track<Point, PointOfSegment, CalculationType, Strategy> type;
+ // There is no shortcut, so the strategy itself is its comparable type
+ typedef cross_track<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 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());
}
};
-template
+template
<
- typename Point, typename PointOfSegment,
- typename CalculationType,
- typename Strategy
+ typename CalculationType,
+ 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
-<
- typename Point, typename PointOfSegment,
- typename CalculationType,
- typename Strategy
->
-struct strategy_point_point<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
-{
- typedef Strategy type;
-};
-
/*
@@ -311,15 +242,13 @@ TODO: spherical polar coordinate system requires "get_as_radian_equatorial<>"
template <typename Point, typename PointOfSegment, typename Strategy>
struct default_strategy
<
- segment_tag, Point, PointOfSegment,
- spherical_polar_tag, spherical_polar_tag,
+ segment_tag, Point, PointOfSegment,
+ spherical_polar_tag, spherical_polar_tag,
Strategy
>
{
typedef cross_track
<
- Point,
- PointOfSegment,
void,
typename boost::mpl::if_
<
@@ -338,22 +267,20 @@ struct default_strategy
template <typename Point, typename PointOfSegment, typename Strategy>
struct default_strategy
<
- segment_tag, Point, PointOfSegment,
- spherical_equatorial_tag, spherical_equatorial_tag,
+ point_tag, segment_tag, Point, PointOfSegment,
+ spherical_equatorial_tag, spherical_equatorial_tag,
Strategy
>
{
typedef cross_track
<
- Point,
- PointOfSegment,
void,
typename boost::mpl::if_
<
boost::is_void<Strategy>,
typename default_strategy
<
- point_tag, Point, PointOfSegment,
+ point_tag, point_tag, Point, PointOfSegment,
spherical_equatorial_tag, spherical_equatorial_tag
>::type,
Strategy
@@ -362,6 +289,22 @@ struct default_strategy
};
+template <typename PointOfSegment, typename Point, typename Strategy>
+struct default_strategy
+ <
+ segment_tag, point_tag, PointOfSegment, Point,
+ spherical_equatorial_tag, spherical_equatorial_tag,
+ Strategy
+ >
+{
+ typedef typename default_strategy
+ <
+ point_tag, segment_tag, Point, PointOfSegment,
+ spherical_equatorial_tag, spherical_equatorial_tag,
+ Strategy
+ >::type type;
+};
+
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS