diff --git a/include/boost/geometry/formulas/distance_point_segment.hpp b/include/boost/geometry/formulas/distance_point_segment.hpp index 83f443ab2..a2f32cd2a 100644 --- a/include/boost/geometry/formulas/distance_point_segment.hpp +++ b/include/boost/geometry/formulas/distance_point_segment.hpp @@ -25,6 +25,8 @@ https://arxiv.org/abs/1102.1215 */ +#define BOOST_GEOMETRY_DISTANCE_POINT_SEGMENT_DEBUG + namespace boost { namespace geometry { namespace formula { @@ -32,15 +34,18 @@ template < typename CT, typename Units, - typename Inverse_type_azimuth, - typename Inverse_type_distance, - typename Direct_type, + template class Inverse, + template class Direct, bool EnableClosestPoint = false > class distance_point_segment{ public: + typedef Inverse inverse_distance_type; + typedef Inverse inverse_azimuth_type; + typedef Direct direct_distance_type; + struct result_distance_point_segment { result_distance_point_segment() @@ -61,7 +66,7 @@ public: Spheroid const& spheroid) { result_distance_point_segment result; - result.distance = Inverse_type_distance::apply(lon1, lat1, + result.distance = inverse_distance_type::apply(lon1, lat1, lon2, lat2, spheroid).distance; if (EnableClosestPoint) @@ -77,10 +82,11 @@ public: static inline apply(CT lon1, CT lat1, //p1 CT lon2, CT lat2, //p2 CT lon3, CT lat3, //query point p3 - Spheroid const& spheroid, - CT earth_radius = - geometry::srs::sphere().get_radius<1>()) + Spheroid const& spheroid) { + CT earth_radius = (CT(2) * spheroid.get_radius<1>() + + spheroid.get_radius<2>()) / CT(3); + result_distance_point_segment result; // Constants @@ -145,8 +151,8 @@ public: } // Compute a1 (GEO) - CT a1 = Inverse_type_azimuth::apply(lon1, lat1, lon2, lat2, spheroid).azimuth; - CT a13 = Inverse_type_azimuth::apply(lon1, lat1, lon3, lat3, spheroid).azimuth; + CT a1 = inverse_azimuth_type::apply(lon1, lat1, lon2, lat2, spheroid).azimuth; + CT a13 = inverse_azimuth_type::apply(lon1, lat1, lon3, lat3, spheroid).azimuth; CT a312 = a1 - a13; @@ -157,8 +163,8 @@ public: return non_iterative_case(lon1, lat1, lon3, lat3, spheroid); } - CT a2 = pi + Inverse_type_azimuth::apply(lon2, lat2, lon1, lat1, spheroid).azimuth; - CT a23 = Inverse_type_azimuth::apply(lon2, lat2, lon3, lat3, spheroid).azimuth; + CT a2 = pi + inverse_azimuth_type::apply(lon2, lat2, lon1, lat1, spheroid).azimuth; + CT a23 = inverse_azimuth_type::apply(lon2, lat2, lon3, lat3, spheroid).azimuth; CT a321 = a2 - a23; @@ -220,13 +226,15 @@ public: prev_distance = res34.distance; // Solve the direct problem to find p4 (GEO) - res14 = Direct_type::apply(lon1, lat1, s14, a1, spheroid); + res14 = direct_distance_type::apply(lon1, lat1, s14, a1, spheroid); // Solve an inverse problem to find g4 // g4 is the angle between segment (p1,p2) and segment (p3,p4) that meet on p4 (GEO) - CT a4 = Inverse_type_azimuth::apply(res14.lon2, res14.lat2, lon2, lat2, spheroid).azimuth; - res34 = Inverse_type_distance::apply(res14.lon2, res14.lat2, lon3, lat3, spheroid); + CT a4 = inverse_azimuth_type::apply(res14.lon2, res14.lat2, + lon2, lat2, spheroid).azimuth; + res34 = inverse_distance_type::apply(res14.lon2, res14.lat2, + lon3, lat3, spheroid); g4 = res34.azimuth - a4; // Normalize g4 @@ -296,20 +304,20 @@ public: std::cout << "s34(sph) =" << s34_sph << std::endl; std::cout << "s34(geo) =" - << Inverse_type_distance::apply(get<0>(p4), get<1>(p4), lon3, lat3, spheroid).distance + << inverse_distance_type::apply(get<0>(p4), get<1>(p4), lon3, lat3, spheroid).distance << ", p4=(" << get<0>(p4) * math::r2d() << "," << get<1>(p4) * math::r2d() << ")" << std::endl; - CT s31 = Inverse_type_distance::apply(lon3, lat3, lon1, lat1, spheroid).distance; - CT s32 = Inverse_type_distance::apply(lon3, lat3, lon2, lat2, spheroid).distance; + CT s31 = inverse_distance_type::apply(lon3, lat3, lon1, lat1, spheroid).distance; + CT s32 = inverse_distance_type::apply(lon3, lat3, lon2, lat2, spheroid).distance; - CT a4 = Inverse_type_azimuth::apply(get<0>(p4), get<1>(p4), lon2, lat2, spheroid).azimuth; - geometry::formula::result_direct res4 = Direct_type::apply(get<0>(p4), get<1>(p4), .04, a4, spheroid); - CT p4_plus = Inverse_type_distance::apply(res4.lon2, res4.lat2, lon3, lat3, spheroid).distance; + CT a4 = inverse_azimuth_type::apply(get<0>(p4), get<1>(p4), lon2, lat2, spheroid).azimuth; + geometry::formula::result_direct res4 = direct_distance_type::apply(get<0>(p4), get<1>(p4), .04, a4, spheroid); + CT p4_plus = inverse_distance_type::apply(res4.lon2, res4.lat2, lon3, lat3, spheroid).distance; - geometry::formula::result_direct res1 = Direct_type::apply(lon1, lat1, s14-.04, a1, spheroid); - CT p4_minus = Inverse_type_distance::apply(res1.lon2, res1.lat2, lon3, lat3, spheroid).distance; + geometry::formula::result_direct res1 = direct_distance_type::apply(lon1, lat1, s14-.04, a1, spheroid); + CT p4_minus = inverse_distance_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() << "," << res4.lat2 * math::r2d() << ")" diff --git a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp index 60ebd54fd..295858f6e 100644 --- a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp @@ -65,7 +65,7 @@ template typename Spheroid = srs::spheroid, typename CalculationType = void > -class cross_track_geo +class geographic_cross_track { public : template @@ -92,7 +92,7 @@ public : return distance_type(m_spheroid); } - explicit cross_track_geo(Spheroid const& spheroid = Spheroid()) + explicit geographic_cross_track(Spheroid const& spheroid = Spheroid()) : m_spheroid(spheroid) {} @@ -104,42 +104,12 @@ public : typedef typename return_type::type CT; - typedef typename FormulaPolicy::template inverse - < - CT, - false, - true, - false, - false, - false - > inverse_type_azimuth; - - typedef typename FormulaPolicy::template inverse - < - CT, - true, - true, - false, - true, - true - > inverse_type_distance; - - typedef typename FormulaPolicy::template direct - < - CT, - true, - false, - false, - false - > direct_type; - return (geometry::formula::distance_point_segment < CT, units_type, - inverse_type_azimuth, - inverse_type_distance, - direct_type + FormulaPolicy::template inverse, + FormulaPolicy::template direct >::apply(get<0>(sp1), get<1>(sp1), get<0>(sp2), get<1>(sp2), get<0>(p), get<1>(p), @@ -159,7 +129,7 @@ namespace services //tags template -struct tag > +struct tag > { typedef strategy_tag_distance_point_segment type; }; @@ -169,7 +139,7 @@ template typename FormulaPolicy, typename Spheroid > -struct tag > +struct tag > { typedef strategy_tag_distance_point_segment type; }; @@ -180,7 +150,7 @@ template typename Spheroid, typename CalculationType > -struct tag > +struct tag > { typedef strategy_tag_distance_point_segment type; }; @@ -188,8 +158,8 @@ struct tag > //return types template -struct return_type, P, PS> - : cross_track_geo::template return_type +struct return_type, P, PS> + : geographic_cross_track::template return_type {}; template @@ -199,8 +169,8 @@ template typename P, typename PS > -struct return_type, P, PS> - : cross_track_geo::template return_type +struct return_type, P, PS> + : geographic_cross_track::template return_type {}; template @@ -211,8 +181,8 @@ template typename P, typename PS > -struct return_type, P, PS> - : cross_track_geo::template return_type +struct return_type, P, PS> + : geographic_cross_track::template return_type {}; //comparable types @@ -222,9 +192,9 @@ template typename Spheroid, typename CalculationType > -struct comparable_type > +struct comparable_type > { - typedef cross_track_geo + typedef geographic_cross_track < FormulaPolicy, Spheroid, CalculationType > type; @@ -236,15 +206,15 @@ template typename Spheroid, typename CalculationType > -struct get_comparable > +struct get_comparable > { typedef typename comparable_type < - cross_track_geo + geographic_cross_track >::type comparable_type; public : static inline comparable_type - apply(cross_track_geo const& strategy) + apply(geographic_cross_track const& strategy) { return comparable_type(); } @@ -257,17 +227,17 @@ template typename P, typename PS > -struct result_from_distance, P, PS> +struct result_from_distance, P, PS> { private : - typedef typename cross_track_geo + typedef typename geographic_cross_track < FormulaPolicy >::template return_type::type return_type; public : template static inline return_type - apply(cross_track_geo const& , T const& distance) + apply(geographic_cross_track const& , T const& distance) { return distance; } @@ -281,7 +251,7 @@ struct default_strategy geographic_tag, geographic_tag > { - typedef cross_track_geo<> type; + typedef geographic_cross_track<> type; }; diff --git a/include/boost/geometry/strategies/geographic/intersection.hpp b/include/boost/geometry/strategies/geographic/intersection.hpp index f4c2c1436..84acd149c 100644 --- a/include/boost/geometry/strategies/geographic/intersection.hpp +++ b/include/boost/geometry/strategies/geographic/intersection.hpp @@ -118,6 +118,7 @@ struct geographic_segments return strategy_type(m_spheroid); } + template struct distance_strategy { typedef distance::geographic @@ -128,9 +129,10 @@ struct geographic_segments > type; }; - inline typename distance_strategy::type get_distance_strategy() const + template + inline typename distance_strategy::type get_distance_strategy() const { - typedef typename distance_strategy::type strategy_type; + typedef typename distance_strategy::type strategy_type; return strategy_type(m_spheroid); } diff --git a/test/algorithms/distance/distance_geo_pl_l.cpp b/test/algorithms/distance/distance_geo_pl_l.cpp index 58cdb3b8b..0e611f065 100644 --- a/test/algorithms/distance/distance_geo_pl_l.cpp +++ b/test/algorithms/distance/distance_geo_pl_l.cpp @@ -40,13 +40,13 @@ typedef bg::strategy::distance::vincenty vincenty_pp; // Strategies for point-segment distance -typedef bg::strategy::distance::cross_track_geo +typedef bg::strategy::distance::geographic_cross_track andoyer_strategy; -typedef bg::strategy::distance::cross_track_geo +typedef bg::strategy::distance::geographic_cross_track thomas_strategy; -typedef bg::strategy::distance::cross_track_geo +typedef bg::strategy::distance::geographic_cross_track vincenty_strategy; //===========================================================================