diff options
Diffstat (limited to 'boost/geometry/strategies/geographic')
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 < |