update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -1,232 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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
// 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)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AREA_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AREA_HPP
#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/strategies/area.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
namespace boost { namespace geometry
{
#include <boost/geometry/strategy/geographic/area.hpp>
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): 61–66, 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;
//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 typename boost::mpl::if_c
<
boost::is_void<CalculationType>::value,
typename geometry::radius_type<Spheroid>::type,
CalculationType
>::type 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
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))
{}
};
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 sum = spheroid_const.m_c2 * m_excess_sum
+ spheroid_const.m_e2 * spheroid_const.m_a2 * m_correction_sum;
// 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
{
if (! geometry::math::equals(get<0>(p1), get<0>(p2)))
{
typedef geometry::formula::area_formulas
<
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);
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))
{
st.m_crosses_prime_meridian++;
}
}
}
template <typename Geometry>
inline typename result_type<Geometry>::type
result(state<Geometry> const& st) const
{
return st.area(m_spheroid_constants);
}
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_STRATEGIES_GEOGRAPHIC_AREA_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2016-2017 Oracle and/or its affiliates.
// Copyright (c) 2016-2021 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,13 +12,14 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AZIMUTH_HPP
#include <type_traits>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
@@ -35,7 +36,14 @@ template
>
class geographic
{
public :
public:
template <typename T1, typename T2>
struct result_type
: geometry::select_most_precise
<
T1, T2, CalculationType
>
{};
typedef Spheroid model_type;
@@ -52,28 +60,28 @@ public :
return m_spheroid;
}
template <typename T>
inline void apply(T const& lon1_rad, T const& lat1_rad,
T const& lon2_rad, T const& lat2_rad,
T& a1, T& a2) const
template <typename T1, typename T2, typename Result>
inline void apply(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a1, Result& a2) const
{
compute<true, true>(lon1_rad, lat1_rad,
lon2_rad, lat2_rad,
a1, a2);
}
template <typename T>
inline void apply(T const& lon1_rad, T const& lat1_rad,
T const& lon2_rad, T const& lat2_rad,
T& a1) const
template <typename T1, typename T2, typename Result>
inline void apply(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a1) const
{
compute<true, false>(lon1_rad, lat1_rad,
lon2_rad, lat2_rad,
a1, a1);
}
template <typename T>
inline void apply_reverse(T const& lon1_rad, T const& lat1_rad,
T const& lon2_rad, T const& lat2_rad,
T& a2) const
template <typename T1, typename T2, typename Result>
inline void apply_reverse(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a2) const
{
compute<false, true>(lon1_rad, lat1_rad,
lon2_rad, lat2_rad,
@@ -82,29 +90,27 @@ public :
private :
template <
template
<
bool EnableAzimuth,
bool EnableReverseAzimuth,
typename T
typename T1, typename T2, typename Result
>
inline void compute(T const& lon1_rad, T const& lat1_rad,
T const& lon2_rad, T const& lat2_rad,
T& a1, T& a2) const
inline void compute(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a1, Result& a2) const
{
typedef typename boost::mpl::if_
<
boost::is_void<CalculationType>, T, CalculationType
>::type calc_t;
typedef typename result_type<T1, T2>::type calc_t;
typedef typename FormulaPolicy::template inverse
<
calc_t,
false,
EnableAzimuth,
EnableReverseAzimuth,
false,
false
> inverse_type;
<
calc_t,
false,
EnableAzimuth,
EnableReverseAzimuth,
false,
false
> inverse_type;
typedef typename inverse_type::result_type inverse_result;
inverse_result i_res = inverse_type::apply(calc_t(lon1_rad), calc_t(lat1_rad),
calc_t(lon2_rad), calc_t(lat2_rad),
@@ -127,14 +133,13 @@ private :
namespace services
{
template <typename CalculationType>
struct default_strategy<geographic_tag, CalculationType>
template <>
struct default_strategy<geographic_tag>
{
typedef strategy::azimuth::geographic
<
strategy::andoyer,
srs::spheroid<double>,
CalculationType
srs::spheroid<double>
> type;
};

View File

@@ -0,0 +1,153 @@
// Boost.Geometry
// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
// 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_BUFFER_END_ROUND_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_END_ROUND_HPP
#include <boost/range/value_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/strategies/geographic/buffer_helper.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace buffer
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic_end_round
{
public :
//! \brief Constructs the strategy with a spheroid
//! \param spheroid The spheroid to be used
//! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
explicit inline geographic_end_round(Spheroid const& spheroid,
std::size_t points_per_circle = default_points_per_circle)
: m_spheroid(spheroid)
, m_points_per_circle(get_point_count_for_end(points_per_circle))
{}
//! \brief Constructs the strategy
//! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
explicit inline geographic_end_round(std::size_t points_per_circle = default_points_per_circle)
: m_points_per_circle(get_point_count_for_end(points_per_circle))
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T, typename RangeOut>
inline void generate(T lon_rad, T lat_rad, T distance, T azimuth, RangeOut& range_out) const
{
using helper = geographic_buffer_helper<FormulaPolicy, T>;
std::size_t const n = m_points_per_circle / 2;
T const angle_diff = geometry::math::pi<T>() / n;
T azi = math::wrap_azimuth_in_radian(azimuth + angle_diff);
// Generate points between 0 and n, not including them
// because left and right are inserted before and after this range.
for (std::size_t i = 1; i < n; i++)
{
helper::append_point(lon_rad, lat_rad, distance, azi, m_spheroid, range_out);
azi = math::wrap_azimuth_in_radian(azi + angle_diff);
}
}
//! Fills output_range with a round end
template <typename Point, typename DistanceStrategy, typename RangeOut>
inline void apply(Point const& penultimate_point, Point const& perp_left_point,
Point const& ultimate_point, Point const& perp_right_point,
buffer_side_selector side, DistanceStrategy const& distance,
RangeOut& range_out) const
{
using calc_t = typename select_calculation_type
<
Point,
typename boost::range_value<RangeOut>::type,
CalculationType
>::type;
using helper = geographic_buffer_helper<FormulaPolicy, calc_t>;
calc_t const lon_rad = get_as_radian<0>(ultimate_point);
calc_t const lat_rad = get_as_radian<1>(ultimate_point);
auto const azimuth = helper::azimuth(lon_rad, lat_rad, perp_left_point, m_spheroid);
calc_t const dist_left = distance.apply(penultimate_point, ultimate_point, buffer_side_left);
calc_t const dist_right = distance.apply(penultimate_point, ultimate_point, buffer_side_right);
bool const reversed = (side == buffer_side_left && dist_right < 0 && -dist_right > dist_left)
|| (side == buffer_side_right && dist_left < 0 && -dist_left > dist_right)
;
if (reversed)
{
range_out.push_back(perp_right_point);
// generate
range_out.push_back(perp_left_point);
}
else
{
range_out.push_back(perp_left_point);
if (geometry::math::equals(dist_left, dist_right))
{
generate(lon_rad, lat_rad, dist_left, azimuth, range_out);
}
else
{
static calc_t const two = 2.0;
calc_t const dist_average = (dist_left + dist_right) / two;
calc_t const dist_half
= (side == buffer_side_right
? (dist_right - dist_left)
: (dist_left - dist_right)) / two;
auto const shifted = helper::direct::apply(lon_rad, lat_rad, dist_half, azimuth, m_spheroid);
generate(shifted.lon2, shifted.lat2, dist_average, azimuth, range_out);
}
range_out.push_back(perp_right_point);
}
}
template <typename NumericType>
static inline NumericType max_distance(NumericType const& distance)
{
return distance;
}
//! Returns the piece_type (flat end)
static inline piece_type get_piece_type()
{
return buffered_round_end;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :
Spheroid m_spheroid;
std::size_t m_points_per_circle;
};
}} // namespace strategy::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_END_ROUND_HPP

View File

@@ -0,0 +1,101 @@
// Boost.Geometry
// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
// 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_BUFFER_HELPER_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_HELPER_HPP
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace buffer
{
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename FormulaPolicy, typename CalculationType>
struct geographic_buffer_helper
{
static bool const enable_azimuth = true;
static bool const enable_coordinates = true;
using inverse = typename FormulaPolicy::template inverse
<
CalculationType, false, enable_azimuth, false, false, false
>;
using direct = typename FormulaPolicy::template direct
<
CalculationType, enable_coordinates, false, false, false
>;
// Calculates the azimuth using the inverse formula, where the first point
// is specified by lon/lat (for pragmatic reasons) and the second point as a point.
template <typename T, typename Point, typename Spheroid>
static inline CalculationType azimuth(T const& lon_rad, T const& lat_rad,
Point const& p, Spheroid const& spheroid)
{
return inverse::apply(lon_rad, lat_rad, get_as_radian<0>(p), get_as_radian<1>(p), spheroid).azimuth;
}
// Using specified points, distance and azimuth it calculates a new point
// and appends it to the range
template <typename T, typename Spheroid, typename RangeOut>
static inline void append_point(T const& lon_rad, T const& lat_rad,
T const& distance, T const& angle,
Spheroid const& spheroid, RangeOut& range_out)
{
using point_t = typename boost::range_value<RangeOut>::type;
point_t point;
auto const d = direct::apply(lon_rad, lat_rad, distance, angle, spheroid);
set_from_radian<0>(point, d.lon2);
set_from_radian<1>(point, d.lat2);
range_out.emplace_back(point);
}
// Calculates the angle diff and azimuth of a point (specified as lon/lat)
// and two points, perpendicular in the buffer context.
template <typename T, typename Point, typename Spheroid>
static inline bool calculate_angles(T const& lon_rad, T const& lat_rad, Point const& perp1,
Point const& perp2, Spheroid const& spheroid,
T& angle_diff, T& first_azimuth)
{
T const inv1 = azimuth(lon_rad, lat_rad, perp1, spheroid);
T const inv2 = azimuth(lon_rad, lat_rad, perp2, spheroid);
static CalculationType const two_pi = geometry::math::two_pi<CalculationType>();
static CalculationType const pi = geometry::math::pi<CalculationType>();
// For a sharp corner, perpendicular points are nearly opposite and the
// angle between the two azimuths can be nearly 180, but not more.
angle_diff = inv2 < inv1 ? (two_pi + inv2) - inv1 : inv2 - inv1;
if (angle_diff < 0 || angle_diff > pi)
{
// Defensive check with asserts
BOOST_GEOMETRY_ASSERT(angle_diff >= 0);
BOOST_GEOMETRY_ASSERT(angle_diff <= pi);
return false;
}
first_azimuth = inv1;
return true;
}
};
#endif // DOXYGEN_SHOULD_SKIP_THIS
}} // namespace strategy::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_HELPER_HPP

View File

@@ -0,0 +1,132 @@
// Boost.Geometry
// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
// 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_BUFFER_JOIN_MITER_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_JOIN_MITER_HPP
#include <boost/range/value_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/strategies/geographic/buffer_helper.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace buffer
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic_join_miter
{
public :
//! \brief Constructs the strategy with a spheroid
//! \param spheroid The spheroid to be used
//! \param miter_limit The miter limit, to avoid excessively long miters around sharp corners
explicit inline geographic_join_miter(Spheroid const& spheroid,
double miter_limit = 5.0)
: m_spheroid(spheroid)
, m_miter_limit(valid_limit(miter_limit))
{}
//! \brief Constructs the strategy
//! \param miter_limit The miter limit, to avoid excessively long miters around sharp corners
explicit inline geographic_join_miter(double miter_limit = 5.0)
: m_miter_limit(valid_limit(miter_limit))
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//! Fills output_range with a sharp shape around a vertex
template <typename Point, typename DistanceType, typename RangeOut>
inline bool apply(Point const& , Point const& vertex,
Point const& perp1, Point const& perp2,
DistanceType const& buffer_distance,
RangeOut& range_out) const
{
using calc_t = typename select_calculation_type
<
Point,
typename boost::range_value<RangeOut>::type,
CalculationType
>::type;
using helper = geographic_buffer_helper<FormulaPolicy, calc_t>;
calc_t const lon_rad = get_as_radian<0>(vertex);
calc_t const lat_rad = get_as_radian<1>(vertex);
calc_t first_azimuth;
calc_t angle_diff;
if (! helper::calculate_angles(lon_rad, lat_rad, perp1, perp2, m_spheroid,
angle_diff, first_azimuth))
{
return false;
}
calc_t const half = 0.5;
calc_t const half_angle_diff = half * angle_diff;
calc_t const azi = math::wrap_azimuth_in_radian(first_azimuth + half_angle_diff);
calc_t const cos_angle = std::cos(half_angle_diff);
if (cos_angle == 0)
{
// It is opposite, perp1==perp2, do not generate a miter cap
return false;
}
// If it is sharp (angle close to 0), the distance will become too high and will be capped.
calc_t const max_distance = m_miter_limit * geometry::math::abs(buffer_distance);
calc_t const distance = (std::min)(max_distance, buffer_distance / cos_angle);
range_out.push_back(perp1);
helper::append_point(lon_rad, lat_rad, distance, azi, m_spheroid, range_out);
range_out.push_back(perp2);
return true;
}
template <typename NumericType>
inline NumericType max_distance(NumericType const& distance) const
{
return distance * m_miter_limit;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :
double valid_limit(double miter_limit) const
{
if (miter_limit < 1.0)
{
// It should always exceed the buffer distance
miter_limit = 1.0;
}
return miter_limit;
}
Spheroid m_spheroid;
double m_miter_limit;
};
}} // namespace strategy::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_JOIN_MITER_HPP

View File

@@ -0,0 +1,123 @@
// Boost.Geometry
// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// 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_BUFFER_JOIN_ROUND_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_JOIN_ROUND_HPP
#include <boost/range/value_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/strategies/geographic/buffer_helper.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace buffer
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic_join_round
{
public :
//! \brief Constructs the strategy with a spheroid
//! \param spheroid The spheroid to be used
//! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
explicit inline geographic_join_round(Spheroid const& spheroid,
std::size_t points_per_circle = default_points_per_circle)
: m_spheroid(spheroid)
, m_points_per_circle(get_point_count_for_join(points_per_circle))
{}
//! \brief Constructs the strategy
//! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
explicit inline geographic_join_round(std::size_t points_per_circle = default_points_per_circle)
: m_points_per_circle(get_point_count_for_join(points_per_circle))
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//! Fills output_range with a rounded shape around a vertex
template <typename Point, typename DistanceType, typename RangeOut>
inline bool apply(Point const& /*ip*/, Point const& vertex,
Point const& perp1, Point const& perp2,
DistanceType const& buffer_distance,
RangeOut& range_out) const
{
using calc_t = typename select_calculation_type
<
Point,
typename boost::range_value<RangeOut>::type,
CalculationType
>::type;
using helper = geographic_buffer_helper<FormulaPolicy, calc_t>;
calc_t const lon_rad = get_as_radian<0>(vertex);
calc_t const lat_rad = get_as_radian<1>(vertex);
calc_t first_azimuth;
calc_t angle_diff;
if (! helper::calculate_angles(lon_rad, lat_rad, perp1, perp2, m_spheroid,
angle_diff, first_azimuth))
{
return false;
}
static calc_t const two_pi = geometry::math::two_pi<calc_t>();
calc_t const circle_fraction = angle_diff / two_pi;
std::size_t const n = (std::max)(static_cast<std::size_t>(
std::ceil(m_points_per_circle * circle_fraction)), std::size_t(1));
calc_t const diff = angle_diff / static_cast<calc_t>(n);
calc_t azi = math::wrap_azimuth_in_radian(first_azimuth + diff);
range_out.push_back(perp1);
// Generate points between 0 and n, not including them
// because perp1 and perp2 are inserted before and after this range.
for (std::size_t i = 1; i < n; i++)
{
helper::append_point(lon_rad, lat_rad, buffer_distance, azi, m_spheroid, range_out);
azi = math::wrap_azimuth_in_radian(azi + diff);
}
range_out.push_back(perp2);
return true;
}
template <typename NumericType>
static inline NumericType max_distance(NumericType const& distance)
{
return distance;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :
Spheroid m_spheroid;
std::size_t m_points_per_circle;
};
}} // namespace strategy::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_JOIN_ROUND_HPP

View File

@@ -1,6 +1,10 @@
// Boost.Geometry
// Copyright (c) 2018-2019 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2018-2022 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2020-2021.
// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates.
// 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
@@ -11,11 +15,16 @@
#include <cstddef>
#include <boost/range.hpp>
#include <boost/range/value_type.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/strategies/geographic/buffer_helper.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
@@ -50,76 +59,75 @@ template
class geographic_point_circle
{
public :
//! \brief Constructs the strategy with a spheroid
//! \param spheroid The spheroid to be used
//! \param count Number of points (minimum 3) for the created circle
explicit inline geographic_point_circle(Spheroid const& spheroid,
std::size_t count = default_points_per_circle)
: m_spheroid(spheroid)
, m_count(get_point_count_for_circle(count))
{}
//! \brief Constructs the strategy
//! \param count number of points for the created circle (if count
//! is smaller than 3, count is internally set to 3)
explicit geographic_point_circle(std::size_t count = 90)
: m_count((count < 3u) ? 3u : count)
//! \param count Number of points (minimum 3) for the created circle
explicit inline geographic_point_circle(std::size_t count = default_points_per_circle)
: m_count(get_point_count_for_circle(count))
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//! Fills output_range with a circle around point using distance_strategy
//! Fills range_out with a circle around point using distance_strategy
template
<
typename Point,
typename OutputRange,
typename DistanceStrategy
typename DistanceStrategy,
typename RangeOut
>
inline void apply(Point const& point,
DistanceStrategy const& distance_strategy,
OutputRange& output_range) const
DistanceStrategy const& distance_strategy,
RangeOut& range_out) const
{
typedef typename boost::range_value<OutputRange>::type output_point_type;
typedef typename select_most_precise
using calc_t = typename select_calculation_type
<
typename geometry::coordinate_type<Point>::type,
typename geometry::coordinate_type<output_point_type>::type,
Point,
typename boost::range_value<RangeOut>::type,
CalculationType
//double
>::type calculation_type;
>::type;
calculation_type const buffer_distance = distance_strategy.apply(point, point,
strategy::buffer::buffer_side_left);
using helper = geographic_buffer_helper<FormulaPolicy, calc_t>;
typedef typename FormulaPolicy::template direct
<
calculation_type, true, false, false, false
> direct_t;
calc_t const lon_rad = get_as_radian<0>(point);
calc_t const lat_rad = get_as_radian<1>(point);
calculation_type const two_pi = geometry::math::two_pi<calculation_type>();
calc_t const buffer_distance = distance_strategy.apply(point,
point, strategy::buffer::buffer_side_left);
calculation_type const diff = two_pi / calculation_type(m_count);
// TODO: after calculation of some angles is corrected,
// we can start at 0.0
calculation_type angle = 0.001;
calc_t const two_pi = geometry::math::two_pi<calc_t>();
calc_t const pi = geometry::math::pi<calc_t>();
calc_t const diff = two_pi / calc_t(m_count);
calc_t angle = -pi;
for (std::size_t i = 0; i < m_count; i++, angle += diff)
{
typename direct_t::result_type
dir_r = direct_t::apply(get_as_radian<0>(point), get_as_radian<1>(point),
buffer_distance, angle,
m_spheroid);
output_point_type p;
set_from_radian<0>(p, dir_r.lon2);
set_from_radian<1>(p, dir_r.lat2);
output_range.push_back(p);
// If angle is zero, shift angle a tiny bit to avoid spikes.
calc_t const eps = angle == 0 ? 1.0e-10 : 0.0;
helper::append_point(lon_rad, lat_rad, buffer_distance, angle + eps, m_spheroid, range_out);
}
{
// Close the range
const output_point_type p = output_range.front();
output_range.push_back(p);
auto const p = range_out.front();
range_out.push_back(p);
}
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :
std::size_t m_count;
Spheroid m_spheroid;
std::size_t m_count;
};
}} // namespace strategy::buffer
}} // namespace boost::geometry

View File

@@ -0,0 +1,119 @@
// Boost.Geometry
// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
// 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_BUFFER_SIDE_STRAIGHT_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_SIDE_STRAIGHT_HPP
#include <cstddef>
#include <boost/range/value_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/strategies/geographic/buffer_helper.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace buffer
{
/*!
\brief Create a straight buffer along a side, on the Earth
\ingroup strategies
\details This strategy can be used as SideStrategy for the buffer algorithm.
*/
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic_side_straight
{
public :
//! \brief Constructs the strategy with a spheroid
//! \param spheroid The spheroid to be used
explicit inline geographic_side_straight(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
//! \brief Constructs the strategy
inline geographic_side_straight()
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Returns true if the buffer distance is always the same
static inline bool equidistant()
{
return true;
}
template
<
typename Point,
typename DistanceStrategy,
typename RangeOut
>
inline result_code apply(Point const& input_p1, Point const& input_p2,
buffer_side_selector side,
DistanceStrategy const& distance_strategy,
RangeOut& range_out) const
{
using calc_t = typename select_calculation_type
<
Point,
typename boost::range_value<RangeOut>::type,
CalculationType
>::type;
using helper = geographic_buffer_helper<FormulaPolicy, calc_t>;
calc_t const lon1_rad = get_as_radian<0>(input_p1);
calc_t const lat1_rad = get_as_radian<1>(input_p1);
calc_t const lon2_rad = get_as_radian<0>(input_p2);
calc_t const lat2_rad = get_as_radian<1>(input_p2);
if (lon1_rad == lon2_rad && lat1_rad == lat2_rad)
{
// Coordinates are simplified and therefore most often not equal.
// But if simplify is skipped, or for lines with two
// equal points, length is 0 and we cannot generate output.
return result_no_output;
}
// Measure the angle from p1 to p2 with the Inverse transformation,
// and subtract pi/2 to make it perpendicular.
auto const inv = helper::azimuth(lon1_rad, lat1_rad, input_p2, m_spheroid);
auto const angle = math::wrap_azimuth_in_radian(inv - geometry::math::half_pi<calc_t>());
// Calculate the distance and generate two points at that distance
auto const distance = distance_strategy.apply(input_p1, input_p2, side);
helper::append_point(lon1_rad, lat1_rad, distance, angle, m_spheroid, range_out);
helper::append_point(lon2_rad, lat2_rad, distance, angle, m_spheroid, range_out);
return result_normal;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :
Spheroid m_spheroid;
};
}} // namespace strategy::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_SIDE_STRAIGHT_HPP

View File

@@ -0,0 +1,100 @@
// Boost.Geometry
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, 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_CLOSEST_POINTS_CROSS_TRACK_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_CLOSEST_POINTS_CROSS_TRACK_HPP
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace closest_points
{
template
<
typename FormulaPolicy = geometry::strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic_cross_track
: public distance::detail::geographic_cross_track
<
FormulaPolicy,
Spheroid,
CalculationType,
false,
true
>
{
using base_t = distance::detail::geographic_cross_track
<
FormulaPolicy,
Spheroid,
CalculationType,
false,
true
>;
template <typename Point, typename PointOfSegment>
struct calculation_type
: promote_floating_point
<
typename select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>::type
>
{};
public :
explicit geographic_cross_track(Spheroid const& spheroid = Spheroid())
: base_t(spheroid)
{}
template <typename Point, typename PointOfSegment>
auto apply(Point const& p,
PointOfSegment const& sp1,
PointOfSegment const& sp2) const
{
auto result = base_t::apply(get_as_radian<0>(sp1), get_as_radian<1>(sp1),
get_as_radian<0>(sp2), get_as_radian<1>(sp2),
get_as_radian<0>(p), get_as_radian<1>(p),
base_t::m_spheroid);
model::point
<
typename calculation_type<Point, PointOfSegment>::type,
dimension<PointOfSegment>::value,
typename coordinate_system<PointOfSegment>::type
> cp;
geometry::set_from_radian<0>(cp, result.lon);
geometry::set_from_radian<1>(cp, result.lat);
return cp;
}
};
}} // namespace strategy::closest_points
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_CLOSEST_POINTS_CROSS_TRACK_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Copyright (c) 2017-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -108,6 +108,11 @@ public:
}
}
inline Spheroid const& model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Copyright (c) 2017-2019 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
@@ -31,11 +31,12 @@
#include <boost/geometry/srs/spheroid.hpp>
// TODO: spherical_point_box currently defined in the same file as cartesian
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
@@ -65,22 +66,11 @@ public:
: m_spheroid(spheroid)
{}
template <typename Segment, typename Box>
struct point_in_geometry_strategy
: services::default_strategy
<
typename point_type<Segment>::type,
Box
>
{};
typedef covered_by::spherical_point_box disjoint_point_box_strategy_type;
template <typename Segment, typename Box>
static inline typename point_in_geometry_strategy<Segment, Box>::type
get_point_in_geometry_strategy()
static inline disjoint_point_box_strategy_type get_disjoint_point_box_strategy()
{
typedef typename point_in_geometry_strategy<Segment, Box>::type strategy_type;
return strategy_type();
return disjoint_point_box_strategy_type();
}
template <typename Segment, typename Box>
@@ -103,6 +93,11 @@ public:
strategy::disjoint::spherical_box_box());
}
Spheroid const& model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};

View File

@@ -17,6 +17,7 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
@@ -32,7 +33,6 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Copyright (c) 2017-2021, 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
@@ -14,8 +14,6 @@
#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>
@@ -119,6 +117,12 @@ public:
typename distance_pp_strategy::type(m_spheroid),
typename distance_ps_strategy::type(m_spheroid));
}
Spheroid model() const
{
return m_spheroid;
}
private :
Spheroid m_spheroid;
};

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Copyright (c) 2017-2021, 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.
@@ -14,8 +14,6 @@
#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>
@@ -103,6 +101,11 @@ public:
typename distance_ps_strategy::type(m_spheroid));
}
Spheroid model() const
{
return m_spheroid;
}
private :
Spheroid m_spheroid;
};

View File

@@ -0,0 +1,116 @@
// Boost.Geometry
// Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan.
// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program.
// 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_KARNEY_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_KARNEY_HPP
#include <boost/geometry/strategies/geographic/distance.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace distance
{
/*!
\brief The solution of the inverse problem of geodesics on latlong coordinates,
after Karney (2011).
\ingroup distance
\tparam Spheroid The reference spheroid model
\tparam CalculationType \tparam_calculation
\author See
- Charles F.F Karney, Algorithms for geodesics, 2011
https://arxiv.org/pdf/1109.4448.pdf
*/
template
<
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class karney
: public strategy::distance::geographic
<
strategy::karney, Spheroid, CalculationType
>
{
typedef strategy::distance::geographic
<
strategy::karney, Spheroid, CalculationType
> base_type;
public:
inline karney()
: base_type()
{}
explicit inline karney(Spheroid const& spheroid)
: base_type(spheroid)
{}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Spheroid, typename CalculationType>
struct tag<karney<Spheroid, CalculationType> >
{
typedef strategy_tag_distance_point_point type;
};
template <typename Spheroid, typename CalculationType, typename P1, typename P2>
struct return_type<karney<Spheroid, CalculationType>, P1, P2>
: karney<Spheroid, CalculationType>::template calculation_type<P1, P2>
{};
template <typename Spheroid, typename CalculationType>
struct comparable_type<karney<Spheroid, CalculationType> >
{
typedef karney<Spheroid, CalculationType> type;
};
template <typename Spheroid, typename CalculationType>
struct get_comparable<karney<Spheroid, CalculationType> >
{
static inline karney<Spheroid, CalculationType> apply(karney<Spheroid, CalculationType> const& input)
{
return input;
}
};
template <typename Spheroid, typename CalculationType, typename P1, typename P2>
struct result_from_distance<karney<Spheroid, CalculationType>, P1, P2 >
{
template <typename T>
static inline typename return_type<karney<Spheroid, CalculationType>, P1, P2>::type
apply(karney<Spheroid, CalculationType> const& , T const& value)
{
return value;
}
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_KARNEY_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2018-2019 Oracle and/or its affiliates.
// Copyright (c) 2018-2021 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
@@ -13,18 +13,21 @@
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
#include <boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
#include <boost/geometry/strategies/spherical/distance_segment_box.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
@@ -55,40 +58,7 @@ struct geographic_segment_box
>
{};
// point-point strategy getters
struct distance_pp_strategy
{
typedef 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);
}
// point-segment strategy getters
struct distance_ps_strategy
{
typedef geographic_cross_track
<
FormulaPolicy,
Spheroid,
CalculationType
> type;
};
inline typename distance_ps_strategy::type get_distance_ps_strategy() const
{
typedef typename distance_ps_strategy::type distance_type;
return distance_type(m_spheroid);
}
typedef within::spherical_point_point equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return equals_point_point_strategy_type();
}
typedef geographic_tag cs_tag;
//constructor
@@ -96,43 +66,33 @@ struct geographic_segment_box
: m_spheroid(spheroid)
{}
Spheroid model() const
{
return m_spheroid;
}
// methods
template <typename LessEqual, typename ReturnType,
typename SegmentPoint, typename BoxPoint>
template
<
typename LessEqual, typename ReturnType,
typename SegmentPoint, typename BoxPoint,
typename Strategies
>
inline ReturnType segment_below_of_box(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right) const
SegmentPoint const& p1,
BoxPoint const& top_left,
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
Strategies const& strategies) const
{
typedef typename azimuth::geographic
<
FormulaPolicy,
Spheroid,
CalculationType
> azimuth_strategy_type;
azimuth_strategy_type az_strategy(m_spheroid);
typedef typename envelope::geographic_segment
<
FormulaPolicy,
Spheroid,
CalculationType
> envelope_segment_strategy_type;
envelope_segment_strategy_type es_strategy(m_spheroid);
return generic_segment_box::segment_below_of_box
<
LessEqual,
ReturnType
>(p0,p1,top_left,top_right,bottom_left,bottom_right,
geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>(),
az_strategy, es_strategy,
normalize::spherical_point(),
covered_by::spherical_point_box(),
disjoint::spherical_box_box());
strategies);
}
template <typename SPoint, typename BPoint>

View File

@@ -1,116 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// 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) 2020, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2018, 2019.
// Modifications copyright (c) 2015-2019, 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)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/expand_segment.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/spherical/envelope.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public spherical<CalculationType>
{
public:
typedef Spheroid model_type;
#include <boost/geometry/strategy/geographic/envelope.hpp>
inline geographic()
: m_spheroid()
{}
explicit inline geographic(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
typedef geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
> element_envelope_strategy_type;
inline element_envelope_strategy_type get_element_envelope_strategy() const
{
return element_envelope_strategy_type(m_spheroid);
}
typedef expand::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
> element_expand_strategy_type;
inline element_expand_strategy_type get_element_expand_strategy() const
{
return element_expand_strategy_type(m_spheroid);
}
template <typename Point1, typename Point2, typename Box>
inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const
{
geographic_segment
<
FormulaPolicy,
Spheroid,
CalculationType
>(m_spheroid).apply(point1, point2, box);
}
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_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP

View File

@@ -1,123 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2020, Oracle and/or its affiliates.
// Copyright (c) 2017-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
// 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)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/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/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/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)
{}
typedef strategy::expand::spherical_box box_expand_strategy_type;
static inline box_expand_strategy_type get_box_expand_strategy()
{
return box_expand_strategy_type();
}
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);
}
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
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
}} // namespace strategy::envelope
#include <boost/geometry/strategy/geographic/envelope_segment.hpp>
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP

View File

@@ -1,102 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// 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.
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_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/strategies/expand.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/spherical/expand_segment.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
namespace boost { namespace geometry
{
#include <boost/geometry/strategy/geographic/expand_segment.hpp>
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);
}
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_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP

View File

@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2016-2019, Oracle and/or its affiliates.
// Copyright (c) 2016-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -13,6 +13,7 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_HPP
#include <algorithm>
#include <type_traits>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
@@ -31,19 +32,22 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/concepts/segment_concept.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/policies/robustness/segment_ratio.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/geographic/area.hpp>
#include <boost/geometry/strategy/geographic/area.hpp>
#include <boost/geometry/strategy/geographic/envelope.hpp>
#include <boost/geometry/strategy/geographic/expand_segment.hpp>
#include <boost/geometry/strategy/spherical/expand_box.hpp>
#include <boost/geometry/strategies/geographic/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
#include <boost/geometry/strategies/geographic/envelope.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/geographic/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/spherical/expand_box.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/intersection.hpp>
@@ -68,132 +72,13 @@ namespace strategy { namespace intersection
template
<
typename FormulaPolicy = strategy::andoyer,
unsigned int Order = strategy::default_order<FormulaPolicy>::value,
std::size_t Order = strategy::default_order<FormulaPolicy>::value,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
struct geographic_segments
{
typedef side::geographic
<
FormulaPolicy, Spheroid, CalculationType
> side_strategy_type;
inline side_strategy_type get_side_strategy() const
{
return side_strategy_type(m_spheroid);
}
template <typename Geometry1, typename Geometry2>
struct point_in_geometry_strategy
{
typedef strategy::within::geographic_winding
<
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type,
FormulaPolicy,
Spheroid,
CalculationType
> type;
};
template <typename Geometry1, typename Geometry2>
inline typename point_in_geometry_strategy<Geometry1, Geometry2>::type
get_point_in_geometry_strategy() const
{
typedef typename point_in_geometry_strategy
<
Geometry1, Geometry2
>::type strategy_type;
return strategy_type(m_spheroid);
}
template <typename Geometry>
struct area_strategy
{
typedef area::geographic
<
FormulaPolicy,
Order,
Spheroid,
CalculationType
> type;
};
template <typename Geometry>
inline typename area_strategy<Geometry>::type get_area_strategy() const
{
typedef typename area_strategy<Geometry>::type strategy_type;
return strategy_type(m_spheroid);
}
template <typename Geometry>
struct distance_strategy
{
typedef distance::geographic
<
FormulaPolicy,
Spheroid,
CalculationType
> type;
};
template <typename Geometry>
inline typename distance_strategy<Geometry>::type get_distance_strategy() const
{
typedef typename distance_strategy<Geometry>::type strategy_type;
return strategy_type(m_spheroid);
}
typedef envelope::geographic<FormulaPolicy, Spheroid, CalculationType>
envelope_strategy_type;
inline envelope_strategy_type get_envelope_strategy() const
{
return envelope_strategy_type(m_spheroid);
}
typedef expand::geographic_segment<FormulaPolicy, Spheroid, CalculationType>
expand_strategy_type;
inline expand_strategy_type get_expand_strategy() const
{
return expand_strategy_type(m_spheroid);
}
typedef within::spherical_point_point point_in_point_strategy_type;
static inline point_in_point_strategy_type get_point_in_point_strategy()
{
return point_in_point_strategy_type();
}
typedef within::spherical_point_point equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return equals_point_point_strategy_type();
}
typedef disjoint::spherical_box_box disjoint_box_box_strategy_type;
static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
{
return disjoint_box_box_strategy_type();
}
typedef disjoint::segment_box_geographic
<
FormulaPolicy, Spheroid, CalculationType
> disjoint_segment_box_strategy_type;
inline disjoint_segment_box_strategy_type get_disjoint_segment_box_strategy() const
{
return disjoint_segment_box_strategy_type(m_spheroid);
}
typedef covered_by::spherical_point_box disjoint_point_box_strategy_type;
typedef expand::spherical_box expand_box_strategy_type;
typedef geographic_tag cs_tag;
enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 };
@@ -238,47 +123,30 @@ struct geographic_segments
: m_spheroid(spheroid)
{}
// Relate segments a and b
template
<
typename Segment1,
typename Segment2,
typename Policy,
typename RobustPolicy
>
inline typename Policy::return_type apply(Segment1 const& a, Segment2 const& b,
Policy const& policy,
RobustPolicy const& robust_policy) const
Spheroid model() const
{
typedef typename point_type<Segment1>::type point1_t;
typedef typename point_type<Segment2>::type point2_t;
point1_t a1, a2;
point2_t b1, b2;
detail::assign_point_from_index<0>(a, a1);
detail::assign_point_from_index<1>(a, a2);
detail::assign_point_from_index<0>(b, b1);
detail::assign_point_from_index<1>(b, b2);
return apply(a, b, policy, robust_policy, a1, a2, b1, b2);
return m_spheroid;
}
// Relate segments a and b
template
<
typename Segment1,
typename Segment2,
typename Policy,
typename RobustPolicy,
typename Point1,
typename Point2
typename UniqueSubRange1,
typename UniqueSubRange2,
typename Policy
>
inline typename Policy::return_type apply(Segment1 const& a, Segment2 const& b,
Policy const&, RobustPolicy const&,
Point1 a1, Point1 a2, Point2 b1, Point2 b2) const
inline typename Policy::return_type apply(UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
Policy const&) const
{
bool is_a_reversed = get<1>(a1) > get<1>(a2);
bool is_b_reversed = get<1>(b1) > get<1>(b2);
typedef typename UniqueSubRange1::point_type point1_type;
typedef typename UniqueSubRange2::point_type point2_type;
typedef model::referring_segment<point1_type const> segment_type1;
typedef model::referring_segment<point2_type const> segment_type2;
BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<point1_type>) );
BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<point2_type>) );
/*
typename coordinate_type<Point1>::type
const a1_lon = get<0>(a1),
@@ -288,18 +156,24 @@ struct geographic_segments
const b2_lon = get<0>(b2);
bool is_a_reversed = a1_lon > a2_lon || a1_lon == a2_lon && get<1>(a1) > get<1>(a2);
bool is_b_reversed = b1_lon > b2_lon || b1_lon == b2_lon && get<1>(b1) > get<1>(b2);
*/
if (is_a_reversed)
{
std::swap(a1, a2);
}
*/
if (is_b_reversed)
{
std::swap(b1, b2);
}
point1_type const& p0 = range_p.at(0);
point1_type const& p1 = range_p.at(1);
point2_type const& q0 = range_q.at(0);
point2_type const& q1 = range_q.at(1);
return apply<Policy>(a, b, a1, a2, b1, b2, is_a_reversed, is_b_reversed);
bool const is_p_reversed = get<1>(p0) > get<1>(p1);
bool const is_q_reversed = get<1>(q0) > get<1>(q1);
// Call apply with original segments and ordered points
return apply<Policy>(segment_type1(p0, p1),
segment_type2(q0, q1),
(is_p_reversed ? p1 : p0),
(is_p_reversed ? p0 : p1),
(is_q_reversed ? q1 : q0),
(is_q_reversed ? q0 : q1),
is_p_reversed, is_q_reversed);
}
private:
@@ -341,7 +215,7 @@ private:
: Policy::disjoint()
;
}
calc_t const a1_lon = get_as_radian<0>(a1);
calc_t const a1_lat = get_as_radian<1>(a1);
calc_t const a2_lon = get_as_radian<0>(a2);
@@ -441,7 +315,7 @@ private:
// NOTE: at this point the segments may still be disjoint
// NOTE: at this point one of the segments may be degenerated
bool collinear = sides.collinear();
bool collinear = sides.collinear();
if (! collinear)
{
@@ -494,7 +368,6 @@ private:
}
// NOTE: this is probably not needed
calc_t const c0 = 0;
int a1_on_b = position_value(c0, dist_a1_b1, dist_a1_b2);
int a2_on_b = position_value(dist_a1_a2, dist_a1_b1, dist_a1_b2);
int b1_on_a = position_value(c0, dist_b1_a1, dist_b1_a2);
@@ -652,7 +525,7 @@ private:
// distance for ratio
dist_1_o = dist_1_2 - dist_1_o;
}
return Policy::one_degenerate(segment, segment_ratio<CalcT>(dist_1_o, dist_1_2), degenerated_a);
}
@@ -891,13 +764,16 @@ private:
{
return false;
}
typedef typename FormulaPolicy::template inverse<CalcT, true, false, false, false, false> inverse_dist;
ip_flag = ipi_inters;
if (is_on_b1)
{
lon = b1_lon;
lat = b1_lat;
dist_a1_ip = inverse_dist::apply(a1_lon, a1_lat, lon, lat, spheroid).distance; // for consistency
dist_b1_ip = 0;
ip_flag = ipi_at_b1;
}
@@ -905,6 +781,7 @@ private:
{
lon = b2_lon;
lat = b2_lat;
dist_a1_ip = inverse_dist::apply(a1_lon, a1_lat, lon, lat, spheroid).distance; // for consistency
dist_b1_ip = res_b1_b2.distance;
ip_flag = ipi_at_b2;
}
@@ -914,6 +791,7 @@ private:
lon = a1_lon;
lat = a1_lat;
dist_a1_ip = 0;
dist_b1_ip = inverse_dist::apply(b1_lon, b1_lat, lon, lat, spheroid).distance; // for consistency
ip_flag = ipi_at_a1;
}
else if (is_on_a2)
@@ -921,8 +799,9 @@ private:
lon = a2_lon;
lat = a2_lat;
dist_a1_ip = res_a1_a2.distance;
dist_b1_ip = inverse_dist::apply(b1_lon, b1_lat, lon, lat, spheroid).distance; // for consistency
ip_flag = ipi_at_a2;
}
}
return true;
}
@@ -939,7 +818,7 @@ private:
static inline bool is_near(CalcT const& dist)
{
// NOTE: This strongly depends on the Inverse method
CalcT const small_number = CalcT(boost::is_same<CalcT, float>::value ? 0.0001 : 0.00000001);
CalcT const small_number = CalcT(std::is_same<CalcT, float>::value ? 0.0001 : 0.00000001);
return math::abs(dist) <= small_number;
}
@@ -994,8 +873,7 @@ private:
template <typename Point1, typename Point2>
static inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
{
return detail::equals::equals_point_point(point1, point2,
point_in_point_strategy_type());
return strategy::within::spherical_point_point::apply(point1, point2);
}
private:

View File

@@ -167,7 +167,7 @@ struct experimental_elliptic_segments_calc_policy
Point3d const v1 = normalized_vec(p1);
Point3d const v2 = normalized_vec(p2);
is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
return dot_product(v1, v2);
}

View File

@@ -1,8 +1,9 @@
// Boost.Geometry
// Copyright (c) 2018, Oracle and/or its affiliates.
// Copyright (c) 2018-2021, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -49,26 +50,12 @@ template
class geographic
{
public:
geographic()
: m_spheroid()
{}
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
// 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,
@@ -101,6 +88,11 @@ public:
set_from_radian<1>(p, dir_r.lat2);
}
inline Spheroid model() const
{
return m_spheroid;
}
private:
Spheroid m_spheroid;
};

View File

@@ -17,10 +17,10 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/side.hpp>

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017, Oracle and/or its affiliates.
// Copyright (c) 2017-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -10,14 +10,16 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_PARAMETERS_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_PARAMETERS_HPP
#include <type_traits>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/formulas/andoyer_inverse.hpp>
#include <boost/geometry/formulas/thomas_direct.hpp>
#include <boost/geometry/formulas/thomas_inverse.hpp>
#include <boost/geometry/formulas/vincenty_direct.hpp>
#include <boost/geometry/formulas/vincenty_inverse.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/geometry/formulas/karney_direct.hpp>
#include <boost/geometry/formulas/karney_inverse.hpp>
namespace boost { namespace geometry { namespace strategy
@@ -136,32 +138,72 @@ struct vincenty
{};
};
struct karney
{
template
<
typename CT,
bool EnableCoordinates = true,
bool EnableReverseAzimuth = false,
bool EnableReducedLength = false,
bool EnableGeodesicScale = false
>
struct direct
: formula::karney_direct
<
CT, EnableCoordinates, EnableReverseAzimuth,
EnableReducedLength, EnableGeodesicScale
>
{};
template
<
typename CT,
bool EnableDistance,
bool EnableAzimuth,
bool EnableReverseAzimuth = false,
bool EnableReducedLength = false,
bool EnableGeodesicScale = false
>
struct inverse
: formula::karney_inverse
<
CT, EnableDistance,
EnableAzimuth, EnableReverseAzimuth,
EnableReducedLength, EnableGeodesicScale
>
{};
};
template <typename FormulaPolicy>
struct default_order
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_TYPE
, (types<FormulaPolicy>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this type.",
FormulaPolicy);
};
template<>
struct default_order<andoyer>
: boost::mpl::integral_c<unsigned int, 1>
: std::integral_constant<unsigned int, 1>
{};
template<>
struct default_order<thomas>
: boost::mpl::integral_c<unsigned int, 2>
: std::integral_constant<unsigned int, 2>
{};
template<>
struct default_order<vincenty>
: boost::mpl::integral_c<unsigned int, 4>
: std::integral_constant<unsigned int, 4>
{};
template<>
struct default_order<karney>
: std::integral_constant<unsigned int, 8>
{};
}}} // namespace boost::geometry::strategy

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017 Oracle and/or its affiliates.
// Copyright (c) 2017-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -38,8 +38,8 @@ namespace strategy { namespace within
*/
template
<
typename Point,
typename PointOfSegment = Point,
typename Point = void, // for backward compatibility
typename PointOfSegment = Point, // for backward compatibility
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
@@ -47,16 +47,12 @@ template
class geographic_winding
: public within::detail::spherical_winding_base
<
Point,
PointOfSegment,
side::geographic<FormulaPolicy, Spheroid, CalculationType>,
CalculationType
>
{
typedef within::detail::spherical_winding_base
<
Point,
PointOfSegment,
side::geographic<FormulaPolicy, Spheroid, CalculationType>,
CalculationType
> base_t;
@@ -68,6 +64,11 @@ public:
explicit geographic_winding(Spheroid const& model)
: base_t(model)
{}
Spheroid const& model() const
{
return base_t::m_side_strategy.model();
}
};

View File

@@ -0,0 +1,120 @@
// Boost.Geometry
// Copyright (c) 2019, 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_POINT_ORDER_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_POINT_ORDER_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/point_order.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace point_order
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
struct geographic
{
typedef azimuth_tag version_tag;
template <typename Geometry>
struct result_type
{
typedef typename geometry::select_calculation_type_alt
<
CalculationType, Geometry
>::type type;
};
geographic()
{}
explicit geographic(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
template <typename Point>
inline bool apply(Point const& p1, Point const& p2,
typename result_type<Point>::type & azi,
typename result_type<Point>::type & razi) const
{
typedef typename result_type<Point>::type calc_t;
if (equals_point_point(p1, p2))
{
return false;
}
formula::result_inverse<calc_t> res = FormulaPolicy::template inverse
<
calc_t, false, true, true, false, false
>::apply(geometry::get_as_radian<0>(p1),
geometry::get_as_radian<1>(p1),
geometry::get_as_radian<0>(p2),
geometry::get_as_radian<1>(p2),
m_spheroid);
azi = res.azimuth;
razi = res.reverse_azimuth;
return true;
}
template <typename Point>
inline typename result_type<Point>::type
apply(Point const& /*p0*/, Point const& /*p1*/, Point const& /*p2*/,
typename result_type<Point>::type const& azi1,
typename result_type<Point>::type const& azi2) const
{
// TODO: support poles
return math::longitude_distance_signed<radian>(azi1, azi2);
}
private:
template <typename Point>
static bool equals_point_point(Point const& p0, Point const& p1)
{
return strategy::within::spherical_point_point::apply(p0, p1);
}
Spheroid m_spheroid;
};
namespace services
{
template <>
struct default_strategy<geographic_tag>
{
typedef geographic<> type;
};
} // namespace services
}} // namespace strategy::point_order
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_POINT_ORDER_HPP

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014-2018.
// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014-2021.
// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -16,6 +16,7 @@
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
@@ -23,17 +24,16 @@
#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>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
#include <boost/geometry/strategies/geographic/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/geographic/envelope.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
#include <boost/geometry/strategy/geographic/envelope.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
@@ -65,38 +65,9 @@ template
class geographic
{
public:
typedef strategy::envelope::geographic
<
FormulaPolicy,
Spheroid,
CalculationType
> envelope_strategy_type;
typedef geographic_tag cs_tag;
inline envelope_strategy_type get_envelope_strategy() const
{
return envelope_strategy_type(m_model);
}
typedef strategy::disjoint::segment_box_geographic
<
FormulaPolicy,
Spheroid,
CalculationType
> disjoint_strategy_type;
inline disjoint_strategy_type get_disjoint_strategy() const
{
return disjoint_strategy_type(m_model);
}
typedef strategy::within::spherical_point_point equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return equals_point_point_strategy_type();
}
geographic()
{}
geographic() = default;
explicit geographic(Spheroid const& model)
: m_model(model)
@@ -105,6 +76,14 @@ public:
template <typename P1, typename P2, typename P>
inline int apply(P1 const& p1, P2 const& p2, P const& p) const
{
typedef strategy::within::spherical_point_point equals_point_point_strategy_type;
if (equals_point_point_strategy_type::apply(p, p1)
|| equals_point_point_strategy_type::apply(p, p2)
|| equals_point_point_strategy_type::apply(p1, p2))
{
return 0;
}
typedef typename promote_floating_point
<
typename select_calculation_type_alt
@@ -123,6 +102,11 @@ public:
return formula::azimuth_side_value(a1p, a12);
}
Spheroid const& model() const
{
return m_model;
}
private:
template <typename ResultType,
typename InverseFormulaType,