summaryrefslogtreecommitdiff
path: root/boost/geometry/strategies/geographic
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/strategies/geographic')
-rw-r--r--boost/geometry/strategies/geographic/area.hpp116
-rw-r--r--boost/geometry/strategies/geographic/azimuth.hpp2
-rw-r--r--boost/geometry/strategies/geographic/densify.hpp136
-rw-r--r--boost/geometry/strategies/geographic/distance.hpp34
-rw-r--r--boost/geometry/strategies/geographic/distance_cross_track.hpp111
-rw-r--r--boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp207
-rw-r--r--boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp218
-rw-r--r--boost/geometry/strategies/geographic/envelope_segment.hpp4
-rw-r--r--boost/geometry/strategies/geographic/intersection.hpp34
-rw-r--r--boost/geometry/strategies/geographic/intersection_elliptic.hpp2
-rw-r--r--boost/geometry/strategies/geographic/side.hpp12
11 files changed, 761 insertions, 115 deletions
diff --git a/boost/geometry/strategies/geographic/area.hpp b/boost/geometry/strategies/geographic/area.hpp
index 40d6c8243e..ac7d933ce7 100644
--- a/boost/geometry/strategies/geographic/area.hpp
+++ b/boost/geometry/strategies/geographic/area.hpp
@@ -1,6 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2016-2017 Oracle and/or its affiliates.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+
+// Copyright (c) 2016-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -12,7 +14,7 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AREA_HPP
-#include <boost/geometry/core/srs.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/formulas/area_formulas.hpp>
#include <boost/geometry/formulas/authalic_radius_sqr.hpp>
@@ -32,7 +34,6 @@ namespace strategy { namespace area
\ingroup strategies
\details Geographic area calculation by trapezoidal rule plus integral
approximation that gives the ellipsoidal correction
-\tparam PointOfSegment \tparam_segment_point
\tparam FormulaPolicy Formula used to calculate azimuths
\tparam SeriesOrder The order of approximation of the geodesic integral
\tparam Spheroid The spheroid model
@@ -43,12 +44,12 @@ namespace strategy { namespace area
\qbk{
[heading See also]
-[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
+\* [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
+\* [link geometry.reference.srs.srs_spheroid srs::spheroid]
}
*/
template
<
- typename PointOfSegment,
typename FormulaPolicy = strategy::andoyer,
std::size_t SeriesOrder = strategy::default_order<FormulaPolicy>::value,
typename Spheroid = srs::spheroid<double>,
@@ -63,58 +64,67 @@ class geographic
//Select default types in case they are not set
- typedef typename boost::mpl::if_c
- <
- boost::is_void<CalculationType>::type::value,
- typename select_most_precise
+public:
+ template <typename Geometry>
+ struct result_type
+ : strategy::area::detail::result_type
<
- typename coordinate_type<PointOfSegment>::type,
- double
- >::type,
- CalculationType
- >::type CT;
+ Geometry,
+ CalculationType
+ >
+ {};
protected :
struct spheroid_constants
{
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_void<CalculationType>::value,
+ typename geometry::radius_type<Spheroid>::type,
+ CalculationType
+ >::type calc_t;
+
Spheroid m_spheroid;
- CT const m_a2; // squared equatorial radius
- CT const m_e2; // squared eccentricity
- CT const m_ep2; // squared second eccentricity
- CT const m_ep; // second eccentricity
- CT const m_c2; // squared authalic radius
+ calc_t const m_a2; // squared equatorial radius
+ calc_t const m_e2; // squared eccentricity
+ calc_t const m_ep2; // squared second eccentricity
+ calc_t const m_ep; // second eccentricity
+ calc_t const m_c2; // squared authalic radius
inline spheroid_constants(Spheroid const& spheroid)
: m_spheroid(spheroid)
, m_a2(math::sqr(get_radius<0>(spheroid)))
- , m_e2(formula::eccentricity_sqr<CT>(spheroid))
- , m_ep2(m_e2 / (CT(1.0) - m_e2))
+ , m_e2(formula::eccentricity_sqr<calc_t>(spheroid))
+ , m_ep2(m_e2 / (calc_t(1.0) - m_e2))
, m_ep(math::sqrt(m_ep2))
, m_c2(formula_dispatch::authalic_radius_sqr
<
- CT, Spheroid, srs_spheroid_tag
+ calc_t, Spheroid, srs_spheroid_tag
>::apply(m_a2, m_e2))
{}
};
- struct area_sums
+public:
+ template <typename Geometry>
+ class state
{
- CT m_excess_sum;
- CT m_correction_sum;
+ friend class geographic;
- // Keep track if encircles some pole
- std::size_t m_crosses_prime_meridian;
+ typedef typename result_type<Geometry>::type return_type;
- inline area_sums()
+ public:
+ inline state()
: m_excess_sum(0)
, m_correction_sum(0)
, m_crosses_prime_meridian(0)
{}
- inline CT area(spheroid_constants spheroid_const) const
+
+ private:
+ inline return_type area(spheroid_constants const& spheroid_const) const
{
- CT result;
+ return_type result;
- CT sum = spheroid_const.m_c2 * m_excess_sum
+ return_type sum = spheroid_const.m_c2 * m_excess_sum
+ spheroid_const.m_e2 * spheroid_const.m_a2 * m_correction_sum;
// If encircles some pole
@@ -123,13 +133,13 @@ protected :
std::size_t times_crosses_prime_meridian
= 1 + (m_crosses_prime_meridian / 2);
- result = CT(2.0)
- * geometry::math::pi<CT>()
+ result = return_type(2.0)
+ * geometry::math::pi<return_type>()
* spheroid_const.m_c2
- * CT(times_crosses_prime_meridian)
+ * return_type(times_crosses_prime_meridian)
- geometry::math::abs(sum);
- if (geometry::math::sign<CT>(sum) == 1)
+ if (geometry::math::sign<return_type>(sum) == 1)
{
result = - result;
}
@@ -142,48 +152,52 @@ protected :
return result;
}
+
+ return_type m_excess_sum;
+ return_type m_correction_sum;
+
+ // Keep track if encircles some pole
+ std::size_t m_crosses_prime_meridian;
};
public :
- typedef CT return_type;
- typedef PointOfSegment segment_point_type;
- typedef area_sums state_type;
-
explicit inline geographic(Spheroid const& spheroid = Spheroid())
: m_spheroid_constants(spheroid)
{}
+ template <typename PointOfSegment, typename Geometry>
inline void apply(PointOfSegment const& p1,
PointOfSegment const& p2,
- area_sums& state) const
+ state<Geometry>& st) const
{
-
if (! geometry::math::equals(get<0>(p1), get<0>(p2)))
{
-
typedef geometry::formula::area_formulas
<
- CT, SeriesOrder, ExpandEpsN
+ typename result_type<Geometry>::type,
+ SeriesOrder, ExpandEpsN
> area_formulas;
typename area_formulas::return_type_ellipsoidal result =
area_formulas::template ellipsoidal<FormulaPolicy::template inverse>
(p1, p2, m_spheroid_constants);
- state.m_excess_sum += result.spherical_term;
- state.m_correction_sum += result.ellipsoidal_term;
+ st.m_excess_sum += result.spherical_term;
+ st.m_correction_sum += result.ellipsoidal_term;
// Keep track whenever a segment crosses the prime meridian
if (area_formulas::crosses_prime_meridian(p1, p2))
{
- state.m_crosses_prime_meridian++;
+ st.m_crosses_prime_meridian++;
}
}
}
- inline return_type result(area_sums const& state) const
+ template <typename Geometry>
+ inline typename result_type<Geometry>::type
+ result(state<Geometry> const& st) const
{
- return state.area(m_spheroid_constants);
+ return st.area(m_spheroid_constants);
}
private:
@@ -197,10 +211,10 @@ namespace services
{
-template <typename Point>
-struct default_strategy<geographic_tag, Point>
+template <>
+struct default_strategy<geographic_tag>
{
- typedef strategy::area::geographic<Point> type;
+ typedef strategy::area::geographic<> type;
};
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
diff --git a/boost/geometry/strategies/geographic/azimuth.hpp b/boost/geometry/strategies/geographic/azimuth.hpp
index 79c49750fb..b918caccea 100644
--- a/boost/geometry/strategies/geographic/azimuth.hpp
+++ b/boost/geometry/strategies/geographic/azimuth.hpp
@@ -12,7 +12,7 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AZIMUTH_HPP
-#include <boost/geometry/core/srs.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
diff --git a/boost/geometry/strategies/geographic/densify.hpp b/boost/geometry/strategies/geographic/densify.hpp
new file mode 100644
index 0000000000..a31ba72200
--- /dev/null
+++ b/boost/geometry/strategies/geographic/densify.hpp
@@ -0,0 +1,136 @@
+// Boost.Geometry
+
+// Copyright (c) 2017-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DENSIFY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DENSIFY_HPP
+
+
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/geometry/strategies/densify.hpp>
+#include <boost/geometry/strategies/geographic/parameters.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace densify
+{
+
+
+/*!
+\brief Densification of geographic segment.
+\ingroup strategies
+\tparam FormulaPolicy The geodesic formulas used internally.
+\tparam Spheroid The spheroid model.
+\tparam CalculationType \tparam_calculation
+
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.densify.densify_4_with_strategy densify (with strategy)]
+\* [link geometry.reference.srs.srs_spheroid srs::spheroid]
+}
+ */
+template
+<
+ typename FormulaPolicy = strategy::andoyer,
+ typename Spheroid = srs::spheroid<double>,
+ typename CalculationType = void
+>
+class geographic
+{
+public:
+ geographic()
+ : m_spheroid()
+ {}
+
+ explicit geographic(Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {}
+
+ template <typename Point, typename AssignPolicy, typename T>
+ inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) const
+ {
+ typedef typename AssignPolicy::point_type out_point_t;
+ typedef typename select_most_precise
+ <
+ typename coordinate_type<Point>::type,
+ typename coordinate_type<out_point_t>::type,
+ CalculationType
+ >::type calc_t;
+
+ typedef typename FormulaPolicy::template direct<calc_t, true, false, false, false> direct_t;
+ typedef typename FormulaPolicy::template inverse<calc_t, true, true, false, false, false> inverse_t;
+
+ typename inverse_t::result_type
+ inv_r = inverse_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0),
+ get_as_radian<0>(p1), get_as_radian<1>(p1),
+ m_spheroid);
+
+ BOOST_GEOMETRY_ASSERT(length_threshold > T(0));
+
+ signed_size_type n = signed_size_type(inv_r.distance / length_threshold);
+ if (n <= 0)
+ return;
+
+ calc_t step = inv_r.distance / (n + 1);
+
+ calc_t current = step;
+ for (signed_size_type i = 0 ; i < n ; ++i, current += step)
+ {
+ typename direct_t::result_type
+ dir_r = direct_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0),
+ current, inv_r.azimuth,
+ m_spheroid);
+
+ out_point_t p;
+ set_from_radian<0>(p, dir_r.lon2);
+ set_from_radian<1>(p, dir_r.lat2);
+ geometry::detail::conversion::point_to_point
+ <
+ Point, out_point_t,
+ 2, dimension<out_point_t>::value
+ >::apply(p0, p);
+
+ policy.apply(p);
+ }
+ }
+
+private:
+ Spheroid m_spheroid;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <>
+struct default_strategy<geographic_tag>
+{
+ typedef strategy::densify::geographic<> type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::densify
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP
diff --git a/boost/geometry/strategies/geographic/distance.hpp b/boost/geometry/strategies/geographic/distance.hpp
index 98ee46a369..01f766c10e 100644
--- a/boost/geometry/strategies/geographic/distance.hpp
+++ b/boost/geometry/strategies/geographic/distance.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014-2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014-2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -20,12 +20,13 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
-#include <boost/geometry/core/srs.hpp>
#include <boost/geometry/formulas/andoyer_inverse.hpp>
#include <boost/geometry/formulas/elliptic_arc_length.hpp>
#include <boost/geometry/formulas/flattening.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
@@ -34,6 +35,7 @@
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
namespace boost { namespace geometry
{
@@ -41,6 +43,19 @@ namespace boost { namespace geometry
namespace strategy { namespace distance
{
+/*!
+\brief Distance calculation for geographic coordinates on a spheroid
+\ingroup strategies
+\tparam FormulaPolicy Formula used to calculate azimuths
+\tparam Spheroid The spheroid model
+\tparam CalculationType \tparam_calculation
+
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+\* [link geometry.reference.srs.srs_spheroid srs::spheroid]
+}
+*/
template
<
typename FormulaPolicy = strategy::andoyer,
@@ -110,6 +125,19 @@ public :
return apply(lon1, lat1, lon2, lat2, m_spheroid);
}
+ // points on a meridian not crossing poles
+ template <typename CT>
+ inline CT meridian(CT lat1, CT lat2) const
+ {
+ typedef typename formula::elliptic_arc_length
+ <
+ CT, strategy::default_order<FormulaPolicy>::value
+ > elliptic_arc_length;
+
+ return elliptic_arc_length::meridian_not_crossing_pole_dist(lat1, lat2,
+ m_spheroid);
+ }
+
inline Spheroid const& model() const
{
return m_spheroid;
diff --git a/boost/geometry/strategies/geographic/distance_cross_track.hpp b/boost/geometry/strategies/geographic/distance_cross_track.hpp
index 799208a96d..be930a3fd4 100644
--- a/boost/geometry/strategies/geographic/distance_cross_track.hpp
+++ b/boost/geometry/strategies/geographic/distance_cross_track.hpp
@@ -40,7 +40,7 @@
#include <boost/geometry/formulas/mean_radius.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
-# include <boost/geometry/io/dsv/write.hpp>
+#include <boost/geometry/io/dsv/write.hpp>
#endif
#ifndef BOOST_GEOMETRY_DETAIL_POINT_SEGMENT_DISTANCE_MAX_STEPS
@@ -165,19 +165,29 @@ private :
}
template <typename CT>
- CT static inline normalize(CT g4)
+ CT static inline normalize(CT g4, CT& der)
{
CT const pi = math::pi<CT>();
- if (g4 < 0 && g4 < -pi)//close to -270
+ if (g4 < -1.25*pi)//close to -270
{
+#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
+ std::cout << "g4=" << g4 << ", close to -270" << std::endl;
+#endif
return g4 + 1.5 * pi;
}
- else if (g4 > 0 && g4 > pi)//close to 270
+ else if (g4 > 1.25*pi)//close to 270
{
+#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
+ std::cout << "g4=" << g4 << ", close to 270" << std::endl;
+#endif
return - g4 + 1.5 * pi;
}
- else if (g4 < 0 && g4 > -pi)//close to -90
+ else if (g4 < 0 && g4 > -0.75*pi)//close to -90
{
+#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
+ std::cout << "g4=" << g4 << ", close to -90" << std::endl;
+#endif
+ der = -der;
return -g4 - pi/2;
}
return g4 - pi/2;
@@ -190,8 +200,8 @@ private :
CT lon3, CT lat3, //query point p3
Spheroid const& spheroid)
{
- typedef typename FormulaPolicy::template inverse<CT, true, false, false, true, true>
- inverse_distance_quantities_type;
+ typedef typename FormulaPolicy::template inverse<CT, true, true, false, true, true>
+ inverse_distance_azimuth_quantities_type;
typedef typename FormulaPolicy::template inverse<CT, false, true, false, false, false>
inverse_azimuth_type;
typedef typename FormulaPolicy::template inverse<CT, false, true, true, false, false>
@@ -204,7 +214,7 @@ private :
result_distance_point_segment<CT> result;
// Constants
- CT const f = geometry::formula::flattening<CT>(spheroid);
+ //CT const f = geometry::formula::flattening<CT>(spheroid);
CT const pi = math::pi<CT>();
CT const half_pi = pi / CT(2);
CT const c0 = CT(0);
@@ -227,11 +237,28 @@ private :
//Note: antipodal points on equator does not define segment on equator
//but pass by the pole
CT diff = geometry::math::longitude_distance_signed<geometry::radian>(lon1, lon2);
- if (math::equals(lat1, c0) && math::equals(lat2, c0)
- && !math::equals(math::abs(diff), pi))
+
+ typedef typename formula::elliptic_arc_length<CT> elliptic_arc_length;
+
+ bool meridian_not_crossing_pole =
+ elliptic_arc_length::meridian_not_crossing_pole(lat1, lat2, diff);
+
+ bool meridian_crossing_pole =
+ elliptic_arc_length::meridian_crossing_pole(diff);
+
+ //bool meridian_crossing_pole = math::equals(math::abs(diff), pi);
+ //bool meridian_not_crossing_pole = math::equals(math::abs(diff), c0);
+
+ if (math::equals(lat1, c0) && math::equals(lat2, c0) && !meridian_crossing_pole)
{
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
std::cout << "Equatorial segment" << std::endl;
+ std::cout << "segment=(" << lon1 * math::r2d<CT>();
+ std::cout << "," << lat1 * math::r2d<CT>();
+ std::cout << "),(" << lon2 * math::r2d<CT>();
+ std::cout << "," << lat2 * math::r2d<CT>();
+ std::cout << ")\np=(" << lon3 * math::r2d<CT>();
+ std::cout << "," << lat3 * math::r2d<CT>() << ")\n";
#endif
if (lon3 <= lon1)
{
@@ -244,7 +271,12 @@ private :
return non_iterative_case(lon3, lat1, lon3, lat3, spheroid);
}
- if (math::equals(math::abs(diff), pi))
+ if ( (meridian_not_crossing_pole || meridian_crossing_pole ) && lat1 > lat2)
+ {
+ std::swap(lat1,lat2);
+ }
+
+ if (meridian_crossing_pole)
{
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
std::cout << "Meridian segment" << std::endl;
@@ -349,12 +381,9 @@ private :
geometry::cs::spherical_equatorial<geometry::radian>
> point;
- CT bet1 = atan((1 - f) * tan(lon1));
- CT bet2 = atan((1 - f) * tan(lon2));
- CT bet3 = atan((1 - f) * tan(lon3));
- point p1 = point(bet1, lat1);
- point p2 = point(bet2, lat2);
- point p3 = point(bet3, lat3);
+ point p1 = point(lon1, lat1);
+ point p2 = point(lon2, lat2);
+ point p3 = point(lon3, lat3);
geometry::strategy::distance::cross_track<CT> cross_track(earth_radius);
CT s34 = cross_track.apply(p3, p1, p2);
@@ -390,22 +419,28 @@ private :
CT a4 = inverse_azimuth_type::apply(res14.lon2, res14.lat2,
lon2, lat2, spheroid).azimuth;
- res34 = inverse_distance_quantities_type::apply(res14.lon2, res14.lat2,
- lon3, lat3, spheroid);
+ res34 = inverse_distance_azimuth_quantities_type::apply(res14.lon2, res14.lat2,
+ lon3, lat3, spheroid);
g4 = res34.azimuth - a4;
- delta_g4 = normalize(g4);
+
CT M43 = res34.geodesic_scale; // cos(s14/earth_radius) is the spherical limit
CT m34 = res34.reduced_length;
CT der = (M43 / m34) * sin(g4);
+
+ // normalize (g4 - pi/2)
+ delta_g4 = normalize(g4, der);
+
s14 = s14 - delta_g4 / der;
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
std::cout << "p4=" << res14.lon2 * math::r2d<CT>() <<
"," << res14.lat2 * math::r2d<CT>() << std::endl;
- std::cout << "delta_g4=" << delta_g4 << std::endl;
+ std::cout << "a34=" << res34.azimuth * math::r2d<CT>() << std::endl;
+ std::cout << "a4=" << a4 * math::r2d<CT>() << std::endl;
std::cout << "g4=" << g4 * math::r2d<CT>() << std::endl;
+ std::cout << "delta_g4=" << delta_g4 * math::r2d<CT>() << std::endl;
std::cout << "der=" << der << std::endl;
std::cout << "M43=" << M43 << std::endl;
std::cout << "spherical limit=" << cos(s14/earth_radius) << std::endl;
@@ -448,20 +483,20 @@ private :
std::cout << "s34(sph) =" << s34_sph << std::endl;
std::cout << "s34(geo) ="
- << inverse_distance_quantities_type::apply(get<0>(p4), get<1>(p4), lon3, lat3, spheroid).distance
+ << inverse_distance_azimuth_quantities_type::apply(get<0>(p4), get<1>(p4), lon3, lat3, spheroid).distance
<< ", p4=(" << get<0>(p4) * math::r2d<double>() << ","
<< get<1>(p4) * math::r2d<double>() << ")"
<< std::endl;
- CT s31 = inverse_distance_quantities_type::apply(lon3, lat3, lon1, lat1, spheroid).distance;
- CT s32 = inverse_distance_quantities_type::apply(lon3, lat3, lon2, lat2, spheroid).distance;
+ CT s31 = inverse_distance_azimuth_quantities_type::apply(lon3, lat3, lon1, lat1, spheroid).distance;
+ CT s32 = inverse_distance_azimuth_quantities_type::apply(lon3, lat3, lon2, lat2, spheroid).distance;
CT a4 = inverse_azimuth_type::apply(get<0>(p4), get<1>(p4), lon2, lat2, spheroid).azimuth;
geometry::formula::result_direct<CT> res4 = direct_distance_type::apply(get<0>(p4), get<1>(p4), .04, a4, spheroid);
- CT p4_plus = inverse_distance_quantities_type::apply(res4.lon2, res4.lat2, lon3, lat3, spheroid).distance;
+ CT p4_plus = inverse_distance_azimuth_quantities_type::apply(res4.lon2, res4.lat2, lon3, lat3, spheroid).distance;
geometry::formula::result_direct<CT> res1 = direct_distance_type::apply(lon1, lat1, s14-.04, a12, spheroid);
- CT p4_minus = inverse_distance_quantities_type::apply(res1.lon2, res1.lat2, lon3, lat3, spheroid).distance;
+ CT p4_minus = inverse_distance_azimuth_quantities_type::apply(res1.lon2, res1.lat2, lon3, lat3, spheroid).distance;
std::cout << "s31=" << s31 << "\ns32=" << s32
<< "\np4_plus=" << p4_plus << ", p4=(" << res4.lon2 * math::r2d<double>() << "," << res4.lat2 * math::r2d<double>() << ")"
@@ -606,6 +641,30 @@ public :
}
};
+template
+<
+ typename FormulaPolicy,
+ typename Spheroid,
+ typename CalculationType,
+ typename P,
+ typename PS
+>
+struct result_from_distance<geographic_cross_track<FormulaPolicy, Spheroid, CalculationType>, P, PS>
+{
+private :
+ typedef typename geographic_cross_track
+ <
+ FormulaPolicy, Spheroid, CalculationType
+ >::template return_type<P, PS>::type return_type;
+public :
+ template <typename T>
+ static inline return_type
+ apply(geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> const& , T const& distance)
+ {
+ return distance;
+ }
+};
+
template <typename Point, typename PointOfSegment>
struct default_strategy
diff --git a/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp b/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp
new file mode 100644
index 0000000000..4f6b3b45b7
--- /dev/null
+++ b/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp
@@ -0,0 +1,207 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2017-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_BOX_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_BOX_BOX_HPP
+
+#include <boost/config.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_void.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
+
+
+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 FormulaPolicy = strategy::andoyer,
+ typename Spheroid = srs::spheroid<double>,
+ typename CalculationType = void
+>
+class geographic_cross_track_box_box
+{
+public:
+ typedef geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> Strategy;
+
+ template <typename Box1, typename Box2>
+ struct return_type
+ : services::return_type<Strategy, typename point_type<Box1>::type, typename point_type<Box2>::type>
+ {};
+
+ inline geographic_cross_track_box_box()
+ {}
+
+ template <typename Box1, typename Box2>
+ inline typename return_type<Box1, Box2>::type
+ apply(Box1 const& box1, Box2 const& box2) const
+ {
+/*
+#if !defined(BOOST_MSVC)
+ BOOST_CONCEPT_ASSERT
+ (
+ (concepts::PointSegmentDistanceStrategy
+ <
+ Strategy,
+ typename point_type<Box1>::type,
+ typename point_type<Box2>::type
+ >)
+ );
+#endif
+*/
+ typedef typename return_type<Box1, Box2>::type return_type;
+ return details::cross_track_box_box_generic
+ <return_type>::apply(box1, box2, Strategy());
+ }
+};
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Strategy, typename Spheroid, typename CalculationType>
+struct tag<geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> >
+{
+ typedef strategy_tag_distance_box_box type;
+};
+
+
+template <typename Strategy, typename Spheroid, typename CalculationType, typename Box1, typename Box2>
+struct return_type<geographic_cross_track_box_box<Strategy, Spheroid, CalculationType>, Box1, Box2>
+ : geographic_cross_track_box_box
+ <
+ Strategy, Spheroid, CalculationType
+ >::template return_type<Box1, Box2>
+{};
+
+template <typename Strategy, typename Spheroid, typename Box1, typename Box2>
+struct return_type<geographic_cross_track_box_box<Strategy, Spheroid>, Box1, Box2>
+ : geographic_cross_track_box_box
+ <
+ Strategy, Spheroid
+ >::template return_type<Box1, Box2>
+{};
+
+template <typename Strategy, typename Box1, typename Box2>
+struct return_type<geographic_cross_track_box_box<Strategy>, Box1, Box2>
+ : geographic_cross_track_box_box
+ <
+ Strategy
+ >::template return_type<Box1, Box2>
+{};
+
+template <typename Strategy, typename Spheroid, typename CalculationType>
+struct comparable_type<geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> >
+{
+ typedef geographic_cross_track_box_box
+ <
+ typename comparable_type<Strategy>::type, Spheroid, CalculationType
+ > type;
+};
+
+
+template <typename Strategy, typename Spheroid, typename CalculationType>
+struct get_comparable<geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> >
+{
+ typedef geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> this_strategy;
+ typedef typename comparable_type<this_strategy>::type comparable_type;
+
+public:
+ static inline comparable_type apply(this_strategy const& /*strategy*/)
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Strategy, typename Spheroid, typename CalculationType, typename Box1, typename Box2>
+struct result_from_distance
+ <
+ geographic_cross_track_box_box<Strategy, Spheroid, CalculationType>, Box1, Box2
+ >
+{
+private:
+ typedef geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> this_strategy;
+
+ typedef typename this_strategy::template return_type
+ <
+ Box1, Box2
+ >::type return_type;
+
+public:
+ template <typename T>
+ static inline return_type apply(this_strategy const& strategy,
+ T const& distance)
+ {
+ result_from_distance
+ <
+ Strategy,
+ typename point_type<Box1>::type,
+ typename point_type<Box2>::type
+ >::apply(strategy, distance);
+ }
+};
+
+template <typename Box1, typename Box2>
+struct default_strategy
+ <
+ box_tag, box_tag, Box1, Box2,
+ geographic_tag, geographic_tag
+ >
+{
+ typedef geographic_cross_track_box_box<> type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_BOX_BOX_HPP
diff --git a/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp b/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp
new file mode 100644
index 0000000000..016427428c
--- /dev/null
+++ b/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp
@@ -0,0 +1,218 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2017-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
+
+#include <boost/config.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_void.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
+#include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
+
+
+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 FormulaPolicy = strategy::andoyer,
+ typename Spheroid = srs::spheroid<double>,
+ typename CalculationType = void
+>
+class geographic_cross_track_point_box
+{
+public:
+ typedef geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> Strategy;
+
+ template <typename Point, typename Box>
+ struct return_type
+ : services::return_type<Strategy, Point, typename point_type<Box>::type>
+ {};
+
+ inline geographic_cross_track_point_box()
+ {}
+
+ 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, Strategy());
+ }
+};
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Strategy, typename Spheroid, typename CalculationType>
+struct tag<geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> >
+{
+ typedef strategy_tag_distance_point_box type;
+};
+
+
+template <typename Strategy, typename Spheroid, typename CalculationType, typename P, typename Box>
+struct return_type<geographic_cross_track_point_box<Strategy, Spheroid, CalculationType>, P, Box>
+ : geographic_cross_track_point_box
+ <
+ Strategy, Spheroid, CalculationType
+ >::template return_type<P, Box>
+{};
+
+template <typename Strategy, typename Spheroid, typename P, typename Box>
+struct return_type<geographic_cross_track_point_box<Strategy, Spheroid>, P, Box>
+ : geographic_cross_track_point_box
+ <
+ Strategy, Spheroid
+ >::template return_type<P, Box>
+{};
+
+template <typename Strategy, typename P, typename Box>
+struct return_type<geographic_cross_track_point_box<Strategy>, P, Box>
+ : geographic_cross_track_point_box
+ <
+ Strategy
+ >::template return_type<P, Box>
+{};
+
+template <typename Strategy, typename Spheroid, typename CalculationType>
+struct comparable_type<geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> >
+{
+ typedef geographic_cross_track_point_box
+ <
+ Strategy, Spheroid, CalculationType
+ > type;
+};
+
+
+template <typename Strategy, typename Spheroid, typename CalculationType>
+struct get_comparable<geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> >
+{
+ typedef geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> this_strategy;
+ typedef typename comparable_type<this_strategy>::type comparable_type;
+
+public:
+ static inline comparable_type apply(this_strategy const&)
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Strategy, typename Spheroid, typename CalculationType, typename P, typename Box>
+struct result_from_distance
+ <
+ geographic_cross_track_point_box<Strategy, Spheroid, CalculationType>, P, Box
+ >
+{
+private:
+ typedef geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> this_strategy;
+
+ typedef typename this_strategy::template return_type
+ <
+ P, Box
+ >::type return_type;
+
+public:
+ template <typename T>
+ static inline return_type apply(this_strategy const& strategy,
+ T const& distance)
+ {
+ result_from_distance
+ <
+ Strategy, P, typename point_type<Box>::type
+ >::apply(strategy, distance);
+ }
+};
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag, Point, Box,
+ geographic_tag, geographic_tag
+ >
+{
+ typedef geographic_cross_track_point_box<> type;
+};
+
+template <typename Box, typename Point>
+struct default_strategy
+ <
+ box_tag, point_tag, Box, Point,
+ geographic_tag, geographic_tag
+ >
+{
+ typedef typename default_strategy
+ <
+ point_tag, box_tag, Point, Box,
+ geographic_tag, geographic_tag
+ >::type type;
+};
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
diff --git a/boost/geometry/strategies/geographic/envelope_segment.hpp b/boost/geometry/strategies/geographic/envelope_segment.hpp
index 3641b39428..5bada63f63 100644
--- a/boost/geometry/strategies/geographic/envelope_segment.hpp
+++ b/boost/geometry/strategies/geographic/envelope_segment.hpp
@@ -14,7 +14,9 @@
#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
-#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/srs/spheroid.hpp>
+
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
diff --git a/boost/geometry/strategies/geographic/intersection.hpp b/boost/geometry/strategies/geographic/intersection.hpp
index e91659d40e..b017097f3e 100644
--- a/boost/geometry/strategies/geographic/intersection.hpp
+++ b/boost/geometry/strategies/geographic/intersection.hpp
@@ -1,5 +1,7 @@
// Boost.Geometry
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+
// Copyright (c) 2016-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,7 +17,6 @@
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
-#include <boost/geometry/core/srs.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/assign_values.hpp>
@@ -33,6 +34,8 @@
#include <boost/geometry/policies/robustness/segment_ratio.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+
#include <boost/geometry/strategies/geographic/area.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
@@ -106,7 +109,6 @@ struct geographic_segments
{
typedef area::geographic
<
- typename point_type<Geometry>::type,
FormulaPolicy,
Order,
Spheroid,
@@ -152,34 +154,8 @@ struct geographic_segments
template <typename CoordinateType, typename SegmentRatio>
struct segment_intersection_info
{
- typedef typename select_most_precise
- <
- CoordinateType, double
- >::type promoted_type;
-
- promoted_type comparable_length_a() const
- {
- return robust_ra.denominator();
- }
-
- promoted_type comparable_length_b() const
- {
- return robust_rb.denominator();
- }
-
- template <typename Point, typename Segment1, typename Segment2>
- void assign_a(Point& point, Segment1 const& a, Segment2 const& b) const
- {
- assign(point, a, b);
- }
- template <typename Point, typename Segment1, typename Segment2>
- void assign_b(Point& point, Segment1 const& a, Segment2 const& b) const
- {
- assign(point, a, b);
- }
-
template <typename Point, typename Segment1, typename Segment2>
- void assign(Point& point, Segment1 const& a, Segment2 const& b) const
+ void calculate(Point& point, Segment1 const& a, Segment2 const& b) const
{
if (ip_flag == ipi_inters)
{
diff --git a/boost/geometry/strategies/geographic/intersection_elliptic.hpp b/boost/geometry/strategies/geographic/intersection_elliptic.hpp
index 76e9940fe3..fce9735255 100644
--- a/boost/geometry/strategies/geographic/intersection_elliptic.hpp
+++ b/boost/geometry/strategies/geographic/intersection_elliptic.hpp
@@ -11,7 +11,7 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
-#include <boost/geometry/core/srs.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/formulas/geographic.hpp>
diff --git a/boost/geometry/strategies/geographic/side.hpp b/boost/geometry/strategies/geographic/side.hpp
index 9276965a97..1201dc2f6d 100644
--- a/boost/geometry/strategies/geographic/side.hpp
+++ b/boost/geometry/strategies/geographic/side.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014-2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014-2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -18,10 +18,11 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
-#include <boost/geometry/core/srs.hpp>
#include <boost/geometry/formulas/spherical.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
@@ -48,6 +49,11 @@ namespace strategy { namespace side
\tparam FormulaPolicy Geodesic solution formula policy.
\tparam Spheroid Reference model of coordinate system.
\tparam CalculationType \tparam_calculation
+
+\qbk{
+[heading See also]
+[link geometry.reference.srs.srs_spheroid srs::spheroid]
+}
*/
template
<