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,195 +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_SPHERICAL_AREA_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_HPP
#include <boost/geometry/formulas/area_formulas.hpp>
#include <boost/geometry/srs/sphere.hpp>
#include <boost/geometry/strategies/area.hpp>
#include <boost/geometry/strategies/spherical/get_radius.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/spherical/area.hpp>
namespace strategy { namespace area
{
/*!
\brief Spherical area calculation
\ingroup strategies
\details Calculates area on the surface of a sphere using the trapezoidal rule
\tparam RadiusTypeOrSphere \tparam_radius_or_sphere
\tparam CalculationType \tparam_calculation
\qbk{
[heading See also]
[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
}
*/
template
<
typename RadiusTypeOrSphere = double,
typename CalculationType = void
>
class spherical
{
// Enables special handling of long segments
static const bool LongSegment = false;
public:
template <typename Geometry>
struct result_type
: strategy::area::detail::result_type
<
Geometry,
CalculationType
>
{};
template <typename Geometry>
class state
{
friend class spherical;
typedef typename result_type<Geometry>::type return_type;
public:
inline state()
: m_sum(0)
, m_crosses_prime_meridian(0)
{}
private:
template <typename RadiusType>
inline return_type area(RadiusType const& r) const
{
return_type result;
return_type radius = r;
// Encircles pole
if(m_crosses_prime_meridian % 2 == 1)
{
size_t times_crosses_prime_meridian
= 1 + (m_crosses_prime_meridian / 2);
result = return_type(2)
* geometry::math::pi<return_type>()
* times_crosses_prime_meridian
- geometry::math::abs(m_sum);
if(geometry::math::sign<return_type>(m_sum) == 1)
{
result = - result;
}
} else {
result = m_sum;
}
result *= radius * radius;
return result;
}
return_type m_sum;
// Keep track if encircles some pole
size_t m_crosses_prime_meridian;
};
public :
// For backward compatibility reasons the radius is set to 1
inline spherical()
: m_radius(1.0)
{}
template <typename RadiusOrSphere>
explicit inline spherical(RadiusOrSphere const& radius_or_sphere)
: m_radius(strategy_detail::get_radius
<
RadiusOrSphere
>::apply(radius_or_sphere))
{}
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
> area_formulas;
st.m_sum += area_formulas::template spherical<LongSegment>(p1, p2);
// 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_radius);
}
private :
typename strategy_detail::get_radius
<
RadiusTypeOrSphere
>::type m_radius;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <>
struct default_strategy<spherical_equatorial_tag>
{
typedef strategy::area::spherical<> type;
};
// Note: spherical polar coordinate system requires "get_as_radian_equatorial"
template <>
struct default_strategy<spherical_polar_tag>
{
typedef strategy::area::spherical<> type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_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,11 +12,13 @@
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AZIMUTH_HPP
#include <boost/geometry/strategies/azimuth.hpp>
#include <type_traits>
#include <boost/geometry/formulas/spherical.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/geometry/strategies/azimuth.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
@@ -25,61 +27,58 @@ namespace boost { namespace geometry
namespace strategy { namespace azimuth
{
template
<
typename CalculationType = void
>
template <typename CalculationType = void>
class spherical
{
public :
public:
template <typename T1, typename T2>
struct result_type
: geometry::select_most_precise
<
T1, T2, CalculationType
>
{};
inline spherical()
{}
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>
static inline void apply(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a1, Result& a2)
{
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>
static inline void apply(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a1)
{
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>
static inline void apply_reverse(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a2)
{
compute<false, true>(lon1_rad, lat1_rad,
lon2_rad, lat2_rad,
a2, a2);
}
private :
private:
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
static inline void compute(T1 const& lon1_rad, T1 const& lat1_rad,
T2 const& lon2_rad, T2 const& lat2_rad,
Result& a1, Result& a2)
{
typedef typename boost::mpl::if_
<
boost::is_void<CalculationType>, T, CalculationType
>::type calc_t;
typedef typename result_type<T1, T2>::type calc_t;
geometry::formula::result_spherical<calc_t>
result = geometry::formula::spherical_azimuth
@@ -105,19 +104,12 @@ private :
namespace services
{
template <typename CalculationType>
struct default_strategy<spherical_equatorial_tag, CalculationType>
template <>
struct default_strategy<spherical_equatorial_tag>
{
typedef strategy::azimuth::spherical<CalculationType> type;
typedef strategy::azimuth::spherical<> type;
};
/*
template <typename CalculationType>
struct default_strategy<spherical_polar_tag, CalculationType>
{
typedef strategy::azimuth::spherical<CalculationType> type;
};
*/
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

View File

@@ -0,0 +1,200 @@
// Boost.Geometry
// 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_SPHERICAL_CLOSEST_POINTS_CROSS_TRACK_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_CLOSEST_POINTS_CROSS_TRACK_HPP
#include <algorithm>
#include <type_traits>
#include <boost/config.hpp>
#include <boost/concept_check.hpp>
#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/tags.hpp>
#include <boost/geometry/formulas/spherical.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/spherical/intersection.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
# include <boost/geometry/io/dsv/write.hpp>
#endif
namespace boost { namespace geometry
{
namespace strategy { namespace closest_points
{
template
<
typename CalculationType = void,
typename Strategy = distance::comparable::haversine<double, CalculationType>
>
class cross_track
{
public:
template <typename Point, typename PointOfSegment>
struct calculation_type
: promote_floating_point
<
typename select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>::type
>
{};
using radius_type = typename Strategy::radius_type;
cross_track() = default;
explicit inline cross_track(typename Strategy::radius_type const& r)
: m_strategy(r)
{}
inline cross_track(Strategy const& s)
: m_strategy(s)
{}
template <typename Point, typename PointOfSegment>
inline auto apply(Point const& p,
PointOfSegment const& sp1,
PointOfSegment const& sp2) const
{
using CT = typename calculation_type<Point, PointOfSegment>::type;
// http://williams.best.vwh.net/avform.htm#XTE
CT d3 = m_strategy.apply(sp1, sp2);
if (geometry::math::equals(d3, 0.0))
{
// "Degenerate" segment, return either d1 or d2
return sp1;
}
CT d1 = m_strategy.apply(sp1, p);
CT d2 = m_strategy.apply(sp2, p);
auto d_crs_pair = distance::detail::compute_cross_track_pair<CT>::apply(
p, sp1, sp2);
// d1, d2, d3 are in principle not needed, only the sign matters
CT projection1 = cos(d_crs_pair.first) * d1 / d3;
CT projection2 = cos(d_crs_pair.second) * d2 / d3;
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " "
<< crs_AD * geometry::math::r2d<CT>() << std::endl;
std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " "
<< crs_AB * geometry::math::r2d<CT>() << std::endl;
std::cout << "Course " << dsv(sp2) << " to " << dsv(sp1) << " "
<< crs_BA * geometry::math::r2d<CT>() << std::endl;
std::cout << "Course " << dsv(sp2) << " to " << dsv(p) << " "
<< crs_BD * geometry::math::r2d<CT>() << std::endl;
std::cout << "Projection AD-AB " << projection1 << " : "
<< d_crs1 * geometry::math::r2d<CT>() << std::endl;
std::cout << "Projection BD-BA " << projection2 << " : "
<< d_crs2 * geometry::math::r2d<CT>() << std::endl;
std::cout << " d1: " << (d1 )
<< " d2: " << (d2 )
<< std::endl;
#endif
if (projection1 > 0.0 && projection2 > 0.0)
{
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
CT XTD = radius() * geometry::math::abs( asin( sin( d1 ) * sin( d_crs1 ) ));
std::cout << "Projection ON the segment" << std::endl;
std::cout << "XTD: " << XTD
<< " d1: " << (d1 * radius())
<< " d2: " << (d2 * radius())
<< std::endl;
#endif
auto distance = distance::detail::compute_cross_track_distance::apply(
d_crs_pair.first, d1);
CT lon1 = geometry::get_as_radian<0>(sp1);
CT lat1 = geometry::get_as_radian<1>(sp1);
CT lon2 = geometry::get_as_radian<0>(sp2);
CT lat2 = geometry::get_as_radian<1>(sp2);
CT dist = CT(2) * asin(math::sqrt(distance)) * m_strategy.radius();
CT dist_d1 = CT(2) * asin(math::sqrt(d1)) * m_strategy.radius();
// Note: this is similar to spherical computation in geographic
// point_segment_distance formula
CT earth_radius = m_strategy.radius();
CT cos_frac = cos(dist_d1 / earth_radius) / cos(dist / earth_radius);
CT s14_sph = cos_frac >= 1
? CT(0) : cos_frac <= -1 ? math::pi<CT>() * earth_radius
: acos(cos_frac) * earth_radius;
CT a12 = geometry::formula::spherical_azimuth<>(lon1, lat1, lon2, lat2);
auto res_direct = geometry::formula::spherical_direct
<
true,
false
>(lon1, lat1, s14_sph, a12, srs::sphere<CT>(earth_radius));
model::point
<
CT,
dimension<PointOfSegment>::value,
typename coordinate_system<PointOfSegment>::type
> cp;
geometry::set_from_radian<0>(cp, res_direct.lon2);
geometry::set_from_radian<1>(cp, res_direct.lat2);
return cp;
}
else
{
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Projection OUTSIDE the segment" << std::endl;
#endif
return d1 < d2 ? sp1 : sp2;
}
}
template <typename T1, typename T2>
inline radius_type vertical_or_meridian(T1 lat1, T2 lat2) const
{
return m_strategy.radius() * (lat1 - lat2);
}
inline typename Strategy::radius_type radius() const
{ return m_strategy.radius(); }
private :
Strategy m_strategy;
};
}} // namespace strategy::closest_points
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_CLOSEST_POINTS_CROSS_TRACK_HPP

View File

@@ -2,9 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2017-2023.
// Modifications copyright (c) 2017-2023, 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
// Use, modification and distribution is subject to the Boost Software License,
@@ -15,10 +16,7 @@
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPARE_HPP
#include <boost/mpl/if.hpp>
#include <boost/mpl/min.hpp>
#include <boost/type_traits/is_same.hpp>
#include <type_traits>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -48,14 +46,14 @@ namespace detail
template <std::size_t I, typename P>
static inline typename geometry::coordinate_type<P>::type
get(P const& p, boost::true_type /*same units*/)
get(P const& p, std::true_type /*same units*/)
{
return geometry::get<I>(p);
}
template <std::size_t I, typename P>
static inline typename geometry::coordinate_type<P>::type
get(P const& p, boost::false_type /*different units*/)
get(P const& p, std::false_type /*different units*/)
{
return geometry::get_as_radian<I>(p);
}
@@ -63,6 +61,7 @@ get(P const& p, boost::false_type /*different units*/)
template
<
typename ComparePolicy,
typename EqualsPolicy,
typename Point1,
typename Point2,
std::size_t DimensionCount
@@ -70,21 +69,21 @@ template
struct spherical_latitude
{
typedef typename geometry::coordinate_type<Point1>::type coordinate1_type;
typedef typename geometry::coordinate_system<Point1>::type::units units1_type;
typedef typename geometry::detail::cs_angular_units<Point1>::type units1_type;
typedef typename geometry::coordinate_type<Point2>::type coordinate2_type;
typedef typename geometry::coordinate_system<Point2>::type::units units2_type;
typedef typename boost::is_same<units1_type, units2_type>::type same_units_type;
typedef typename geometry::detail::cs_angular_units<Point2>::type units2_type;
typedef std::is_same<units1_type, units2_type> same_units_type;
template <typename T1, typename T2>
static inline bool apply(Point1 const& left, Point2 const& right,
T1 const& l1, T2 const& r1)
{
// latitudes equal
if (math::equals(l1, r1))
if (EqualsPolicy::apply(l1, r1))
{
return compare::detail::compare_loop
<
ComparePolicy, 2, DimensionCount
ComparePolicy, EqualsPolicy, 2, DimensionCount
>::apply(left, right);
}
else
@@ -105,10 +104,11 @@ struct spherical_latitude
template
<
typename ComparePolicy,
typename EqualsPolicy,
typename Point1,
typename Point2
>
struct spherical_latitude<ComparePolicy, Point1, Point2, 1>
struct spherical_latitude<ComparePolicy, EqualsPolicy, Point1, Point2, 1>
{
template <typename T1, typename T2>
static inline bool apply(Point1 const& left, Point2 const& right,
@@ -121,7 +121,7 @@ struct spherical_latitude<ComparePolicy, Point1, Point2, 1>
{
return compare::detail::compare_loop
<
ComparePolicy, 1, 1
ComparePolicy, EqualsPolicy, 1, 1
>::apply(left, right);
}
};
@@ -129,6 +129,7 @@ struct spherical_latitude<ComparePolicy, Point1, Point2, 1>
template
<
typename ComparePolicy,
typename EqualsPolicy,
typename Point1,
typename Point2,
std::size_t DimensionCount
@@ -136,13 +137,13 @@ template
struct spherical_longitude
{
typedef typename geometry::coordinate_type<Point1>::type coordinate1_type;
typedef typename geometry::coordinate_system<Point1>::type::units units1_type;
typedef typename geometry::detail::cs_angular_units<Point1>::type units1_type;
typedef typename geometry::coordinate_type<Point2>::type coordinate2_type;
typedef typename geometry::coordinate_system<Point2>::type::units units2_type;
typedef typename boost::is_same<units1_type, units2_type>::type same_units_type;
typedef typename boost::mpl::if_<same_units_type, units1_type, geometry::radian>::type units_type;
typedef typename geometry::detail::cs_angular_units<Point2>::type units2_type;
typedef std::is_same<units1_type, units2_type> same_units_type;
typedef std::conditional_t<same_units_type::value, units1_type, geometry::radian> units_type;
static const bool is_equatorial = ! boost::is_same
static const bool is_equatorial = ! std::is_same
<
typename geometry::cs_tag<Point1>::type,
geometry::spherical_polar_tag
@@ -168,18 +169,18 @@ struct spherical_longitude
bool is_left_at_antimeridian = false;
bool is_right_at_antimeridian = false;
// longitudes equal
if (math::equals(l0, r0)
if (EqualsPolicy::apply(l0, r0)
// both at antimeridian
|| are_both_at_antimeridian(l0, r0, is_left_at_antimeridian, is_right_at_antimeridian)
// both at pole
|| (math::equals(l1, r1)
|| (EqualsPolicy::apply(l1, r1)
&& math::is_latitude_pole<units_type, is_equatorial>(l1)))
{
return spherical_latitude
<
ComparePolicy, Point1, Point2, DimensionCount
ComparePolicy, EqualsPolicy, Point1, Point2, DimensionCount
>::apply(left, right, l1, r1);
}
// if left is at antimeridian and right is not at antimeridian
@@ -217,16 +218,17 @@ struct spherical_longitude
template
<
typename ComparePolicy,
typename EqualsPolicy,
int Dimension = -1
>
struct spherical
: cartesian<ComparePolicy, Dimension>
: cartesian<ComparePolicy, EqualsPolicy, Dimension>
{};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
// all dimensions starting from longitude
template <typename ComparePolicy>
struct spherical<ComparePolicy, -1>
template <typename ComparePolicy, typename EqualsPolicy>
struct spherical<ComparePolicy, EqualsPolicy, -1>
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right)
@@ -234,41 +236,43 @@ struct spherical<ComparePolicy, -1>
return compare::detail::spherical_longitude
<
ComparePolicy,
EqualsPolicy,
Point1,
Point2,
boost::mpl::min
std::conditional_t
<
geometry::dimension<Point1>,
geometry::dimension<Point2>
>::type::value
(dimension<Point1>::value < dimension<Point2>::value),
std::integral_constant<std::size_t, dimension<Point1>::value>,
std::integral_constant<std::size_t, dimension<Point2>::value>
>::value
>::apply(left, right);
}
};
// only longitudes (and latitudes to check poles)
template <typename ComparePolicy>
struct spherical<ComparePolicy, 0>
template <typename ComparePolicy, typename EqualsPolicy>
struct spherical<ComparePolicy, EqualsPolicy, 0>
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right)
{
return compare::detail::spherical_longitude
<
ComparePolicy, Point1, Point2, 1
ComparePolicy, EqualsPolicy, Point1, Point2, 1
>::apply(left, right);
}
};
// only latitudes
template <typename ComparePolicy>
struct spherical<ComparePolicy, 1>
template <typename ComparePolicy, typename EqualsPolicy>
struct spherical<ComparePolicy, EqualsPolicy, 1>
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right)
{
return compare::detail::spherical_latitude
<
ComparePolicy, Point1, Point2, 2
ComparePolicy, EqualsPolicy, Point1, Point2, 2
>::apply(left, right);
}
};
@@ -280,34 +284,48 @@ namespace services
{
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension>
template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy
<
ComparePolicy, Point1, Point2, Dimension,
ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
spherical_tag, spherical_tag
>
{
typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
};
template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy
<
ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
spherical_polar_tag, spherical_polar_tag
>
{
typedef compare::spherical<ComparePolicy, Dimension> type;
typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
};
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension>
template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy
<
ComparePolicy, Point1, Point2, Dimension,
ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
spherical_equatorial_tag, spherical_equatorial_tag
>
{
typedef compare::spherical<ComparePolicy, Dimension> type;
typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
};
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension>
template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy
<
ComparePolicy, Point1, Point2, Dimension,
ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
geographic_tag, geographic_tag
>
{
typedef compare::spherical<ComparePolicy, Dimension> type;
typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
};

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017-2019, 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
@@ -58,6 +58,11 @@ template
class spherical
{
public:
typedef typename strategy_detail::get_radius
<
RadiusTypeOrSphere
>::type radius_type;
// For consistency with area strategy the radius is set to 1
inline spherical()
: m_radius(1.0)
@@ -113,11 +118,13 @@ public:
}
}
inline radius_type radius() const
{
return m_radius;
}
private:
typename strategy_detail::get_radius
<
RadiusTypeOrSphere
>::type m_radius;
radius_type m_radius;
};

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
@@ -46,22 +46,11 @@ namespace boost { namespace geometry { namespace strategy { namespace disjoint
// other strategies that are used are intersection and covered_by strategies.
struct segment_box_spherical
{
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>

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2014 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 Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -17,14 +17,14 @@
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
#include <algorithm>
#include <type_traits>
#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/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/tags.hpp>
@@ -34,9 +34,9 @@
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/spherical/intersection.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
@@ -50,6 +50,82 @@ namespace boost { namespace geometry
namespace strategy { namespace distance
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename CalculationType>
struct compute_cross_track_pair
{
template <typename Point, typename PointOfSegment>
static inline auto apply(Point const& p,
PointOfSegment const& sp1,
PointOfSegment const& sp2)
{
CalculationType lon1 = geometry::get_as_radian<0>(sp1);
CalculationType lat1 = geometry::get_as_radian<1>(sp1);
CalculationType lon2 = geometry::get_as_radian<0>(sp2);
CalculationType lat2 = geometry::get_as_radian<1>(sp2);
CalculationType lon = geometry::get_as_radian<0>(p);
CalculationType lat = geometry::get_as_radian<1>(p);
CalculationType const crs_AD = geometry::formula::spherical_azimuth
<
CalculationType,
false
>(lon1, lat1, lon, lat).azimuth;
auto result = geometry::formula::spherical_azimuth
<
CalculationType,
true
>(lon1, lat1, lon2, lat2);
CalculationType crs_AB = result.azimuth;
CalculationType crs_BA = result.reverse_azimuth -
geometry::math::pi<CalculationType>();
CalculationType crs_BD = geometry::formula::spherical_azimuth
<
CalculationType,
false
>(lon2, lat2, lon, lat).azimuth;
CalculationType d_crs1 = crs_AD - crs_AB;
CalculationType d_crs2 = crs_BD - crs_BA;
return std::pair<CalculationType, CalculationType>(d_crs1, d_crs2);
}
};
struct compute_cross_track_distance
{
template <typename CalculationType>
static inline auto apply(CalculationType const& d_crs1,
CalculationType const& d1)
{
CalculationType const half(0.5);
CalculationType const quarter(0.25);
CalculationType sin_d_crs1 = sin(d_crs1);
/*
This is the straightforward obvious way to continue:
return_type discriminant
= 1.0 - 4.0 * (d1 - d1 * d1) * sin_d_crs1 * sin_d_crs1;
return 0.5 - 0.5 * math::sqrt(discriminant);
Below we optimize the number of arithmetic operations
and account for numerical robustness:
*/
CalculationType d1_x_sin = d1 * sin_d_crs1;
CalculationType d = d1_x_sin * (sin_d_crs1 - d1_x_sin);
return d / (half + math::sqrt(quarter - d));
}
};
}
#endif // DOXYGEN_NO_DETAIL
namespace comparable
{
@@ -159,7 +235,7 @@ namespace comparable
The distance d1 needed when the projection of the point D is within the
segment must be the true distance. However, comparable::haversine<>
returns a comparable distance instead of the one needed.
To remedy this, we implicitly compute what is needed.
To remedy this, we implicitly compute what is needed.
More precisely, we need to compute sin(true_d1):
sin(true_d1) = sin(2 * asin(sqrt(d1)))
@@ -329,9 +405,7 @@ template
>
class cross_track
{
public :
typedef within::spherical_point_point equals_point_point_strategy_type;
public:
template <typename Point, typename PointOfSegment>
struct return_type
: promote_floating_point
@@ -345,10 +419,9 @@ public :
>
{};
typedef typename Strategy::radius_type radius_type;
using radius_type = typename Strategy::radius_type;
inline cross_track()
{}
cross_track() = default;
explicit inline cross_track(typename Strategy::radius_type const& r)
: m_strategy(r)
@@ -375,7 +448,7 @@ public :
);
#endif
typedef typename return_type<Point, PointOfSegment>::type return_type;
using return_type = typename return_type<Point, PointOfSegment>::type;
// http://williams.best.vwh.net/avform.htm#XTE
return_type d1 = m_strategy.apply(sp1, p);
@@ -389,31 +462,12 @@ public :
return_type d2 = m_strategy.apply(sp2, p);
return_type lon1 = geometry::get_as_radian<0>(sp1);
return_type lat1 = geometry::get_as_radian<1>(sp1);
return_type lon2 = geometry::get_as_radian<0>(sp2);
return_type lat2 = geometry::get_as_radian<1>(sp2);
return_type lon = geometry::get_as_radian<0>(p);
return_type lat = geometry::get_as_radian<1>(p);
return_type crs_AD = geometry::formula::spherical_azimuth<return_type, false>
(lon1, lat1, lon, lat).azimuth;
geometry::formula::result_spherical<return_type> result =
geometry::formula::spherical_azimuth<return_type, true>
(lon1, lat1, lon2, lat2);
return_type crs_AB = result.azimuth;
return_type crs_BA = result.reverse_azimuth - geometry::math::pi<return_type>();
return_type crs_BD = geometry::formula::spherical_azimuth<return_type, false>
(lon2, lat2, lon, lat).azimuth;
return_type d_crs1 = crs_AD - crs_AB;
return_type d_crs2 = crs_BD - crs_BA;
auto d_crs_pair = detail::compute_cross_track_pair<return_type>::apply(
p, sp1, sp2);
// d1, d2, d3 are in principle not needed, only the sign matters
return_type projection1 = cos( d_crs1 ) * d1 / d3;
return_type projection2 = cos( d_crs2 ) * d2 / d3;
return_type projection1 = cos(d_crs_pair.first) * d1 / d3;
return_type projection2 = cos(d_crs_pair.second) * d2 / d3;
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " "
@@ -444,30 +498,14 @@ public :
<< " d2: " << (d2 * radius())
<< std::endl;
#endif
return_type const half(0.5);
return_type const quarter(0.25);
return_type sin_d_crs1 = sin(d_crs1);
/*
This is the straightforward obvious way to continue:
return_type discriminant
= 1.0 - 4.0 * (d1 - d1 * d1) * sin_d_crs1 * sin_d_crs1;
return 0.5 - 0.5 * math::sqrt(discriminant);
Below we optimize the number of arithmetic operations
and account for numerical robustness:
*/
return_type d1_x_sin = d1 * sin_d_crs1;
return_type d = d1_x_sin * (sin_d_crs1 - d1_x_sin);
return d / (half + math::sqrt(quarter - d));
return detail::compute_cross_track_distance::apply(
d_crs_pair.first, d1);
}
else
{
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Projection OUTSIDE the segment" << std::endl;
#endif
// Return shortest distance, project either on point sp1 or sp2
return return_type( (std::min)( d1 , d2 ) );
}
@@ -511,7 +549,6 @@ template
class cross_track
{
public :
typedef within::spherical_point_point equals_point_point_strategy_type;
template <typename Point, typename PointOfSegment>
struct return_type
@@ -526,7 +563,7 @@ public :
>
{};
typedef typename Strategy::radius_type radius_type;
using radius_type = typename Strategy::radius_type;
inline cross_track()
{}
@@ -545,8 +582,9 @@ public :
template <typename Point, typename PointOfSegment>
inline typename return_type<Point, PointOfSegment>::type
apply(Point const& p, PointOfSegment const& sp1, PointOfSegment const& sp2) const
inline auto apply(Point const& p,
PointOfSegment const& sp1,
PointOfSegment const& sp2) const
{
#if !defined(BOOST_MSVC)
@@ -555,13 +593,13 @@ public :
(concepts::PointDistanceStrategy<Strategy, Point, PointOfSegment>)
);
#endif
typedef typename return_type<Point, PointOfSegment>::type return_type;
typedef cross_track<CalculationType, Strategy> this_type;
using return_type = typename return_type<Point, PointOfSegment>::type;
using this_type = cross_track<CalculationType, Strategy>;
typedef typename services::comparable_type
using comparable_type = typename services::comparable_type
<
this_type
>::type comparable_type;
>::type;
comparable_type cstrategy
= services::get_comparable<this_type>::apply(m_strategy);
@@ -594,7 +632,7 @@ namespace services
template <typename CalculationType, typename Strategy>
struct tag<cross_track<CalculationType, Strategy> >
{
typedef strategy_tag_distance_point_segment type;
using type = strategy_tag_distance_point_segment;
};
@@ -607,10 +645,10 @@ struct return_type<cross_track<CalculationType, Strategy>, P, PS>
template <typename CalculationType, typename Strategy>
struct comparable_type<cross_track<CalculationType, Strategy> >
{
typedef comparable::cross_track
using type = comparable::cross_track
<
CalculationType, typename comparable_type<Strategy>::type
> type;
> ;
};
@@ -621,10 +659,10 @@ template
>
struct get_comparable<cross_track<CalculationType, Strategy> >
{
typedef typename comparable_type
using comparable_type = typename comparable_type
<
cross_track<CalculationType, Strategy>
>::type comparable_type;
>::type;
public :
static inline comparable_type
apply(cross_track<CalculationType, Strategy> const& strategy)
@@ -644,10 +682,10 @@ template
struct result_from_distance<cross_track<CalculationType, Strategy>, P, PS>
{
private :
typedef typename cross_track
using return_type = typename cross_track
<
CalculationType, Strategy
>::template return_type<P, PS>::type return_type;
>::template return_type<P, PS>::type;
public :
template <typename T>
static inline return_type
@@ -662,7 +700,7 @@ public :
template <typename RadiusType, typename CalculationType>
struct tag<comparable::cross_track<RadiusType, CalculationType> >
{
typedef strategy_tag_distance_point_segment type;
using type = strategy_tag_distance_point_segment;
};
@@ -684,7 +722,7 @@ struct return_type<comparable::cross_track<RadiusType, CalculationType>, P, PS>
template <typename RadiusType, typename CalculationType>
struct comparable_type<comparable::cross_track<RadiusType, CalculationType> >
{
typedef comparable::cross_track<RadiusType, CalculationType> type;
using type = comparable::cross_track<RadiusType, CalculationType>;
};
@@ -692,7 +730,7 @@ template <typename RadiusType, typename CalculationType>
struct get_comparable<comparable::cross_track<RadiusType, CalculationType> >
{
private :
typedef comparable::cross_track<RadiusType, CalculationType> this_type;
using this_type = comparable::cross_track<RadiusType, CalculationType>;
public :
static inline this_type apply(this_type const& input)
{
@@ -714,8 +752,8 @@ struct result_from_distance
>
{
private :
typedef comparable::cross_track<RadiusType, CalculationType> strategy_type;
typedef typename return_type<strategy_type, P, PS>::type return_type;
using strategy_type = comparable::cross_track<RadiusType, CalculationType>;
using return_type = typename return_type<strategy_type, P, PS>::type;
public :
template <typename T>
static inline return_type apply(strategy_type const& strategy,
@@ -744,16 +782,16 @@ struct default_strategy
typedef cross_track
<
void,
typename boost::mpl::if_
std::conditional_t
<
boost::is_void<Strategy>,
std::is_void<Strategy>::value,
typename default_strategy
<
point_tag, Point, PointOfSegment,
spherical_polar_tag, spherical_polar_tag
>::type,
Strategy
>::type
>
> type;
};
*/
@@ -766,20 +804,20 @@ struct default_strategy
Strategy
>
{
typedef cross_track
using type = cross_track
<
void,
typename boost::mpl::if_
std::conditional_t
<
boost::is_void<Strategy>,
std::is_void<Strategy>::value,
typename default_strategy
<
point_tag, point_tag, Point, PointOfSegment,
spherical_equatorial_tag, spherical_equatorial_tag
>::type,
Strategy
>::type
> type;
>
>;
};
@@ -791,12 +829,12 @@ struct default_strategy
Strategy
>
{
typedef typename default_strategy
using type = typename default_strategy
<
point_tag, segment_tag, Point, PointOfSegment,
spherical_equatorial_tag, spherical_equatorial_tag,
Strategy
>::type type;
>::type;
};

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2016-2018 Oracle and/or its affiliates.
// 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
@@ -11,10 +11,11 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_BOX_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_BOX_BOX_HPP
#include <type_traits>
#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>
@@ -295,19 +296,19 @@ public:
Strategy
>::type pp_comparable_strategy;
typedef typename boost::mpl::if_
typedef std::conditional_t
<
boost::is_same
std::is_same
<
pp_comparable_strategy,
Strategy
>,
>::value,
typename strategy::distance::services::comparable_type
<
typename distance_ps_strategy::type
>::type,
typename distance_ps_strategy::type
>::type ps_strategy_type;
> ps_strategy_type;
// constructors
@@ -448,9 +449,9 @@ struct default_strategy
typedef cross_track_box_box
<
void,
typename boost::mpl::if_
std::conditional_t
<
boost::is_void<Strategy>,
std::is_void<Strategy>::value,
typename default_strategy
<
point_tag, point_tag,
@@ -458,7 +459,7 @@ struct default_strategy
spherical_equatorial_tag, spherical_equatorial_tag
>::type,
Strategy
>::type
>
> type;
};

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014-2017.
// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-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
@@ -18,10 +18,11 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
#include <type_traits>
#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>
@@ -222,19 +223,19 @@ public:
Strategy
>::type pp_comparable_strategy;
typedef typename boost::mpl::if_
typedef std::conditional_t
<
boost::is_same
std::is_same
<
pp_comparable_strategy,
Strategy
>,
>::value,
typename strategy::distance::services::comparable_type
<
typename distance_ps_strategy::type
>::type,
typename distance_ps_strategy::type
>::type ps_strategy_type;
> ps_strategy_type;
// constructors
@@ -372,9 +373,9 @@ struct default_strategy
typedef cross_track_point_box
<
void,
typename boost::mpl::if_
std::conditional_t
<
boost::is_void<Strategy>,
std::is_void<Strategy>::value,
typename default_strategy
<
point_tag, point_tag,
@@ -382,7 +383,7 @@ struct default_strategy
spherical_equatorial_tag, spherical_equatorial_tag
>::type,
Strategy
>::type
>
> type;
};

View File

@@ -17,6 +17,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/radian_access.hpp>
@@ -26,7 +27,6 @@
#include <boost/geometry/strategies/spherical/get_radius.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.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
@@ -11,14 +11,19 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_SEGMENT_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_SEGMENT_BOX_HPP
#include <type_traits>
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
#include <boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp> // spherical
#include <boost/geometry/strategies/spherical/ssf.hpp>
namespace boost { namespace geometry
{
@@ -35,12 +40,7 @@ struct generic_segment_box
typename ReturnType,
typename SegmentPoint,
typename BoxPoint,
typename SegmentBoxStrategy,
typename AzimuthStrategy,
typename EnvelopeSegmentStrategy,
typename NormalizePointStrategy,
typename DisjointPointBoxStrategy,
typename DisjointBoxBoxStrategy
typename Strategies
>
static inline ReturnType segment_below_of_box(
SegmentPoint const& p0,
@@ -49,23 +49,32 @@ struct generic_segment_box
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
SegmentBoxStrategy const& sb_strategy,
AzimuthStrategy const& az_strategy,
EnvelopeSegmentStrategy const& es_strategy,
NormalizePointStrategy const& np_strategy,
DisjointPointBoxStrategy const& dpb_strategy,
DisjointBoxBoxStrategy const& dbb_strategy)
Strategies const& strategies)
{
ReturnType result;
typename LessEqual::other less_equal;
typedef geometry::model::segment<SegmentPoint> Segment;
typedef typename cs_tag<Segment>::type segment_cs_type;
typedef geometry::model::segment<SegmentPoint> segment_type;
// if cs_tag is spherical_tag check segment's cs_tag with spherical_equatorial_tag as default
typedef std::conditional_t
<
std::is_same<typename Strategies::cs_tag, spherical_tag>::value,
std::conditional_t
<
std::is_same
<
typename geometry::cs_tag<segment_type>::type,
spherical_polar_tag
>::value,
spherical_polar_tag, spherical_equatorial_tag
>,
typename Strategies::cs_tag
> cs_tag;
typedef geometry::detail::disjoint::
disjoint_segment_box_sphere_or_spheroid<segment_cs_type>
disjoint_segment_box_sphere_or_spheroid<cs_tag>
disjoint_sb;
typedef typename disjoint_sb::disjoint_info disjoint_info_type;
Segment seg(p0, p1);
segment_type seg(p0, p1);
geometry::model::box<BoxPoint> input_box;
geometry::set_from_radian<geometry::min_corner, 0>
@@ -79,9 +88,14 @@ struct generic_segment_box
SegmentPoint p_max;
// TODO: Think about rewriting this and simply passing strategies
// The problem is that this algorithm is called by disjoint(S/B) strategies.
disjoint_info_type disjoint_result = disjoint_sb::
apply(seg, input_box, p_max,
az_strategy, np_strategy, dpb_strategy, dbb_strategy);
strategies.azimuth(),
strategies.normalize(p0),
strategies.covered_by(p0, input_box), // disjoint
strategies.disjoint(input_box, input_box));
if (disjoint_result == disjoint_info_type::intersect) //intersect
{
@@ -93,7 +107,7 @@ struct generic_segment_box
typedef typename coordinate_type<SegmentPoint>::type CT;
geometry::model::box<SegmentPoint> mbr;
geometry::envelope(seg, mbr, es_strategy);
geometry::envelope(seg, mbr, strategies);
CT lon1 = geometry::get_as_radian<0>(p0);
CT lat1 = geometry::get_as_radian<1>(p0);
@@ -116,13 +130,15 @@ struct generic_segment_box
}
CT alp1;
az_strategy.apply(lon1, lat1, lon2, lat2, alp1);
strategies.azimuth().apply(lon1, lat1, lon2, lat2, alp1);
// TODO: formula should not call strategy!
CT vertex_lon = geometry::formula::vertex_longitude
<
CT,
segment_cs_type
CT,
cs_tag
>::apply(lon1, lat1, lon2, lat2,
vertex_lat, alp1, az_strategy);
vertex_lat, alp1, strategies.azimuth());
geometry::set_from_radian<0>(p_max, vertex_lon);
geometry::set_from_radian<1>(p_max, vertex_lat);
@@ -132,21 +148,22 @@ struct generic_segment_box
if (less_equal(geometry::get_as_radian<0>(bottom_left),
geometry::get_as_radian<0>(p_max)))
{
result = boost::numeric_cast<ReturnType>(typename
SegmentBoxStrategy::distance_ps_strategy::type().apply(bottom_left, p0, p1));
result = boost::numeric_cast<ReturnType>(
strategies.distance(bottom_left, seg).apply(bottom_left, p0, p1));
}
else
{
// TODO: The strategy should not call the algorithm like that
result = geometry::detail::distance::segment_to_box_2D
<
ReturnType,
SegmentPoint,
BoxPoint,
SegmentBoxStrategy
>::template call_above_of_box
<
typename LessEqual::other
>(p1, p0, p_max, bottom_right, sb_strategy);
<
ReturnType,
SegmentPoint,
BoxPoint,
Strategies
>::template call_above_of_box
<
typename LessEqual::other
>(p1, p0, p_max, bottom_right, strategies);
}
return result;
}
@@ -196,64 +213,48 @@ struct spherical_segment_box
>
{};
// strategy getters
typedef spherical_tag cs_tag;
// point-point strategy getters
struct distance_pp_strategy
{
typedef Strategy type;
};
// constructors
inline typename distance_pp_strategy::type get_distance_pp_strategy() const
{
return typename distance_pp_strategy::type();
}
// point-segment strategy getters
struct distance_ps_strategy
{
typedef cross_track<CalculationType, Strategy> type;
};
inline spherical_segment_box()
{}
inline typename distance_ps_strategy::type get_distance_ps_strategy() const
{
return typename distance_ps_strategy::type();
}
explicit inline spherical_segment_box(typename Strategy::radius_type const& r)
: m_strategy(r)
{}
typedef within::spherical_point_point equals_point_point_strategy_type;
inline spherical_segment_box(Strategy const& s)
: m_strategy(s)
{}
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
typename Strategy::radius_type radius() const
{
return equals_point_point_strategy_type();
return m_strategy.radius();
}
// 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::spherical<CalculationType> azimuth_strategy_type;
azimuth_strategy_type az_strategy;
typedef typename envelope::spherical_segment<CalculationType>
envelope_segment_strategy_type;
envelope_segment_strategy_type es_strategy;
return generic_segment_box::segment_below_of_box
<
LessEqual,
ReturnType
>(p0,p1,top_left,top_right,bottom_left,bottom_right,
spherical_segment_box<CalculationType>(),
az_strategy, es_strategy,
normalize::spherical_point(),
covered_by::spherical_point_box(),
disjoint::spherical_box_box());
strategies);
}
template <typename SPoint, typename BPoint>
@@ -270,6 +271,8 @@ struct spherical_segment_box
top_left, top_right);
}
private:
Strategy m_strategy;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

View File

@@ -1,146 +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.
// 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
// 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_SPHERICAL_ENVELOPE_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_HPP
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
#include <boost/geometry/iterators/segment_iterator.hpp>
#include <boost/geometry/strategies/spherical/envelope_box.hpp>
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/expand_box.hpp>
#include <boost/geometry/strategies/spherical/expand_segment.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
template <typename CalculationType = void>
class spherical
{
public:
typedef spherical_segment<CalculationType> element_envelope_strategy_type;
static inline element_envelope_strategy_type get_element_envelope_strategy()
{
return element_envelope_strategy_type();
}
typedef expand::spherical_segment<CalculationType> element_expand_strategy_type;
static inline element_expand_strategy_type get_element_expand_strategy()
{
return element_expand_strategy_type();
}
typedef strategy::expand::spherical_box box_expand_strategy_type;
static inline box_expand_strategy_type get_box_expand_strategy()
{
return box_expand_strategy_type();
}
// Linestring, Ring, Polygon
template <typename Range>
static inline geometry::segment_iterator<Range const> begin(Range const& range)
{
return geometry::segments_begin(range);
}
template <typename Range>
static inline geometry::segment_iterator<Range const> end(Range const& range)
{
return geometry::segments_end(range);
}
// MultiLinestring, MultiPolygon
template <typename Box>
struct multi_state
{
void apply(Box const& single_box)
{
m_boxes.push_back(single_box);
}
void result(Box & box)
{
if (!m_boxes.empty())
{
geometry::detail::envelope::envelope_range_of_boxes::apply(m_boxes, box);
}
else
{
geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(box);
}
}
private:
std::vector<Box> m_boxes;
};
// Segment
template <typename Point1, typename Point2, typename Box>
static inline void apply(Point1 const& point1, Point2 const& point2,
Box& box)
{
spherical_segment<CalculationType>::apply(point1, point2, box);
}
// Box
template <typename BoxIn, typename Box>
static inline void apply(BoxIn const& box_in, Box& box)
{
spherical_box::apply(box_in, box);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Tag, typename CalculationType>
struct default_strategy<Tag, spherical_equatorial_tag, CalculationType>
{
typedef strategy::envelope::spherical<CalculationType> type;
};
template <typename Tag, typename CalculationType>
struct default_strategy<Tag, spherical_polar_tag, CalculationType>
{
typedef strategy::envelope::spherical<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/spherical/envelope.hpp>
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_HPP

View File

@@ -1,145 +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-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_SPHERICAL_ENVELOPE_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_BOX_HPP
#include <cstddef>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
#include <boost/geometry/strategies/envelope.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
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace envelope
{
template
<
std::size_t Index,
std::size_t DimensionCount
>
struct envelope_indexed_box_on_spheroid
{
template <typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
// transform() does not work with boxes of dimension higher
// than 2; to account for such boxes we transform the min/max
// points of the boxes using the indexed_point_view
detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
// first transform the units
transform_units(box_in_corner, mbr_corner);
// now transform the remaining coordinates
detail::conversion::point_to_point
<
detail::indexed_point_view<BoxIn const, Index>,
detail::indexed_point_view<BoxOut, Index>,
2,
DimensionCount
>::apply(box_in_corner, mbr_corner);
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
namespace strategy { namespace envelope
{
struct spherical_box
{
template <typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
BoxIn box_in_normalized = box_in;
if (!is_inverse_spheroidal_coordinates(box_in))
{
strategy::normalize::spherical_box::apply(box_in, box_in_normalized);
}
geometry::detail::envelope::envelope_indexed_box_on_spheroid
<
min_corner, dimension<BoxIn>::value
>::apply(box_in_normalized, mbr);
geometry::detail::envelope::envelope_indexed_box_on_spheroid
<
max_corner, dimension<BoxIn>::value
>::apply(box_in_normalized, mbr);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<box_tag, spherical_equatorial_tag, CalculationType>
{
typedef strategy::envelope::spherical_box type;
};
template <typename CalculationType>
struct default_strategy<box_tag, spherical_polar_tag, CalculationType>
{
typedef strategy::envelope::spherical_box type;
};
template <typename CalculationType>
struct default_strategy<box_tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::spherical_box type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#include <boost/geometry/strategy/spherical/envelope_box.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_BOX_HPP

View File

@@ -1,379 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2015-2018, Oracle and/or its affiliates.
// Copyright (c) 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
// 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_SPHERICAL_ENVELOPE_MULTIPOINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_MULTIPOINT_HPP
#include <cstddef>
#include <algorithm>
#include <utility>
#include <vector>
#include <boost/algorithm/minmax_element.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/helper_geometry.hpp>
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
#include <boost/geometry/algorithms/detail/expand/point.hpp>
#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/spherical/envelope_box.hpp>
#include <boost/geometry/strategies/spherical/envelope_point.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/spherical/envelope_multipoint.hpp>
namespace strategy { namespace envelope
{
class spherical_multipoint
{
private:
template <std::size_t Dim>
struct coordinate_less
{
template <typename Point>
inline bool operator()(Point const& point1, Point const& point2) const
{
return math::smaller(geometry::get<Dim>(point1),
geometry::get<Dim>(point2));
}
};
template <typename Constants, typename MultiPoint, typename OutputIterator>
static inline void analyze_point_coordinates(MultiPoint const& multipoint,
bool& has_south_pole,
bool& has_north_pole,
OutputIterator oit)
{
typedef typename boost::range_value<MultiPoint>::type point_type;
typedef typename boost::range_iterator
<
MultiPoint const
>::type iterator_type;
// analyze point coordinates:
// (1) normalize point coordinates
// (2) check if any point is the north or the south pole
// (3) put all non-pole points in a container
//
// notice that at this point in the algorithm, we have at
// least two points on the spheroid
has_south_pole = false;
has_north_pole = false;
for (iterator_type it = boost::begin(multipoint);
it != boost::end(multipoint);
++it)
{
point_type point;
normalize::spherical_point::apply(*it, point);
if (math::equals(geometry::get<1>(point),
Constants::min_latitude()))
{
has_south_pole = true;
}
else if (math::equals(geometry::get<1>(point),
Constants::max_latitude()))
{
has_north_pole = true;
}
else
{
*oit++ = point;
}
}
}
template <typename SortedRange, typename Value>
static inline Value maximum_gap(SortedRange const& sorted_range,
Value& max_gap_left,
Value& max_gap_right)
{
typedef typename boost::range_iterator
<
SortedRange const
>::type iterator_type;
iterator_type it1 = boost::begin(sorted_range), it2 = it1;
++it2;
max_gap_left = geometry::get<0>(*it1);
max_gap_right = geometry::get<0>(*it2);
Value max_gap = max_gap_right - max_gap_left;
for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2)
{
Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1);
if (math::larger(gap, max_gap))
{
max_gap_left = geometry::get<0>(*it1);
max_gap_right = geometry::get<0>(*it2);
max_gap = gap;
}
}
return max_gap;
}
template
<
typename Constants,
typename PointRange,
typename LongitudeLess,
typename CoordinateType
>
static inline void get_min_max_longitudes(PointRange& range,
LongitudeLess const& lon_less,
CoordinateType& lon_min,
CoordinateType& lon_max)
{
typedef typename boost::range_iterator
<
PointRange const
>::type iterator_type;
// compute min and max longitude values
std::pair<iterator_type, iterator_type> min_max_longitudes
= boost::minmax_element(boost::begin(range),
boost::end(range),
lon_less);
lon_min = geometry::get<0>(*min_max_longitudes.first);
lon_max = geometry::get<0>(*min_max_longitudes.second);
// if the longitude span is "large" compute the true maximum gap
if (math::larger(lon_max - lon_min, Constants::half_period()))
{
std::sort(boost::begin(range), boost::end(range), lon_less);
CoordinateType max_gap_left = 0, max_gap_right = 0;
CoordinateType max_gap
= maximum_gap(range, max_gap_left, max_gap_right);
CoordinateType complement_gap
= Constants::period() + lon_min - lon_max;
if (math::larger(max_gap, complement_gap))
{
lon_min = max_gap_right;
lon_max = max_gap_left + Constants::period();
}
}
}
template
<
typename Constants,
typename Iterator,
typename LatitudeLess,
typename CoordinateType
>
static inline void get_min_max_latitudes(Iterator const first,
Iterator const last,
LatitudeLess const& lat_less,
bool has_south_pole,
bool has_north_pole,
CoordinateType& lat_min,
CoordinateType& lat_max)
{
if (has_south_pole && has_north_pole)
{
lat_min = Constants::min_latitude();
lat_max = Constants::max_latitude();
}
else if (has_south_pole)
{
lat_min = Constants::min_latitude();
lat_max
= geometry::get<1>(*std::max_element(first, last, lat_less));
}
else if (has_north_pole)
{
lat_min
= geometry::get<1>(*std::min_element(first, last, lat_less));
lat_max = Constants::max_latitude();
}
else
{
std::pair<Iterator, Iterator> min_max_latitudes
= boost::minmax_element(first, last, lat_less);
lat_min = geometry::get<1>(*min_max_latitudes.first);
lat_max = geometry::get<1>(*min_max_latitudes.second);
}
}
public:
template <typename MultiPoint, typename Box>
static inline void apply(MultiPoint const& multipoint, Box& mbr)
{
typedef typename point_type<MultiPoint>::type point_type;
typedef typename coordinate_type<MultiPoint>::type coordinate_type;
typedef typename boost::range_iterator
<
MultiPoint const
>::type iterator_type;
typedef math::detail::constants_on_spheroid
<
coordinate_type,
typename geometry::detail::cs_angular_units<MultiPoint>::type
> constants;
if (boost::empty(multipoint))
{
geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(mbr);
return;
}
geometry::detail::envelope::initialize<Box, 0, 2>::apply(mbr);
if (boost::size(multipoint) == 1)
{
return dispatch::envelope
<
typename boost::range_value<MultiPoint>::type
>::apply(range::front(multipoint), mbr, strategy::envelope::spherical_point());
}
// analyze the points and put the non-pole ones in the
// points vector
std::vector<point_type> points;
bool has_north_pole = false, has_south_pole = false;
analyze_point_coordinates<constants>(multipoint,
has_south_pole, has_north_pole,
std::back_inserter(points));
coordinate_type lon_min, lat_min, lon_max, lat_max;
if (points.size() == 1)
{
// we have one non-pole point and at least one pole point
lon_min = geometry::get<0>(range::front(points));
lon_max = geometry::get<0>(range::front(points));
lat_min = has_south_pole
? constants::min_latitude()
: constants::max_latitude();
lat_max = has_north_pole
? constants::max_latitude()
: constants::min_latitude();
}
else if (points.empty())
{
// all points are pole points
BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole);
lon_min = coordinate_type(0);
lon_max = coordinate_type(0);
lat_min = has_south_pole
? constants::min_latitude()
: constants::max_latitude();
lat_max = (has_north_pole)
? constants::max_latitude()
: constants::min_latitude();
}
else
{
get_min_max_longitudes<constants>(points,
coordinate_less<0>(),
lon_min,
lon_max);
get_min_max_latitudes<constants>(points.begin(),
points.end(),
coordinate_less<1>(),
has_south_pole,
has_north_pole,
lat_min,
lat_max);
}
typedef typename helper_geometry
<
Box,
coordinate_type,
typename geometry::detail::cs_angular_units<MultiPoint>::type
>::type helper_box_type;
helper_box_type helper_mbr;
geometry::set<min_corner, 0>(helper_mbr, lon_min);
geometry::set<min_corner, 1>(helper_mbr, lat_min);
geometry::set<max_corner, 0>(helper_mbr, lon_max);
geometry::set<max_corner, 1>(helper_mbr, lat_max);
// now transform to output MBR (per index)
geometry::detail::envelope::envelope_indexed_box_on_spheroid<min_corner, 2>::apply(helper_mbr, mbr);
geometry::detail::envelope::envelope_indexed_box_on_spheroid<max_corner, 2>::apply(helper_mbr, mbr);
// compute envelope for higher coordinates
iterator_type it = boost::begin(multipoint);
geometry::detail::envelope::envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr);
for (++it; it != boost::end(multipoint); ++it)
{
strategy::expand::detail::point_loop
<
2, dimension<Box>::value
>::apply(mbr, *it);
}
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<multi_point_tag, spherical_equatorial_tag, CalculationType>
{
typedef strategy::envelope::spherical_multipoint type;
};
template <typename CalculationType>
struct default_strategy<multi_point_tag, spherical_polar_tag, CalculationType>
{
typedef strategy::envelope::spherical_multipoint type;
};
template <typename CalculationType>
struct default_strategy<multi_point_tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::spherical_multipoint type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_MULTIPOINT_HPP

View File

@@ -1,111 +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, 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_SPHERICAL_ENVELOPE_POINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_POINT_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
#include <boost/geometry/strategies/envelope.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
{
namespace strategy { namespace envelope
{
struct spherical_point
{
template<typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
{
Point normalized_point;
strategy::normalize::spherical_point::apply(point, normalized_point);
typename point_type<Box>::type box_point;
// transform units of input point to units of a box point
geometry::detail::envelope::transform_units(normalized_point, box_point);
geometry::set<min_corner, 0>(mbr, geometry::get<0>(box_point));
geometry::set<min_corner, 1>(mbr, geometry::get<1>(box_point));
geometry::set<max_corner, 0>(mbr, geometry::get<0>(box_point));
geometry::set<max_corner, 1>(mbr, geometry::get<1>(box_point));
typedef geometry::detail::envelope::envelope_one_point
<
2, dimension<Point>::value
> per_corner;
per_corner::template apply<min_corner>(normalized_point, mbr);
per_corner::template apply<max_corner>(normalized_point, mbr);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<point_tag, spherical_equatorial_tag, CalculationType>
{
typedef strategy::envelope::spherical_point type;
};
template <typename CalculationType>
struct default_strategy<point_tag, spherical_polar_tag, CalculationType>
{
typedef strategy::envelope::spherical_point type;
};
template <typename CalculationType>
struct default_strategy<point_tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::spherical_point type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#include <boost/geometry/strategy/spherical/envelope_point.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_POINT_HPP

View File

@@ -1,445 +1,22 @@
// 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_SPHERICAL_ENVELOPE_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP
#include <cstddef>
#include <utility>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/strategy/spherical/envelope_segment.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/formulas/meridian_segment.hpp>
#include <boost/geometry/formulas/vertex_latitude.hpp>
#include <boost/geometry/geometries/helper_geometry.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/spherical/azimuth.hpp>
#include <boost/geometry/strategies/spherical/expand_box.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace strategy { namespace envelope
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename CalculationType, typename CS_Tag>
struct envelope_segment_call_vertex_latitude
{
template <typename T1, typename T2, typename Strategy>
static inline CalculationType apply(T1 const& lat1,
T2 const& alp1,
Strategy const& )
{
return geometry::formula::vertex_latitude<CalculationType, CS_Tag>
::apply(lat1, alp1);
}
};
template <typename CalculationType>
struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag>
{
template <typename T1, typename T2, typename Strategy>
static inline CalculationType apply(T1 const& lat1,
T2 const& alp1,
Strategy const& strategy)
{
return geometry::formula::vertex_latitude<CalculationType, geographic_tag>
::apply(lat1, alp1, strategy.model());
}
};
template <typename Units, typename CS_Tag>
struct envelope_segment_convert_polar
{
template <typename T>
static inline void pre(T & , T & ) {}
template <typename T>
static inline void post(T & , T & ) {}
};
template <typename Units>
struct envelope_segment_convert_polar<Units, spherical_polar_tag>
{
template <typename T>
static inline void pre(T & lat1, T & lat2)
{
lat1 = math::latitude_convert_ep<Units>(lat1);
lat2 = math::latitude_convert_ep<Units>(lat2);
}
template <typename T>
static inline void post(T & lat1, T & lat2)
{
lat1 = math::latitude_convert_ep<Units>(lat1);
lat2 = math::latitude_convert_ep<Units>(lat2);
std::swap(lat1, lat2);
}
};
template <typename CS_Tag>
class envelope_segment_impl
{
private:
// degrees or radians
template <typename CalculationType>
static inline void swap(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2)
{
std::swap(lon1, lon2);
std::swap(lat1, lat2);
}
// radians
template <typename CalculationType>
static inline bool contains_pi_half(CalculationType const& a1,
CalculationType const& a2)
{
// azimuths a1 and a2 are assumed to be in radians
BOOST_GEOMETRY_ASSERT(! math::equals(a1, a2));
static CalculationType const pi_half = math::half_pi<CalculationType>();
return (a1 < a2)
? (a1 < pi_half && pi_half < a2)
: (a1 > pi_half && pi_half > a2);
}
// radians or degrees
template <typename Units, typename CoordinateType>
static inline bool crosses_antimeridian(CoordinateType const& lon1,
CoordinateType const& lon2)
{
typedef math::detail::constants_on_spheroid
<
CoordinateType, Units
> constants;
return math::abs(lon1 - lon2) > constants::half_period(); // > pi
}
// degrees or radians
template <typename Units, typename CalculationType, typename Strategy>
static inline void compute_box_corners(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2,
CalculationType a1,
CalculationType a2,
Strategy const& strategy)
{
// coordinates are assumed to be in radians
BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
boost::ignore_unused(lon1, lon2);
CalculationType lat1_rad = math::as_radian<Units>(lat1);
CalculationType lat2_rad = math::as_radian<Units>(lat2);
if (math::equals(a1, a2))
{
// the segment must lie on the equator or is very short or is meridian
return;
}
if (lat1 > lat2)
{
std::swap(lat1, lat2);
std::swap(lat1_rad, lat2_rad);
std::swap(a1, a2);
}
if (contains_pi_half(a1, a2))
{
CalculationType p_max = envelope_segment_call_vertex_latitude
<CalculationType, CS_Tag>::apply(lat1_rad, a1, strategy);
CalculationType const mid_lat = lat1 + lat2;
if (mid_lat < 0)
{
// update using min latitude
CalculationType const lat_min_rad = -p_max;
CalculationType const lat_min
= math::from_radian<Units>(lat_min_rad);
if (lat1 > lat_min)
{
lat1 = lat_min;
}
}
else
{
// update using max latitude
CalculationType const lat_max_rad = p_max;
CalculationType const lat_max
= math::from_radian<Units>(lat_max_rad);
if (lat2 < lat_max)
{
lat2 = lat_max;
}
}
}
}
template <typename Units, typename CalculationType>
static inline void special_cases(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2)
{
typedef math::detail::constants_on_spheroid
<
CalculationType, Units
> constants;
bool is_pole1 = math::equals(math::abs(lat1), constants::max_latitude());
bool is_pole2 = math::equals(math::abs(lat2), constants::max_latitude());
if (is_pole1 && is_pole2)
{
// both points are poles; nothing more to do:
// longitudes are already normalized to 0
// but just in case
lon1 = 0;
lon2 = 0;
}
else if (is_pole1 && !is_pole2)
{
// first point is a pole, second point is not:
// make the longitude of the first point the same as that
// of the second point
lon1 = lon2;
}
else if (!is_pole1 && is_pole2)
{
// second point is a pole, first point is not:
// make the longitude of the second point the same as that
// of the first point
lon2 = lon1;
}
if (lon1 == lon2)
{
// segment lies on a meridian
if (lat1 > lat2)
{
std::swap(lat1, lat2);
}
return;
}
BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2);
if (lon1 > lon2)
{
swap(lon1, lat1, lon2, lat2);
}
if (crosses_antimeridian<Units>(lon1, lon2))
{
lon1 += constants::period();
swap(lon1, lat1, lon2, lat2);
}
}
template
<
typename Units,
typename CalculationType,
typename Box
>
static inline void create_box(CalculationType lon1,
CalculationType lat1,
CalculationType lon2,
CalculationType lat2,
Box& mbr)
{
typedef typename coordinate_type<Box>::type box_coordinate_type;
typedef typename helper_geometry
<
Box, box_coordinate_type, Units
>::type helper_box_type;
helper_box_type helper_mbr;
geometry::set
<
min_corner, 0
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
geometry::set
<
min_corner, 1
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat1));
geometry::set
<
max_corner, 0
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon2));
geometry::set
<
max_corner, 1
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat2));
geometry::detail::envelope::transform_units(helper_mbr, mbr);
}
template <typename Units, typename CalculationType, typename Strategy>
static inline void apply(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2,
Strategy const& strategy)
{
special_cases<Units>(lon1, lat1, lon2, lat2);
CalculationType lon1_rad = math::as_radian<Units>(lon1);
CalculationType lat1_rad = math::as_radian<Units>(lat1);
CalculationType lon2_rad = math::as_radian<Units>(lon2);
CalculationType lat2_rad = math::as_radian<Units>(lat2);
CalculationType alp1, alp2;
strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp1, alp2);
compute_box_corners<Units>(lon1, lat1, lon2, lat2, alp1, alp2, strategy);
}
public:
template
<
typename Units,
typename CalculationType,
typename Box,
typename Strategy
>
static inline void apply(CalculationType lon1,
CalculationType lat1,
CalculationType lon2,
CalculationType lat2,
Box& mbr,
Strategy const& strategy)
{
typedef envelope_segment_convert_polar<Units, typename cs_tag<Box>::type> convert_polar;
convert_polar::pre(lat1, lat2);
apply<Units>(lon1, lat1, lon2, lat2, strategy);
convert_polar::post(lat1, lat2);
create_box<Units>(lon1, lat1, lon2, lat2, mbr);
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
template
<
typename CalculationType = void
>
class spherical_segment
{
public:
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>
static inline void apply(Point const& point1, Point const& point2,
Box& box)
{
Point p1_normalized, p2_normalized;
strategy::normalize::spherical_point::apply(point1, p1_normalized);
strategy::normalize::spherical_point::apply(point2, p2_normalized);
geometry::strategy::azimuth::spherical<CalculationType> azimuth_spherical;
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
<
spherical_equatorial_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_spherical);
// 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);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, spherical_equatorial_tag, CalculationType>
{
typedef strategy::envelope::spherical_segment<CalculationType> type;
};
template <typename CalculationType>
struct default_strategy<segment_tag, spherical_polar_tag, CalculationType>
{
typedef strategy::envelope::spherical_segment<CalculationType> type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP

View File

@@ -1,98 +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_SPHERICAL_EXPAND_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP
#include <cstddef>
#include <algorithm>
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
#include <boost/geometry/strategies/expand.hpp>
#include <boost/geometry/strategies/spherical/envelope_box.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
struct box_on_spheroid
{
template <typename BoxOut, typename BoxIn>
static inline void apply(BoxOut& box_out, BoxIn const& box_in)
{
// normalize both boxes and convert box-in to be of type of box-out
BoxOut mbrs[2];
strategy::envelope::spherical_box::apply(box_in, mbrs[0]);
strategy::envelope::spherical_box::apply(box_out, mbrs[1]);
// compute the envelope of the two boxes
geometry::detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out);
}
};
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
#include <boost/geometry/strategy/spherical/expand_box.hpp>
struct spherical_box
: detail::box_on_spheroid
{};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<box_tag, spherical_equatorial_tag, CalculationType>
{
typedef spherical_box type;
};
template <typename CalculationType>
struct default_strategy<box_tag, spherical_polar_tag, CalculationType>
{
typedef spherical_box type;
};
template <typename CalculationType>
struct default_strategy<box_tag, geographic_tag, CalculationType>
{
typedef spherical_box type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP

View File

@@ -1,233 +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-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
// 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_SPHERICAL_EXPAND_POINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP
#include <cstddef>
#include <algorithm>
#include <functional>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/strategies/expand.hpp>
#include <boost/geometry/strategies/cartesian/expand_point.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/spherical/expand_point.hpp>
namespace strategy { namespace expand
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
// implementation for the spherical and geographic coordinate systems
template <std::size_t DimensionCount, bool IsEquatorial>
struct point_loop_on_spheroid
{
template <typename Box, typename Point>
static inline void apply(Box& box, Point const& point)
{
typedef typename point_type<Box>::type box_point_type;
typedef typename coordinate_type<Box>::type box_coordinate_type;
typedef typename geometry::detail::cs_angular_units<Box>::type units_type;
typedef math::detail::constants_on_spheroid
<
box_coordinate_type,
units_type
> constants;
// normalize input point and input box
Point p_normalized;
strategy::normalize::spherical_point::apply(point, p_normalized);
// transform input point to be of the same type as the box point
box_point_type box_point;
geometry::detail::envelope::transform_units(p_normalized, box_point);
if (is_inverse_spheroidal_coordinates(box))
{
geometry::set_from_radian<min_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
geometry::set_from_radian<min_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
geometry::set_from_radian<max_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
geometry::set_from_radian<max_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
} else {
strategy::normalize::spherical_box::apply(box, box);
box_coordinate_type p_lon = geometry::get<0>(box_point);
box_coordinate_type p_lat = geometry::get<1>(box_point);
typename coordinate_type<Box>::type
b_lon_min = geometry::get<min_corner, 0>(box),
b_lat_min = geometry::get<min_corner, 1>(box),
b_lon_max = geometry::get<max_corner, 0>(box),
b_lat_max = geometry::get<max_corner, 1>(box);
if (math::is_latitude_pole<units_type, IsEquatorial>(p_lat))
{
// the point of expansion is the either the north or the
// south pole; the only important coordinate here is the
// pole's latitude, as the longitude can be anything;
// we, thus, take into account the point's latitude only and return
geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
return;
}
if (math::equals(b_lat_min, b_lat_max)
&& math::is_latitude_pole<units_type, IsEquatorial>(b_lat_min))
{
// the box degenerates to either the north or the south pole;
// the only important coordinate here is the pole's latitude,
// as the longitude can be anything;
// we thus take into account the box's latitude only and return
geometry::set<min_corner, 0>(box, p_lon);
geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
geometry::set<max_corner, 0>(box, p_lon);
geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
return;
}
// update latitudes
b_lat_min = (std::min)(b_lat_min, p_lat);
b_lat_max = (std::max)(b_lat_max, p_lat);
// update longitudes
if (math::smaller(p_lon, b_lon_min))
{
box_coordinate_type p_lon_shifted = p_lon + constants::period();
if (math::larger(p_lon_shifted, b_lon_max))
{
// here we could check using: ! math::larger(.., ..)
if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max))
{
b_lon_min = p_lon;
}
else
{
b_lon_max = p_lon_shifted;
}
}
}
else if (math::larger(p_lon, b_lon_max))
{
// in this case, and since p_lon is normalized in the range
// (-180, 180], we must have that b_lon_max <= 180
if (b_lon_min < 0
&& math::larger(p_lon - b_lon_max,
constants::period() - p_lon + b_lon_min))
{
b_lon_min = p_lon;
b_lon_max += constants::period();
}
else
{
b_lon_max = p_lon;
}
}
geometry::set<min_corner, 0>(box, b_lon_min);
geometry::set<min_corner, 1>(box, b_lat_min);
geometry::set<max_corner, 0>(box, b_lon_max);
geometry::set<max_corner, 1>(box, b_lat_max);
}
point_loop
<
2, DimensionCount
>::apply(box, point);
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
struct spherical_point
{
template <typename Box, typename Point>
static void apply(Box & box, Point const& point)
{
expand::detail::point_loop_on_spheroid
<
dimension<Point>::value,
! boost::is_same<typename cs_tag<Point>::type, spherical_polar_tag>::value
>::apply(box, point);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<point_tag, spherical_equatorial_tag, CalculationType>
{
typedef spherical_point type;
};
template <typename CalculationType>
struct default_strategy<point_tag, spherical_polar_tag, CalculationType>
{
typedef spherical_point type;
};
template <typename CalculationType>
struct default_strategy<point_tag, geographic_tag, CalculationType>
{
typedef spherical_point type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP

View File

@@ -1,118 +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_SPHERICAL_EXPAND_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_SEGMENT_HPP
#include <cstddef>
#include <functional>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/select_coordinate_type.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/strategies/expand.hpp>
#include <boost/geometry/strategies/spherical/envelope_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/spherical/expand_segment.hpp>
namespace strategy { namespace expand
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
struct segment_on_spheroid
{
template <typename Box, typename Segment, typename EnvelopeStrategy>
static inline void apply(Box& box, Segment const& segment, EnvelopeStrategy const& strategy)
{
Box mbrs[2];
// compute the envelope of the segment
typename point_type<Segment>::type p[2];
geometry::detail::assign_point_from_index<0>(segment, p[0]);
geometry::detail::assign_point_from_index<1>(segment, p[1]);
geometry::detail::envelope::envelope_segment
<
dimension<Segment>::value
>::apply(p[0], p[1], mbrs[0], strategy);
// normalize the box
strategy::envelope::spherical_box::apply(box, mbrs[1]);
// compute the envelope of the two boxes
geometry::detail::envelope::envelope_range_of_boxes::apply(mbrs, box);
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
template
<
typename CalculationType = void
>
class spherical_segment
{
public:
template <typename Box, typename Segment>
static inline void apply(Box& box, Segment const& segment)
{
detail::segment_on_spheroid::apply(box, segment,
strategy::envelope::spherical_segment<CalculationType>());
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, spherical_equatorial_tag, CalculationType>
{
typedef spherical_segment<CalculationType> type;
};
template <typename CalculationType>
struct default_strategy<segment_tag, spherical_polar_tag, CalculationType>
{
typedef spherical_segment<CalculationType> type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_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_SPHERICAL_INTERSECTION_HPP
#include <algorithm>
#include <type_traits>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
@@ -32,20 +33,23 @@
#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/strategy/spherical/area.hpp>
#include <boost/geometry/strategy/spherical/envelope.hpp>
#include <boost/geometry/strategy/spherical/expand_box.hpp>
#include <boost/geometry/strategy/spherical/expand_segment.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/side_info.hpp>
#include <boost/geometry/strategies/spherical/area.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
#include <boost/geometry/strategies/spherical/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
#include <boost/geometry/strategies/spherical/envelope.hpp>
#include <boost/geometry/strategies/spherical/expand_box.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/spherical/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
@@ -90,115 +94,7 @@ template
>
struct ecef_segments
{
typedef side::spherical_side_formula<CalculationType> side_strategy_type;
static inline side_strategy_type get_side_strategy()
{
return side_strategy_type();
}
template <typename Geometry1, typename Geometry2>
struct point_in_geometry_strategy
{
typedef strategy::within::spherical_winding
<
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type,
CalculationType
> type;
};
template <typename Geometry1, typename Geometry2>
static inline typename point_in_geometry_strategy<Geometry1, Geometry2>::type
get_point_in_geometry_strategy()
{
typedef typename point_in_geometry_strategy
<
Geometry1, Geometry2
>::type strategy_type;
return strategy_type();
}
template <typename Geometry>
struct area_strategy
{
typedef area::spherical
<
typename coordinate_type<Geometry>::type,
CalculationType
> type;
};
template <typename Geometry>
static inline typename area_strategy<Geometry>::type get_area_strategy()
{
typedef typename area_strategy<Geometry>::type strategy_type;
return strategy_type();
}
template <typename Geometry>
struct distance_strategy
{
typedef distance::haversine
<
typename coordinate_type<Geometry>::type,
CalculationType
> type;
};
template <typename Geometry>
static inline typename distance_strategy<Geometry>::type get_distance_strategy()
{
typedef typename distance_strategy<Geometry>::type strategy_type;
return strategy_type();
}
typedef envelope::spherical<CalculationType>
envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
return envelope_strategy_type();
}
typedef expand::spherical_segment<CalculationType>
expand_strategy_type;
static inline expand_strategy_type get_expand_strategy()
{
return expand_strategy_type();
}
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_spherical disjoint_segment_box_strategy_type;
static inline disjoint_segment_box_strategy_type get_disjoint_segment_box_strategy()
{
return disjoint_segment_box_strategy_type();
}
typedef covered_by::spherical_point_box disjoint_point_box_strategy_type;
typedef expand::spherical_box expand_box_strategy_type;
typedef spherical_tag cs_tag;
enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 };
@@ -247,43 +143,13 @@ struct ecef_segments
// Relate segments a and b
template
<
typename Segment1,
typename Segment2,
typename Policy,
typename RobustPolicy
typename UniqueSubRange1,
typename UniqueSubRange2,
typename Policy
>
static inline typename Policy::return_type
apply(Segment1 const& a, Segment2 const& b,
Policy const& policy, RobustPolicy const& robust_policy)
{
typedef typename point_type<Segment1>::type point1_t;
typedef typename point_type<Segment2>::type point2_t;
point1_t a1, a2;
point2_t b1, b2;
// TODO: use indexed_point_view if possible?
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);
}
// Relate segments a and b
template
<
typename Segment1,
typename Segment2,
typename Policy,
typename RobustPolicy,
typename Point1,
typename Point2
>
static inline typename Policy::return_type
apply(Segment1 const& a, Segment2 const& b,
Policy const&, RobustPolicy const&,
Point1 const& a1, Point1 const& a2, Point2 const& b1, Point2 const& b2)
apply(UniqueSubRange1 const& range_p, UniqueSubRange2 const& range_q,
Policy const&)
{
// For now create it using default constructor. In the future it could
// be stored in strategy. However then apply() wouldn't be static and
@@ -291,8 +157,21 @@ struct ecef_segments
// Initialize explicitly to prevent compiler errors in case of PoD type
CalcPolicy const calc_policy = CalcPolicy();
BOOST_CONCEPT_ASSERT( (concepts::ConstSegment<Segment1>) );
BOOST_CONCEPT_ASSERT( (concepts::ConstSegment<Segment2>) );
typedef typename UniqueSubRange1::point_type point1_type;
typedef typename UniqueSubRange2::point_type point2_type;
BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<point1_type>) );
BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<point2_type>) );
point1_type const& a1 = range_p.at(0);
point1_type const& a2 = range_p.at(1);
point2_type const& b1 = range_q.at(0);
point2_type const& b2 = range_q.at(1);
typedef model::referring_segment<point1_type const> segment1_type;
typedef model::referring_segment<point2_type const> segment2_type;
segment1_type const a(a1, a2);
segment2_type const b(b1, b2);
// TODO: check only 2 first coordinates here?
bool a_is_point = equals_point_point(a1, a2);
@@ -307,7 +186,7 @@ struct ecef_segments
}
typedef typename select_calculation_type
<Segment1, Segment2, CalculationType>::type calc_t;
<segment1_type, segment2_type, CalculationType>::type calc_t;
calc_t const c0 = 0;
calc_t const c1 = 1;
@@ -318,7 +197,7 @@ struct ecef_segments
vec3d_t const a2v = calc_policy.template to_cart3d<vec3d_t>(a2);
vec3d_t const b1v = calc_policy.template to_cart3d<vec3d_t>(b1);
vec3d_t const b2v = calc_policy.template to_cart3d<vec3d_t>(b2);
bool degen_neq_coords = false;
side_info sides;
@@ -407,7 +286,7 @@ struct ecef_segments
// 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)
{
@@ -445,7 +324,7 @@ struct ecef_segments
sides.set<0>(0, 0);
sides.set<1>(0, 0);
}
if (collinear)
{
if (a_is_point)
@@ -463,29 +342,25 @@ struct ecef_segments
{
calc_t dist_a1_b1, dist_a1_b2;
calc_t dist_b1_a1, dist_b1_a2;
// use shorter segment
if (len1 <= len2)
{
calculate_collinear_data(a1, a2, b1, b2, a1v, a2v, plane1, b1v, b2v, dist_a1_a2, dist_a1_b1);
calculate_collinear_data(a1, a2, b2, b1, a1v, a2v, plane1, b2v, b1v, dist_a1_a2, dist_a1_b2);
dist_b1_b2 = dist_a1_b2 - dist_a1_b1;
dist_b1_a1 = -dist_a1_b1;
dist_b1_a2 = dist_a1_a2 - dist_a1_b1;
}
else
{
calculate_collinear_data(b1, b2, a1, a2, b1v, b2v, plane2, a1v, a2v, dist_b1_b2, dist_b1_a1);
calculate_collinear_data(b1, b2, a2, a1, b1v, b2v, plane2, a2v, a1v, dist_b1_b2, dist_b1_a2);
dist_a1_a2 = dist_b1_a2 - dist_b1_a1;
dist_a1_b1 = -dist_b1_a1;
dist_a1_b2 = dist_b1_b2 - dist_b1_a1;
}
calculate_collinear_data(a1, a2, b1, b2, a1v, a2v, plane1, b1v, b2v, dist_a1_a2, dist_a1_b1);
calculate_collinear_data(a1, a2, b2, b1, a1v, a2v, plane1, b2v, b1v, dist_a1_a2, dist_a1_b2);
calculate_collinear_data(b1, b2, a1, a2, b1v, b2v, plane2, a1v, a2v, dist_b1_b2, dist_b1_a1);
calculate_collinear_data(b1, b2, a2, a1, b1v, b2v, plane2, a2v, a1v, dist_b1_b2, dist_b1_a2);
// NOTE: The following optimization causes problems with consitency
// It may either be caused by numerical issues or the way how distance is coded:
// as cosine of angle scaled and translated, see: calculate_dist()
/*dist_b1_b2 = dist_a1_b2 - dist_a1_b1;
dist_b1_a1 = -dist_a1_b1;
dist_b1_a2 = dist_a1_a2 - dist_a1_b1;
dist_a1_a2 = dist_b1_a2 - dist_b1_a1;
dist_a1_b1 = -dist_b1_a1;
dist_a1_b2 = dist_b1_b2 - dist_b1_a1;*/
segment_ratio<calc_t> ra_from(dist_b1_a1, dist_b1_b2);
segment_ratio<calc_t> ra_to(dist_b1_a2, dist_b1_b2);
segment_ratio<calc_t> rb_from(dist_a1_b1, dist_a1_a2);
segment_ratio<calc_t> rb_to(dist_a1_b2, dist_a1_a2);
// NOTE: this is probably not needed
int const a1_wrt_b = position_value(c0, dist_a1_b1, dist_a1_b2);
int const a2_wrt_b = position_value(dist_a1_a2, dist_a1_b1, dist_a1_b2);
@@ -651,7 +526,7 @@ private:
{
Vec3d ip1, ip2;
calc_policy.intersection_points(plane1, plane2, ip1, ip2);
calculate_dist(a1v, a2v, plane1, ip1, dist_a1_ip);
ip = ip1;
@@ -697,7 +572,7 @@ private:
ip_flag = ipi_at_a1;
return true;
}
if (is_near_b2 && equals_point_point(a1, b2))
{
dist_a1_ip = 0;
@@ -736,6 +611,7 @@ private:
{
if (is_near_b1 && sides.template get<1, 0>() == 0) // b1 wrt a
{
calculate_dist(a1v, a2v, plane1, b1v, dist_a1_ip); // for consistency
dist_b1_ip = 0;
//i1 = b1v;
ip_flag = ipi_at_b1;
@@ -744,6 +620,7 @@ private:
if (is_near_b2 && sides.template get<1, 1>() == 0) // b2 wrt a
{
calculate_dist(a1v, a2v, plane1, b2v, dist_a1_ip); // for consistency
dist_b1_ip = dist_b1_b2;
//i1 = b2v;
ip_flag = ipi_at_b2;
@@ -756,6 +633,7 @@ private:
if (is_near_a1 && sides.template get<0, 0>() == 0) // a1 wrt b
{
dist_a1_ip = 0;
calculate_dist(b1v, b2v, plane2, a1v, dist_b1_ip); // for consistency
//i1 = a1v;
ip_flag = ipi_at_a1;
return true;
@@ -764,6 +642,7 @@ private:
if (is_near_a2 && sides.template get<0, 1>() == 0) // a2 wrt b
{
dist_a1_ip = dist_a1_a2;
calculate_dist(b1v, b2v, plane2, a2v, dist_b1_ip); // for consistency
//i1 = a2v;
ip_flag = ipi_at_a2;
return true;
@@ -869,7 +748,7 @@ private:
template <typename CalcT>
static inline bool is_near(CalcT const& dist)
{
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;
}
@@ -894,8 +773,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);
}
};
@@ -962,13 +840,15 @@ struct spherical_segments_calc_policy
// not checked before this function is called the length
// should be checked here (math::equals(len, c0))
coord_t const len = math::sqrt(dot_product(ip1, ip1));
divide_value(ip1, len); // normalize i1
ip2 = ip1;
multiply_value(ip2, coord_t(-1));
geometry::detail::for_each_dimension<Point3d>([&](auto index)
{
coord_t const coord = get<index>(ip1) / len; // normalize
set<index>(ip1, coord);
set<index>(ip2, -coord);
});
return true;
}
}
};

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
@@ -51,8 +52,7 @@ public:
typedef typename DistanceStrategy::radius_type radius_type;
inline spherical()
{}
spherical() = default;
explicit inline spherical(typename DistanceStrategy::radius_type const& r)
: m_strategy(r)
@@ -62,17 +62,6 @@ public:
: m_strategy(s)
{}
// point-point strategy getters
struct distance_pp_strategy
{
typedef DistanceStrategy type;
};
inline typename distance_pp_strategy::type get_distance_pp_strategy() const
{
return m_strategy;
}
template <typename Point, typename Fraction, typename Distance>
inline void apply(Point const& p0,
Point const& p1,
@@ -95,6 +84,12 @@ public:
calc_t a = angle01 * fraction;
formula.compute_point(a, p);
}
inline radius_type radius() const
{
return m_strategy.radius();
}
private :
DistanceStrategy m_strategy;
};

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2020.
// Modifications copyright (c) 2013-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -18,15 +18,17 @@
// 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_SPHERICAL_POINT_IN_POINT_HPP
#define BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP
#include <cstddef>
#include <type_traits>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.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/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
@@ -56,6 +58,9 @@ namespace detail { namespace within
class point_point_on_spheroid
{
public:
typedef spherical_tag cs_tag;
private:
template <typename Point1, typename Point2, bool SameUnits>
struct are_same_points
@@ -67,7 +72,7 @@ private:
helper_point_type1 point1_normalized;
strategy::normalize::spherical_point::apply(point1, point1_normalized);
helper_point_type2 point2_normalized;
helper_point_type2 point2_normalized;
strategy::normalize::spherical_point::apply(point2, point2_normalized);
return point_point_generic
@@ -93,8 +98,10 @@ private:
Point1, calculation_type, radian
>::type helper_point1, helper_point2;
Point1 point1_normalized = return_normalized<Point1>(point1);
Point2 point2_normalized = return_normalized<Point2>(point2);
Point1 point1_normalized;
strategy::normalize::spherical_point::apply(point1, point1_normalized);
Point2 point2_normalized;
strategy::normalize::spherical_point::apply(point2, point2_normalized);
geometry::transform(point1_normalized, helper_point1);
geometry::transform(point2_normalized, helper_point2);
@@ -114,7 +121,7 @@ public:
<
Point1,
Point2,
boost::is_same
std::is_same
<
typename detail::cs_angular_units<Point1>::type,
typename detail::cs_angular_units<Point2>::type

View File

@@ -3,8 +3,9 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013, 2014, 2016, 2017, 2018.
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2023.
// Modifications copyright (c) 2013-2023 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -27,6 +28,8 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/strategy/spherical/expand_point.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/side.hpp>
@@ -46,28 +49,19 @@ namespace strategy { namespace within
namespace detail
{
template
<
typename Point,
typename PointOfSegment = Point,
typename SideStrategy = typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
>::type,
typename CalculationType = void
>
template <typename SideStrategy, typename CalculationType>
class spherical_winding_base
{
typedef typename select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>::type calculation_type;
template <typename Point, typename PointOfSegment>
struct calculation_type
: select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>
{};
typedef typename geometry::detail::cs_angular_units<Point>::type units_t;
typedef math::detail::constants_on_spheroid<calculation_type, units_t> constants;
/*! subclass to keep state */
class counter
{
@@ -84,7 +78,7 @@ class spherical_winding_base
{
return 0;
}
if (m_raw_count != 0 && m_raw_count_anti != 0)
{
if (m_raw_count > 0) // right, wrap around south pole
@@ -128,36 +122,9 @@ class spherical_winding_base
};
public:
typedef typename SideStrategy::envelope_strategy_type envelope_strategy_type;
typedef typename SideStrategy::cs_tag cs_tag;
inline envelope_strategy_type get_envelope_strategy() const
{
return m_side_strategy.get_envelope_strategy();
}
typedef typename SideStrategy::disjoint_strategy_type disjoint_strategy_type;
inline disjoint_strategy_type get_disjoint_strategy() const
{
return m_side_strategy.get_disjoint_strategy();
}
typedef typename SideStrategy::equals_point_point_strategy_type equals_point_point_strategy_type;
inline equals_point_point_strategy_type get_equals_point_point_strategy() const
{
return m_side_strategy.get_equals_point_point_strategy();
}
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 covered_by::spherical_point_box disjoint_point_box_strategy_type;
spherical_winding_base()
{}
spherical_winding_base() = default;
template <typename Model>
explicit spherical_winding_base(Model const& model)
@@ -165,14 +132,17 @@ public:
{}
// Typedefs and static methods to fulfill the concept
typedef Point point_type;
typedef PointOfSegment segment_point_type;
typedef counter state_type;
template <typename Point, typename PointOfSegment>
inline bool apply(Point const& point,
PointOfSegment const& s1, PointOfSegment const& s2,
counter& state) const
{
typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
typedef typename geometry::detail::cs_angular_units<Point>::type units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
bool eq1 = false;
bool eq2 = false;
bool s_antipodal = false;
@@ -196,9 +166,9 @@ public:
}
else
{
calculation_type const pi = constants::half_period();
calculation_type const s1_lat = get<1>(s1);
calculation_type const s2_lat = get<1>(s2);
calc_t const pi = constants::half_period();
calc_t const s1_lat = get<1>(s1);
calc_t const s2_lat = get<1>(s2);
side = math::sign(ci.count)
* (pi - s1_lat - s2_lat <= pi // segment goes through north pole
@@ -206,7 +176,7 @@ public:
: 1); // going right all points will be on left side
}
}
if (side == 0)
{
// Point is lying on segment
@@ -250,8 +220,8 @@ public:
return state.code();
}
private:
protected:
template <typename Point, typename PointOfSegment>
static inline count_info check_segment(Point const& point,
PointOfSegment const& seg1,
PointOfSegment const& seg2,
@@ -266,6 +236,7 @@ private:
return calculate_count(point, seg1, seg2, eq1, eq2, s_antipodal);
}
template <typename Point, typename PointOfSegment>
static inline int check_touch(Point const& point,
PointOfSegment const& seg1,
PointOfSegment const& seg2,
@@ -274,39 +245,41 @@ private:
bool& eq2,
bool& s_antipodal)
{
calculation_type const c0 = 0;
calculation_type const c2 = 2;
calculation_type const pi = constants::half_period();
calculation_type const half_pi = pi / c2;
typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
typedef typename geometry::detail::cs_angular_units<Point>::type units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
calculation_type const p_lon = get<0>(point);
calculation_type const s1_lon = get<0>(seg1);
calculation_type const s2_lon = get<0>(seg2);
calculation_type const p_lat = get<1>(point);
calculation_type const s1_lat = get<1>(seg1);
calculation_type const s2_lat = get<1>(seg2);
calc_t const c0 = 0;
calc_t const c2 = 2;
calc_t const pi = constants::half_period();
calc_t const half_pi = pi / c2;
calc_t const p_lon = get<0>(point);
calc_t const s1_lon = get<0>(seg1);
calc_t const s2_lon = get<0>(seg2);
calc_t const p_lat = get<1>(point);
calc_t const s1_lat = get<1>(seg1);
calc_t const s2_lat = get<1>(seg2);
// NOTE: lat in {-90, 90} and arbitrary lon
// it doesn't matter what lon it is if it's a pole
// so e.g. if one of the segment endpoints is a pole
// then only the other lon matters
bool eq1_strict = longitudes_equal(s1_lon, p_lon);
bool eq2_strict = longitudes_equal(s2_lon, p_lon);
bool eq1_strict = longitudes_equal<units_t>(s1_lon, p_lon);
bool eq2_strict = longitudes_equal<units_t>(s2_lon, p_lon);
bool eq1_anti = false;
bool eq2_anti = false;
calculation_type const anti_p_lon = p_lon + (p_lon <= c0 ? pi : -pi);
calc_t const anti_p_lon = p_lon + (p_lon <= c0 ? pi : -pi);
eq1 = eq1_strict // lon strictly equal to s1
|| (eq1_anti = longitudes_equal(s1_lon, anti_p_lon)) // anti-lon strictly equal to s1
|| math::equals(math::abs(s1_lat), half_pi); // s1 is pole
|| (eq1_anti = longitudes_equal<units_t>(s1_lon, anti_p_lon)); // anti-lon strictly equal to s1
eq2 = eq2_strict // lon strictly equal to s2
|| (eq2_anti = longitudes_equal(s2_lon, anti_p_lon)) // anti-lon strictly equal to s2
|| math::equals(math::abs(s2_lat), half_pi); // s2 is pole
|| (eq2_anti = longitudes_equal<units_t>(s2_lon, anti_p_lon)); // anti-lon strictly equal to s2
// segment overlapping pole
calculation_type const s_lon_diff = math::longitude_distance_signed<units_t>(s1_lon, s2_lon);
calc_t const s_lon_diff = math::longitude_distance_signed<units_t>(s1_lon, s2_lon);
s_antipodal = math::equals(s_lon_diff, pi);
if (s_antipodal)
{
@@ -318,7 +291,29 @@ private:
eq1 = eq2 = true;
}
}
// check whether point is on a segment with a pole endpoint
if (math::longitude_distance_signed<units_t>(s2_lon, p_lon) == c0)
{
bool const s1_north = math::equals(get<1>(seg1), half_pi);
bool const s1_south = math::equals(get<1>(seg1), -half_pi);
if (s1_north || s1_south)
{
state.m_touches = s1_south ? s2_lat > p_lat : s2_lat < p_lat;
return state.m_touches;
}
}
if (math::longitude_distance_signed<units_t>(s1_lon, p_lon) == c0)
{
bool const s2_north = math::equals(get<1>(seg2), half_pi);
bool const s2_south = math::equals(get<1>(seg2), -half_pi);
if (s2_north || s2_south)
{
state.m_touches = s2_south ? s1_lat > p_lat : s1_lat < p_lat;
return state.m_touches;
}
}
// Both equal p -> segment vertical
// The only thing which has to be done is check if point is ON segment
if (eq1 && eq2)
@@ -371,36 +366,51 @@ private:
}
// Called if point is not aligned with a vertical segment
template <typename Point, typename PointOfSegment>
static inline count_info calculate_count(Point const& point,
PointOfSegment const& seg1,
PointOfSegment const& seg2,
bool eq1, bool eq2, bool s_antipodal)
{
typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
typedef typename geometry::detail::cs_angular_units<Point>::type units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
// If both segment endpoints were poles below checks wouldn't be enough
// but this means that either both are the same or that they are N/S poles
// and therefore the segment is not valid.
// If needed (eq1 && eq2 ? 0) could be returned
calculation_type const c0 = 0;
calculation_type const pi = constants::half_period();
calc_t const c0 = 0;
calc_t const c2 = 2;
calc_t const pi = constants::half_period();
calc_t const half_pi = pi / c2;
calculation_type const p = get<0>(point);
calculation_type const s1 = get<0>(seg1);
calculation_type const s2 = get<0>(seg2);
bool const s1_is_pole = math::equals(std::abs(get<1>(seg1)), half_pi);
bool const s2_is_pole = math::equals(std::abs(get<1>(seg2)), half_pi);
if (s1_is_pole && s2_is_pole)
{
return count_info(0, false);
}
calc_t const p = get<0>(point);
calc_t const s1 = get<0>(seg1);
calc_t const s2 = get<0>(seg2);
calc_t const s1_p = math::longitude_distance_signed<units_t>(s1, p);
calculation_type const s1_p = math::longitude_distance_signed<units_t>(s1, p);
if (s_antipodal)
{
return count_info(s1_p < c0 ? -2 : 2, false); // choose W/E
}
calculation_type const s1_s2 = math::longitude_distance_signed<units_t>(s1, s2);
calc_t const s1_s2 = math::longitude_distance_signed<units_t>(s1, s2);
if (eq1 || eq2) // Point on level s1 or s2
{
return count_info(s1_s2 < c0 ? -1 : 1, // choose W/E
longitudes_equal(p + pi, (eq1 ? s1 : s2)));
longitudes_equal<units_t>(p + pi, (eq1 ? s1 : s2)));
}
// Point between s1 and s2
@@ -409,8 +419,8 @@ private:
{
return count_info(s1_s2 < c0 ? -2 : 2, false); // choose W/E
}
calculation_type const s1_p_anti = math::longitude_distance_signed<units_t>(s1, p + pi);
calc_t const s1_p_anti = math::longitude_distance_signed<units_t>(s1, p + pi);
// Anti-Point between s1 and s2
if ( math::sign(s1_p_anti) == math::sign(s1_s2)
@@ -445,12 +455,13 @@ private:
// In the code below actually D = 0, so segments are nearly-vertical
// Called when the point is on the same level as one of the segment's points
// but the point is not aligned with a vertical segment
template <typename Point, typename PointOfSegment>
inline int side_equal(Point const& point,
PointOfSegment const& se,
count_info const& ci) const
{
typedef typename coordinate_type<PointOfSegment>::type scoord_t;
typedef typename geometry::detail::cs_angular_units<PointOfSegment>::type units_t;
typedef typename geometry::detail::cs_angular_units<Point>::type units_t;
if (math::equals(get<1>(point), get<1>(se)))
{
@@ -466,11 +477,11 @@ private:
scoord_t ss20 = get<0>(se);
if (ci.count > 0)
{
ss20 += small_angle();
ss20 += small_angle<scoord_t, units_t>();
}
else
{
ss20 -= small_angle();
ss20 -= small_angle<scoord_t, units_t>();
}
math::normalize_longitude<units_t>(ss20);
set<0>(ss2, ss20);
@@ -480,16 +491,20 @@ private:
}
// 1 deg or pi/180 rad
static inline calculation_type small_angle()
template <typename CalcT, typename Units>
static inline CalcT small_angle()
{
return constants::half_period() / calculation_type(180);
};
typedef math::detail::constants_on_spheroid<CalcT, Units> constants;
static inline bool longitudes_equal(calculation_type const& lon1, calculation_type const& lon2)
return constants::half_period() / CalcT(180);
}
template <typename Units, typename CalcT>
static inline bool longitudes_equal(CalcT const& lon1, CalcT const& lon2)
{
return math::equals(
math::longitude_distance_signed<units_t>(lon1, lon2),
calculation_type(0));
math::longitude_distance_signed<Units>(lon1, lon2),
CalcT(0));
}
SideStrategy m_side_strategy;
@@ -514,15 +529,13 @@ private:
*/
template
<
typename Point,
typename PointOfSegment = Point,
typename Point = void, // for backward compatibility
typename PointOfSegment = Point, // for backward compatibility
typename CalculationType = void
>
class spherical_winding
: public within::detail::spherical_winding_base
<
Point,
PointOfSegment,
side::spherical_side_formula<CalculationType>,
CalculationType
>
@@ -537,21 +550,13 @@ namespace services
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, polygonal_tag, spherical_tag, spherical_tag>
{
typedef within::detail::spherical_winding_base
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
typedef within::spherical_winding<> type;
};
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, spherical_tag, spherical_tag>
{
typedef within::detail::spherical_winding_base
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
typedef within::spherical_winding<> type;
};
} // namespace services
@@ -569,21 +574,13 @@ namespace strategy { namespace covered_by { namespace services
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, polygonal_tag, spherical_tag, spherical_tag>
{
typedef within::detail::spherical_winding_base
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
typedef within::spherical_winding<> type;
};
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, spherical_tag, spherical_tag>
{
typedef within::detail::spherical_winding_base
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
typedef within::spherical_winding<> type;
};
}}} // namespace strategy::covered_by::services

View File

@@ -0,0 +1,146 @@
// Boost.Geometry
// Copyright (c) 2019-2020, 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_SPHERICAL_POINT_ORDER_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_POINT_ORDER_HPP
//#include <type_traits>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/formulas/spherical.hpp>
#include <boost/geometry/strategy/spherical/area.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/point_order.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 CalculationType = void>
//struct spherical
//{
// typedef azimuth_tag version_tag;
//
// template <typename Geometry>
// struct result_type
// {
// typedef typename geometry::select_calculation_type_alt
// <
// CalculationType, Geometry
// >::type type;
// };
//
// 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;
// }
//
// calc_t lon1 = geometry::get_as_radian<0>(p1);
// calc_t lat1 = geometry::get_as_radian<1>(p1);
// calc_t lon2 = geometry::get_as_radian<0>(p2);
// calc_t lat2 = geometry::get_as_radian<1>(p2);
//
// convert_latitudes<Point>(lat1, lat2);
//
// formula::result_spherical<calc_t>
// res = formula::spherical_azimuth<calc_t, true>(lon1, lat1, lon2, lat2);
//
// 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);
// }
//
// template <typename Point, typename CalcT>
// static void convert_latitudes(CalcT & lat1, CalcT & lat2)
// {
// static const bool is_polar = std::is_same
// <
// typename geometry::cs_tag<Point>::type,
// spherical_polar_tag
// >::value;
//
// if (BOOST_GEOMETRY_CONDITION(is_polar))
// {
// CalcT pi_half = math::half_pi<CalcT>();
// lat1 = pi_half - lat1;
// lat2 = pi_half - lat2;
// }
// }
//};
template <typename CalculationType = void>
struct spherical
: strategy::area::spherical<double, CalculationType>
{
typedef area_tag version_tag;
// TEMP
static strategy::area::spherical<double, CalculationType> get_area_strategy()
{
return strategy::area::spherical<double, CalculationType>();
}
};
namespace services
{
template <>
struct default_strategy<spherical_equatorial_tag>
{
typedef spherical<> type;
};
/*template <>
struct default_strategy<spherical_polar_tag>
{
typedef spherical<> type;
};*/
} // namespace services
}} // namespace strategy::point_order
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_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-2017.
// Modifications copyright (c) 2014-2017, 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 Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,19 +15,19 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SIDE_BY_CROSS_TRACK_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SIDE_BY_CROSS_TRACK_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/formulas/spherical.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>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
#include <boost/geometry/strategies/side.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
{
@@ -50,6 +50,15 @@ public :
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
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

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2016, 2018.
// Modifications copyright (c) 2016-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2016-2021.
// Modifications 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,
@@ -16,15 +16,16 @@
#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/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategy/spherical/envelope.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/spherical/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/spherical/envelope.hpp>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
@@ -85,25 +86,7 @@ class spherical_side_formula
{
public :
typedef strategy::envelope::spherical<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
return envelope_strategy_type();
}
typedef strategy::disjoint::segment_box_spherical disjoint_strategy_type;
static inline disjoint_strategy_type get_disjoint_strategy()
{
return disjoint_strategy_type();
}
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();
}
typedef spherical_tag cs_tag;
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)