[strategy] Remove azimuth precomputation from line_interpolate strategies

This commit is contained in:
Vissarion Fysikopoulos 2019-02-12 16:54:04 +02:00
parent 0472b64b52
commit 0ab93f5280
5 changed files with 57 additions and 105 deletions

View File

@ -83,8 +83,6 @@ struct range
typedef typename boost::range_iterator<Range const>::type iterator_t;
typedef typename boost::range_value<Range const>::type point_t;
typedef typename Strategy::template result_type<point_t> result_type;
iterator_t it = boost::begin(range);
iterator_t end = boost::end(range);
@ -107,18 +105,17 @@ struct range
for ( ; it != end ; ++it)
{
result_type res = strategy.compute(*prev, *it);
current_distance = prev_distance + res.distance;
Distance dist = strategy.get_distance_pp_strategy().apply(*prev, *it);
current_distance = prev_distance + dist;
while (current_distance >= repeated_distance )
{
point_t p;
Distance diff_distance = current_distance - prev_distance;
strategy.apply(start_p, *it,
(repeated_distance - prev_distance)
/(current_distance - prev_distance),
(repeated_distance - prev_distance)/diff_distance,
p,
current_distance - prev_distance,
res);
diff_distance);
policy.apply(p, pointlike);
if (boost::is_same<PointLike, point_t>::value)
{

View File

@ -46,32 +46,16 @@ class cartesian
{
public:
//result type
template <typename Point>
struct result_type
// point-point strategy getters
struct distance_pp_strategy
{
typedef typename select_calculation_type_alt
<
CalculationType,
Point
>::type calc_t;
result_type()
: distance(0)
{}
result_type(calc_t d)
: distance(d)
{}
calc_t distance;
typedef DistanceStrategy type;
};
template <typename Point>
inline result_type<Point> compute(Point const& p0,
Point const& p1) const
inline typename distance_pp_strategy::type get_distance_pp_strategy() const
{
return result_type<Point>(DistanceStrategy().apply(p0,p1));
typedef typename distance_pp_strategy::type distance_type;
return distance_type();
}
template <typename Point, typename Fraction, typename Distance>
@ -79,10 +63,13 @@ public:
Point const& p1,
Fraction const& fraction,
Point & p,
Distance const&,
result_type<Point> const&) const
Distance const&) const
{
typedef typename result_type<Point>::calc_t calc_t;
typedef typename select_calculation_type_alt
<
CalculationType,
Point
>::type calc_t;
typedef model::point
<

View File

@ -57,9 +57,24 @@ public:
: m_spheroid(spheroid)
{}
//result type
template <typename Point>
struct result_type
// point-point strategy getters
struct distance_pp_strategy
{
typedef distance::geographic<FormulaPolicy, Spheroid, CalculationType> type;
};
inline typename distance_pp_strategy::type get_distance_pp_strategy() const
{
typedef typename distance_pp_strategy::type distance_type;
return distance_type(m_spheroid);
}
template <typename Point, typename Fraction, typename Distance>
inline void apply(Point const& p0,
Point const& p1,
Fraction const& fraction, //fraction of segment
Point & p,
Distance const& distance) const
{
typedef typename select_calculation_type_alt
<
@ -67,53 +82,19 @@ public:
Point
>::type calc_t;
result_type()
: distance(0)
, azimuth(0)
{}
result_type(calc_t d, calc_t a)
: distance(d)
, azimuth(a)
{}
calc_t distance;
calc_t azimuth;
};
template <typename Point>
inline result_type<Point> compute(Point const& p0,
Point const& p1) const
{
typedef typename result_type<Point>::calc_t calc_t;
typedef typename FormulaPolicy::template inverse
<calc_t, true, true, false, false, false> inverse_t;
<calc_t, false, 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);
return result_type<Point>(inv_r.distance, inv_r.azimuth);
}
template <typename Point, typename Fraction, typename Distance>
inline void apply(Point const& p0,
Point const&,
Fraction const& fraction, //fraction of segment
Point & p,
Distance const& distance,
result_type<Point> const& res) const
{
typedef typename result_type<Point>::calc_t calc_t;
calc_t azimuth = 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).azimuth;
typedef typename FormulaPolicy::template direct
<calc_t, true, false, false, false> direct_t;
typename direct_t::result_type
dir_r = direct_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0),
distance * fraction, res.azimuth,
distance * fraction, azimuth,
m_spheroid);
set_from_radian<0>(p, dir_r.lon2);

View File

@ -48,28 +48,16 @@ class spherical
{
public:
//result type
template <typename Point>
struct result_type
// point-point strategy getters
struct distance_pp_strategy
{
typedef typename select_calculation_type_alt
<
CalculationType,
Point
>::type calc_t;
result_type(calc_t d) :
distance(d)
{}
calc_t distance;
typedef DistanceStrategy type;
};
template <typename Point>
inline result_type<Point> compute(Point const& p0,
Point const& p1) const
inline typename distance_pp_strategy::type get_distance_pp_strategy() const
{
return result_type<Point>(DistanceStrategy().apply(p0,p1));
typedef typename distance_pp_strategy::type distance_type;
return distance_type();
}
template <typename Point, typename Fraction, typename Distance>
@ -77,10 +65,13 @@ public:
Point const& p1,
Fraction const& fraction,
Point & p,
Distance const& distance,
result_type<Point> const&) const
Distance const& distance) const
{
typedef typename result_type<Point>::calc_t calc_t;
typedef typename select_calculation_type_alt
<
CalculationType,
Point
>::type calc_t;
calc_t const c0 = 0;
calc_t const c1 = 1;
@ -143,9 +134,7 @@ public:
geometry::add_point(v_rot, s3);
p = formula::cart3d_to_sph<Point>(v_rot);
}
};

View File

@ -264,12 +264,12 @@ void test_geo(Strategy str)
test<LS,MP>(l, 0, "MULTIPOINT((1 1))", str);
test<LS,MP>(l, 0.1, "MULTIPOINT((1.3986445638301882 1.0000367522730751)\
(1.79728912766037641 1.0000735036506381)\
(1.79728912766037641 1.0000247772582571)\
(2 1.1972285554368427)\
(2 1.598498298996567)\
(2 1.9997664696834965)\
(1.6013936980010324 2.0000734568388099)\
(1.2025664628960846 2.0001469249038197)\
(1.2025664628960846 2.0000495003440779)\
(1 2.1974612279909937)\
(1 2.5987263175375022)\
(1 3))", str);
@ -286,10 +286,8 @@ void test_geo(Strategy str)
test<LS,MP>(l, 1, "MULTIPOINT((1 3))", str);
test<LS,MP>(l2, 0.3, "MULTIPOINT((5.306157814 1.0006937303)\
(11.60351281 1.0091515976)\
(17.90073492 1.0175580865))", str);
(11.60351281 1.0085614548123072)\
(17.90073492 1.004178475142552))", str);
}
int test_main(int, char* [])
@ -297,11 +295,11 @@ int test_main(int, char* [])
test_car();
test_car_edge_cases();
test_sph();
//adnoyer is missing the last point of linestring due to inaccuracy
//test_geo(bg::strategy::line_interpolate_point::geographic<bg::strategy::andoyer>());
test_geo(bg::strategy::line_interpolate_point::geographic<bg::strategy::thomas>());
test_geo(bg::strategy::line_interpolate_point::geographic<bg::strategy::vincenty>());
//TODO:add distance longer than length
return 0;
}