mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-27 17:12:10 +00:00
[formulas] [strategies] [distance] Change interface and earth radius in distance point segment geographic formula
This commit is contained in:
@@ -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 <typename, bool, bool, bool, bool ,bool> class Inverse,
|
||||
template <typename, bool, bool, bool, bool> class Direct,
|
||||
bool EnableClosestPoint = false
|
||||
>
|
||||
class distance_point_segment{
|
||||
|
||||
public:
|
||||
|
||||
typedef Inverse<CT, true, false, false, false, false> inverse_distance_type;
|
||||
typedef Inverse<CT, false, true, false, false, false> inverse_azimuth_type;
|
||||
typedef Direct<CT, true, false, false, false> 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<CT>().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<double>() << ","
|
||||
<< get<1>(p4) * math::r2d<double>() << ")"
|
||||
<< 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<CT> 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<CT> 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<CT> 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<CT> 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<double>() << "," << res4.lat2 * math::r2d<double>() << ")"
|
||||
|
||||
@@ -65,7 +65,7 @@ template
|
||||
typename Spheroid = srs::spheroid<double>,
|
||||
typename CalculationType = void
|
||||
>
|
||||
class cross_track_geo
|
||||
class geographic_cross_track
|
||||
{
|
||||
public :
|
||||
template <typename Point, typename PointOfSegment>
|
||||
@@ -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<Point, PointOfSegment>::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 <typename FormulaPolicy>
|
||||
struct tag<cross_track_geo<FormulaPolicy> >
|
||||
struct tag<geographic_cross_track<FormulaPolicy> >
|
||||
{
|
||||
typedef strategy_tag_distance_point_segment type;
|
||||
};
|
||||
@@ -169,7 +139,7 @@ template
|
||||
typename FormulaPolicy,
|
||||
typename Spheroid
|
||||
>
|
||||
struct tag<cross_track_geo<FormulaPolicy, Spheroid> >
|
||||
struct tag<geographic_cross_track<FormulaPolicy, Spheroid> >
|
||||
{
|
||||
typedef strategy_tag_distance_point_segment type;
|
||||
};
|
||||
@@ -180,7 +150,7 @@ template
|
||||
typename Spheroid,
|
||||
typename CalculationType
|
||||
>
|
||||
struct tag<cross_track_geo<FormulaPolicy, Spheroid, CalculationType> >
|
||||
struct tag<geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> >
|
||||
{
|
||||
typedef strategy_tag_distance_point_segment type;
|
||||
};
|
||||
@@ -188,8 +158,8 @@ struct tag<cross_track_geo<FormulaPolicy, Spheroid, CalculationType> >
|
||||
|
||||
//return types
|
||||
template <typename FormulaPolicy, typename P, typename PS>
|
||||
struct return_type<cross_track_geo<FormulaPolicy>, P, PS>
|
||||
: cross_track_geo<FormulaPolicy>::template return_type<P, PS>
|
||||
struct return_type<geographic_cross_track<FormulaPolicy>, P, PS>
|
||||
: geographic_cross_track<FormulaPolicy>::template return_type<P, PS>
|
||||
{};
|
||||
|
||||
template
|
||||
@@ -199,8 +169,8 @@ template
|
||||
typename P,
|
||||
typename PS
|
||||
>
|
||||
struct return_type<cross_track_geo<FormulaPolicy, Spheroid>, P, PS>
|
||||
: cross_track_geo<FormulaPolicy, Spheroid>::template return_type<P, PS>
|
||||
struct return_type<geographic_cross_track<FormulaPolicy, Spheroid>, P, PS>
|
||||
: geographic_cross_track<FormulaPolicy, Spheroid>::template return_type<P, PS>
|
||||
{};
|
||||
|
||||
template
|
||||
@@ -211,8 +181,8 @@ template
|
||||
typename P,
|
||||
typename PS
|
||||
>
|
||||
struct return_type<cross_track_geo<FormulaPolicy, Spheroid, CalculationType>, P, PS>
|
||||
: cross_track_geo<FormulaPolicy, Spheroid, CalculationType>::template return_type<P, PS>
|
||||
struct return_type<geographic_cross_track<FormulaPolicy, Spheroid, CalculationType>, P, PS>
|
||||
: geographic_cross_track<FormulaPolicy, Spheroid, CalculationType>::template return_type<P, PS>
|
||||
{};
|
||||
|
||||
//comparable types
|
||||
@@ -222,9 +192,9 @@ template
|
||||
typename Spheroid,
|
||||
typename CalculationType
|
||||
>
|
||||
struct comparable_type<cross_track_geo<FormulaPolicy, Spheroid, CalculationType> >
|
||||
struct comparable_type<geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> >
|
||||
{
|
||||
typedef cross_track_geo
|
||||
typedef geographic_cross_track
|
||||
<
|
||||
FormulaPolicy, Spheroid, CalculationType
|
||||
> type;
|
||||
@@ -236,15 +206,15 @@ template
|
||||
typename Spheroid,
|
||||
typename CalculationType
|
||||
>
|
||||
struct get_comparable<cross_track_geo<FormulaPolicy, Spheroid, CalculationType> >
|
||||
struct get_comparable<geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> >
|
||||
{
|
||||
typedef typename comparable_type
|
||||
<
|
||||
cross_track_geo<FormulaPolicy, Spheroid, CalculationType>
|
||||
geographic_cross_track<FormulaPolicy, Spheroid, CalculationType>
|
||||
>::type comparable_type;
|
||||
public :
|
||||
static inline comparable_type
|
||||
apply(cross_track_geo<FormulaPolicy, Spheroid, CalculationType> const& strategy)
|
||||
apply(geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> const& strategy)
|
||||
{
|
||||
return comparable_type();
|
||||
}
|
||||
@@ -257,17 +227,17 @@ template
|
||||
typename P,
|
||||
typename PS
|
||||
>
|
||||
struct result_from_distance<cross_track_geo<FormulaPolicy>, P, PS>
|
||||
struct result_from_distance<geographic_cross_track<FormulaPolicy>, P, PS>
|
||||
{
|
||||
private :
|
||||
typedef typename cross_track_geo
|
||||
typedef typename geographic_cross_track
|
||||
<
|
||||
FormulaPolicy
|
||||
>::template return_type<P, PS>::type return_type;
|
||||
public :
|
||||
template <typename T>
|
||||
static inline return_type
|
||||
apply(cross_track_geo<FormulaPolicy> const& , T const& distance)
|
||||
apply(geographic_cross_track<FormulaPolicy> 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ struct geographic_segments
|
||||
return strategy_type(m_spheroid);
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
struct distance_strategy
|
||||
{
|
||||
typedef distance::geographic
|
||||
@@ -128,9 +129,10 @@ struct geographic_segments
|
||||
> type;
|
||||
};
|
||||
|
||||
inline typename distance_strategy::type get_distance_strategy() const
|
||||
template <typename Geometry>
|
||||
inline typename distance_strategy<Geometry>::type get_distance_strategy() const
|
||||
{
|
||||
typedef typename distance_strategy::type strategy_type;
|
||||
typedef typename distance_strategy<Geometry>::type strategy_type;
|
||||
return strategy_type(m_spheroid);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user