summaryrefslogtreecommitdiff
path: root/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp')
-rw-r--r--boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp202
1 files changed, 111 insertions, 91 deletions
diff --git a/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp b/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
index ee805c36d1..9c8e7f1a3e 100644
--- a/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
+++ b/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
@@ -4,11 +4,12 @@
// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014, 2015.
-// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014-2017.
+// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -42,92 +43,46 @@ namespace boost { namespace geometry
namespace strategy { namespace distance
{
-
-/*!
-\brief Strategy functor for distance point to box calculation
-\ingroup strategies
-\details Class which calculates the distance of a point to a box, for
-points and boxes on a sphere or globe
-\tparam CalculationType \tparam_calculation
-\tparam Strategy underlying point-segment distance strategy, defaults
-to cross track
-
-\qbk{
-[heading See also]
-[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
-}
-
-*/
-template
-<
- typename CalculationType = void,
- typename Strategy = cross_track<CalculationType>
->
-class cross_track_point_box
+namespace details
{
-public:
- template <typename Point, typename Box>
- struct return_type
- : services::return_type<Strategy, Point, typename point_type<Box>::type>
- {};
-
- typedef typename Strategy::radius_type radius_type;
-
- inline cross_track_point_box()
- {}
-
- explicit inline cross_track_point_box(typename Strategy::radius_type const& r)
- : m_ps_strategy(r)
- {}
-
- inline cross_track_point_box(Strategy const& s)
- : m_ps_strategy(s)
- {}
+template <typename ReturnType>
+class cross_track_point_box_generic
+{
+public :
- // It might be useful in the future
- // to overload constructor with strategy info.
- // crosstrack(...) {}
-
- template <typename Point, typename Box>
- inline typename return_type<Point, Box>::type
- apply(Point const& point, Box const& box) const
+ template
+ <
+ typename Point,
+ typename Box,
+ typename Strategy
+ >
+ ReturnType static inline apply (Point const& point,
+ Box const& box,
+ Strategy ps_strategy)
{
-#if !defined(BOOST_MSVC)
- BOOST_CONCEPT_ASSERT
- (
- (concepts::PointSegmentDistanceStrategy
- <
- Strategy, Point, typename point_type<Box>::type
- >)
- );
-#endif
-
// this method assumes that the coordinates of the point and
// the box are normalized
- typedef typename return_type<Point, Box>::type return_type;
typedef typename point_type<Box>::type box_point_type;
- // TODO: This strategy as well as other cross-track strategies
- // and therefore e.g. spherical within(Point, Box) may not work
- // properly for a Box degenerated to a Segment or Point
-
box_point_type bottom_left, bottom_right, top_left, top_right;
geometry::detail::assign_box_corners(box,
bottom_left, bottom_right,
top_left, top_right);
- return_type const plon = geometry::get_as_radian<0>(point);
- return_type const plat = geometry::get_as_radian<1>(point);
+ ReturnType const plon = geometry::get_as_radian<0>(point);
+ ReturnType const plat = geometry::get_as_radian<1>(point);
- return_type const lon_min = geometry::get_as_radian<0>(bottom_left);
- return_type const lat_min = geometry::get_as_radian<1>(bottom_left);
- return_type const lon_max = geometry::get_as_radian<0>(top_right);
- return_type const lat_max = geometry::get_as_radian<1>(top_right);
+ ReturnType const lon_min = geometry::get_as_radian<0>(bottom_left);
+ ReturnType const lat_min = geometry::get_as_radian<1>(bottom_left);
+ ReturnType const lon_max = geometry::get_as_radian<0>(top_right);
+ ReturnType const lat_max = geometry::get_as_radian<1>(top_right);
- return_type const pi = math::pi<return_type>();
- return_type const two_pi = math::two_pi<return_type>();
+ ReturnType const pi = math::pi<ReturnType>();
+ ReturnType const two_pi = math::two_pi<ReturnType>();
+
+ typedef typename point_type<Box>::type box_point_type;
// First check if the point is within the band defined by the
// minimum and maximum longitude of the box; if yes, determine
@@ -142,22 +97,22 @@ public:
{
if (plat > lat_max)
{
- return services::result_from_distance
- <
- Strategy, Point, box_point_type
- >::apply(m_ps_strategy, radius() * (plat - lat_max));
+ return geometry::strategy::distance::services::result_from_distance
+ <
+ Strategy, Point, box_point_type
+ >::apply(ps_strategy, ps_strategy.get_distance_strategy().meridian(plat, lat_max));
}
else if (plat < lat_min)
{
- return services::result_from_distance
- <
- Strategy, Point, box_point_type
- >::apply(m_ps_strategy, radius() * (lat_min - plat));
+ return geometry::strategy::distance::services::result_from_distance
+ <
+ Strategy, Point, box_point_type
+ >::apply(ps_strategy, ps_strategy.get_distance_strategy().meridian(lat_min, plat));
}
else
{
BOOST_GEOMETRY_ASSERT(plat >= lat_min && plat <= lat_max);
- return return_type(0);
+ return ReturnType(0);
}
}
@@ -169,14 +124,14 @@ public:
// (1) is midway between the meridians of the left and right
// meridians of the box, and
// (2) does not intersect the box
- return_type const two = 2.0;
+ ReturnType const two = 2.0;
bool use_left_segment;
if (lon_max > pi)
{
// the box crosses the antimeridian
// midway longitude = lon_min - (lon_min + (lon_max - 2 * pi)) / 2;
- return_type const lon_midway = (lon_min - lon_max) / two + pi;
+ ReturnType const lon_midway = (lon_min - lon_max) / two + pi;
BOOST_GEOMETRY_ASSERT(lon_midway >= -pi && lon_midway <= pi);
use_left_segment = plon > lon_midway;
@@ -185,8 +140,8 @@ public:
{
// the box does not cross the antimeridian
- return_type const lon_sum = lon_min + lon_max;
- if (math::equals(lon_sum, return_type(0)))
+ ReturnType const lon_sum = lon_min + lon_max;
+ if (math::equals(lon_sum, ReturnType(0)))
{
// special case: the box is symmetric with respect to
// the prime meridian; the midway meridian is the antimeridian
@@ -196,7 +151,7 @@ public:
else
{
// midway long. = lon_min - (2 * pi - (lon_max - lon_min)) / 2;
- return_type lon_midway = (lon_min + lon_max) / two - pi;
+ ReturnType lon_midway = (lon_min + lon_max) / two - pi;
// normalize the midway longitude
if (lon_midway > pi)
@@ -212,14 +167,79 @@ public:
// if lon_sum is positive the midway meridian is left
// of the box, or right of the box otherwise
use_left_segment = lon_sum > 0
- ? (plon < lon_min && plon >= lon_midway)
- : (plon <= lon_max || plon > lon_midway);
+ ? (plon < lon_min && plon >= lon_midway)
+ : (plon <= lon_max || plon > lon_midway);
}
}
return use_left_segment
- ? m_ps_strategy.apply(point, bottom_left, top_left)
- : m_ps_strategy.apply(point, bottom_right, top_right);
+ ? ps_strategy.apply(point, bottom_left, top_left)
+ : ps_strategy.apply(point, bottom_right, top_right);
+ }
+};
+
+} //namespace details
+
+/*!
+\brief Strategy functor for distance point to box calculation
+\ingroup strategies
+\details Class which calculates the distance of a point to a box, for
+points and boxes on a sphere or globe
+\tparam CalculationType \tparam_calculation
+\tparam Strategy underlying point-segment distance strategy, defaults
+to cross track
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+}
+*/
+template
+<
+ typename CalculationType = void,
+ typename Strategy = cross_track<CalculationType>
+>
+class cross_track_point_box
+{
+public:
+ template <typename Point, typename Box>
+ struct return_type
+ : services::return_type<Strategy, Point, typename point_type<Box>::type>
+ {};
+
+ typedef typename Strategy::radius_type radius_type;
+
+ inline cross_track_point_box()
+ {}
+
+ explicit inline cross_track_point_box(typename Strategy::radius_type const& r)
+ : m_ps_strategy(r)
+ {}
+
+ inline cross_track_point_box(Strategy const& s)
+ : m_ps_strategy(s)
+ {}
+
+
+ // It might be useful in the future
+ // to overload constructor with strategy info.
+ // crosstrack(...) {}
+
+ template <typename Point, typename Box>
+ inline typename return_type<Point, Box>::type
+ apply(Point const& point, Box const& box) const
+ {
+#if !defined(BOOST_MSVC)
+ BOOST_CONCEPT_ASSERT
+ (
+ (concepts::PointSegmentDistanceStrategy
+ <
+ Strategy, Point, typename point_type<Box>::type
+ >)
+ );
+#endif
+ typedef typename return_type<Point, Box>::type return_type;
+ return details::cross_track_point_box_generic
+ <return_type>::apply(point, box, m_ps_strategy);
}
inline typename Strategy::radius_type radius() const