Added thirdparty: boost library

This commit is contained in:
Viacheslav Demydiuk
2024-01-06 19:55:56 +02:00
parent bf49f439e1
commit bccd1e7051
15683 changed files with 3239840 additions and 0 deletions
+269
View File
@@ -0,0 +1,269 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2016-2020 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
// 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_STRATEGY_GEOGRAPHIC_AREA_HPP
#define BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_AREA_HPP
#include <type_traits>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/formulas/area_formulas.hpp>
#include <boost/geometry/formulas/authalic_radius_sqr.hpp>
#include <boost/geometry/formulas/eccentricity_sqr.hpp>
#include <boost/geometry/strategy/area.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace area
{
/*!
\brief Geographic area calculation
\ingroup strategies
\details Geographic area calculation by trapezoidal rule plus integral
approximation that gives the ellipsoidal correction
\tparam FormulaPolicy Formula used to calculate azimuths
\tparam SeriesOrder The order of approximation of the geodesic integral
\tparam Spheroid The spheroid model
\tparam CalculationType \tparam_calculation
\author See
- Danielsen JS, The area under the geodesic. Surv Rev 30(232): 6166, 1989
- Charles F.F Karney, Algorithms for geodesics, 2011 https://arxiv.org/pdf/1109.4448.pdf
\qbk{
[heading See also]
\* [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
\* [link geometry.reference.srs.srs_spheroid srs::spheroid]
}
*/
template
<
typename FormulaPolicy = strategy::andoyer,
std::size_t SeriesOrder = strategy::default_order<FormulaPolicy>::value,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic
{
// Switch between two kinds of approximation(series in eps and n v.s.series in k ^ 2 and e'^2)
static const bool ExpandEpsN = true;
// LongSegment Enables special handling of long segments
static const bool LongSegment = false;
// Area formula is implemented for a maximum series order 5
static constexpr auto SeriesOrderNorm = SeriesOrder > 5 ? 5 : SeriesOrder;
//Select default types in case they are not set
public:
template <typename Geometry>
struct result_type
: strategy::area::detail::result_type
<
Geometry,
CalculationType
>
{};
protected :
struct spheroid_constants
{
typedef std::conditional_t
<
std::is_void<CalculationType>::value,
typename geometry::radius_type<Spheroid>::type,
CalculationType
> calc_t;
Spheroid m_spheroid;
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
calc_t const m_f; // the flattening
calc_t m_coeffs_var[((SeriesOrderNorm+2)*(SeriesOrderNorm+1))/2];
inline spheroid_constants(Spheroid const& spheroid)
: m_spheroid(spheroid)
, m_a2(math::sqr(get_radius<0>(spheroid)))
, 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
<
calc_t, Spheroid, srs_spheroid_tag
>::apply(m_a2, m_e2))
, m_f(formula::flattening<calc_t>(spheroid))
{
typedef geometry::formula::area_formulas
<
calc_t, SeriesOrderNorm, ExpandEpsN
> area_formulas;
calc_t const n = m_f / (calc_t(2) - m_f);
// Generate and evaluate the polynomials on n
// to get the series coefficients (that depend on eps)
area_formulas::evaluate_coeffs_n(n, m_coeffs_var);
}
};
public:
template <typename Geometry>
class state
{
friend class geographic;
typedef typename result_type<Geometry>::type return_type;
public:
inline state()
: m_excess_sum(0)
, m_correction_sum(0)
, m_crosses_prime_meridian(0)
{}
private:
inline return_type area(spheroid_constants const& spheroid_const) const
{
return_type result;
return_type const spherical_term = spheroid_const.m_c2 * m_excess_sum;
return_type const ellipsoidal_term = spheroid_const.m_e2
* spheroid_const.m_a2 * m_correction_sum;
// ignore ellipsoidal term if is large (probably from an azimuth
// inaccuracy)
return_type sum = math::abs(ellipsoidal_term/spherical_term) > 0.01
? spherical_term : spherical_term + ellipsoidal_term;
// If encircles some pole
if (m_crosses_prime_meridian % 2 == 1)
{
std::size_t times_crosses_prime_meridian
= 1 + (m_crosses_prime_meridian / 2);
result = return_type(2.0)
* geometry::math::pi<return_type>()
* spheroid_const.m_c2
* return_type(times_crosses_prime_meridian)
- geometry::math::abs(sum);
if (geometry::math::sign<return_type>(sum) == 1)
{
result = - result;
}
}
else
{
result = sum;
}
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 :
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,
state<Geometry>& st) const
{
using CT = typename result_type<Geometry>::type;
// if the segment in not on a meridian
if (! geometry::math::equals(get<0>(p1), get<0>(p2)))
{
typedef geometry::formula::area_formulas
<
CT, SeriesOrderNorm, ExpandEpsN
> area_formulas;
// Keep track whenever a segment crosses the prime meridian
if (area_formulas::crosses_prime_meridian(p1, p2))
{
st.m_crosses_prime_meridian++;
}
// if the segment in not on equator
if (! (geometry::math::equals(get<1>(p1), 0)
&& geometry::math::equals(get<1>(p2), 0)))
{
auto result = area_formulas::template ellipsoidal
<
FormulaPolicy::template inverse
>(p1, p2, m_spheroid_constants);
st.m_excess_sum += result.spherical_term;
st.m_correction_sum += result.ellipsoidal_term;
}
}
}
template <typename Geometry>
inline typename result_type<Geometry>::type
result(state<Geometry> const& st) const
{
return st.area(m_spheroid_constants);
}
Spheroid model() const
{
return m_spheroid_constants.m_spheroid;
}
private:
spheroid_constants m_spheroid_constants;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <>
struct default_strategy<geographic_tag>
{
typedef strategy::area::geographic<> type;
};
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}
}} // namespace strategy::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_AREA_HPP
+191
View File
@@ -0,0 +1,191 @@
// Boost.Geometry
// Copyright (c) 2021, 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_STRATEGY_GEOGRAPHIC_AREA_BOX_HPP
#define BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_AREA_BOX_HPP
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/spherical/get_radius.hpp>
#include <boost/geometry/strategy/area.hpp>
#include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace area
{
// Based on the approach for spherical coordinate system:
// https://math.stackexchange.com/questions/131735/surface-element-in-spherical-coordinates
// http://www.cs.cmu.edu/afs/cs/academic/class/16823-s16/www/pdfs/appearance-modeling-3.pdf
// https://www.astronomyclub.xyz/celestial-sphere-2/solid-angle-on-the-celestial-sphere.html
// https://mathworld.wolfram.com/SolidAngle.html
// https://en.wikipedia.org/wiki/Spherical_coordinate_system
// and equations for spheroid:
// https://en.wikipedia.org/wiki/Geographic_coordinate_conversion
// https://en.wikipedia.org/wiki/Meridian_arc
// Note that the equations use geodetic latitudes so we do not have to convert them.
// assume(y_max > y_min);
// assume(x_max > x_min);
// M: a*(1-e^2) / (1-e^2*sin(y)^2)^(3/2);
// N: a / sqrt(1-e^2*sin(y)^2);
// O: N*cos(y)*M;
// tellsimp(log(abs(e*sin(y_min)+1)), p_min);
// tellsimp(log(abs(e*sin(y_min)-1)), m_min);
// tellsimp(log(abs(e*sin(y_max)+1)), p_max);
// tellsimp(log(abs(e*sin(y_max)-1)), m_max);
// S: integrate(integrate(O, y, y_min, y_max), x, x_min, x_max);
// combine(S);
//
// An alternative solution to the above formula was suggested by Charles Karney
// https://github.com/boostorg/geometry/pull/832
// The following are formulas for area of a box defined by the equator and some latitude,
// not arbitrary box.
// For e^2 > 0
// dlambda*b^2*sin(phi)/2*(1/(1-e^2*sin(phi)^2) + atanh(e*sin(phi))/(e*sin(phi)))
// For e^2 < 0
// dlambda*b^2*sin(phi)/2*(1/(1-e^2*sin(phi)^2) + atan(ea*sin(phi))/(ea*sin(phi)))
// where ea = sqrt(-e^2)
template
<
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic_box
{
public:
template <typename Box>
struct result_type
: strategy::area::detail::result_type
<
Box,
CalculationType
>
{};
geographic_box() = default;
explicit geographic_box(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
template <typename Box>
inline auto apply(Box const& box) const
{
typedef typename result_type<Box>::type return_type;
return_type const c0 = 0;
return_type x_min = get_as_radian<min_corner, 0>(box); // lon
return_type y_min = get_as_radian<min_corner, 1>(box); // lat
return_type x_max = get_as_radian<max_corner, 0>(box);
return_type y_max = get_as_radian<max_corner, 1>(box);
math::normalize_spheroidal_box_coordinates<radian>(x_min, y_min, x_max, y_max);
if (x_min == x_max || y_max == y_min)
{
return c0;
}
return_type const e2 = formula::eccentricity_sqr<return_type>(m_spheroid);
return_type const x_diff = x_max - x_min;
return_type const sin_y_min = sin(y_min);
return_type const sin_y_max = sin(y_max);
if (math::equals(e2, c0))
{
// spherical formula
return_type const a = get_radius<0>(m_spheroid);
return x_diff * (sin_y_max - sin_y_min) * a * a;
}
return_type const c1 = 1;
return_type const c2 = 2;
return_type const b = get_radius<2>(m_spheroid);
/*
return_type const c4 = 4;
return_type const e = math::sqrt(e2);
return_type const p_min = log(math::abs(e * sin_y_min + c1));
return_type const p_max = log(math::abs(e * sin_y_max + c1));
return_type const m_min = log(math::abs(e * sin_y_min - c1));
return_type const m_max = log(math::abs(e * sin_y_max - c1));
return_type const n_min = e * sin_y_min * sin_y_min;
return_type const n_max = e * sin_y_max * sin_y_max;
return_type const d_min = e * n_min - c1;
return_type const d_max = e * n_max - c1;
// NOTE: For equal latitudes the original formula generated by maxima may give negative
// result. It's caused by the order of operations, so here they're rearranged for
// symmetry.
return_type const comp0 = (p_min - m_min) / (c4 * e * d_min);
return_type const comp1 = sin_y_min / (c2 * d_min);
return_type const comp2 = n_min * (m_min - p_min) / (c4 * d_min);
return_type const comp3 = (p_max - m_max) / (c4 * e * d_max);
return_type const comp4 = sin_y_max / (c2 * d_max);
return_type const comp5 = n_max * (m_max - p_max) / (c4 * d_max);
return_type const comp02 = comp0 + comp1 + comp2;
return_type const comp35 = comp3 + comp4 + comp5;
return b * b * x_diff * (comp02 - comp35);
*/
return_type const comp0_min = c1 / (c1 - e2 * sin_y_min * sin_y_min);
return_type const comp0_max = c1 / (c1 - e2 * sin_y_max * sin_y_max);
// NOTE: For latitudes equal to 0 the original formula returns NAN
return_type comp1_min = 0, comp1_max = 0;
if (e2 > c0)
{
return_type const e = math::sqrt(e2);
return_type const e_sin_y_min = e * sin_y_min;
return_type const e_sin_y_max = e * sin_y_max;
comp1_min = e_sin_y_min == c0 ? c1 : atanh(e_sin_y_min) / e_sin_y_min;
comp1_max = e_sin_y_max == c0 ? c1 : atanh(e_sin_y_max) / e_sin_y_max;
}
else
{
return_type const ea = math::sqrt(-e2);
return_type const ea_sin_y_min = ea * sin_y_min;
return_type const ea_sin_y_max = ea * sin_y_max;
comp1_min = ea_sin_y_min == c0 ? c1 : atan(ea_sin_y_min) / ea_sin_y_min;
comp1_max = ea_sin_y_max == c0 ? c1 : atan(ea_sin_y_max) / ea_sin_y_max;
}
return_type const comp01_min = sin_y_min * (comp0_min + comp1_min);
return_type const comp01_max = sin_y_max * (comp0_max + comp1_max);
return b * b * x_diff * (comp01_max - comp01_min) / c2;
}
Spheroid model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};
}} // namespace strategy::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_AREA_BOX_HPP
+94
View File
@@ -0,0 +1,94 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015-2020.
// Modifications copyright (c) 2015-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// Distributed under 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_STRATEGY_GEOGRAPHIC_ENVELOPE_HPP
#define BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_ENVELOPE_HPP
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategy/geographic/envelope_segment.hpp>
#include <boost/geometry/strategy/geographic/expand_segment.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategy/spherical/envelope.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public spherical<CalculationType>
{
public:
typedef geographic_tag cs_tag;
typedef Spheroid model_type;
inline geographic()
: m_spheroid()
{}
explicit inline geographic(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
Spheroid model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Tag, typename CalculationType>
struct default_strategy<Tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::geographic
<
strategy::andoyer,
geometry::srs::spheroid<double>,
CalculationType
> type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_ENVELOPE_HPP
+118
View File
@@ -0,0 +1,118 @@
// Boost.Geometry
// Copyright (c) 2021-2022, 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_STRATEGY_GEOGRAPHIC_ENVELOPE_RANGE_HPP
#define BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_ENVELOPE_RANGE_HPP
#include <boost/geometry/strategy/geographic/envelope_segment.hpp>
#include <boost/geometry/strategy/geographic/expand_segment.hpp>
#include <boost/geometry/strategy/spherical/envelope_range.hpp>
// Get rid of this dependency?
#include <boost/geometry/strategies/spherical/point_in_poly_winding.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic_linestring
{
public:
using model_type = Spheroid;
geographic_linestring()
: m_spheroid()
{}
explicit geographic_linestring(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
template <typename Range, typename Box>
void apply(Range const& range, Box& mbr) const
{
auto const envelope_s = envelope::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
>(m_spheroid);
auto const expand_s = expand::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
>(m_spheroid);
detail::spheroidal_linestring(range, mbr, envelope_s, expand_s);
}
Spheroid model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic_ring
{
public:
using model_type = Spheroid;
geographic_ring()
: m_spheroid()
{}
explicit geographic_ring(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
template <typename Range, typename Box>
void apply(Range const& range, Box& mbr) const
{
auto const envelope_s = envelope::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
>(m_spheroid);
auto const expand_s = expand::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
>(m_spheroid);
auto const within_s = within::detail::spherical_winding_base
<
envelope::detail::side_of_pole<CalculationType>, CalculationType
>();
detail::spheroidal_ring(range, mbr, envelope_s, expand_s, within_s);
}
Spheroid model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};
}} // namespace strategy::envelope
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_ENVELOPE_RANGE_HPP
@@ -0,0 +1,122 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2017-2020 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
// 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_STRATEGY_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategy/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategy/envelope.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategy/spherical/envelope_segment.hpp>
#include <boost/geometry/strategy/spherical/expand_box.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic_segment
{
public:
typedef Spheroid model_type;
inline geographic_segment()
: m_spheroid()
{}
explicit inline geographic_segment(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
template <typename Point, typename Box>
inline void apply(Point const& point1, Point const& point2, Box& box) const
{
Point p1_normalized, p2_normalized;
strategy::normalize::spherical_point::apply(point1, p1_normalized);
strategy::normalize::spherical_point::apply(point2, p2_normalized);
geometry::strategy::azimuth::geographic
<
FormulaPolicy,
Spheroid,
CalculationType
> azimuth_geographic(m_spheroid);
typedef typename geometry::detail::cs_angular_units
<
Point
>::type units_type;
// first compute the envelope range for the first two coordinates
strategy::envelope::detail::envelope_segment_impl
<
geographic_tag
>::template apply<units_type>(geometry::get<0>(p1_normalized),
geometry::get<1>(p1_normalized),
geometry::get<0>(p2_normalized),
geometry::get<1>(p2_normalized),
box,
azimuth_geographic);
// now compute the envelope range for coordinates of
// dimension 2 and higher
strategy::envelope::detail::envelope_one_segment
<
2, dimension<Point>::value
>::apply(point1, point2, box);
}
Spheroid model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::geographic_segment
<
strategy::andoyer,
srs::spheroid<double>,
CalculationType
> type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP
+107
View File
@@ -0,0 +1,107 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under 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_STRATEGY_GEOGRAPHIC_EXPAND_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_EXPAND_SEGMENT_HPP
#include <cstddef>
#include <functional>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategy/expand.hpp>
#include <boost/geometry/strategy/geographic/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategy/spherical/expand_segment.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic_segment
{
public:
inline geographic_segment()
: m_envelope_strategy()
{}
explicit inline geographic_segment(Spheroid const& spheroid)
: m_envelope_strategy(spheroid)
{}
template <typename Box, typename Segment>
inline void apply(Box& box, Segment const& segment) const
{
detail::segment_on_spheroid::apply(box, segment, m_envelope_strategy);
}
Spheroid model() const
{
return m_envelope_strategy.model();
}
private:
strategy::envelope::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
> m_envelope_strategy;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, geographic_tag, CalculationType>
{
typedef geographic_segment
<
strategy::andoyer,
geometry::srs::spheroid<double>,
CalculationType
> type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_GEOGRAPHIC_EXPAND_SEGMENT_HPP