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

@@ -76,6 +76,11 @@ public :
return m_left < 0 && m_right < 0;
}
inline bool empty(buffer_side_selector side) const
{
return side == buffer_side_left ? m_left == 0 : m_right == 0;
}
//! Returns the max distance distance up to the buffer will reach
template <typename JoinStrategy, typename EndStrategy>
inline NumericType max_distance(JoinStrategy const& join_strategy,

View File

@@ -74,6 +74,11 @@ public :
return m_distance < 0;
}
inline bool empty(buffer_side_selector ) const
{
return m_distance == 0;
}
//! Returns the max distance distance up to the buffer will reach
template <typename JoinStrategy, typename EndStrategy>
inline NumericType max_distance(JoinStrategy const& join_strategy,

View File

@@ -1,386 +0,0 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014, 2018.
// Modifications copyright (c) 2014, 2018 Oracle and/or its affiliates.
// 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.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
#include <cstddef>
#include <algorithm>
#include <vector>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/geometry/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/convex_hull.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/views/detail/range_type.hpp>
#include <boost/geometry/views/reversible_view.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace convex_hull
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template
<
typename InputRange,
typename RangeIterator,
typename StrategyLess,
typename StrategyGreater
>
struct get_extremes
{
typedef typename point_type<InputRange>::type point_type;
point_type left, right;
bool first;
StrategyLess less;
StrategyGreater greater;
inline get_extremes()
: first(true)
{}
inline void apply(InputRange const& range)
{
if (boost::size(range) == 0)
{
return;
}
// First iterate through this range
// (this two-stage approach avoids many point copies,
// because iterators are kept in memory. Because iterators are
// not persistent (in MSVC) this approach is not applicable
// for more ranges together)
RangeIterator left_it = boost::begin(range);
RangeIterator right_it = boost::begin(range);
for (RangeIterator it = boost::begin(range) + 1;
it != boost::end(range);
++it)
{
if (less(*it, *left_it))
{
left_it = it;
}
if (greater(*it, *right_it))
{
right_it = it;
}
}
// Then compare with earlier
if (first)
{
// First time, assign left/right
left = *left_it;
right = *right_it;
first = false;
}
else
{
// Next time, check if this range was left/right from
// the extremes already collected
if (less(*left_it, left))
{
left = *left_it;
}
if (greater(*right_it, right))
{
right = *right_it;
}
}
}
};
template
<
typename InputRange,
typename RangeIterator,
typename Container,
typename SideStrategy
>
struct assign_range
{
Container lower_points, upper_points;
typedef typename point_type<InputRange>::type point_type;
point_type const& most_left;
point_type const& most_right;
inline assign_range(point_type const& left, point_type const& right)
: most_left(left)
, most_right(right)
{}
inline void apply(InputRange const& range)
{
typedef SideStrategy side;
// Put points in one of the two output sequences
for (RangeIterator it = boost::begin(range);
it != boost::end(range);
++it)
{
// check if it is lying most_left or most_right from the line
int dir = side::apply(most_left, most_right, *it);
switch(dir)
{
case 1 : // left side
upper_points.push_back(*it);
break;
case -1 : // right side
lower_points.push_back(*it);
break;
// 0: on line most_left-most_right,
// or most_left, or most_right,
// -> all never part of hull
}
}
}
};
template <typename Range>
static inline void sort(Range& range)
{
typedef typename boost::range_value<Range>::type point_type;
typedef geometry::less<point_type> comparator;
std::sort(boost::begin(range), boost::end(range), comparator());
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
/*!
\brief Graham scan strategy to calculate convex hull
\ingroup strategies
*/
template <typename InputGeometry, typename OutputPoint>
class graham_andrew
{
public :
typedef OutputPoint point_type;
typedef InputGeometry geometry_type;
private:
typedef typename cs_tag<point_type>::type cs_tag;
typedef typename std::vector<point_type> container_type;
typedef typename std::vector<point_type>::const_iterator iterator;
typedef typename std::vector<point_type>::const_reverse_iterator rev_iterator;
class partitions
{
friend class graham_andrew;
container_type m_lower_hull;
container_type m_upper_hull;
container_type m_copied_input;
};
public:
typedef partitions state_type;
inline void apply(InputGeometry const& geometry, partitions& state) const
{
// First pass.
// Get min/max (in most cases left / right) points
// This makes use of the geometry::less/greater predicates
// For the left boundary it is important that multiple points
// are sorted from bottom to top. Therefore the less predicate
// does not take the x-only template parameter (this fixes ticket #6019.
// For the right boundary it is not necessary (though also not harmful),
// because points are sorted from bottom to top in a later stage.
// For symmetry and to get often more balanced lower/upper halves
// we keep it.
typedef typename geometry::detail::range_type<InputGeometry>::type range_type;
typedef typename boost::range_iterator
<
range_type const
>::type range_iterator;
detail::get_extremes
<
range_type,
range_iterator,
geometry::less<point_type>,
geometry::greater<point_type>
> extremes;
geometry::detail::for_each_range(geometry, extremes);
// Bounding left/right points
// Second pass, now that extremes are found, assign all points
// in either lower, either upper
detail::assign_range
<
range_type,
range_iterator,
container_type,
typename strategy::side::services::default_strategy<cs_tag>::type
> assigner(extremes.left, extremes.right);
geometry::detail::for_each_range(geometry, assigner);
// Sort both collections, first on x(, then on y)
detail::sort(assigner.lower_points);
detail::sort(assigner.upper_points);
//std::cout << boost::size(assigner.lower_points) << std::endl;
//std::cout << boost::size(assigner.upper_points) << std::endl;
// And decide which point should be in the final hull
build_half_hull<-1>(assigner.lower_points, state.m_lower_hull,
extremes.left, extremes.right);
build_half_hull<1>(assigner.upper_points, state.m_upper_hull,
extremes.left, extremes.right);
}
template <typename OutputIterator>
inline void result(partitions const& state,
OutputIterator out,
bool clockwise,
bool closed) const
{
if (clockwise)
{
output_ranges(state.m_upper_hull, state.m_lower_hull, out, closed);
}
else
{
output_ranges(state.m_lower_hull, state.m_upper_hull, out, closed);
}
}
private:
template <int Factor>
static inline void build_half_hull(container_type const& input,
container_type& output,
point_type const& left, point_type const& right)
{
output.push_back(left);
for(iterator it = input.begin(); it != input.end(); ++it)
{
add_to_hull<Factor>(*it, output);
}
add_to_hull<Factor>(right, output);
}
template <int Factor>
static inline void add_to_hull(point_type const& p, container_type& output)
{
typedef typename strategy::side::services::default_strategy<cs_tag>::type side;
output.push_back(p);
std::size_t output_size = output.size();
while (output_size >= 3)
{
rev_iterator rit = output.rbegin();
point_type const last = *rit++;
point_type const& last2 = *rit++;
if (Factor * side::apply(*rit, last, last2) <= 0)
{
// Remove last two points from stack, and add last again
// This is much faster then erasing the one but last.
output.pop_back();
output.pop_back();
output.push_back(last);
output_size--;
}
else
{
return;
}
}
}
template <typename OutputIterator>
static inline void output_ranges(container_type const& first, container_type const& second,
OutputIterator out, bool closed)
{
std::copy(boost::begin(first), boost::end(first), out);
BOOST_GEOMETRY_ASSERT(closed ? !boost::empty(second) : boost::size(second) > 1);
std::copy(++boost::rbegin(second), // skip the first Point
closed ? boost::rend(second) : --boost::rend(second), // skip the last Point if open
out);
typedef typename boost::range_size<container_type>::type size_type;
size_type const count = boost::size(first) + boost::size(second) - 1;
// count describes a closed case but comparison with min size of closed
// gives the result compatible also with open
// here core_detail::closure::minimum_ring_size<closed> could be used
if (count < 4)
{
// there should be only one missing
*out++ = *boost::begin(first);
}
}
};
}} // namespace strategy::convex_hull
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
template <typename InputGeometry, typename OutputPoint>
struct strategy_convex_hull<InputGeometry, OutputPoint, cartesian_tag>
{
typedef strategy::convex_hull::graham_andrew<InputGeometry, OutputPoint> type;
};
#endif
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP

View File

@@ -3,9 +3,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018 Oracle and/or its affiliates.
// This file was modified by Oracle on 2018-2020.
// Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -18,13 +19,17 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
#include <boost/array.hpp>
#include <array>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/within.hpp>
@@ -34,6 +39,10 @@ namespace boost { namespace geometry { namespace strategy
namespace within
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
struct decide_within
{
static inline bool apply(int side, bool& result)
@@ -65,45 +74,186 @@ struct decide_covered_by
// This strategy is not suitable for boxes in non-cartesian CSes having edges
// longer than 180deg because e.g. the SSF formula picks the side of the closer
// longitude, so for long edges the side is the opposite.
template <typename Decide = decide_within>
struct point_in_box_by_side
// Actually it is not suitable for shorter edges either because the edges of
// boxes are defined by meridians and parallels, not great circles or geodesics.
template <typename Decide, typename Point, typename Box, typename Strategy>
inline bool point_in_box_by_side(Point const& point, Box const& box,
Strategy const& strategy)
{
boost::ignore_unused(strategy);
// Create (counterclockwise) array of points, the fifth one closes it
// Every point should be on the LEFT side (=1), or ON the border (=0),
// So >= 1 or >= 0
std::array<typename point_type<Box>::type, 5> bp;
geometry::detail::assign_box_corners_oriented<true>(box, bp);
bp[4] = bp[0];
bool result = true;
for (int i = 1; i < 5; i++)
{
int const side = strategy.apply(point, bp[i - 1], bp[i]);
if (! Decide::apply(side, result))
{
return result;
}
}
return result;
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
// There should probably be another category of geometry different than box,
// e.g. rectangle or convex_ring. This strategy should probably be an
// algorithm calling side strategy.
template <typename CalculationType = void>
struct cartesian_point_box_by_side
{
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
typedef typename strategy::side::services::default_strategy
using side_strategy_type
= typename strategy::side::services::default_strategy
<cartesian_tag, CalculationType>::type;
return within::detail::point_in_box_by_side
<
typename cs_tag<Box>::type
>::type side_strategy_type;
// Create (counterclockwise) array of points, the fifth one closes it
// Every point should be on the LEFT side (=1), or ON the border (=0),
// So >= 1 or >= 0
boost::array<typename point_type<Box>::type, 5> bp;
geometry::detail::assign_box_corners_oriented<true>(box, bp);
bp[4] = bp[0];
bool result = true;
side_strategy_type strategy;
boost::ignore_unused(strategy);
for (int i = 1; i < 5; i++)
{
int const side = strategy.apply(point, bp[i - 1], bp[i]);
if (! Decide::apply(side, result))
{
return result;
}
}
return result;
within::detail::decide_within
>(point, box, side_strategy_type());
}
};
template <typename CalculationType = void>
struct spherical_point_box_by_side
{
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
return within::detail::point_in_box_by_side
<
within::detail::decide_within
>(point, box,
strategy::side::spherical_side_formula<CalculationType>());
}
};
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
struct geographic_point_box_by_side
{
geographic_point_box_by_side() = default;
explicit geographic_point_box_by_side(Spheroid const& spheroid)
: m_side(spheroid)
{}
template <typename Point, typename Box>
bool apply(Point const& point, Box const& box) const
{
return within::detail::point_in_box_by_side
<
within::detail::decide_within
>(point, box, m_side);
}
Spheroid const& model() const
{
return m_side.model();
}
private:
strategy::side::geographic
<
FormulaPolicy, Spheroid, CalculationType
> m_side;
};
} // namespace within
namespace covered_by
{
template <typename CalculationType = void>
struct cartesian_point_box_by_side
{
template <typename Point, typename Box>
static bool apply(Point const& point, Box const& box)
{
using side_strategy_type
= typename strategy::side::services::default_strategy
<cartesian_tag, CalculationType>::type;
return within::detail::point_in_box_by_side
<
within::detail::decide_covered_by
>(point, box, side_strategy_type());
}
};
template <typename CalculationType = void>
struct spherical_point_box_by_side
{
template <typename Point, typename Box>
static bool apply(Point const& point, Box const& box)
{
return within::detail::point_in_box_by_side
<
within::detail::decide_covered_by
>(point, box,
strategy::side::spherical_side_formula<CalculationType>());
}
};
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
struct geographic_point_box_by_side
{
geographic_point_box_by_side() = default;
explicit geographic_point_box_by_side(Spheroid const& spheroid)
: m_side(spheroid)
{}
template <typename Point, typename Box>
bool apply(Point const& point, Box const& box) const
{
return within::detail::point_in_box_by_side
<
within::detail::decide_covered_by
>(point, box, m_side);
}
Spheroid const& model() const
{
return m_side.model();
}
private:
strategy::side::geographic
<
FormulaPolicy, Spheroid, CalculationType
> m_side;
};
}
}}} // namespace boost::geometry::strategy

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013, 2014, 2016, 2017.
// Modifications copyright (c) 2013-2017 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -18,9 +18,8 @@
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -54,30 +53,35 @@ template
>
struct winding_base_type
{
BOOST_MPL_ASSERT_MSG(false,
NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM,
(CSTag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this coordinate system.",
Point, PointOfSegment, CSTag);
};
template <typename Point, typename PointOfSegment, typename CalculationType>
struct winding_base_type<Point, PointOfSegment, CalculationType, cartesian_tag>
{
typedef within::cartesian_winding<Point, PointOfSegment, CalculationType> type;
};
template <typename Point, typename PointOfSegment, typename CalculationType>
struct winding_base_type<Point, PointOfSegment, CalculationType, spherical_tag>
{
typedef within::detail::spherical_winding_base
using type = within::detail::cartesian_winding_base
<
Point,
PointOfSegment,
typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
>::type,
CalculationType
> type;
>;
};
template <typename Point, typename PointOfSegment, typename CalculationType>
struct winding_base_type<Point, PointOfSegment, CalculationType, spherical_tag>
{
using type = within::detail::spherical_winding_base
<
typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
>::type,
CalculationType
>;
};

View File

@@ -3,10 +3,10 @@
// Copyright (c) 1995, 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 1995 Maarten Hilferink, Amsterdam, the Netherlands
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2021.
// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
// 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.
@@ -19,23 +19,9 @@
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP
#include <cstddef>
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
#include <iostream>
#endif
#include <vector>
#include <boost/range.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/strategies/distance.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
#include <boost/geometry/io/dsv/write.hpp>
#endif
namespace boost { namespace geometry
{
@@ -43,202 +29,7 @@ namespace strategy { namespace simplify
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
/*!
\brief Small wrapper around a point, with an extra member "included"
\details
It has a const-reference to the original point (so no copy here)
\tparam the enclosed point type
*/
template<typename Point>
struct douglas_peucker_point
{
Point const& p;
bool included;
inline douglas_peucker_point(Point const& ap)
: p(ap)
, included(false)
{}
// Necessary for proper compilation
inline douglas_peucker_point<Point> operator=(douglas_peucker_point<Point> const& )
{
return douglas_peucker_point<Point>(*this);
}
};
template
<
typename Point,
typename PointDistanceStrategy,
typename LessCompare
= std::less
<
typename strategy::distance::services::return_type
<
PointDistanceStrategy,
Point, Point
>::type
>
>
class douglas_peucker
: LessCompare // for empty base optimization
{
public :
// See also ticket 5954 https://svn.boost.org/trac/boost/ticket/5954
// Comparable is currently not possible here because it has to be compared to the squared of max_distance, and more.
// For now we have to take the real distance.
typedef PointDistanceStrategy distance_strategy_type;
// typedef typename strategy::distance::services::comparable_type<PointDistanceStrategy>::type distance_strategy_type;
typedef typename strategy::distance::services::return_type
<
distance_strategy_type,
Point, Point
>::type distance_type;
douglas_peucker()
{}
douglas_peucker(LessCompare const& less_compare)
: LessCompare(less_compare)
{}
private :
typedef detail::douglas_peucker_point<Point> dp_point_type;
typedef typename std::vector<dp_point_type>::iterator iterator_type;
LessCompare const& less() const
{
return *this;
}
inline void consider(iterator_type begin,
iterator_type end,
distance_type const& max_dist,
int& n,
distance_strategy_type const& ps_distance_strategy) const
{
std::size_t size = end - begin;
// size must be at least 3
// because we want to consider a candidate point in between
if (size <= 2)
{
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
if (begin != end)
{
std::cout << "ignore between " << dsv(begin->p)
<< " and " << dsv((end - 1)->p)
<< " size=" << size << std::endl;
}
std::cout << "return because size=" << size << std::endl;
#endif
return;
}
iterator_type last = end - 1;
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
std::cout << "find between " << dsv(begin->p)
<< " and " << dsv(last->p)
<< " size=" << size << std::endl;
#endif
// Find most far point, compare to the current segment
//geometry::segment<Point const> s(begin->p, last->p);
distance_type md(-1.0); // any value < 0
iterator_type candidate;
for(iterator_type it = begin + 1; it != last; ++it)
{
distance_type dist = ps_distance_strategy.apply(it->p, begin->p, last->p);
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
std::cout << "consider " << dsv(it->p)
<< " at " << double(dist)
<< ((dist > max_dist) ? " maybe" : " no")
<< std::endl;
#endif
if ( less()(md, dist) )
{
md = dist;
candidate = it;
}
}
// If a point is found, set the include flag
// and handle segments in between recursively
if ( less()(max_dist, md) )
{
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
std::cout << "use " << dsv(candidate->p) << std::endl;
#endif
candidate->included = true;
n++;
consider(begin, candidate + 1, max_dist, n, ps_distance_strategy);
consider(candidate, end, max_dist, n, ps_distance_strategy);
}
}
public :
template <typename Range, typename OutputIterator>
inline OutputIterator apply(Range const& range,
OutputIterator out,
distance_type max_distance) const
{
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
std::cout << "max distance: " << max_distance
<< std::endl << std::endl;
#endif
distance_strategy_type strategy;
// Copy coordinates, a vector of references to all points
std::vector<dp_point_type> ref_candidates(boost::begin(range),
boost::end(range));
// Include first and last point of line,
// they are always part of the line
int n = 2;
ref_candidates.front().included = true;
ref_candidates.back().included = true;
// Get points, recursively, including them if they are further away
// than the specified distance
consider(boost::begin(ref_candidates), boost::end(ref_candidates), max_distance, n, strategy);
// Copy included elements to the output
for(typename std::vector<dp_point_type>::const_iterator it
= boost::begin(ref_candidates);
it != boost::end(ref_candidates);
++it)
{
if (it->included)
{
// copy-coordinates does not work because OutputIterator
// does not model Point (??)
//geometry::convert(it->p, *out);
*out = it->p;
out++;
}
}
return out;
}
};
}
#endif // DOXYGEN_NO_DETAIL
// NOTE: Left here for backward compatibility.
/*!
@@ -270,52 +61,24 @@ public :
typedef PointDistanceStrategy distance_strategy_type;
typedef typename detail::douglas_peucker
<
Point,
PointDistanceStrategy
>::distance_type distance_type;
typedef typename strategy::distance::services::return_type
<
distance_strategy_type,
Point, Point
>::type distance_type;
template <typename Range, typename OutputIterator>
static inline OutputIterator apply(Range const& range,
static inline OutputIterator apply(Range const& ,
OutputIterator out,
distance_type const& max_distance)
distance_type const& )
{
namespace services = strategy::distance::services;
typedef typename services::comparable_type
<
PointDistanceStrategy
>::type comparable_distance_strategy_type;
return detail::douglas_peucker
<
Point, comparable_distance_strategy_type
>().apply(range, out,
services::result_from_distance
<
comparable_distance_strategy_type, Point, Point
>::apply(comparable_distance_strategy_type(),
max_distance)
);
return out;
}
};
}} // namespace strategy::simplify
namespace traits {
template <typename P>
struct point_type<geometry::strategy::simplify::detail::douglas_peucker_point<P> >
{
typedef P type;
};
} // namespace traits
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP

View File

@@ -1,92 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020, Oracle and/or its affiliates.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// 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_AREA_HPP
#define BOOST_GEOMETRY_STRATEGIES_AREA_HPP
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/mpl/assert.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/area.hpp>
namespace strategy { namespace area
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
// If user specified a CalculationType, use that type, whatever it is
// and whatever the Geometry is.
// Else, use Geometry's coordinate-type promoted to double if needed.
template
<
typename Geometry,
typename CalculationType
>
struct result_type
{
typedef CalculationType type;
};
template
<
typename Geometry
>
struct result_type<Geometry, void>
: select_most_precise
<
typename coordinate_type<Geometry>::type,
double
>
{};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
namespace services
{
/*!
\brief Traits class binding a default area strategy to a coordinate system
\ingroup area
\tparam Tag tag of coordinate system
*/
template <typename Tag>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM
, (types<Tag>)
);
};
} // namespace services
}} // namespace strategy::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AREA_HPP

View File

@@ -0,0 +1,72 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_AREA_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_AREA_CARTESIAN_HPP
#include <boost/geometry/strategy/cartesian/area.hpp>
#include <boost/geometry/strategy/cartesian/area_box.hpp>
#include <boost/geometry/strategies/area/services.hpp>
#include <boost/geometry/strategies/detail.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace area
{
template <typename CalculationType = void>
struct cartesian : strategies::detail::cartesian_base
{
template <typename Geometry>
static auto area(Geometry const&,
std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr)
{
return strategy::area::cartesian<CalculationType>();
}
template <typename Geometry>
static auto area(Geometry const&,
std::enable_if_t<util::is_box<Geometry>::value> * = nullptr)
{
return strategy::area::cartesian_box<CalculationType>();
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, cartesian_tag>
{
using type = strategies::area::cartesian<>;
};
template <typename CT>
struct strategy_converter<strategy::area::cartesian<CT> >
{
static auto get(strategy::area::cartesian<CT> const&)
{
return strategies::area::cartesian<CT>();
}
};
} // namespace services
}} // namespace strategies::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AREA_CARTESIAN_HPP

View File

@@ -0,0 +1,111 @@
// Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_AREA_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_AREA_GEOGRAPHIC_HPP
#include <boost/geometry/strategy/geographic/area.hpp>
#include <boost/geometry/strategy/geographic/area_box.hpp>
#include <boost/geometry/strategies/area/services.hpp>
#include <boost/geometry/strategies/detail.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace area
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public strategies::detail::geographic_base<Spheroid>
{
using base_t = strategies::detail::geographic_base<Spheroid>;
public:
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
template <typename Geometry>
auto area(Geometry const&,
std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr) const
{
return strategy::area::geographic
<
FormulaPolicy,
strategy::default_order<FormulaPolicy>::value,
Spheroid, CalculationType
>(base_t::m_spheroid);
}
template <typename Geometry>
auto area(Geometry const&,
std::enable_if_t<util::is_box<Geometry>::value> * = nullptr) const
{
return strategy::area::geographic_box
<
Spheroid, CalculationType
>(base_t::m_spheroid);
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, geographic_tag>
{
using type = strategies::area::geographic<>;
};
template <typename FP, std::size_t SO, typename S, typename CT>
struct strategy_converter<strategy::area::geographic<FP, SO, S, CT> >
{
struct altered_strategy
: strategies::area::geographic<FP, S, CT>
{
explicit altered_strategy(S const& spheroid)
: strategies::area::geographic<FP, S, CT>(spheroid)
{}
using strategies::area::geographic<FP, S, CT>::area;
template <typename Geometry>
auto area(Geometry const&,
std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr) const
{
return strategy::area::geographic<FP, SO, S, CT>(this->m_spheroid);
}
};
static auto get(strategy::area::geographic<FP, SO, S, CT> const& strategy)
{
return altered_strategy(strategy.model());
}
};
} // namespace services
}} // namespace strategies::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AREA_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,55 @@
// Boost.Geometry
// Copyright (c) 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_AREA_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_AREA_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace area {
namespace services
{
template
<
typename Geometry,
typename CSTag = typename geometry::cs_tag<Geometry>::type
>
struct default_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Geometry's coordinate system.",
Geometry, CSTag);
};
template <typename Strategy>
struct strategy_converter
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
} // namespace services
}} // namespace strategies::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AREA_SERVICES_HPP

View File

@@ -0,0 +1,107 @@
// Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_AREA_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_AREA_SPHERICAL_HPP
#include <boost/geometry/strategy/spherical/area.hpp>
#include <boost/geometry/strategy/spherical/area_box.hpp>
#include <boost/geometry/strategies/area/services.hpp>
#include <boost/geometry/strategies/detail.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace area
{
template
<
typename RadiusTypeOrSphere = double,
typename CalculationType = void
>
class spherical
: public strategies::detail::spherical_base<RadiusTypeOrSphere>
{
using base_t = strategies::detail::spherical_base<RadiusTypeOrSphere>;
public:
spherical()
: base_t()
{}
template <typename RadiusOrSphere>
explicit spherical(RadiusOrSphere const& radius_or_sphere)
: base_t(radius_or_sphere)
{}
template <typename Geometry>
auto area(Geometry const&,
std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr) const
{
return strategy::area::spherical
<
typename base_t::radius_type, CalculationType
>(base_t::m_radius);
}
template <typename Geometry>
auto area(Geometry const&,
std::enable_if_t<util::is_box<Geometry>::value> * = nullptr) const
{
return strategy::area::spherical_box
<
typename base_t::radius_type, CalculationType
>(base_t::m_radius);
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, spherical_tag>
{
using type = strategies::area::spherical<>;
};
template <typename Geometry>
struct default_strategy<Geometry, spherical_equatorial_tag>
{
using type = strategies::area::spherical<>;
};
template <typename Geometry>
struct default_strategy<Geometry, spherical_polar_tag>
{
using type = strategies::area::spherical<>;
};
template <typename R, typename CT>
struct strategy_converter<strategy::area::spherical<R, CT> >
{
static auto get(strategy::area::spherical<R, CT> const& strategy)
{
return strategies::area::spherical<R, CT>(strategy.model());
}
};
} // namespace services
}} // namespace strategies::area
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AREA_SPHERICAL_HPP

View File

@@ -1,116 +1,21 @@
// Boost.Geometry
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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)
// 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_AREA_RESULT_HPP
#define BOOST_GEOMETRY_STRATEGIES_AREA_RESULT_HPP
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/strategies/area.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/util/select_sequence_element.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/variant/variant_fwd.hpp>
namespace boost { namespace geometry
{
/*!
\brief Meta-function defining return type of area function
\ingroup area
\note The return-type is defined by Geometry and Strategy
*/
template
<
typename Geometry,
typename Strategy = default_strategy
>
struct area_result
: Strategy::template result_type<Geometry>
{};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy>
struct area_result<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy>
: geometry::area_result
<
typename geometry::util::select_sequence_element
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
>::type,
Strategy
>
{};
template <typename Geometry>
struct area_result<Geometry, default_strategy>
: geometry::area_result
<
Geometry,
typename geometry::strategy::area::services::default_strategy
<
typename cs_tag<Geometry>::type
>::type
>
{};
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace area
{
template <typename Curr, typename Next>
struct pred_more_precise_default_area_result
{
typedef typename geometry::area_result<Curr, default_strategy>::type curr_result_t;
typedef typename geometry::area_result<Next, default_strategy>::type next_result_t;
typedef typename boost::mpl::if_c
<
boost::is_same
<
curr_result_t,
typename geometry::select_most_precise
<
curr_result_t,
next_result_t
>::type
>::value,
Curr,
Next
>::type type;
};
}} // namespace detail::area
#endif //DOXYGEN_NO_DETAIL
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct area_result<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, default_strategy>
: geometry::area_result
<
typename geometry::util::select_sequence_element
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
geometry::detail::area::pred_more_precise_default_area_result
>::type,
default_strategy
>
{};
}} // namespace boost::geometry
#include <boost/geometry/algorithms/area_result.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_AREA_RESULT_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
@@ -11,7 +11,7 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_AZIMUTH_HPP
#define BOOST_GEOMETRY_STRATEGIES_AZIMUTH_HPP
#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
{
@@ -26,14 +26,12 @@ namespace strategy { namespace azimuth { namespace services
\tparam CSTag tag of coordinate system
\tparam CalculationType \tparam_calculation
*/
template <typename CSTag, typename CalculationType = void>
template <typename CSTag>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_TYPE
, (types<CSTag>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this type.",
CSTag);
};
}}} // namespace strategy::azimuth::services

View File

@@ -0,0 +1,63 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_AZIMUTH_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_AZIMUTH_CARTESIAN_HPP
// TODO: move this file to boost/geometry/strategy
#include <boost/geometry/strategies/cartesian/azimuth.hpp>
#include <boost/geometry/strategies/azimuth/services.hpp>
#include <boost/geometry/strategies/detail.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace azimuth
{
template <typename CalculationType = void>
struct cartesian : strategies::detail::cartesian_base
{
static auto azimuth()
{
return strategy::azimuth::cartesian<CalculationType>();
}
};
namespace services
{
template <typename Point1, typename Point2>
struct default_strategy<Point1, Point2, cartesian_tag, cartesian_tag>
{
using type = strategies::azimuth::cartesian<>;
};
template <typename CT>
struct strategy_converter<strategy::azimuth::cartesian<CT> >
{
static auto get(strategy::azimuth::cartesian<CT> const&)
{
return strategies::azimuth::cartesian<CT>();
}
};
} // namespace services
}} // namespace strategies::azimuth
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AZIMUTH_CARTESIAN_HPP

View File

@@ -0,0 +1,81 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_AZIMUTH_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_AZIMUTH_GEOGRAPHIC_HPP
// TODO: move this file to boost/geometry/strategy
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/azimuth/services.hpp>
#include <boost/geometry/strategies/detail.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace azimuth
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic : strategies::detail::geographic_base<Spheroid>
{
using base_t = strategies::detail::geographic_base<Spheroid>;
public:
geographic()
: base_t()
{}
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
auto azimuth() const
{
return strategy::azimuth::geographic
<
FormulaPolicy, Spheroid, CalculationType
>(base_t::m_spheroid);
}
};
namespace services
{
template <typename Point1, typename Point2>
struct default_strategy<Point1, Point2, geographic_tag, geographic_tag>
{
using type = strategies::azimuth::geographic<>;
};
template <typename FP, typename S, typename CT>
struct strategy_converter<strategy::azimuth::geographic<FP, S, CT> >
{
static auto get(strategy::azimuth::geographic<FP, S, CT> const& strategy)
{
return strategies::azimuth::geographic<FP, S, CT>(strategy.model());
}
};
} // namespace services
}} // namespace strategies::azimuth
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AZIMUTH_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,56 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_AZIMUTH_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_AZIMUTH_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace azimuth {
namespace services
{
template
<
typename Point1, typename Point2,
typename CSTag1 = typename geometry::cs_tag<Point1>::type,
typename CSTag2 = typename geometry::cs_tag<Point2>::type
>
struct default_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for these Points' coordinate systems.",
Point1, Point2, CSTag1, CSTag2);
};
template <typename Strategy>
struct strategy_converter
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
} // namespace services
}} // namespace strategies::azimuth
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AZIMUTH_SERVICES_HPP

View File

@@ -0,0 +1,67 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_AZIMUTH_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_AZIMUTH_SPHERICAL_HPP
// TODO: move this file to boost/geometry/strategy
#include <boost/geometry/strategies/spherical/azimuth.hpp>
#include <boost/geometry/strategies/azimuth/services.hpp>
#include <boost/geometry/strategies/detail.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace azimuth
{
template <typename CalculationType = void>
class spherical : strategies::detail::spherical_base<void>
{
using base_t = strategies::detail::spherical_base<void>;
public:
static auto azimuth()
{
return strategy::azimuth::spherical<CalculationType>();
}
};
namespace services
{
template <typename Point1, typename Point2>
struct default_strategy<Point1, Point2, spherical_equatorial_tag, spherical_equatorial_tag>
{
using type = strategies::azimuth::spherical<>;
};
template <typename CT>
struct strategy_converter<strategy::azimuth::spherical<CT> >
{
static auto get(strategy::azimuth::spherical<CT> const&)
{
return strategies::azimuth::spherical<CT>();
}
};
} // namespace services
}} // namespace strategies::azimuth
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_AZIMUTH_SPHERICAL_HPP

View File

@@ -6,8 +6,10 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_HPP
#ifndef BOOST_GEOMETRY_STRATEGIES_BUFFER_HPP
#define BOOST_GEOMETRY_STRATEGIES_BUFFER_HPP
#include <cstdint>
namespace boost { namespace geometry
{
@@ -55,6 +57,27 @@ namespace strategy { namespace buffer
*/
enum buffer_side_selector { buffer_side_left, buffer_side_right };
// Default number of points in a circle
constexpr std::size_t default_points_per_circle = 90u;
inline std::size_t get_point_count_for_join(std::size_t count)
{
std::size_t const min_count = 4u;
return count > min_count ? count : min_count;
}
inline std::size_t get_point_count_for_end(std::size_t count)
{
std::size_t const min_count = 4u;
return count > min_count ? count : min_count;
}
inline std::size_t get_point_count_for_circle(std::size_t count)
{
std::size_t const min_count = 3u;
return count > min_count ? count : min_count;
}
/*!
\brief Enumerates types of pieces (parts of buffer) around geometries
\ingroup enum
@@ -67,6 +90,7 @@ enum piece_type
buffered_flat_end,
buffered_point,
buffered_concave, // always on the inside
buffered_empty_side, // for one-sided buffers
piece_type_unknown
};
@@ -100,4 +124,4 @@ enum result_code
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_HPP
#endif // BOOST_GEOMETRY_STRATEGIES_BUFFER_HPP

View File

@@ -0,0 +1,46 @@
// Boost.Geometry
// Copyright (c) 2021-2022, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_BUFFER_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_BUFFER_CARTESIAN_HPP
#include <boost/geometry/strategies/buffer/services.hpp>
#include <boost/geometry/strategies/distance/cartesian.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace buffer
{
template <typename CalculationType = void>
struct cartesian
: public strategies::distance::cartesian<CalculationType>
{};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, cartesian_tag>
{
using type = strategies::buffer::cartesian<>;
};
} // namespace services
}} // namespace strategies::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_BUFFER_CARTESIAN_HPP

View File

@@ -0,0 +1,61 @@
// Boost.Geometry
// Copyright (c) 2021-2022, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_BUFFER_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_BUFFER_GEOGRAPHIC_HPP
#include <boost/geometry/strategies/buffer/services.hpp>
#include <boost/geometry/strategies/distance/geographic.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace buffer
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public strategies::distance::geographic<FormulaPolicy, Spheroid, CalculationType>
{
using base_t = strategies::distance::geographic<FormulaPolicy, Spheroid, CalculationType>;
public:
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, geographic_tag>
{
using type = strategies::buffer::geographic<>;
};
} // namespace services
}} // namespace strategies::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_BUFFER_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,46 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_BUFFER_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_BUFFER_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace buffer
{
namespace services
{
template
<
typename Geometry,
typename CSTag = typename geometry::cs_tag<Geometry>::type
>
struct default_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Geometry's coordinate systems.",
Geometry, CSTag);
};
} // namespace services
}} // namespace strategies::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_BUFFER_SERVICES_HPP

View File

@@ -0,0 +1,60 @@
// Boost.Geometry
// Copyright (c) 2021-2022, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_BUFFER_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_BUFFER_SPHERICAL_HPP
#include <boost/geometry/strategies/buffer/services.hpp>
#include <boost/geometry/strategies/distance/spherical.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace buffer
{
template
<
typename RadiusTypeOrSphere = double,
typename CalculationType = void
>
class spherical
: public strategies::distance::detail::spherical<RadiusTypeOrSphere, CalculationType>
{
using base_t = strategies::distance::detail::spherical<RadiusTypeOrSphere, CalculationType>;
public:
spherical() = default;
template <typename RadiusOrSphere>
explicit spherical(RadiusOrSphere const& radius_or_sphere)
: base_t(radius_or_sphere)
{}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, spherical_equatorial_tag>
{
using type = strategies::buffer::spherical<>;
};
} // namespace services
}} // namespace strategies::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_BUFFER_SPHERICAL_HPP

View File

@@ -0,0 +1,61 @@
// Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_HPP
#include <boost/geometry/strategies/area/cartesian.hpp>
#include <boost/geometry/strategies/azimuth/cartesian.hpp>
#include <boost/geometry/strategies/buffer/cartesian.hpp>
#include <boost/geometry/strategies/convex_hull/cartesian.hpp>
#include <boost/geometry/strategies/distance/cartesian.hpp>
#include <boost/geometry/strategies/envelope/cartesian.hpp>
#include <boost/geometry/strategies/expand/cartesian.hpp>
#include <boost/geometry/strategies/io/cartesian.hpp>
#include <boost/geometry/strategies/index/cartesian.hpp>
#include <boost/geometry/strategies/is_convex/cartesian.hpp>
#include <boost/geometry/strategies/relate/cartesian.hpp>
#include <boost/geometry/strategies/simplify/cartesian.hpp>
namespace boost { namespace geometry
{
namespace strategies
{
template <typename CalculationType = void>
class cartesian
// derived from the umbrella strategy defining the most strategies
: public strategies::index::cartesian<CalculationType>
{
public:
static auto azimuth()
{
return strategy::azimuth::cartesian<CalculationType>();
}
static auto point_order()
{
return strategy::point_order::cartesian<CalculationType>();
}
};
} // namespace strategies
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_HPP

View File

@@ -1,147 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2016, 2017, 2018.
// Modifications copyright (c) 2016-2018, Oracle and/or its affiliates.
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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.
// 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_CARTESIAN_AREA_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_HPP
#include <boost/mpl/if.hpp>
//#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/strategies/area.hpp>
#include <boost/geometry/util/select_most_precise.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 area
{
/*!
\brief Cartesian area calculation
\ingroup strategies
\details Calculates cartesian area using the trapezoidal rule
\tparam CalculationType \tparam_calculation
\qbk{
[heading See also]
[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
}
*/
template
<
typename CalculationType = void
>
class cartesian
{
public :
template <typename Geometry>
struct result_type
: strategy::area::detail::result_type
<
Geometry,
CalculationType
>
{};
template <typename Geometry>
class state
{
friend class cartesian;
typedef typename result_type<Geometry>::type return_type;
public:
inline state()
: sum(0)
{
// Strategy supports only 2D areas
assert_dimension<Geometry, 2>();
}
private:
inline return_type area() const
{
return_type const two = 2;
return sum / two;
}
return_type sum;
};
template <typename PointOfSegment, typename Geometry>
static inline void apply(PointOfSegment const& p1,
PointOfSegment const& p2,
state<Geometry>& st)
{
typedef typename state<Geometry>::return_type return_type;
// Below formulas are equivalent, however the two lower ones
// suffer less from accuracy loss for great values of coordinates.
// See: https://svn.boost.org/trac/boost/ticket/11928
// SUM += x2 * y1 - x1 * y2;
// state.sum += detail::determinant<return_type>(p2, p1);
// SUM += (x2 - x1) * (y2 + y1)
//state.sum += (return_type(get<0>(p2)) - return_type(get<0>(p1)))
// * (return_type(get<1>(p2)) + return_type(get<1>(p1)));
// SUM += (x1 + x2) * (y1 - y2)
st.sum += (return_type(get<0>(p1)) + return_type(get<0>(p2)))
* (return_type(get<1>(p1)) - return_type(get<1>(p2)));
}
template <typename Geometry>
static inline typename result_type<Geometry>::type
result(state<Geometry>& st)
{
return st.area();
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <>
struct default_strategy<cartesian_tag>
{
typedef strategy::area::cartesian<> type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::area
}} // namespace boost::geometry
#include <boost/geometry/strategy/cartesian/area.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_HPP

View File

@@ -1,29 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2016, 2017.
// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates.
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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.
// 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_CARTESIAN_AREA_SURVEYOR_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
// keep this file for now, for backward compatibility
// functionality-wise, make it equivalent to boost/geometry/strategies/cartesian/area.hpp
#include <boost/geometry/strategies/cartesian/area.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
#include <boost/geometry/strategy/cartesian/area.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP

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-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,32 +11,81 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AZIMUTH_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AZIMUTH_HPP
#include <cmath>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/strategies/azimuth.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace azimuth
{
template
<
typename CalculationType = void
>
template <typename CalculationType = void>
class cartesian
{};
{
public:
template <typename T1, typename T2>
struct result_type
: geometry::select_most_precise
<
// NOTE: this promotes any integer type to double
typename geometry::promote_floating_point<T1, double>::type,
typename geometry::promote_floating_point<T2, double>::type,
CalculationType
>
{};
template <typename T1, typename T2, typename Result>
static inline void apply(T1 const& x1, T1 const& y1,
T2 const& x2, T2 const& y2,
Result& a1, Result& a2)
{
compute(x1, y1, x2, y2, a1, a2);
}
template <typename T1, typename T2, typename Result>
static inline void apply(T1 const& x1, T1 const& y1,
T2 const& x2, T2 const& y2,
Result& a1)
{
compute(x1, y1, x2, y2, a1, a1);
}
template <typename T1, typename T2, typename Result>
static inline void apply_reverse(T1 const& x1, T1 const& y1,
T2 const& x2, T2 const& y2,
Result& a2)
{
compute(x1, y1, x2, y2, a2, a2);
}
private:
template <typename T1, typename T2, typename Result>
static inline void compute(T1 const& x1, T1 const& y1,
T2 const& x2, T2 const& y2,
Result& a1, Result& a2)
{
typedef typename result_type<T1, T2>::type calc_t;
// NOTE: azimuth 0 is at Y axis, increasing right
// as in spherical/geographic where 0 is at North axis
a1 = a2 = atan2(calc_t(x2) - calc_t(x1), calc_t(y2) - calc_t(y1));
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<cartesian_tag, CalculationType>
template <>
struct default_strategy<cartesian_tag>
{
typedef strategy::azimuth::cartesian<CalculationType> type;
typedef strategy::azimuth::cartesian<> type;
};
}

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 2015, 2016, 2017.
// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2020.
// Modifications copyright (c) 2016-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -36,6 +36,11 @@ namespace within
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
struct box_within_coord
{
template <typename BoxContainedValue, typename BoxContainingValue>
@@ -63,18 +68,6 @@ struct box_covered_by_coord
};
template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_within_range
: box_within_coord
{};
template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_covered_by_range
: box_covered_by_coord
{};
struct box_within_longitude_diff
{
template <typename CalcT>
@@ -109,7 +102,7 @@ struct box_longitude_range
BoxContainedValue,
BoxContainingValue
>::type calc_t;
typedef typename coordinate_system<Geometry>::type::units units_t;
typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
if (CoordCheck::apply(bed_min, bed_max, bing_min, bing_max))
@@ -120,7 +113,7 @@ struct box_longitude_range
// min <= max <=> diff >= 0
calc_t const diff_ed = bed_max - bed_min;
calc_t const diff_ing = bing_max - bing_min;
// if containing covers the whole globe it contains all
if (diff_ing >= constants::period())
{
@@ -144,35 +137,21 @@ struct box_longitude_range
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
template <typename Geometry>
struct box_within_range<Geometry, 0, spherical_tag>
: box_longitude_range<Geometry, box_within_coord, box_within_longitude_diff>
{};
template <typename Geometry>
struct box_covered_by_range<Geometry, 0, spherical_tag>
: box_longitude_range<Geometry, box_covered_by_coord, box_covered_by_longitude_diff>
{};
template
<
template <typename, std::size_t, typename> class SubStrategy,
typename Box1,
typename Box2,
typename CSTag,
std::size_t Dimension,
std::size_t DimensionCount
>
struct relate_box_box_loop
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& b_contained, Box2 const& b_containing)
{
assert_dimension_equal<Box1, Box2>();
typedef typename tag_cast<typename cs_tag<Box1>::type, spherical_tag>::type cs_tag_t;
if (! SubStrategy<Box1, Dimension, cs_tag_t>::apply(
if (! SubStrategy<Box1, Dimension, CSTag>::apply(
get<min_corner, Dimension>(b_contained),
get<max_corner, Dimension>(b_contained),
get<min_corner, Dimension>(b_containing),
@@ -183,10 +162,9 @@ struct relate_box_box_loop
return false;
}
return relate_box_box_loop
return within::detail::relate_box_box_loop
<
SubStrategy,
Box1, Box2,
SubStrategy, CSTag,
Dimension + 1, DimensionCount
>::apply(b_contained, b_containing);
}
@@ -195,32 +173,82 @@ struct relate_box_box_loop
template
<
template <typename, std::size_t, typename> class SubStrategy,
typename Box1,
typename Box2,
typename CSTag,
std::size_t DimensionCount
>
struct relate_box_box_loop<SubStrategy, Box1, Box2, DimensionCount, DimensionCount>
struct relate_box_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount>
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& , Box2 const& )
{
return true;
}
};
template
<
typename Box1,
typename Box2,
template <typename, std::size_t, typename> class SubStrategy = box_within_range
>
struct box_in_box
template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_within_range
: within::detail::box_within_coord
{};
template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_covered_by_range
: within::detail::box_covered_by_coord
{};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
template <typename Geometry>
struct box_within_range<Geometry, 0, spherical_tag>
: within::detail::box_longitude_range
<
Geometry,
within::detail::box_within_coord,
within::detail::box_within_longitude_diff
>
{};
template <typename Geometry>
struct box_covered_by_range<Geometry, 0, spherical_tag>
: within::detail::box_longitude_range
<
Geometry,
within::detail::box_covered_by_coord,
within::detail::box_covered_by_longitude_diff
>
{};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
struct cartesian_box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
return relate_box_box_loop
return within::detail::relate_box_box_loop
<
SubStrategy,
Box1, Box2, 0, dimension<Box1>::type::value
within::detail::box_within_range,
cartesian_tag,
0, dimension<Box1>::type::value
>::apply(box1, box2);
}
};
struct spherical_box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
return within::detail::relate_box_box_loop
<
within::detail::box_within_range,
spherical_tag,
0, dimension<Box1>::type::value
>::apply(box1, box2);
}
};
@@ -229,6 +257,42 @@ struct box_in_box
} // namespace within
namespace covered_by
{
struct cartesian_box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
return within::detail::relate_box_box_loop
<
within::detail::box_covered_by_range,
cartesian_tag,
0, dimension<Box1>::type::value
>::apply(box1, box2);
}
};
struct spherical_box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
return within::detail::relate_box_box_loop
<
within::detail::box_covered_by_range,
spherical_tag,
0, dimension<Box1>::type::value
>::apply(box1, box2);
}
};
}
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
@@ -244,7 +308,7 @@ struct default_strategy
cartesian_tag, cartesian_tag
>
{
typedef within::box_in_box<BoxContained, BoxContaining> type;
typedef cartesian_box_box type;
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
@@ -257,7 +321,7 @@ struct default_strategy
spherical_tag, spherical_tag
>
{
typedef within::box_in_box<BoxContained, BoxContaining> type;
typedef spherical_box_box type;
};
@@ -275,11 +339,7 @@ struct default_strategy
cartesian_tag, cartesian_tag
>
{
typedef within::box_in_box
<
BoxContained, BoxContaining,
within::box_covered_by_range
> type;
typedef cartesian_box_box type;
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
@@ -292,11 +352,7 @@ struct default_strategy
spherical_tag, spherical_tag
>
{
typedef within::box_in_box
<
BoxContained, BoxContaining,
within::box_covered_by_range
> type;
typedef spherical_box_box type;
};

View File

@@ -54,7 +54,7 @@ public :
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//! Fills output_range with a flat end
template <typename Point, typename RangeOut, typename DistanceStrategy>
template <typename Point, typename DistanceStrategy, typename RangeOut>
inline void apply(Point const& penultimate_point,
Point const& perp_left_point,
Point const& ultimate_point,
@@ -63,20 +63,13 @@ public :
DistanceStrategy const& distance,
RangeOut& range_out) const
{
typedef typename coordinate_type<Point>::type coordinate_type;
auto const dist_left = distance.apply(penultimate_point, ultimate_point, buffer_side_left);
auto const dist_right = distance.apply(penultimate_point, ultimate_point, buffer_side_right);
typedef typename geometry::select_most_precise
<
coordinate_type,
double
>::type promoted_type;
bool const reversed =
(side == buffer_side_left && dist_right < 0 && -dist_right > dist_left)
|| (side == buffer_side_right && dist_left < 0 && -dist_left > dist_right);
promoted_type const dist_left = distance.apply(penultimate_point, ultimate_point, buffer_side_left);
promoted_type const dist_right = distance.apply(penultimate_point, ultimate_point, buffer_side_right);
bool reversed = (side == buffer_side_left && dist_right < 0 && -dist_right > dist_left)
|| (side == buffer_side_right && dist_left < 0 && -dist_left > dist_right)
;
if (reversed)
{
range_out.push_back(perp_right_point);
@@ -89,7 +82,7 @@ public :
}
// Don't add the ultimate_point (endpoint of the linestring).
// The buffer might be generated completely at one side.
// In other cases it does no harm but is further useless
// In other cases it does no harm but it is useless
}
template <typename NumericType>

View File

@@ -2,9 +2,9 @@
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2023.
// Modifications copyright (c) 2015-2023, 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
// Use, modification and distribution is subject to the Boost Software License,
@@ -14,7 +14,11 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_END_ROUND_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_END_ROUND_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@@ -22,8 +26,6 @@
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
namespace boost { namespace geometry
{
@@ -80,8 +82,8 @@ private :
for (std::size_t i = 0; i < point_buffer_count; i++, alpha -= diff)
{
typename boost::range_value<RangeOut>::type p;
set<0>(p, get<0>(point) + buffer_distance * cos(alpha));
set<1>(p, get<1>(point) + buffer_distance * sin(alpha));
geometry::set<0>(p, geometry::get<0>(point) + buffer_distance * cos(alpha));
geometry::set<1>(p, geometry::get<1>(point) + buffer_distance * sin(alpha));
range_out.push_back(p);
}
}
@@ -98,16 +100,15 @@ private :
public :
//! \brief Constructs the strategy
//! \param points_per_circle points which would be used for a full circle
//! (if points_per_circle is smaller than 4, it is internally set to 4)
explicit inline end_round(std::size_t points_per_circle = 90)
: m_points_per_circle((points_per_circle < 4u) ? 4u : points_per_circle)
//! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
explicit inline end_round(std::size_t points_per_circle = default_points_per_circle)
: m_points_per_circle(get_point_count_for_end(points_per_circle))
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//! Fills output_range with a flat end
template <typename Point, typename RangeOut, typename DistanceStrategy>
//! Fills output_range with a round end
template <typename Point, typename DistanceStrategy, typename RangeOut>
inline void apply(Point const& penultimate_point,
Point const& perp_left_point,
Point const& ultimate_point,
@@ -116,6 +117,7 @@ public :
DistanceStrategy const& distance,
RangeOut& range_out) const
{
boost::ignore_unused(perp_left_point);
typedef typename coordinate_type<Point>::type coordinate_type;
typedef typename geometry::select_most_precise
@@ -124,28 +126,29 @@ public :
double
>::type promoted_type;
promoted_type const alpha = calculate_angle<promoted_type>(perp_left_point, ultimate_point);
promoted_type const dist_left = distance.apply(penultimate_point, ultimate_point, buffer_side_left);
promoted_type const dist_right = distance.apply(penultimate_point, ultimate_point, buffer_side_right);
promoted_type const alpha
= calculate_angle<promoted_type>(penultimate_point, ultimate_point)
- geometry::math::half_pi<promoted_type>();
if (geometry::math::equals(dist_left, dist_right))
{
generate_points(ultimate_point, alpha, dist_left, range_out);
}
else
{
promoted_type const two = 2.0;
promoted_type dist_half_diff = (dist_left - dist_right) / two;
if (side == buffer_side_right)
{
dist_half_diff = -dist_half_diff;
}
static promoted_type const two = 2.0;
promoted_type const dist_average = (dist_left + dist_right) / two;
promoted_type const dist_half
= (side == buffer_side_right
? (dist_right - dist_left)
: (dist_left - dist_right)) / two;
Point shifted_point;
set<0>(shifted_point, get<0>(ultimate_point) + dist_half_diff * cos(alpha));
set<1>(shifted_point, get<1>(ultimate_point) + dist_half_diff * sin(alpha));
generate_points(shifted_point, alpha, (dist_left + dist_right) / two, range_out);
geometry::set<0>(shifted_point, geometry::get<0>(ultimate_point) + dist_half * cos(alpha));
geometry::set<1>(shifted_point, geometry::get<1>(ultimate_point) + dist_half * sin(alpha));
generate_points(shifted_point, alpha, dist_average, range_out);
}
if (m_points_per_circle % 2 == 1)

View File

@@ -89,8 +89,8 @@ public:
// Check the distance ip-vertex (= miter distance)
// (We calculate it manually (not using Pythagoras strategy) to reuse
// dx and dy)
coordinate_type const dx = get<0>(p) - get<0>(vertex);
coordinate_type const dy = get<1>(p) - get<1>(vertex);
promoted_type const dx = get<0>(p) - get<0>(vertex);
promoted_type const dy = get<1>(p) - get<1>(vertex);
promoted_type const distance = geometry::math::sqrt(dx * dx + dy * dy);

View File

@@ -1,6 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
@@ -58,9 +59,9 @@ class join_round
public :
//! \brief Constructs the strategy
//! \param points_per_circle points which would be used for a full circle
explicit inline join_round(std::size_t points_per_circle = 90)
: m_points_per_circle(points_per_circle)
//! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
explicit inline join_round(std::size_t points_per_circle = default_points_per_circle)
: m_points_per_circle(get_point_count_for_join(points_per_circle))
{}
private :
@@ -143,26 +144,15 @@ public :
geometry::equal_to<Point> equals;
if (equals(perp1, perp2))
{
boost::ignore_unused(ip);
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
std::cout << "Corner for equal points " << geometry::wkt(ip) << " " << geometry::wkt(perp1) << std::endl;
#endif
return false;
}
// Generate 'vectors'
coordinate_type vix = (get<0>(ip) - get<0>(vertex));
coordinate_type viy = (get<1>(ip) - get<1>(vertex));
promoted_type length_i = geometry::math::sqrt(vix * vix + viy * viy);
DistanceType const bd = geometry::math::abs(buffer_distance);
promoted_type prop = bd / length_i;
Point bp;
set<0>(bp, get<0>(vertex) + vix * prop);
set<1>(bp, get<1>(vertex) + viy * prop);
range_out.push_back(perp1);
generate_points<promoted_type>(vertex, perp1, perp2, bd, range_out);
generate_points<promoted_type>(vertex, perp1, perp2, geometry::math::abs(buffer_distance), range_out);
range_out.push_back(perp2);
return true;
}

View File

@@ -48,23 +48,21 @@ public :
RangeOut& range_out,
std::size_t level = 1) const
{
typedef typename coordinate_type<Point>::type coordinate_type;
// Generate 'vectors'
coordinate_type const vp1_x = get<0>(p1) - get<0>(vertex);
coordinate_type const vp1_y = get<1>(p1) - get<1>(vertex);
PromotedType const vp1_x = get<0>(p1) - get<0>(vertex);
PromotedType const vp1_y = get<1>(p1) - get<1>(vertex);
coordinate_type const vp2_x = (get<0>(p2) - get<0>(vertex));
coordinate_type const vp2_y = (get<1>(p2) - get<1>(vertex));
PromotedType const vp2_x = (get<0>(p2) - get<0>(vertex));
PromotedType const vp2_y = (get<1>(p2) - get<1>(vertex));
// Average them to generate vector in between
coordinate_type const two = 2;
coordinate_type const v_x = (vp1_x + vp2_x) / two;
coordinate_type const v_y = (vp1_y + vp2_y) / two;
PromotedType const two = 2;
PromotedType const v_x = (vp1_x + vp2_x) / two;
PromotedType const v_y = (vp1_y + vp2_y) / two;
PromotedType const length2 = geometry::math::sqrt(v_x * v_x + v_y * v_y);
PromotedType prop = buffer_distance / length2;
PromotedType const prop = buffer_distance / length2;
Point mid_point;
set<0>(mid_point, get<0>(vertex) + v_x * prop);
@@ -106,13 +104,13 @@ public :
}
// Generate 'vectors'
coordinate_type const vix = (get<0>(ip) - get<0>(vertex));
coordinate_type const viy = (get<1>(ip) - get<1>(vertex));
promoted_type const vix = (get<0>(ip) - get<0>(vertex));
promoted_type const viy = (get<1>(ip) - get<1>(vertex));
promoted_type const length_i = geometry::math::sqrt(vix * vix + viy * viy);
promoted_type const bd = geometry::math::abs(buffer_distance);
promoted_type prop = bd / length_i;
promoted_type const prop = bd / length_i;
Point bp;
set<0>(bp, get<0>(vertex) + vix * prop);

View File

@@ -57,10 +57,9 @@ class point_circle
{
public :
//! \brief Constructs the strategy
//! \param count number of points for the created circle (if count
//! is smaller than 3, count is internally set to 3)
explicit point_circle(std::size_t count = 90)
: m_count((count < 3u) ? 3u : count)
//! \param count Number of points (minimum 3) for the created circle
explicit point_circle(std::size_t count = default_points_per_circle)
: m_count(get_point_count_for_circle(count))
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS

View File

@@ -54,12 +54,13 @@ class point_square
<
typename Point,
typename DistanceType,
typename MultiplierType,
typename OutputRange
>
inline void add_point(Point const& point,
DistanceType const& distance,
DistanceType const& x,
DistanceType const& y,
MultiplierType const& x,
MultiplierType const& y,
OutputRange& output_range) const
{
typename boost::range_value<OutputRange>::type p;

View File

@@ -47,6 +47,13 @@ class side_straight
{
public :
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Returns true if the buffer distance is always the same
static inline bool equidistant()
{
return true;
}
template
<
typename Point,
@@ -69,8 +76,8 @@ public :
// Generate a block along (left or right of) the segment
// Simulate a vector d (dx,dy)
coordinate_type const dx = get<0>(input_p2) - get<0>(input_p1);
coordinate_type const dy = get<1>(input_p2) - get<1>(input_p1);
promoted_type const dx = get<0>(input_p2) - get<0>(input_p1);
promoted_type const dy = get<1>(input_p2) - get<1>(input_p1);
// For normalization [0,1] (=dot product d.d, sqrt)
promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2021.
// Modifications copyright (c) 2015-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -44,19 +44,20 @@ namespace strategy { namespace centroid
*/
template
<
typename PointCentroid,
typename Point = PointCentroid
typename Ignored1 = void,
typename Ignored2 = void
>
class average
{
private :
/*! subclass to keep state */
template <typename GeometryPoint, typename ResultPoint>
class sum
{
friend class average;
signed_size_type count;
PointCentroid centroid;
ResultPoint centroid;
public :
inline sum()
@@ -67,17 +68,23 @@ private :
};
public :
typedef sum state_type;
typedef PointCentroid centroid_point_type;
typedef Point point_type;
template <typename GeometryPoint, typename ResultPoint>
struct state_type
{
typedef sum<GeometryPoint, ResultPoint> type;
};
static inline void apply(Point const& p, sum& state)
template <typename GeometryPoint, typename ResultPoint>
static inline void apply(GeometryPoint const& p,
sum<GeometryPoint, ResultPoint>& state)
{
add_point(state.centroid, p);
state.count++;
}
static inline bool result(sum const& state, PointCentroid& centroid)
template <typename GeometryPoint, typename ResultPoint>
static inline bool result(sum<GeometryPoint, ResultPoint> const& state,
ResultPoint& centroid)
{
centroid = state.centroid;
if ( state.count > 0 )

View File

@@ -4,9 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015, 2018.
// Modifications copyright (c) 2015, 2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2021.
// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -23,16 +22,14 @@
#include <cstddef>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
@@ -121,8 +118,8 @@ Statements:
*/
template
<
typename Point,
typename PointOfSegment = Point,
typename Ignored1 = void,
typename Ignored2 = void,
typename CalculationType = void
>
class bashein_detmer
@@ -132,45 +129,52 @@ private :
// whatever it is and whatever the point-type(s) are.
// Else, use the most appropriate coordinate type
// of the two points, but at least double
typedef typename
boost::mpl::if_c
<
boost::is_void<CalculationType>::type::value,
typename select_most_precise
template <typename GeometryPoint, typename ResultPoint>
struct calculation_type
: std::conditional
<
typename select_coordinate_type
std::is_void<CalculationType>::value,
typename select_most_precise
<
Point,
PointOfSegment
typename coordinate_type<GeometryPoint>::type,
typename coordinate_type<ResultPoint>::type,
double
>::type,
double
>::type,
CalculationType
>::type calculation_type;
CalculationType
>
{};
/*! subclass to keep state */
template <typename GeometryPoint, typename ResultPoint>
class sums
{
typedef typename calculation_type<GeometryPoint, ResultPoint>::type calc_type;
friend class bashein_detmer;
std::size_t count;
calculation_type sum_a2;
calculation_type sum_x;
calculation_type sum_y;
calc_type sum_a2;
calc_type sum_x;
calc_type sum_y;
public :
inline sums()
: count(0)
, sum_a2(calculation_type())
, sum_x(calculation_type())
, sum_y(calculation_type())
, sum_a2(calc_type())
, sum_x(calc_type())
, sum_y(calc_type())
{}
};
public :
typedef sums state_type;
template <typename GeometryPoint, typename ResultPoint>
struct state_type
{
typedef sums<GeometryPoint, ResultPoint> type;
};
static inline void apply(PointOfSegment const& p1,
PointOfSegment const& p2, sums& state)
template <typename GeometryPoint, typename ResultPoint>
static inline void apply(GeometryPoint const& p1, GeometryPoint const& p2,
sums<GeometryPoint, ResultPoint>& state)
{
/* Algorithm:
For each segment:
@@ -183,29 +187,35 @@ public :
return POINT(sum_x / (3 * sum_a2), sum_y / (3 * sum_a2) )
*/
typedef typename calculation_type<GeometryPoint, ResultPoint>::type calc_type;
// Get coordinates and promote them to calculation_type
calculation_type const x1 = boost::numeric_cast<calculation_type>(get<0>(p1));
calculation_type const y1 = boost::numeric_cast<calculation_type>(get<1>(p1));
calculation_type const x2 = boost::numeric_cast<calculation_type>(get<0>(p2));
calculation_type const y2 = boost::numeric_cast<calculation_type>(get<1>(p2));
calculation_type const ai = geometry::detail::determinant<calculation_type>(p1, p2);
calc_type const x1 = boost::numeric_cast<calc_type>(get<0>(p1));
calc_type const y1 = boost::numeric_cast<calc_type>(get<1>(p1));
calc_type const x2 = boost::numeric_cast<calc_type>(get<0>(p2));
calc_type const y2 = boost::numeric_cast<calc_type>(get<1>(p2));
calc_type const ai = geometry::detail::determinant<calc_type>(p1, p2);
state.count++;
state.sum_a2 += ai;
state.sum_x += ai * (x1 + x2);
state.sum_y += ai * (y1 + y2);
}
static inline bool result(sums const& state, Point& centroid)
template <typename GeometryPoint, typename ResultPoint>
static inline bool result(sums<GeometryPoint, ResultPoint> const& state,
ResultPoint& centroid)
{
calculation_type const zero = calculation_type();
typedef typename calculation_type<GeometryPoint, ResultPoint>::type calc_type;
calc_type const zero = calc_type();
if (state.count > 0 && ! math::equals(state.sum_a2, zero))
{
calculation_type const v3 = 3;
calculation_type const a3 = v3 * state.sum_a2;
calc_type const v3 = 3;
calc_type const a3 = v3 * state.sum_a2;
typedef typename geometry::coordinate_type
<
Point
ResultPoint
>::type coordinate_type;
// Prevent NaN centroid coordinates

View File

@@ -3,9 +3,9 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2023.
// Modifications copyright (c) 2015-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
@@ -21,17 +21,19 @@
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/algorithms/detail/distance/interface.hpp>
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/util/for_each_coordinate.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
// Helper geometry
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/util/algorithm.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
@@ -39,66 +41,85 @@ namespace boost { namespace geometry
namespace strategy { namespace centroid
{
namespace detail
{
template <typename Type, std::size_t DimensionCount>
struct weighted_length_sums
{
typedef typename geometry::model::point
<
Type, DimensionCount,
cs::cartesian
> work_point;
Type length;
work_point average_sum;
inline weighted_length_sums()
: length(Type())
{
geometry::assign_zero(average_sum);
}
};
}
template
<
typename Point,
typename PointOfSegment = Point
typename Ignored1 = void,
typename Ignored2 = void,
typename CalculationType = void
>
class weighted_length
{
private :
typedef typename select_most_precise
<
typename default_distance_result<Point>::type,
typename default_distance_result<PointOfSegment>::type
>::type distance_type;
typedef geometry::strategy::distance::pythagoras<CalculationType> pythagoras_strategy;
template <typename GeometryPoint, typename ResultPoint>
struct calculation_type
{
// Below the distance between two GeometryPoints is calculated.
// ResultPoint is taken into account by passing them together here.
typedef typename pythagoras_strategy::template calculation_type
<
GeometryPoint, ResultPoint
>::type type;
};
template <typename GeometryPoint, typename ResultPoint>
class sums
{
friend class weighted_length;
template <typename, typename> friend struct set_sum_div_length;
typedef typename calculation_type<GeometryPoint, ResultPoint>::type calc_type;
typedef typename geometry::model::point
<
calc_type,
geometry::dimension<ResultPoint>::value,
cs::cartesian
> work_point;
calc_type length;
work_point average_sum;
public:
inline sums()
: length(calc_type())
{
geometry::assign_zero(average_sum);
}
};
public :
typedef detail::weighted_length_sums
<
distance_type,
geometry::dimension<Point>::type::value
> state_type;
static inline void apply(PointOfSegment const& p1,
PointOfSegment const& p2, state_type& state)
template <typename GeometryPoint, typename ResultPoint>
struct state_type
{
distance_type const d = geometry::distance(p1, p2);
typedef sums<GeometryPoint, ResultPoint> type;
};
template <typename GeometryPoint, typename ResultPoint>
static inline void apply(GeometryPoint const& p1, GeometryPoint const& p2,
sums<GeometryPoint, ResultPoint>& state)
{
typedef typename calculation_type<GeometryPoint, ResultPoint>::type distance_type;
distance_type const d = pythagoras_strategy::apply(p1, p2);
state.length += d;
typename state_type::work_point weighted_median;
geometry::assign_zero(weighted_median);
geometry::add_point(weighted_median, p1);
geometry::add_point(weighted_median, p2);
geometry::multiply_value(weighted_median, d/2);
geometry::add_point(state.average_sum, weighted_median);
distance_type const d_half = d / distance_type(2);
geometry::detail::for_each_dimension<ResultPoint>([&](auto dimension)
{
distance_type const coord1 = get<dimension>(p1);
distance_type const coord2 = get<dimension>(p2);
distance_type const wm = (coord1 + coord2) * d_half; // weighted median
set<dimension>(state.average_sum, get<dimension>(state.average_sum) + wm);
});
}
static inline bool result(state_type const& state, Point& centroid)
template <typename GeometryPoint, typename ResultPoint>
static inline bool result(sums<GeometryPoint, ResultPoint> const& state,
ResultPoint& centroid)
{
typedef typename calculation_type<GeometryPoint, ResultPoint>::type distance_type;
distance_type const zero = distance_type();
if (! geometry::math::equals(state.length, zero)
&& boost::math::isfinite(state.length)) // Prevent NaN centroid coordinates
@@ -106,31 +127,21 @@ public :
// NOTE: above distance_type is checked, not the centroid coordinate_type
// which means that the centroid can still be filled with INF
// if e.g. distance_type is double and centroid contains floats
geometry::for_each_coordinate(centroid, set_sum_div_length(state));
geometry::detail::for_each_dimension<ResultPoint>([&](auto dimension)
{
typedef typename geometry::coordinate_type<ResultPoint>::type coordinate_type;
geometry::set<dimension>(
centroid,
boost::numeric_cast<coordinate_type>(
geometry::get<dimension>(state.average_sum) / state.length
)
);
});
return true;
}
return false;
}
struct set_sum_div_length
{
state_type const& m_state;
set_sum_div_length(state_type const& state)
: m_state(state)
{}
template <typename Pt, std::size_t Dimension>
void apply(Pt & centroid) const
{
typedef typename geometry::coordinate_type<Pt>::type coordinate_type;
geometry::set<Dimension>(
centroid,
boost::numeric_cast<coordinate_type>(
geometry::get<Dimension>(m_state.average_sum) / m_state.length
)
);
}
};
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

View File

@@ -0,0 +1,146 @@
// Boost.Geometry
// Copyright (c) 2021-2023, 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_CARTESIAN_CLOSEST_POINTS_PT_SEG_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CLOSEST_POINTS_PT_SEG_HPP
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/closest_points/services.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace closest_points
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename CalculationType>
struct compute_closest_point_to_segment
{
template <typename Point, typename PointOfSegment>
static inline auto
apply(Point const& p, PointOfSegment const& p1, PointOfSegment const& p2)
{
// A projected point of points in Integer coordinates must be able to be
// represented in FP.
using fp_point_type = model::point
<
CalculationType,
dimension<PointOfSegment>::value,
typename coordinate_system<PointOfSegment>::type
>;
// For convenience
using fp_vector_type = fp_point_type;
/*
Algorithm [p: (px,py), p1: (x1,y1), p2: (x2,y2)]
VECTOR v(x2 - x1, y2 - y1)
VECTOR w(px - x1, py - y1)
c1 = w . v
c2 = v . v
b = c1 / c2
RETURN POINT(x1 + b * vx, y1 + b * vy)
*/
// v is multiplied below with a (possibly) FP-value, so should be in FP
// For consistency we define w also in FP
fp_vector_type v, w, projected;
geometry::convert(p2, v);
geometry::convert(p, w);
geometry::convert(p1, projected);
subtract_point(v, projected);
subtract_point(w, projected);
CalculationType const zero = CalculationType();
CalculationType const c1 = dot_product(w, v);
if (c1 <= zero)
{
fp_vector_type fp_p1;
geometry::convert(p1, fp_p1);
return fp_p1;
}
CalculationType const c2 = dot_product(v, v);
if (c2 <= c1)
{
fp_vector_type fp_p2;
geometry::convert(p2, fp_p2);
return fp_p2;
}
// See above, c1 > 0 AND c2 > c1 so: c2 != 0
CalculationType const b = c1 / c2;
multiply_value(v, b);
add_point(projected, v);
return projected;
}
};
}
#endif // DOXYGEN_NO_DETAIL
template
<
typename CalculationType = void
>
class projected_point
{
public:
// The three typedefs below are necessary to calculate distances
// from segments defined in integer coordinates.
// Integer coordinates can still result in FP distances.
// There is a division, which must be represented in FP.
// So promote.
template <typename Point, typename PointOfSegment>
struct calculation_type
: promote_floating_point
<
typename select_most_precise
<
typename coordinate_type<Point>::type,
typename coordinate_type<PointOfSegment>::type,
CalculationType
>::type
>
{};
template <typename Point, typename PointOfSegment>
inline auto
apply(Point const& p, PointOfSegment const& p1, PointOfSegment const& p2) const
{
assert_dimension_equal<Point, PointOfSegment>();
using calculation_type = typename calculation_type<Point, PointOfSegment>::type;
return detail::compute_closest_point_to_segment<calculation_type>::apply(p, p1, p2);
}
};
}} // namespace strategy::closest_points
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CLOSEST_POINTS_PT_SEG_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Copyright (c) 2017-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -20,6 +20,7 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/strategies/densify.hpp>
#include <boost/geometry/util/algorithm.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@@ -52,60 +53,53 @@ public:
static inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold)
{
typedef typename AssignPolicy::point_type out_point_t;
typedef typename coordinate_type<out_point_t>::type out_coord_t;
typedef typename select_most_precise
<
typename coordinate_type<Point>::type,
typename coordinate_type<out_point_t>::type,
typename coordinate_type<Point>::type, out_coord_t,
CalculationType
>::type calc_t;
typedef model::point<calc_t, geometry::dimension<Point>::value, cs::cartesian> calc_point_t;
calc_point_t cp0, cp1;
geometry::detail::conversion::convert_point_to_point(p0, cp0);
geometry::detail::conversion::convert_point_to_point(p1, cp1);
// dir01 = xy1 - xy0
calc_point_t dir01 = cp1;
geometry::subtract_point(dir01, cp0);
assert_dimension_equal<calc_point_t, out_point_t>();
calc_point_t cp0, dir01;
// dir01 = p1 - p0
geometry::detail::for_each_dimension<calc_point_t>([&](auto index)
{
calc_t const coord0 = boost::numeric_cast<calc_t>(get<index>(p0));
calc_t const coord1 = boost::numeric_cast<calc_t>(get<index>(p1));
set<index>(cp0, coord0);
set<index>(dir01, coord1 - coord0);
});
calc_t const dot01 = geometry::dot_product(dir01, dir01);
calc_t const len = math::sqrt(dot01);
BOOST_GEOMETRY_ASSERT(length_threshold > T(0));
signed_size_type n = signed_size_type(len / length_threshold);
signed_size_type const n = signed_size_type(len / length_threshold);
if (n <= 0)
{
return;
}
// NOTE: Normalization will not work for integral coordinates
// normalize
//geometry::divide_value(dir01, len);
calc_t step = len / (n + 1);
calc_t d = step;
for (signed_size_type i = 0 ; i < n ; ++i, d += step)
calc_t const den = calc_t(n + 1);
for (signed_size_type i = 0 ; i < n ; ++i)
{
// pd = xy0 + d * dir01
calc_point_t pd = dir01;
out_point_t out;
// without normalization
geometry::multiply_value(pd, calc_t(i + 1));
geometry::divide_value(pd, calc_t(n + 1));
// with normalization
//geometry::multiply_value(pd, d);
geometry::add_point(pd, cp0);
calc_t const num = calc_t(i + 1);
geometry::detail::for_each_dimension<out_point_t>([&](auto index)
{
// out = p0 + d * dir01
calc_t const coord = get<index>(cp0) + get<index>(dir01) * num / den;
// NOTE: Only needed if types calc_point_t and out_point_t are different
// otherwise pd could simply be passed into policy
out_point_t p;
assert_dimension_equal<calc_point_t, out_point_t>();
geometry::detail::conversion::convert_point_to_point(pd, p);
policy.apply(p);
set<index>(out, boost::numeric_cast<out_coord_t>(coord));
});
policy.apply(out);
}
}
};

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2019.
// Modifications copyright (c) 2013-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -35,6 +35,7 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
@@ -161,7 +162,7 @@ struct disjoint_segment_box_impl
<
RelativeDistance,
SegmentPoint,
Box,
Box,
I + 1,
Dimension
>::apply(p0, p1, box, t_min, t_max);
@@ -246,22 +247,11 @@ struct disjoint_segment_box_impl
// other strategies that are used are intersection and covered_by strategies.
struct segment_box
{
template <typename Segment, typename Box>
struct point_in_geometry_strategy
: services::default_strategy
<
typename point_type<Segment>::type,
Box
>
{};
typedef covered_by::cartesian_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

@@ -4,9 +4,9 @@
// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// 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
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -21,10 +21,10 @@
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
#include <type_traits>
#include <boost/concept_check.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -36,10 +36,10 @@
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
#include <boost/geometry/strategies/cartesian/closest_points_pt_seg.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/strategies/cartesian/intersection.hpp>
// Helper geometry (projected point on line)
#include <boost/geometry/geometries/point.hpp>
@@ -77,9 +77,7 @@ template
>
class projected_point
{
public :
typedef within::cartesian_point_point equals_point_point_strategy_type;
public:
// The three typedefs below are necessary to calculate distances
// from segments defined in integer coordinates.
@@ -107,60 +105,10 @@ public :
typedef typename calculation_type<Point, PointOfSegment>::type calculation_type;
// A projected point of points in Integer coordinates must be able to be
// represented in FP.
typedef model::point
<
calculation_type,
dimension<PointOfSegment>::value,
typename coordinate_system<PointOfSegment>::type
> fp_point_type;
auto closest_point = closest_points::detail::compute_closest_point_to_segment
<calculation_type>::apply(p, p1, p2);
// For convenience
typedef fp_point_type fp_vector_type;
/*
Algorithm [p: (px,py), p1: (x1,y1), p2: (x2,y2)]
VECTOR v(x2 - x1, y2 - y1)
VECTOR w(px - x1, py - y1)
c1 = w . v
c2 = v . v
b = c1 / c2
RETURN POINT(x1 + b * vx, y1 + b * vy)
*/
// v is multiplied below with a (possibly) FP-value, so should be in FP
// For consistency we define w also in FP
fp_vector_type v, w, projected;
geometry::convert(p2, v);
geometry::convert(p, w);
geometry::convert(p1, projected);
subtract_point(v, projected);
subtract_point(w, projected);
Strategy strategy;
boost::ignore_unused(strategy);
calculation_type const zero = calculation_type();
calculation_type const c1 = dot_product(w, v);
if (c1 <= zero)
{
return strategy.apply(p, p1);
}
calculation_type const c2 = dot_product(v, v);
if (c2 <= c1)
{
return strategy.apply(p, p2);
}
// See above, c1 > 0 AND c2 > c1 so: c2 != 0
calculation_type const b = c1 / c2;
multiply_value(v, b);
add_point(projected, v);
return strategy.apply(p, projected);
return Strategy().apply(p, closest_point);
}
template <typename CT>
@@ -245,19 +193,19 @@ struct default_strategy
>
{
typedef strategy::distance::projected_point
<
void,
typename boost::mpl::if_
<
boost::is_void<Strategy>,
typename default_strategy
<
point_tag, point_tag, Point, PointOfSegment,
cartesian_tag, cartesian_tag
>::type,
Strategy
>::type
> type;
<
void,
std::conditional_t
<
std::is_void<Strategy>::value,
typename default_strategy
<
point_tag, point_tag, Point, PointOfSegment,
cartesian_tag, cartesian_tag
>::type,
Strategy
>
> type;
};
template <typename PointOfSegment, typename Point, typename Strategy>

View File

@@ -128,7 +128,7 @@ public :
assert_dimension_equal<Box1, Box2>();
typename calculation_type<Box1, Box2>::type result(0);
detail::compute_pythagoras_box_box
<
dimension<Box1>::value

View File

@@ -123,7 +123,7 @@ public :
assert_dimension_equal<Point, Box>();
typename calculation_type<Point, Box>::type result(0);
detail::compute_pythagoras_point_box
<
dimension<Point>::value

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
@@ -14,6 +14,8 @@
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
namespace boost { namespace geometry
@@ -43,55 +45,33 @@ struct cartesian_segment_box
>
{};
// point-point strategy getters
struct distance_pp_strategy
{
typedef Strategy type;
};
typedef cartesian_tag cs_tag;
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 projected_point<CalculationType, Strategy> type;
};
inline typename distance_ps_strategy::type get_distance_ps_strategy() const
{
return typename distance_ps_strategy::type();
}
typedef within::cartesian_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();
}
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&,
BoxPoint const&,
BoxPoint const&,
BoxPoint const& bottom_right) const
SegmentPoint const& p1,
BoxPoint const&,
BoxPoint const&,
BoxPoint const&,
BoxPoint const& bottom_right,
Strategies const& strategies) const
{
// TODO: The strategy should not call the algorithm like that
return geometry::detail::distance::segment_to_box_2D
<
ReturnType,
SegmentPoint,
BoxPoint,
cartesian_segment_box<CalculationType, Strategy>
Strategies
>::template call_above_of_box
<
typename LessEqual::other
>(p1, p0, bottom_right, *this);
>(p1, p0, bottom_right, strategies);
}
template <typename SPoint, typename BPoint>

View File

@@ -1,153 +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_CARTESIAN_ENVELOPE_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
#include <boost/geometry/strategies/cartesian/envelope_box.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/cartesian/expand_box.hpp>
#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
template <typename CalculationType = void>
class cartesian
{
public:
typedef cartesian_point element_envelope_strategy_type;
static inline element_envelope_strategy_type get_element_envelope_strategy()
{
return element_envelope_strategy_type();
}
typedef expand::cartesian_point element_expand_strategy_type;
static inline element_expand_strategy_type get_element_expand_strategy()
{
return element_expand_strategy_type();
}
typedef expand::cartesian_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 typename boost::range_iterator<Range const>::type begin(Range const& range)
{
return boost::begin(range);
}
template <typename Range>
static inline typename boost::range_iterator<Range const>::type end(Range const& range)
{
return boost::end(range);
}
// MultiLinestring, MultiPolygon
template <typename Box>
struct multi_state
{
multi_state()
: m_initialized(false)
{}
void apply(Box const& single_box)
{
if (! m_initialized)
{
m_box = single_box;
m_initialized = true;
}
else
{
box_expand_strategy_type::apply(m_box, single_box);
}
}
void result(Box & box)
{
if (m_initialized)
{
box = m_box;
}
else
{
geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(box);
}
}
private:
bool m_initialized;
Box m_box;
};
// Segment
template <typename Point1, typename Point2, typename Box>
static inline void apply(Point1 const& point1, Point2 const& point2,
Box& box)
{
cartesian_segment<CalculationType>::apply(point1, point2, box);
}
// Box
template <typename BoxIn, typename Box>
static inline void apply(BoxIn const& box_in, Box& box)
{
cartesian_box::apply(box_in, box);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Tag, typename CalculationType>
struct default_strategy<Tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian<CalculationType> type;
};
} // namespace services
#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/cartesian/envelope.hpp>
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP

View File

@@ -1,119 +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_CARTESIAN_ENVELOPE_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.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 Dimension,
std::size_t DimensionCount
>
struct envelope_indexed_box
{
template <typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
detail::conversion::point_to_point
<
detail::indexed_point_view<BoxIn const, Index>,
detail::indexed_point_view<BoxOut, Index>,
Dimension,
DimensionCount
>::apply(box_in_corner, mbr_corner);
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
namespace strategy { namespace envelope
{
struct cartesian_box
{
template<typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
geometry::detail::envelope::envelope_indexed_box
<
min_corner, 0, dimension<BoxIn>::value
>::apply(box_in, mbr);
geometry::detail::envelope::envelope_indexed_box
<
max_corner, 0, dimension<BoxIn>::value
>::apply(box_in, mbr);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<box_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_box type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#include <boost/geometry/strategy/cartesian/envelope_box.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP

View File

@@ -1,59 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2018, Oracle and/or its affiliates.
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
#include <boost/geometry/strategies/cartesian/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
{
#include <boost/geometry/strategy/cartesian/envelope_multipoint.hpp>
namespace strategy { namespace envelope
{
class cartesian_multipoint
{
public:
template <typename MultiPoint, typename Box>
static inline void apply(MultiPoint const& multipoint, Box& mbr)
{
geometry::detail::envelope::envelope_range::apply(multipoint, mbr, cartesian<>());
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<multi_point_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_multipoint type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_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_CARTESIAN_ENVELOPE_POINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_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/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 Dimension, std::size_t DimensionCount>
struct envelope_one_point
{
template <std::size_t Index, typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
{
detail::indexed_point_view<Box, Index> box_corner(mbr);
detail::conversion::point_to_point
<
Point,
detail::indexed_point_view<Box, Index>,
Dimension,
DimensionCount
>::apply(point, box_corner);
}
template <typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
{
apply<min_corner>(point, mbr);
apply<max_corner>(point, mbr);
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
namespace strategy { namespace envelope
{
struct cartesian_point
{
template <typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
{
geometry::detail::envelope::envelope_one_point
<
0, dimension<Point>::value
>::apply(point, mbr);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<point_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_point type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#include <boost/geometry/strategy/cartesian/envelope_point.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP

View File

@@ -1,93 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2020, Oracle and/or its affiliates.
// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP
#include <cstddef>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
#include <boost/geometry/strategies/cartesian/expand_point.hpp>
#include <boost/geometry/strategies/envelope.hpp>
namespace boost { namespace geometry { namespace strategy { namespace envelope
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_one_segment
{
template<typename Point, typename Box>
static inline void apply(Point const& p1,
Point const& p2,
Box& mbr)
{
geometry::detail::envelope::envelope_one_point
<
Dimension, DimensionCount
>::apply(p1, mbr);
strategy::expand::detail::point_loop
<
Dimension, DimensionCount
>::apply(mbr, p2);
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
template
<
typename CalculationType = void
>
class cartesian_segment
{
public:
template <typename Point, typename Box>
static inline void apply(Point const& point1, Point const& point2, Box& box)
{
strategy::envelope::detail::envelope_one_segment
<
0,
dimension<Point>::value
>::apply(point1, point2, box);
}
#include <boost/geometry/strategy/cartesian/envelope_segment.hpp>
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_segment<CalculationType> type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP

View File

@@ -1,69 +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.
// Modifications copyright (c) 2015-2017, 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_CARTESIAN_EXPAND_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
#include <boost/geometry/strategies/expand.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/cartesian/expand_box.hpp>
namespace strategy { namespace expand
{
struct cartesian_box
{
template <typename BoxOut, typename BoxIn>
static void apply(BoxOut & box_out, BoxIn const& box_in)
{
geometry::detail::expand::expand_indexed
<
0, dimension<BoxIn>::value
>::apply(box_out, box_in);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<box_tag, cartesian_tag, CalculationType>
{
typedef cartesian_box type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP

View File

@@ -1,125 +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_CARTESIAN_EXPAND_POINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP
#include <cstddef>
#include <functional>
#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/select_coordinate_type.hpp>
#include <boost/geometry/strategies/expand.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <std::size_t Dimension, std::size_t DimensionCount>
struct point_loop
{
template <typename Box, typename Point>
static inline void apply(Box& box, Point const& source)
{
typedef typename select_coordinate_type
<
Point, Box
>::type coordinate_type;
std::less<coordinate_type> less;
std::greater<coordinate_type> greater;
coordinate_type const coord = get<Dimension>(source);
if (less(coord, get<min_corner, Dimension>(box)))
{
set<min_corner, Dimension>(box, coord);
}
if (greater(coord, get<max_corner, Dimension>(box)))
{
set<max_corner, Dimension>(box, coord);
}
point_loop<Dimension + 1, DimensionCount>::apply(box, source);
}
};
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
template <std::size_t DimensionCount>
struct point_loop<DimensionCount, DimensionCount>
{
template <typename Box, typename Point>
static inline void apply(Box&, Point const&) {}
};
#include <boost/geometry/strategy/cartesian/expand_point.hpp>
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
struct cartesian_point
{
template <typename Box, typename Point>
static void apply(Box & box, Point const& point)
{
expand::detail::point_loop
<
0, dimension<Point>::value
>::apply(box, point);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<point_tag, cartesian_tag, CalculationType>
{
typedef cartesian_point type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP

View File

@@ -1,71 +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_CARTESIAN_EXPAND_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
#include <boost/geometry/strategies/expand.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/cartesian/expand_segment.hpp>
namespace strategy { namespace expand
{
class cartesian_segment
{
public:
template <typename Box, typename Segment>
static void apply(Box & box, Segment const& segment)
{
geometry::detail::expand::expand_indexed
<
0, dimension<Segment>::value
>::apply(box, segment);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, cartesian_tag, CalculationType>
{
typedef cartesian_segment type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP

View File

@@ -1,10 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2013-2023 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2016, 2017, 2018, 2019.
// Modifications copyright (c) 2014-2019, 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -22,6 +22,7 @@
#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/arithmetic/determinant.hpp>
#include <boost/geometry/algorithms/detail/assign_values.hpp>
@@ -33,16 +34,16 @@
#include <boost/geometry/util/promote_integral.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/cartesian/area.hpp>
#include <boost/geometry/strategy/cartesian/area.hpp>
#include <boost/geometry/strategy/cartesian/envelope.hpp>
#include <boost/geometry/strategy/cartesian/expand_box.hpp>
#include <boost/geometry/strategy/cartesian/expand_segment.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/envelope.hpp>
#include <boost/geometry/strategies/cartesian/expand_box.hpp>
#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
@@ -50,8 +51,8 @@
#include <boost/geometry/strategies/side_info.hpp>
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/policies/robustness/rescale_policy_tags.hpp>
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS)
@@ -66,6 +67,61 @@ namespace boost { namespace geometry
namespace strategy { namespace intersection
{
namespace detail_usage
{
// When calculating the intersection, the information of "a" or "b" can be used.
// Theoretically this gives equal results, but due to floating point precision
// there might be tiny differences. These are edge cases.
// This structure is to determine if "a" or "b" should be used.
// Prefer the segment closer to the endpoint.
// If both are about equally close, then prefer the longer segment
// To avoid hard thresholds, behavior is made fluent.
// Calculate comparable length indications,
// the longer the segment (relatively), the lower the value
// such that the shorter lengths are evaluated higher and will
// be preferred.
template <bool IsArithmetic>
struct use_a
{
template <typename Ct, typename Ev>
static bool apply(Ct const& cla, Ct const& clb, Ev const& eva, Ev const& evb)
{
auto const clm = (std::max)(cla, clb);
if (clm <= 0)
{
return true;
}
// Relative comparible length
auto const rcla = Ct(1.0) - cla / clm;
auto const rclb = Ct(1.0) - clb / clm;
// Multipliers for edgevalue (ev) and relative comparible length (rcl)
// They determine the balance between edge value (should be larger)
// and segment length. In 99.9xx% of the cases there is no difference
// at all (if either a or b is used). Therefore the values of the
// constants are not sensitive for the majority of the situations.
// One known case is #mysql_23023665_6 (difference) which needs mev >= 2
Ev const mev = 5;
Ev const mrcl = 1;
return mev * eva + mrcl * rcla > mev * evb + mrcl * rclb;
}
};
// Specialization for non arithmetic types. They will always use "a"
template <>
struct use_a<false>
{
template <typename Ct, typename Ev>
static bool apply(Ct const& , Ct const& , Ev const& , Ev const& )
{
return true;
}
};
}
/*!
\see http://mathworld.wolfram.com/Line-LineIntersection.html
@@ -76,111 +132,7 @@ template
>
struct cartesian_segments
{
typedef side::side_by_triangle<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::cartesian_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::cartesian
<
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::pythagoras
<
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::cartesian<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
return envelope_strategy_type();
}
typedef expand::cartesian_segment expand_strategy_type;
static inline expand_strategy_type get_expand_strategy()
{
return expand_strategy_type();
}
typedef within::cartesian_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::cartesian_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::cartesian_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 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::cartesian_point_box disjoint_point_box_strategy_type;
typedef expand::cartesian_box expand_box_strategy_type;
typedef cartesian_tag cs_tag;
template <typename CoordinateType, typename SegmentRatio>
struct segment_intersection_info
@@ -213,61 +165,80 @@ struct cartesian_segments
}
template <typename Point, typename Segment>
void assign(Point& point, Segment const& segment, CoordinateType const& dx, CoordinateType const& dy, SegmentRatio const& ratio) const
void assign(Point& point, Segment const& segment,
CoordinateType const& dx, CoordinateType const& dy,
SegmentRatio const& ratio) const
{
// Calculate the intersection point based on segment_ratio
// Up to now, division was postponed. Here we divide using numerator/
// denominator. In case of integer this results in an integer
// division.
BOOST_GEOMETRY_ASSERT(ratio.denominator() != 0);
// The division, postponed until here, is done now. In case of integer this
// results in an integer which rounds to the nearest integer.
BOOST_GEOMETRY_ASSERT(ratio.denominator() != typename SegmentRatio::int_type(0));
typedef typename promote_integral<CoordinateType>::type promoted_type;
typedef typename promote_integral<CoordinateType>::type calc_type;
promoted_type const numerator
= boost::numeric_cast<promoted_type>(ratio.numerator());
promoted_type const denominator
= boost::numeric_cast<promoted_type>(ratio.denominator());
promoted_type const dx_promoted = boost::numeric_cast<promoted_type>(dx);
promoted_type const dy_promoted = boost::numeric_cast<promoted_type>(dy);
calc_type const numerator
= boost::numeric_cast<calc_type>(ratio.numerator());
calc_type const denominator
= boost::numeric_cast<calc_type>(ratio.denominator());
calc_type const dx_calc = boost::numeric_cast<calc_type>(dx);
calc_type const dy_calc = boost::numeric_cast<calc_type>(dy);
set<0>(point, get<0, 0>(segment) + boost::numeric_cast
<
CoordinateType
>(numerator * dx_promoted / denominator));
set<1>(point, get<0, 1>(segment) + boost::numeric_cast
<
CoordinateType
>(numerator * dy_promoted / denominator));
set<0>(point, get<0, 0>(segment)
+ boost::numeric_cast<CoordinateType>(
math::divide<calc_type>(numerator * dx_calc, denominator)));
set<1>(point, get<0, 1>(segment)
+ boost::numeric_cast<CoordinateType>(
math::divide<calc_type>(numerator * dy_calc, denominator)));
}
template <int Index, int Dim, typename Point, typename Segment>
static bool exceeds_side_in_dimension(Point& p, Segment const& s)
{
// Situation a (positive)
// 0>-------------->1 segment
// * point left of segment<I> in D x or y
// Situation b (negative)
// 1<--------------<0 segment
// * point right of segment<I>
// Situation c (degenerate), return false (check other dimension)
auto const& c = get<Dim>(p);
auto const& c0 = get<Index, Dim>(s);
auto const& c1 = get<1 - Index, Dim>(s);
return c0 < c1 ? math::smaller(c, c0)
: c0 > c1 ? math::larger(c, c0)
: false;
}
template <int Index, typename Point, typename Segment>
static bool exceeds_side_of_segment(Point& p, Segment const& s)
{
return exceeds_side_in_dimension<Index, 0>(p, s)
|| exceeds_side_in_dimension<Index, 1>(p, s);
}
template <typename Point, typename Segment>
static void assign_if_exceeds(Point& point, Segment const& s)
{
if (exceeds_side_of_segment<0>(point, s))
{
detail::assign_point_from_index<0>(s, point);
}
else if (exceeds_side_of_segment<1>(point, s))
{
detail::assign_point_from_index<1>(s, point);
}
}
public :
template <typename Point, typename Segment1, typename Segment2>
void calculate(Point& point, Segment1 const& a, Segment2 const& b) const
{
bool use_a = true;
// Prefer one segment if one is on or near an endpoint
bool const a_near_end = robust_ra.near_end();
bool const b_near_end = robust_rb.near_end();
if (a_near_end && ! b_near_end)
{
use_a = true;
}
else if (b_near_end && ! a_near_end)
{
use_a = false;
}
else
{
// Prefer shorter segment
promoted_type const len_a = comparable_length_a();
promoted_type const len_b = comparable_length_b();
if (len_b < len_a)
{
use_a = false;
}
// else use_a is true but was already assigned like that
}
bool const use_a
= detail_usage::use_a
<
std::is_arithmetic<CoordinateType>::value
>::apply(comparable_length_a(), comparable_length_b(),
robust_ra.edge_value(), robust_rb.edge_value());
if (use_a)
{
@@ -277,6 +248,23 @@ struct cartesian_segments
{
assign_b(point, a, b);
}
#ifndef BOOST_GEOMETRY_USE_RESCALING
// Verify nearly collinear cases (the threshold is arbitrary
// but influences performance). If the intersection is located
// outside the segments, then it should be moved.
if (robust_ra.possibly_collinear(1.0e-3)
&& robust_rb.possibly_collinear(1.0e-3))
{
// The segments are nearly collinear and because of the calculation
// method with very small denominator, the IP appears outside the
// segment(s). Correct it to the end point.
// Because they are nearly collinear, it doesn't really matter to
// to which endpoint (or it is corrected twice).
assign_if_exceeds(point, a);
assign_if_exceeds(point, b);
}
#endif
}
CoordinateType dx_a, dy_a;
@@ -289,87 +277,170 @@ struct cartesian_segments
static inline void cramers_rule(D const& dx_a, D const& dy_a,
D const& dx_b, D const& dy_b, W const& wx, W const& wy,
// out:
ResultType& d, ResultType& da)
ResultType& nominator, ResultType& denominator)
{
// Cramers rule
d = geometry::detail::determinant<ResultType>(dx_a, dy_a, dx_b, dy_b);
da = geometry::detail::determinant<ResultType>(dx_b, dy_b, wx, wy);
// Ratio is da/d , collinear if d == 0, intersecting if 0 <= r <= 1
nominator = geometry::detail::determinant<ResultType>(dx_b, dy_b, wx, wy);
denominator = geometry::detail::determinant<ResultType>(dx_a, dy_a, dx_b, dy_b);
// Ratio r = nominator/denominator
// Collinear if denominator == 0, intersecting if 0 <= r <= 1
// IntersectionPoint = (x1 + r * dx_a, y1 + r * dy_a)
}
// Relate segments a and b
// Version for non-rescaled policies
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)
apply(UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
Policy const& policy)
{
// type them all as in Segment1 - TODO reconsider this, most precise?
typedef typename geometry::point_type<Segment1>::type point_type;
typedef typename geometry::robust_point_type
<
point_type, RobustPolicy
>::type robust_point_type;
point_type a0, a1, b0, b1;
robust_point_type a0_rob, a1_rob, b0_rob, b1_rob;
detail::assign_point_from_index<0>(a, a0);
detail::assign_point_from_index<1>(a, a1);
detail::assign_point_from_index<0>(b, b0);
detail::assign_point_from_index<1>(b, b1);
geometry::recalculate(a0_rob, a0, robust_policy);
geometry::recalculate(a1_rob, a1, robust_policy);
geometry::recalculate(b0_rob, b0, robust_policy);
geometry::recalculate(b1_rob, b1, robust_policy);
return apply(a, b, policy, robust_policy, a0_rob, a1_rob, b0_rob, b1_rob);
// Pass the same ranges both as normal ranges and as modelled ranges
return apply(range_p, range_q, policy, range_p, range_q);
}
// The main entry-routine, calculating intersections of segments a / b
// NOTE: Robust* types may be the same as Segments' point types
// Version for non rescaled versions.
// The "modelled" parameter might be rescaled (will be removed later)
template
<
typename UniqueSubRange1,
typename UniqueSubRange2,
typename Policy,
typename ModelledUniqueSubRange1,
typename ModelledUniqueSubRange2
>
static inline typename Policy::return_type
apply(UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
Policy const& policy,
ModelledUniqueSubRange1 const& modelled_range_p,
ModelledUniqueSubRange2 const& modelled_range_q)
{
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& p1 = range_p.at(0);
point1_type const& p2 = range_p.at(1);
point2_type const& q1 = range_q.at(0);
point2_type const& q2 = range_q.at(1);
// Declare segments, currently necessary for the policies
// (segment_crosses, segment_colinear, degenerate, one_degenerate, etc)
model::referring_segment<point1_type const> const p(p1, p2);
model::referring_segment<point2_type const> const q(q1, q2);
typedef typename select_most_precise
<
typename geometry::coordinate_type<typename ModelledUniqueSubRange1::point_type>::type,
typename geometry::coordinate_type<typename ModelledUniqueSubRange1::point_type>::type
>::type modelled_coordinate_type;
typedef segment_ratio<modelled_coordinate_type> ratio_type;
segment_intersection_info
<
typename select_calculation_type<point1_type, point2_type, CalculationType>::type,
ratio_type
> sinfo;
sinfo.dx_a = get<0>(p2) - get<0>(p1); // distance in x-dir
sinfo.dx_b = get<0>(q2) - get<0>(q1);
sinfo.dy_a = get<1>(p2) - get<1>(p1); // distance in y-dir
sinfo.dy_b = get<1>(q2) - get<1>(q1);
return unified<ratio_type>(sinfo, p, q, policy, modelled_range_p, modelled_range_q);
}
//! Returns true if two segments do not overlap.
//! If not, then no further calculations need to be done.
template
<
std::size_t Dimension,
typename PointP,
typename PointQ
>
static inline bool disjoint_by_range(PointP const& p1, PointP const& p2,
PointQ const& q1, PointQ const& q2)
{
auto minp = get<Dimension>(p1);
auto maxp = get<Dimension>(p2);
auto minq = get<Dimension>(q1);
auto maxq = get<Dimension>(q2);
if (minp > maxp)
{
std::swap(minp, maxp);
}
if (minq > maxq)
{
std::swap(minq, maxq);
}
// In this case, max(p) < min(q)
// P Q
// <-------> <------->
// (and the space in between is not extremely small)
return math::smaller(maxp, minq) || math::smaller(maxq, minp);
}
// Implementation for either rescaled or non rescaled versions.
template
<
typename RatioType,
typename SegmentInfo,
typename Segment1,
typename Segment2,
typename Policy,
typename RobustPolicy,
typename RobustPoint1,
typename RobustPoint2
typename UniqueSubRange1,
typename UniqueSubRange2
>
static inline typename Policy::return_type
apply(Segment1 const& a, Segment2 const& b,
Policy const&, RobustPolicy const& /*robust_policy*/,
RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2,
RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2)
unified(SegmentInfo& sinfo,
Segment1 const& p, Segment2 const& q, Policy const&,
UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q)
{
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;
typedef typename select_most_precise
<
typename geometry::coordinate_type<point1_type>::type,
typename geometry::coordinate_type<point2_type>::type
>::type coordinate_type;
using geometry::detail::equals::equals_point_point;
bool const a_is_point = equals_point_point(robust_a1, robust_a2, point_in_point_strategy_type());
bool const b_is_point = equals_point_point(robust_b1, robust_b2, point_in_point_strategy_type());
point1_type const& p1 = range_p.at(0);
point1_type const& p2 = range_p.at(1);
point2_type const& q1 = range_q.at(0);
point2_type const& q2 = range_q.at(1);
if(a_is_point && b_is_point)
bool const p_is_point = equals_point_point(p1, p2);
bool const q_is_point = equals_point_point(q1, q2);
if (p_is_point && q_is_point)
{
return equals_point_point(robust_a1, robust_b2, point_in_point_strategy_type())
? Policy::degenerate(a, true)
return equals_point_point(p1, q2)
? Policy::degenerate(p, true)
: Policy::disjoint()
;
}
if (disjoint_by_range<0>(p1, p2, q1, q2)
|| disjoint_by_range<1>(p1, p2, q1, q2))
{
return Policy::disjoint();
}
using side_strategy_type
= typename side::services::default_strategy
<cartesian_tag, CalculationType>::type;
side_info sides;
sides.set<0>(side_strategy_type::apply(robust_b1, robust_b2, robust_a1),
side_strategy_type::apply(robust_b1, robust_b2, robust_a2));
sides.set<0>(side_strategy_type::apply(q1, q2, p1),
side_strategy_type::apply(q1, q2, p2));
if (sides.same<0>())
{
@@ -377,9 +448,9 @@ struct cartesian_segments
return Policy::disjoint();
}
sides.set<1>(side_strategy_type::apply(robust_a1, robust_a2, robust_b1),
side_strategy_type::apply(robust_a1, robust_a2, robust_b2));
sides.set<1>(side_strategy_type::apply(p1, p2, q1),
side_strategy_type::apply(p1, p2, q2));
if (sides.same<1>())
{
// Both points are at same side of other segment, we can leave
@@ -388,78 +459,58 @@ struct cartesian_segments
bool collinear = sides.collinear();
typedef typename select_most_precise
<
typename geometry::coordinate_type<RobustPoint1>::type,
typename geometry::coordinate_type<RobustPoint2>::type
>::type robust_coordinate_type;
typedef typename segment_ratio_type
<
typename geometry::point_type<Segment1>::type, // TODO: most precise point?
RobustPolicy
>::type ratio_type;
segment_intersection_info
<
typename select_calculation_type<Segment1, Segment2, CalculationType>::type,
ratio_type
> sinfo;
sinfo.dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
sinfo.dx_b = get<1, 0>(b) - get<0, 0>(b);
sinfo.dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
sinfo.dy_b = get<1, 1>(b) - get<0, 1>(b);
robust_coordinate_type const robust_dx_a = get<0>(robust_a2) - get<0>(robust_a1);
robust_coordinate_type const robust_dx_b = get<0>(robust_b2) - get<0>(robust_b1);
robust_coordinate_type const robust_dy_a = get<1>(robust_a2) - get<1>(robust_a1);
robust_coordinate_type const robust_dy_b = get<1>(robust_b2) - get<1>(robust_b1);
// Calculate the differences again
// (for rescaled version, this is different from dx_p etc)
coordinate_type const dx_p = get<0>(p2) - get<0>(p1);
coordinate_type const dx_q = get<0>(q2) - get<0>(q1);
coordinate_type const dy_p = get<1>(p2) - get<1>(p1);
coordinate_type const dy_q = get<1>(q2) - get<1>(q1);
// r: ratio 0-1 where intersection divides A/B
// (only calculated for non-collinear segments)
if (! collinear)
{
robust_coordinate_type robust_da0, robust_da;
robust_coordinate_type robust_db0, robust_db;
coordinate_type denominator_a, nominator_a;
coordinate_type denominator_b, nominator_b;
cramers_rule(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b,
get<0>(robust_a1) - get<0>(robust_b1),
get<1>(robust_a1) - get<1>(robust_b1),
robust_da0, robust_da);
cramers_rule(dx_p, dy_p, dx_q, dy_q,
get<0>(p1) - get<0>(q1),
get<1>(p1) - get<1>(q1),
nominator_a, denominator_a);
cramers_rule(robust_dx_b, robust_dy_b, robust_dx_a, robust_dy_a,
get<0>(robust_b1) - get<0>(robust_a1),
get<1>(robust_b1) - get<1>(robust_a1),
robust_db0, robust_db);
cramers_rule(dx_q, dy_q, dx_p, dy_p,
get<0>(q1) - get<0>(p1),
get<1>(q1) - get<1>(p1),
nominator_b, denominator_b);
math::detail::equals_factor_policy<robust_coordinate_type>
policy(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b);
robust_coordinate_type const zero = 0;
if (math::detail::equals_by_policy(robust_da0, zero, policy)
|| math::detail::equals_by_policy(robust_db0, zero, policy))
math::detail::equals_factor_policy<coordinate_type>
policy(dx_p, dy_p, dx_q, dy_q);
coordinate_type const zero = 0;
if (math::detail::equals_by_policy(denominator_a, zero, policy)
|| math::detail::equals_by_policy(denominator_b, zero, policy))
{
// If this is the case, no rescaling is done for FP precision.
// We set it to collinear, but it indicates a robustness issue.
sides.set<0>(0,0);
sides.set<1>(0,0);
sides.set<0>(0, 0);
sides.set<1>(0, 0);
collinear = true;
}
else
{
sinfo.robust_ra.assign(robust_da, robust_da0);
sinfo.robust_rb.assign(robust_db, robust_db0);
sinfo.robust_ra.assign(nominator_a, denominator_a);
sinfo.robust_rb.assign(nominator_b, denominator_b);
}
}
if (collinear)
{
std::pair<bool, bool> const collinear_use_first
= is_x_more_significant(geometry::math::abs(robust_dx_a),
geometry::math::abs(robust_dy_a),
geometry::math::abs(robust_dx_b),
geometry::math::abs(robust_dy_b),
a_is_point, b_is_point);
= is_x_more_significant(geometry::math::abs(dx_p),
geometry::math::abs(dy_p),
geometry::math::abs(dx_q),
geometry::math::abs(dy_q),
p_is_point, q_is_point);
if (collinear_use_first.second)
{
@@ -468,32 +519,32 @@ struct cartesian_segments
if (collinear_use_first.first)
{
return relate_collinear<0, Policy, ratio_type>(a, b,
robust_a1, robust_a2, robust_b1, robust_b2,
a_is_point, b_is_point);
return relate_collinear<0, Policy, RatioType>(p, q,
p1, p2, q1, q2,
p_is_point, q_is_point);
}
else
{
// Y direction contains larger segments (maybe dx is zero)
return relate_collinear<1, Policy, ratio_type>(a, b,
robust_a1, robust_a2, robust_b1, robust_b2,
a_is_point, b_is_point);
return relate_collinear<1, Policy, RatioType>(p, q,
p1, p2, q1, q2,
p_is_point, q_is_point);
}
}
}
return Policy::segments_crosses(sides, sinfo, a, b);
return Policy::segments_crosses(sides, sinfo, p, q);
}
private:
// first is true if x is more significant
// second is true if the more significant difference is not 0
template <typename RobustCoordinateType>
template <typename CoordinateType>
static inline std::pair<bool, bool>
is_x_more_significant(RobustCoordinateType const& abs_robust_dx_a,
RobustCoordinateType const& abs_robust_dy_a,
RobustCoordinateType const& abs_robust_dx_b,
RobustCoordinateType const& abs_robust_dy_b,
is_x_more_significant(CoordinateType const& abs_dx_a,
CoordinateType const& abs_dy_a,
CoordinateType const& abs_dx_b,
CoordinateType const& abs_dy_b,
bool const a_is_point,
bool const b_is_point)
{
@@ -504,18 +555,18 @@ private:
if (a_is_point)
{
return std::make_pair(abs_robust_dx_b >= abs_robust_dy_b, true);
return std::make_pair(abs_dx_b >= abs_dy_b, true);
}
else if (b_is_point)
{
return std::make_pair(abs_robust_dx_a >= abs_robust_dy_a, true);
return std::make_pair(abs_dx_a >= abs_dy_a, true);
}
else
{
RobustCoordinateType const min_dx = (std::min)(abs_robust_dx_a, abs_robust_dx_b);
RobustCoordinateType const min_dy = (std::min)(abs_robust_dy_a, abs_robust_dy_b);
CoordinateType const min_dx = (std::min)(abs_dx_a, abs_dx_b);
CoordinateType const min_dy = (std::min)(abs_dy_a, abs_dy_b);
return min_dx == min_dy ?
std::make_pair(true, min_dx > RobustCoordinateType(0)) :
std::make_pair(true, min_dx > CoordinateType(0)) :
std::make_pair(min_dx > min_dy, true);
}
}
@@ -565,13 +616,13 @@ private:
typename RatioType,
typename Segment1,
typename Segment2,
typename RobustType1,
typename RobustType2
typename Type1,
typename Type2
>
static inline typename Policy::return_type
relate_collinear(Segment1 const& a, Segment2 const& b,
RobustType1 oa_1, RobustType1 oa_2,
RobustType2 ob_1, RobustType2 ob_2)
Type1 oa_1, Type1 oa_2,
Type2 ob_1, Type2 ob_2)
{
// Calculate the ratios where a starts in b, b starts in a
// a1--------->a2 (2..7)
@@ -603,8 +654,8 @@ private:
// b2 is located w.r.t. a at ratio: (5-2)/5=3/5 (on a)
// a1 is located w.r.t. b at ratio: (2-8)/-3=6/3 (after b ends)
// a2 is located w.r.t. b at ratio: (7-8)/-3=1/3 (on b)
RobustType1 const length_a = oa_2 - oa_1; // no abs, see above
RobustType2 const length_b = ob_2 - ob_1;
Type1 const length_a = oa_2 - oa_1; // no abs, see above
Type2 const length_b = ob_2 - ob_1;
RatioType ra_from(oa_1 - ob_1, length_b);
RatioType ra_to(oa_2 - ob_1, length_b);
@@ -617,7 +668,7 @@ private:
int const a2_wrt_b = position_value(oa_2, ob_1, ob_2);
int const b1_wrt_a = position_value(ob_1, oa_1, oa_2);
int const b2_wrt_a = position_value(ob_2, oa_1, oa_2);
// fix the ratios if necessary
// CONSIDER: fixing ratios also in other cases, if they're inconsistent
// e.g. if ratio == 1 or 0 (so IP at the endpoint)
@@ -634,7 +685,7 @@ private:
{
ra_from.assign(1, 1);
rb_to.assign(0, 1);
}
}
if (a2_wrt_b == 1)
{
@@ -666,12 +717,12 @@ private:
typename Policy,
typename RatioType,
typename DegenerateSegment,
typename RobustType1,
typename RobustType2
typename Type1,
typename Type2
>
static inline typename Policy::return_type
relate_one_degenerate(DegenerateSegment const& degenerate_segment,
RobustType1 d, RobustType2 s1, RobustType2 s2,
Type1 d, Type2 s1, Type2 s2,
bool a_degenerate)
{
// Calculate the ratios where ds starts in s
@@ -705,6 +756,12 @@ private:
: ca1 < cb2 ? 4
: 2 );
}
template <typename Point1, typename Point2>
static inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
{
return strategy::within::cartesian_point_point::apply(point1, point2);
}
};

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
@@ -15,6 +16,7 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/strategies/line_interpolate.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/util/algorithm.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
@@ -45,19 +47,6 @@ template
class cartesian
{
public:
// point-point strategy getters
struct distance_pp_strategy
{
typedef DistanceStrategy type;
};
inline typename distance_pp_strategy::type get_distance_pp_strategy() const
{
typedef typename distance_pp_strategy::type distance_type;
return distance_type();
}
template <typename Point, typename Fraction, typename Distance>
inline void apply(Point const& p0,
Point const& p1,
@@ -67,41 +56,22 @@ public:
{
typedef typename select_calculation_type_alt
<
CalculationType,
Point
CalculationType, Point
>::type calc_t;
typedef model::point
<
calc_t,
geometry::dimension<Point>::value,
cs::cartesian
> calc_point_t;
calc_point_t cp0, cp1;
geometry::detail::conversion::convert_point_to_point(p0, cp0);
geometry::detail::conversion::convert_point_to_point(p1, cp1);
typedef typename coordinate_type<Point>::type coord_t;
//segment convex combination: p0*fraction + p1*(1-fraction)
Fraction const one_minus_fraction = 1-fraction;
for_each_coordinate(cp1, detail::value_operation
<
Fraction,
std::multiplies
>(fraction));
for_each_coordinate(cp0, detail::value_operation
<
Fraction,
std::multiplies
>(one_minus_fraction));
for_each_coordinate(cp1, detail::point_operation
<
calc_point_t,
std::plus
>(cp0));
assert_dimension_equal<calc_point_t, Point>();
geometry::detail::conversion::convert_point_to_point(cp1, p);
geometry::detail::for_each_dimension<Point>([&](auto dimension)
{
// NOTE: numeric_cast is a leftover from convert, it could probably be ommited.
// NOTE: the order of points is different than in the formula above
// this is also a leftover from the previous implementation
calc_t coord0 = boost::numeric_cast<calc_t>(get<dimension>(p0));
calc_t coord1 = boost::numeric_cast<calc_t>(get<dimension>(p1));
calc_t result = calc_t(coord1 * fraction) + calc_t(coord0 * one_minus_fraction);
set<dimension>(p, boost::numeric_cast<coord_t>(result));
});
}
};

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, 2014, 2015, 2017, 2018, 2019.
// Modifications copyright (c) 2013-2019, 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
@@ -76,6 +76,8 @@ namespace strategy { namespace within
struct cartesian_point_point
{
typedef cartesian_tag cs_tag;
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& point1, Point2 const& point2)
{

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2018, 2019.
// Modifications copyright (c) 2018, 2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -47,18 +47,21 @@ namespace strategy { namespace within
template
<
typename Point,
typename PointOfSegment = Point,
typename Point_, // for backward compatibility
typename PointOfSegment_ = Point_, // for backward compatibility
typename CalculationType = void
>
class crossings_multiply
{
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
>
{};
class flags
{
@@ -79,20 +82,21 @@ class crossings_multiply
public :
typedef Point point_type;
typedef PointOfSegment segment_point_type;
typedef flags state_type;
template <typename Point, typename PointOfSegment>
static inline bool apply(Point const& point,
PointOfSegment const& seg1, PointOfSegment const& seg2,
flags& state)
{
calculation_type const tx = get<0>(point);
calculation_type const ty = get<1>(point);
calculation_type const x0 = get<0>(seg1);
calculation_type const y0 = get<1>(seg1);
calculation_type const x1 = get<0>(seg2);
calculation_type const y1 = get<1>(seg2);
typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
calc_t const tx = get<0>(point);
calc_t const ty = get<1>(point);
calc_t const x0 = get<0>(seg1);
calc_t const y0 = get<1>(seg1);
calc_t const x1 = get<0>(seg2);
calc_t const y1 = get<1>(seg2);
if (state.first)
{

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2018, 2019.
// Modifications copyright (c) 2018, 2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -51,48 +51,52 @@ namespace strategy { namespace within
template
<
typename Point,
typename PointOfSegment = Point,
typename Point_, // for backward compatibility
typename PointOfSegment_ = Point_, // for backward compatibility
typename CalculationType = void
>
class franklin
{
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
>
{};
/*! subclass to keep state */
class crossings
{
bool crosses;
/*! subclass to keep state */
class crossings
{
bool crosses;
public :
public :
friend class franklin;
inline crossings()
: crosses(false)
{}
};
friend class franklin;
inline crossings()
: crosses(false)
{}
};
public :
typedef Point point_type;
typedef PointOfSegment segment_point_type;
typedef crossings state_type;
template <typename Point, typename PointOfSegment>
static inline bool apply(Point const& point,
PointOfSegment const& seg1, PointOfSegment const& seg2,
crossings& state)
{
calculation_type const& px = get<0>(point);
calculation_type const& py = get<1>(point);
calculation_type const& x1 = get<0>(seg1);
calculation_type const& y1 = get<1>(seg1);
calculation_type const& x2 = get<0>(seg2);
calculation_type const& y2 = get<1>(seg2);
typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
calc_t const& px = get<0>(point);
calc_t const& py = get<1>(point);
calc_t const& x1 = get<0>(seg1);
calc_t const& y1 = get<1>(seg1);
calc_t const& x2 = get<0>(seg2);
calc_t const& y2 = get<1>(seg2);
if (
( (y2 <= py && py < y1) || (y1 <= py && py < y2) )

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013 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-2021.
// Modifications copyright (c) 2013-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -23,9 +23,11 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategy/cartesian/expand_point.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
@@ -36,37 +38,29 @@ namespace boost { namespace geometry
namespace strategy { namespace within
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
/*!
\brief Within detection using winding rule in cartesian coordinate system.
\ingroup strategies
\tparam Point \tparam_point
\tparam PointOfSegment \tparam_segment_point
\tparam SideStrategy A strategy defining creation along sides
\tparam CalculationType \tparam_calculation
\author Barend Gehrels
\qbk{
[heading See also]
[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
}
*/
template
<
typename Point,
typename PointOfSegment = Point,
typename CalculationType = void
>
class cartesian_winding
template <typename SideStrategy, typename CalculationType>
class cartesian_winding_base
{
typedef side::side_by_triangle<CalculationType> side_strategy_type;
template <typename Point, typename PointOfSegment>
struct calculation_type
: select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>
{};
typedef typename select_calculation_type
<
Point,
PointOfSegment,
CalculationType
>::type calculation_type;
/*! subclass to keep state */
class counter
{
@@ -79,7 +73,7 @@ class cartesian_winding
}
public :
friend class cartesian_winding;
friend class cartesian_winding_base;
inline counter()
: m_count(0)
@@ -89,39 +83,12 @@ class cartesian_winding
};
public:
typedef typename side_strategy_type::envelope_strategy_type envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
return side_strategy_type::get_envelope_strategy();
}
typedef typename side_strategy_type::disjoint_strategy_type disjoint_strategy_type;
static inline disjoint_strategy_type get_disjoint_strategy()
{
return side_strategy_type::get_disjoint_strategy();
}
typedef typename side_strategy_type::equals_point_point_strategy_type equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return side_strategy_type::get_equals_point_point_strategy();
}
typedef disjoint::cartesian_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::cartesian_point_box disjoint_point_box_strategy_type;
typedef cartesian_tag cs_tag;
// 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>
static inline bool apply(Point const& point,
PointOfSegment const& s1, PointOfSegment const& s2,
counter& state)
@@ -140,9 +107,9 @@ public:
else // count == 2 || count == -2
{
// 1 left, -1 right
side = side_strategy_type::apply(s1, s2, point);
side = SideStrategy::apply(s1, s2, point);
}
if (side == 0)
{
// Point is lying on segment
@@ -169,6 +136,7 @@ public:
}
private:
template <typename Point, typename PointOfSegment>
static inline int check_segment(Point const& point,
PointOfSegment const& seg1,
PointOfSegment const& seg2,
@@ -183,15 +151,18 @@ private:
return calculate_count(point, seg1, seg2, eq1, eq2);
}
template <typename Point, typename PointOfSegment>
static inline bool check_touch(Point const& point,
PointOfSegment const& seg1,
PointOfSegment const& seg2,
counter& state,
bool& eq1, bool& eq2)
{
calculation_type const px = get<0>(point);
calculation_type const s1x = get<0>(seg1);
calculation_type const s2x = get<0>(seg2);
typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
calc_t const px = get<0>(point);
calc_t const s1x = get<0>(seg1);
calc_t const s2x = get<0>(seg2);
eq1 = math::equals(s1x, px);
eq2 = math::equals(s2x, px);
@@ -200,9 +171,9 @@ private:
// The only thing which has to be done is check if point is ON segment
if (eq1 && eq2)
{
calculation_type const py = get<1>(point);
calculation_type const s1y = get<1>(seg1);
calculation_type const s2y = get<1>(seg2);
calc_t const py = get<1>(point);
calc_t const s1y = get<1>(seg1);
calc_t const s2y = get<1>(seg2);
if ((s1y <= py && s2y >= py) || (s2y <= py && s1y >= py))
{
state.m_touches = true;
@@ -212,14 +183,17 @@ private:
return false;
}
template <typename Point, typename PointOfSegment>
static inline int calculate_count(Point const& point,
PointOfSegment const& seg1,
PointOfSegment const& seg2,
bool eq1, bool eq2)
{
calculation_type const p = get<0>(point);
calculation_type const s1 = get<0>(seg1);
calculation_type const s2 = get<0>(seg2);
typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
calc_t const p = get<0>(point);
calc_t const s1 = get<0>(seg1);
calc_t const s2 = get<0>(seg2);
return eq1 ? (s2 > p ? 1 : -1) // Point on level s1, E/W depending on s2
: eq2 ? (s1 > p ? -1 : 1) // idem
@@ -228,6 +202,7 @@ private:
: 0;
}
template <typename Point, typename PointOfSegment>
static inline int side_equal(Point const& point,
PointOfSegment const& se,
int count)
@@ -242,6 +217,34 @@ private:
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
/*!
\brief Within detection using winding rule in cartesian coordinate system.
\ingroup strategies
\tparam Point_ \tparam_point
\tparam PointOfSegment_ \tparam_segment_point
\tparam CalculationType \tparam_calculation
\qbk{
[heading See also]
[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
}
*/
template
<
typename Point_ = void, // for backward compatibility
typename PointOfSegment_ = Point_, // for backward compatibility
typename CalculationType = void
>
class cartesian_winding
: public detail::cartesian_winding_base
<
typename side::services::default_strategy<cartesian_tag, CalculationType>::type,
CalculationType
>
{};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
@@ -251,21 +254,13 @@ namespace services
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, polygonal_tag, cartesian_tag, cartesian_tag>
{
typedef cartesian_winding
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
using type = cartesian_winding<>;
};
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, cartesian_tag, cartesian_tag>
{
typedef cartesian_winding
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
using type = cartesian_winding<>;
};
} // namespace services
@@ -283,21 +278,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, cartesian_tag, cartesian_tag>
{
typedef within::cartesian_winding
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
using type = within::cartesian_winding<>;
};
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, cartesian_tag, cartesian_tag>
{
typedef within::cartesian_winding
<
typename geometry::point_type<PointLike>::type,
typename geometry::point_type<Geometry>::type
> type;
using type = within::cartesian_winding<>;
};
}}} // namespace strategy::covered_by::services

View File

@@ -0,0 +1,54 @@
// 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_CARTESIAN_POINT_ORDER_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_ORDER_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategy/cartesian/area.hpp>
#include <boost/geometry/strategies/point_order.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace point_order
{
template <typename CalculationType = void>
struct cartesian
: strategy::area::cartesian<CalculationType>
{
typedef area_tag version_tag;
// TEMP
static strategy::area::cartesian<CalculationType> get_area_strategy()
{
return strategy::area::cartesian<CalculationType>();
}
};
namespace services
{
template <>
struct default_strategy<cartesian_tag>
{
typedef cartesian<> type;
};
} // namespace services
}} // namespace strategy::point_order
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_ORDER_HPP

View File

@@ -1,296 +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) 2021, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/envelope.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/algorithms/detail/equals/point_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
{
namespace strategy { namespace side
{
/*!
\brief Check at which side of a segment a point lies:
left of segment (> 0), right of segment (< 0), on segment (0)
\ingroup strategies
\tparam CalculationType \tparam_calculation
*/
template <typename CalculationType = void>
class side_by_triangle
{
template <typename Policy>
struct eps_policy
{
eps_policy() {}
template <typename Type>
eps_policy(Type const& a, Type const& b, Type const& c, Type const& d)
: policy(a, b, c, d)
{}
Policy policy;
};
struct eps_empty
{
eps_empty() {}
template <typename Type>
eps_empty(Type const&, Type const&, Type const&, Type const&) {}
};
public :
typedef strategy::envelope::cartesian<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
return envelope_strategy_type();
}
typedef strategy::disjoint::segment_box disjoint_strategy_type;
static inline disjoint_strategy_type get_disjoint_strategy()
{
return disjoint_strategy_type();
}
typedef strategy::within::cartesian_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();
}
// Template member function, because it is not always trivial
// or convenient to explicitly mention the typenames in the
// strategy-struct itself.
// Types can be all three different. Therefore it is
// not implemented (anymore) as "segment"
template
<
typename CoordinateType,
typename PromotedType,
typename P1,
typename P2,
typename P,
typename EpsPolicy
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy)
{
CoordinateType const x = get<0>(p);
CoordinateType const y = get<1>(p);
CoordinateType const sx1 = get<0>(p1);
CoordinateType const sy1 = get<1>(p1);
CoordinateType const sx2 = get<0>(p2);
CoordinateType const sy2 = get<1>(p2);
PromotedType const dx = sx2 - sx1;
PromotedType const dy = sy2 - sy1;
PromotedType const dpx = x - sx1;
PromotedType const dpy = y - sy1;
eps_policy = EpsPolicy(dx, dy, dpx, dpy);
return geometry::detail::determinant<PromotedType>
(
dx, dy,
dpx, dpy
);
}
template
<
typename CoordinateType,
typename PromotedType,
typename P1,
typename P2,
typename P
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p)
{
eps_empty dummy;
return side_value<CoordinateType, PromotedType>(p1, p2, p, dummy);
}
template
<
typename CoordinateType,
typename PromotedType,
bool AreAllIntegralCoordinates
>
struct compute_side_value
{
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
};
template <typename CoordinateType, typename PromotedType>
struct compute_side_value<CoordinateType, PromotedType, false>
{
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
// For robustness purposes, first check if any two points are
// the same; in this case simply return that the points are
// collinear
if (equals_point_point(p1, p2)
|| equals_point_point(p1, p)
|| equals_point_point(p2, p))
{
return PromotedType(0);
}
// The side_by_triangle strategy computes the signed area of
// the point triplet (p1, p2, p); as such it is (in theory)
// invariant under cyclic permutations of its three arguments.
//
// In the context of numerical errors that arise in
// floating-point computations, and in order to make the strategy
// consistent with respect to cyclic permutations of its three
// arguments, we cyclically permute them so that the first
// argument is always the lexicographically smallest point.
typedef compare::cartesian<compare::less> less;
if (less::apply(p, p1))
{
if (less::apply(p, p2))
{
// p is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p, p1, p2, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
if (less::apply(p1, p2))
{
// p1 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
};
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
typedef typename coordinate_type<P1>::type coordinate_type1;
typedef typename coordinate_type<P2>::type coordinate_type2;
typedef typename coordinate_type<P>::type coordinate_type3;
typedef typename boost::mpl::if_c
<
boost::is_void<CalculationType>::type::value,
typename select_most_precise
<
typename select_most_precise
<
coordinate_type1, coordinate_type2
>::type,
coordinate_type3
>::type,
CalculationType
>::type coordinate_type;
// Promote float->double, small int->int
typedef typename select_most_precise
<
coordinate_type,
double
>::type promoted_type;
bool const are_all_integral_coordinates =
boost::is_integral<coordinate_type1>::value
&& boost::is_integral<coordinate_type2>::value
&& boost::is_integral<coordinate_type3>::value;
eps_policy< math::detail::equals_factor_policy<promoted_type> > epsp;
promoted_type s = compute_side_value
<
coordinate_type, promoted_type, are_all_integral_coordinates
>::apply(p1, p2, p, epsp);
promoted_type const zero = promoted_type();
return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0
: s > zero ? 1
: -1;
}
private:
template <typename P1, typename P2>
static inline bool equals_point_point(P1 const& p1, P2 const& p2)
{
typedef equals_point_point_strategy_type strategy_t;
return geometry::detail::equals::equals_point_point(p1, p2, strategy_t());
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<cartesian_tag, CalculationType>
{
typedef side_by_triangle<CalculationType> type;
};
}
#endif
}} // namespace strategy::side
}} // namespace boost::geometry
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP

View File

@@ -1,351 +0,0 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015, 2019.
// Modifications copyright (c) 2015-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_OF_INTERSECTION_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_OF_INTERSECTION_HPP
#include <limits>
#include <boost/core/ignore_unused.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/util/math.hpp>
#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
#include <boost/math/common_factor_ct.hpp>
#include <boost/math/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#endif
namespace boost { namespace geometry
{
namespace strategy { namespace side
{
namespace detail
{
// A tool for multiplication of integers avoiding overflow
// It's a temporary workaround until we can use Multiprecision
// The algorithm is based on Karatsuba algorithm
// see: http://en.wikipedia.org/wiki/Karatsuba_algorithm
template <typename T>
struct multiplicable_integral
{
// Currently this tool can't be used with non-integral coordinate types.
// Also side_of_intersection strategy sign_of_product() and sign_of_compare()
// functions would have to be modified to properly support floating-point
// types (comparisons and multiplication).
BOOST_STATIC_ASSERT(boost::is_integral<T>::value);
static const std::size_t bits = CHAR_BIT * sizeof(T);
static const std::size_t half_bits = bits / 2;
typedef typename boost::make_unsigned<T>::type unsigned_type;
static const unsigned_type base = unsigned_type(1) << half_bits; // 2^half_bits
int m_sign;
unsigned_type m_ms;
unsigned_type m_ls;
multiplicable_integral(int sign, unsigned_type ms, unsigned_type ls)
: m_sign(sign), m_ms(ms), m_ls(ls)
{}
explicit multiplicable_integral(T const& val)
{
unsigned_type val_u = val > 0 ?
unsigned_type(val)
: val == (std::numeric_limits<T>::min)() ?
unsigned_type((std::numeric_limits<T>::max)()) + 1
: unsigned_type(-val);
// MMLL -> S 00MM 00LL
m_sign = math::sign(val);
m_ms = val_u >> half_bits; // val_u / base
m_ls = val_u - m_ms * base;
}
friend multiplicable_integral operator*(multiplicable_integral const& a,
multiplicable_integral const& b)
{
// (S 00MM 00LL) * (S 00MM 00LL) -> (S Z2MM 00LL)
unsigned_type z2 = a.m_ms * b.m_ms;
unsigned_type z0 = a.m_ls * b.m_ls;
unsigned_type z1 = (a.m_ms + a.m_ls) * (b.m_ms + b.m_ls) - z2 - z0;
// z0 may be >= base so it must be normalized to allow comparison
unsigned_type z0_ms = z0 >> half_bits; // z0 / base
return multiplicable_integral(a.m_sign * b.m_sign,
z2 * base + z1 + z0_ms,
z0 - base * z0_ms);
}
friend bool operator<(multiplicable_integral const& a,
multiplicable_integral const& b)
{
if ( a.m_sign == b.m_sign )
{
bool u_less = a.m_ms < b.m_ms
|| (a.m_ms == b.m_ms && a.m_ls < b.m_ls);
return a.m_sign > 0 ? u_less : (! u_less);
}
else
{
return a.m_sign < b.m_sign;
}
}
friend bool operator>(multiplicable_integral const& a,
multiplicable_integral const& b)
{
return b < a;
}
#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
template <typename CmpVal>
void check_value(CmpVal const& cmp_val) const
{
unsigned_type b = base; // a workaround for MinGW - undefined reference base
CmpVal val = CmpVal(m_sign) * (CmpVal(m_ms) * CmpVal(b) + CmpVal(m_ls));
BOOST_GEOMETRY_ASSERT(cmp_val == val);
}
#endif // BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
};
} // namespace detail
// Calculates the side of the intersection-point (if any) of
// of segment a//b w.r.t. segment c
// This is calculated without (re)calculating the IP itself again and fully
// based on integer mathematics; there are no divisions
// It can be used for either integer (rescaled) points, and also for FP
class side_of_intersection
{
private :
template <typename T, typename U>
static inline
int sign_of_product(T const& a, U const& b)
{
return a == 0 || b == 0 ? 0
: a > 0 && b > 0 ? 1
: a < 0 && b < 0 ? 1
: -1;
}
template <typename T>
static inline
int sign_of_compare(T const& a, T const& b, T const& c, T const& d)
{
// Both a*b and c*d are positive
// We have to judge if a*b > c*d
using side::detail::multiplicable_integral;
multiplicable_integral<T> ab = multiplicable_integral<T>(a)
* multiplicable_integral<T>(b);
multiplicable_integral<T> cd = multiplicable_integral<T>(c)
* multiplicable_integral<T>(d);
int result = ab > cd ? 1
: ab < cd ? -1
: 0
;
#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
using namespace boost::multiprecision;
cpp_int const lab = cpp_int(a) * cpp_int(b);
cpp_int const lcd = cpp_int(c) * cpp_int(d);
ab.check_value(lab);
cd.check_value(lcd);
int result2 = lab > lcd ? 1
: lab < lcd ? -1
: 0
;
BOOST_GEOMETRY_ASSERT(result == result2);
#endif
return result;
}
template <typename T>
static inline
int sign_of_addition_of_two_products(T const& a, T const& b, T const& c, T const& d)
{
// sign of a*b+c*d, 1 if positive, -1 if negative, else 0
int const ab = sign_of_product(a, b);
int const cd = sign_of_product(c, d);
if (ab == 0)
{
return cd;
}
if (cd == 0)
{
return ab;
}
if (ab == cd)
{
// Both positive or both negative
return ab;
}
// One is positive, one is negative, both are non zero
// If ab is positive, we have to judge if a*b > -c*d (then 1 because sum is positive)
// If ab is negative, we have to judge if c*d > -a*b (idem)
return ab == 1
? sign_of_compare(a, b, -c, d)
: sign_of_compare(c, d, -a, b);
}
public :
// Calculates the side of the intersection-point (if any) of
// of segment a//b w.r.t. segment c
// This is calculated without (re)calculating the IP itself again and fully
// based on integer mathematics
template <typename T, typename Segment, typename Point>
static inline T side_value(Segment const& a, Segment const& b,
Segment const& c, Point const& fallback_point)
{
// The first point of the three segments is reused several times
T const ax = get<0, 0>(a);
T const ay = get<0, 1>(a);
T const bx = get<0, 0>(b);
T const by = get<0, 1>(b);
T const cx = get<0, 0>(c);
T const cy = get<0, 1>(c);
T const dx_a = get<1, 0>(a) - ax;
T const dy_a = get<1, 1>(a) - ay;
T const dx_b = get<1, 0>(b) - bx;
T const dy_b = get<1, 1>(b) - by;
T const dx_c = get<1, 0>(c) - cx;
T const dy_c = get<1, 1>(c) - cy;
// Cramer's rule: d (see cart_intersect.hpp)
T const d = geometry::detail::determinant<T>
(
dx_a, dy_a,
dx_b, dy_b
);
T const zero = T();
if (d == zero)
{
// There is no IP of a//b, they are collinear or parallel
// Assuming they intersect (this method should be called for
// segments known to intersect), they are collinear and overlap.
// They have one or two intersection points - we don't know and
// have to rely on the fallback intersection point
Point c1, c2;
geometry::detail::assign_point_from_index<0>(c, c1);
geometry::detail::assign_point_from_index<1>(c, c2);
return side_by_triangle<>::apply(c1, c2, fallback_point);
}
// Cramer's rule: da (see cart_intersect.hpp)
T const da = geometry::detail::determinant<T>
(
dx_b, dy_b,
ax - bx, ay - by
);
// IP is at (ax + (da/d) * dx_a, ay + (da/d) * dy_a)
// Side of IP is w.r.t. c is: determinant(dx_c, dy_c, ipx-cx, ipy-cy)
// We replace ipx by expression above and multiply each term by d
#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
T const result1 = geometry::detail::determinant<T>
(
dx_c * d, dy_c * d,
d * (ax - cx) + dx_a * da, d * (ay - cy) + dy_a * da
);
// Note: result / (d * d)
// is identical to the side_value of side_by_triangle
// Therefore, the sign is always the same as that result, and the
// resulting side (left,right,collinear) is the same
// The first row we divide again by d because of determinant multiply rule
T const result2 = d * geometry::detail::determinant<T>
(
dx_c, dy_c,
d * (ax - cx) + dx_a * da, d * (ay - cy) + dy_a * da
);
// Write out:
T const result3 = d * (dx_c * (d * (ay - cy) + dy_a * da)
- dy_c * (d * (ax - cx) + dx_a * da));
// Write out in braces:
T const result4 = d * (dx_c * d * (ay - cy) + dx_c * dy_a * da
- dy_c * d * (ax - cx) - dy_c * dx_a * da);
// Write in terms of d * XX + da * YY
T const result5 = d * (d * (dx_c * (ay - cy) - dy_c * (ax - cx))
+ da * (dx_c * dy_a - dy_c * dx_a));
boost::ignore_unused(result1, result2, result3, result4, result5);
//return result;
#endif
// We consider the results separately
// (in the end we only have to return the side-value 1,0 or -1)
// To avoid multiplications we judge the product (easy, avoids *d)
// and the sign of p*q+r*s (more elaborate)
T const result = sign_of_product
(
d,
sign_of_addition_of_two_products
(
d, dx_c * (ay - cy) - dy_c * (ax - cx),
da, dx_c * dy_a - dy_c * dx_a
)
);
return result;
}
template <typename Segment, typename Point>
static inline int apply(Segment const& a, Segment const& b,
Segment const& c,
Point const& fallback_point)
{
typedef typename geometry::coordinate_type<Segment>::type coordinate_type;
coordinate_type const s = side_value<coordinate_type>(a, b, c, fallback_point);
coordinate_type const zero = coordinate_type();
return math::equals(s, zero) ? 0
: s > zero ? 1
: -1;
}
};
}} // namespace strategy::side
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_OF_INTERSECTION_HPP

View File

@@ -0,0 +1,65 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2021 Tinko Bartels, Berlin, Germany.
// This file was modified by Oracle on 2023.
// Modifications copyright (c) 2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROUNDED_INPUT_HPP
#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROUNDED_INPUT_HPP
#include <limits>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/config.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace side
{
template <typename CalculationType = void, int Coeff1 = 5, int Coeff2 = 32>
struct side_rounded_input
{
using cs_tag = cartesian_tag;
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
using coor_t = typename select_calculation_type_alt<CalculationType, P1, P2, P>::type;
coor_t const p1_x = geometry::get<0>(p1);
coor_t const p1_y = geometry::get<1>(p1);
coor_t const p2_x = geometry::get<0>(p2);
coor_t const p2_y = geometry::get<1>(p2);
coor_t const p_x = geometry::get<0>(p);
coor_t const p_y = geometry::get<1>(p);
constexpr coor_t eps = std::numeric_limits<coor_t>::epsilon() / 2;
coor_t const det = (p1_x - p_x) * (p2_y - p_y) - (p1_y - p_y) * (p2_x - p_x);
coor_t const err_bound = (Coeff1 * eps + Coeff2 * eps * eps) *
( (geometry::math::abs(p1_x) + geometry::math::abs(p_x))
* (geometry::math::abs(p2_y) + geometry::math::abs(p_y))
+ (geometry::math::abs(p2_x) + geometry::math::abs(p_x))
* (geometry::math::abs(p1_y) + geometry::math::abs(p_y)));
return (det > err_bound) - (det < -err_bound);
}
};
}} // namespace strategy::side
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROUNDED_INPUT_HPP

View File

@@ -0,0 +1,230 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2023.
// Modifications copyright (c) 2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_TURN_IN_RING_WINDING_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_TURN_IN_RING_WINDING_HPP
#include <boost/geometry/arithmetic/infinite_line_functions.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/config.hpp>
#include <boost/geometry/algorithms/detail/make/make.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/cartesian/side_rounded_input.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace buffer
{
#ifndef DOXYGEN_NO_DETAIL
enum place_on_ring_type
{
// +----offsetted----> (offsetted is considered as outside)
// | |
// | |
// left right (first point outside, rest inside)
// | |
// | |
// <-----original----+ (original is considered as inside)
place_on_ring_offsetted,
place_on_ring_original,
place_on_ring_to_offsetted,
place_on_ring_from_offsetted,
};
template <typename CalculationType>
class turn_in_ring_winding
{
// Implements the winding rule.
// Basic calculations (on a clockwise ring of 5 segments)
// (as everywhere in BG, -1 = right, 0 = on segment, +1 = left)
// +--------2--------+ // P : For 1/3, nothing happens, it returns
// | | // For 2, side is right (-1), multiplier=2, -2
// | P | // For 4, side is right (-1), multiplier=1, -1
// 1 3 // For 5, side is right (-1), multiplier=1, -1, total -4
// | Q | // Q : For 2: -2, for 4: -2, total -4
// | | // R : For 2: -2, for 5: +2, total 0
// +----5---*----4---+ // S : For 2: -1, 3: nothing, 4: +1, total 0
//
// R S
//
public:
struct counter
{
//! Counter, is increased if point is left of a segment (outside),
//! and decreased if point is right of a segment (inside)
int count{0};
int count_on_offsetted{0};
int count_on_origin{0};
int count_on_edge{0};
CalculationType edge_min_fraction{(std::numeric_limits<CalculationType>::max)()};
#if defined(BOOST_GEOMETRY_USE_RESCALING)
CalculationType inside_min_measure{(std::numeric_limits<CalculationType>::max)()};
#endif
inline bool is_inside() const
{
return count < 0 || count_on_origin > 0;
}
inline bool is_on_boundary() const
{
return count_on_origin == 0
&& (count_on_offsetted > 0
|| (count_on_edge > 0 && edge_min_fraction < 1.0e-3)
#if defined(BOOST_GEOMETRY_USE_RESCALING)
|| (count < 0 && inside_min_measure < 1.0e-5)
#endif
);
}
};
using state_type = counter;
template <typename Point, typename PointOfSegment>
static inline bool is_in_vertical_range(Point const& point,
PointOfSegment const& s1,
PointOfSegment const& s2)
{
CalculationType const py = get<1>(point);
CalculationType const s1y = get<1>(s1);
CalculationType const s2y = get<1>(s2);
return s1y < s2y ? (py >= s1y && py <= s2y) : (py >= s2y && py <= s1y);
}
template <typename Point, typename PointOfSegment>
static inline void apply_on_boundary(Point const& point,
PointOfSegment const& s1,
PointOfSegment const& s2,
place_on_ring_type place_on_ring,
counter& the_state)
{
if (place_on_ring == place_on_ring_offsetted)
{
the_state.count_on_offsetted++;
}
else if (place_on_ring == place_on_ring_to_offsetted
|| place_on_ring == place_on_ring_from_offsetted)
{
the_state.count_on_edge++;
auto const line1 = detail::make::make_perpendicular_line<CalculationType>(s1, s2, s1);
auto const line2 = detail::make::make_perpendicular_line<CalculationType>(s2, s1, s2);
auto const value1 = arithmetic::side_value(line1, point);
auto const value2 = arithmetic::side_value(line2, point);
if (value1 >= 0 && value2 >= 0)
{
auto const length_value = value1 + value2;
if (length_value > 0)
{
// If it is to the utmost point s1 or s2, it is "outside"
auto const fraction = (place_on_ring == place_on_ring_to_offsetted ? value2 : value1) / length_value;
if (fraction < the_state.edge_min_fraction)
{
the_state.edge_min_fraction = fraction;
}
}
}
}
else
{
the_state.count_on_origin++;
}
}
template <typename Point, typename PointOfSegment>
static inline bool apply(Point const& point,
PointOfSegment const& s1,
PointOfSegment const& s2,
place_on_ring_type place_on_ring,
bool is_convex,
counter& the_state)
{
int const side = strategy::side::side_rounded_input<CalculationType>::apply(s1, s2, point);
if (is_convex && side > 0)
{
// If the point is left of this segment of a convex piece, it can never be inside.
// Stop further processing
the_state.count = 1;
return false;
}
CalculationType const px = get<0>(point);
CalculationType const s1x = get<0>(s1);
CalculationType const s2x = get<0>(s2);
bool const in_horizontal_range = s1x < s2x ? (px >= s1x && px <= s2x) : (px >= s2x && px <= s1x);
bool const vertical = s1x == s2x;
if (in_horizontal_range || (vertical && is_in_vertical_range(point, s1, s2)))
{
if (side == 0)
{
apply_on_boundary(point, s1, s2, place_on_ring, the_state);
}
#if defined(BOOST_GEOMETRY_USE_RESCALING)
else if (side == -1)
{
auto const line = detail::make::make_infinite_line<CalculationType>(s1, s2);
auto const value = -arithmetic::side_value(line, point);
if (value > 0 && value < the_state.inside_min_measure) { the_state.inside_min_measure = value; }
}
#endif
}
if (in_horizontal_range)
{
auto const on_boundary = the_state.count_on_offsetted + the_state.count_on_edge + the_state.count_on_origin;
if (on_boundary == 0)
{
// Use only absolute comparisons, because the ring is continuous -
// what was missed is there earlier or later, and turns should
// not be counted twice (which can happen if an epsilon is used).
bool const eq1 = s1x == px;
bool const eq2 = s2x == px;
// Account for 1 or 2 for left side (outside)
// and for -1 or -2 for right side (inside)
int const multiplier = eq1 || eq2 ? 1 : 2;
the_state.count += side * multiplier;
}
}
return true;
}
};
#endif // DOXYGEN_NO_DETAIL
}} // namespace strategy::buffer
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_TURN_IN_RING_WINDING_HPP

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020, Oracle and/or its affiliates.
// 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.
@@ -17,8 +21,6 @@
#include <cstddef>
#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/tags.hpp>

View File

@@ -0,0 +1,123 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CENTROID_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_CENTROID_CARTESIAN_HPP
#include <boost/geometry/strategies/cartesian/centroid_average.hpp>
#include <boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp>
#include <boost/geometry/strategies/cartesian/centroid_weighted_length.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/centroid/services.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace centroid
{
template <typename CalculationType = void>
struct cartesian
: public strategies::detail::cartesian_base
{
template <typename Geometry>
static auto centroid(Geometry const&,
std::enable_if_t
<
util::is_pointlike<Geometry>::value
> * = nullptr)
{
return strategy::centroid::average<>();
}
template <typename Geometry>
static auto centroid(Geometry const&,
std::enable_if_t
<
util::is_polylinear<Geometry>::value
> * = nullptr)
{
return strategy::centroid::weighted_length<void, void, CalculationType>();
}
template <typename Geometry>
static auto centroid(Geometry const&,
std::enable_if_t
<
util::is_polygonal<Geometry>::value
// TODO: This condition was used for the legacy default strategy
// && geometry::dimension<Geometry>::value == 2
> * = nullptr)
{
return strategy::centroid::bashein_detmer<void, void, CalculationType>();
}
// TODO: Box and Segment should have proper strategies.
template <typename Geometry, typename Point>
static auto centroid(Geometry const&, Point const&,
std::enable_if_t
<
util::is_segment<Geometry>::value
|| util::is_box<Geometry>::value
> * = nullptr)
{
return strategy::centroid::not_applicable_strategy();
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, cartesian_tag>
{
using type = strategies::centroid::cartesian<>;
};
template <typename PC, typename PG>
struct strategy_converter<strategy::centroid::average<PC, PG> >
{
static auto get(strategy::centroid::average<PC, PG> const&)
{
return strategies::centroid::cartesian<>();
}
};
template <typename PC, typename PG>
struct strategy_converter<strategy::centroid::weighted_length<PC, PG> >
{
static auto get(strategy::centroid::weighted_length<PC, PG> const&)
{
return strategies::centroid::cartesian<>();
}
};
template <typename PC, typename PG, typename CT>
struct strategy_converter<strategy::centroid::bashein_detmer<PC, PG, CT> >
{
static auto get(strategy::centroid::bashein_detmer<PC, PG, CT> const&)
{
return strategies::centroid::cartesian<CT>();
}
};
} // namespace services
}} // namespace strategies::centroid
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CENTROID_CARTESIAN_HPP

View File

@@ -0,0 +1,71 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CENTROID_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_CENTROID_GEOGRAPHIC_HPP
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/strategies/centroid/services.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace centroid
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public strategies::detail::geographic_base<Spheroid>
{
using base_t = strategies::detail::geographic_base<Spheroid>;
public:
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
// TODO: Box and Segment should have proper strategies.
template <typename Geometry, typename Point>
static auto centroid(Geometry const&, Point const&,
std::enable_if_t
<
util::is_segment<Geometry>::value
|| util::is_box<Geometry>::value
> * = nullptr)
{
return strategy::centroid::not_applicable_strategy();
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, geographic_tag>
{
using type = strategies::centroid::geographic<>;
};
} // namespace services
}} // namespace strategies::centroid
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CENTROID_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,54 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CENTROID_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_CENTROID_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace centroid
{
namespace services
{
template
<
typename Geometry,
typename CSTag = typename geometry::cs_tag<Geometry>::type
>
struct default_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Geometry's coordinate systems.",
Geometry, CSTag);
};
template <typename Strategy>
struct strategy_converter
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
} // namespace services
}} // namespace strategies::centroid
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CENTROID_SERVICES_HPP

View File

@@ -0,0 +1,66 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CENTROID_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_CENTROID_SPHERICAL_HPP
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/strategies/centroid/services.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace centroid
{
template
<
typename CalculationType = void
>
class spherical
: public strategies::detail::spherical_base<void>
{
using base_t = strategies::detail::spherical_base<void>;
public:
spherical() = default;
// TODO: Box and Segment should have proper strategies.
template <typename Geometry, typename Point>
static auto centroid(Geometry const&, Point const&,
std::enable_if_t
<
util::is_segment<Geometry>::value
|| util::is_box<Geometry>::value
> * = nullptr)
{
return strategy::centroid::not_applicable_strategy();
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, spherical_equatorial_tag>
{
using type = strategies::centroid::spherical<>;
};
} // namespace services
}} // namespace strategies::centroid
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CENTROID_SPHERICAL_HPP

View File

@@ -0,0 +1,68 @@
// 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_CLOSEST_POINTS_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_CARTESIAN_HPP
//#include <boost/geometry/strategies/cartesian/azimuth.hpp>
//#include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
//#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/closest_points_pt_seg.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/strategies/closest_points/services.hpp>
//#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/distance/cartesian.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace closest_points
{
template <typename CalculationType = void>
struct cartesian
: public strategies::distance::cartesian<CalculationType>
{
template <typename Geometry1, typename Geometry2>
static auto closest_points(Geometry1 const&, Geometry2 const&,
distance::detail::enable_if_ps_t<Geometry1, Geometry2> * = nullptr)
{
return strategy::closest_points::projected_point<CalculationType>();
}
};
namespace services
{
template <typename Geometry1, typename Geometry2>
struct default_strategy<Geometry1, Geometry2, cartesian_tag, cartesian_tag>
{
using type = strategies::closest_points::cartesian<>;
};
} // namespace services
}} // namespace strategies::closest_points
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_CARTESIAN_HPP

View File

@@ -0,0 +1,78 @@
// 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_CLOSEST_POINTS_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_GEOGRAPHIC_HPP
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/strategies/closest_points/services.hpp>
#include <boost/geometry/strategies/geographic/closest_points_pt_seg.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/distance/geographic.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace closest_points
{
template
<
typename FormulaPolicy = geometry::strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public strategies::distance::geographic<FormulaPolicy, Spheroid, CalculationType>
{
using base_t = strategies::distance::geographic<FormulaPolicy, Spheroid, CalculationType>;
public:
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
template <typename Geometry1, typename Geometry2>
auto closest_points(Geometry1 const&, Geometry2 const&,
distance::detail::enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::closest_points::geographic_cross_track
<
FormulaPolicy,
Spheroid,
CalculationType
>(base_t::m_spheroid);
}
};
namespace services
{
template <typename Geometry1, typename Geometry2>
struct default_strategy<Geometry1, Geometry2, geographic_tag, geographic_tag>
{
using type = strategies::closest_points::geographic<>;
};
} // namespace services
}} // namespace strategies::closest_points
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,48 @@
// 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_CLOSEST_POINTS_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/strategies/detail.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace closest_points
{
namespace services
{
template
<
typename Geometry1,
typename Geometry2,
typename CSTag1 = typename geometry::cs_tag<Geometry1>::type,
typename CSTag2 = typename geometry::cs_tag<Geometry2>::type
>
struct default_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for these Geometries' coordinate systems.",
Geometry1, Geometry2, CSTag1, CSTag2);
};
} // namespace services
}} // namespace strategies::closest_points
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_SERVICES_HPP

View File

@@ -0,0 +1,78 @@
// 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_CLOSEST_POINTS_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_SPHERICAL_HPP
#include <boost/geometry/strategies/spherical/closest_points_pt_seg.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/strategies/closest_points/services.hpp>
#include <boost/geometry/strategies/distance/spherical.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace closest_points
{
template
<
typename RadiusTypeOrSphere = double,
typename CalculationType = void
>
class spherical
: public strategies::distance::spherical<RadiusTypeOrSphere, CalculationType>
{
using base_t = strategies::distance::spherical<RadiusTypeOrSphere, CalculationType>;
public:
spherical() = default;
template <typename RadiusOrSphere>
explicit spherical(RadiusOrSphere const& radius_or_sphere)
: base_t(radius_or_sphere)
{}
template <typename Geometry1, typename Geometry2>
auto closest_points(Geometry1 const&, Geometry2 const&,
distance::detail::enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::closest_points::cross_track<CalculationType>(base_t::radius());
}
};
namespace services
{
template <typename Geometry1, typename Geometry2>
struct default_strategy
<
Geometry1,
Geometry2,
spherical_equatorial_tag,
spherical_equatorial_tag
>
{
using type = strategies::closest_points::spherical<>;
};
} // namespace services
}} // namespace strategies::closest_points
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CLOSEST_POINTS_SPHERICAL_HPP

View File

@@ -1,8 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, 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
@@ -10,22 +10,17 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP
#define BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP
#include <boost/mpl/always.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/select_geometry_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/reverse_dispatch.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/util/compress_variant.hpp>
#include <boost/geometry/util/transform_variant.hpp>
#include <boost/geometry/util/combine_if.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/strategies/distance/services.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/util/sequence.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
@@ -34,14 +29,55 @@ namespace boost { namespace geometry
namespace resolve_strategy
{
// TODO: This utility could be entirely implemented as:
// decltype(geometry::comparable_distance(std::declval<Geometry1>(), std::declval<Geometry2>(), std::declval<Strategy>()))
// however then the algorithm would have to be compiled.
template
<
typename Geometry1, typename Geometry2, typename Strategy,
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
>
struct comparable_distance_strategy2_type
{
typedef decltype(std::declval<Strategy>().distance(
std::declval<Geometry1>(), std::declval<Geometry2>())) type;
};
template <typename Geometry1, typename Geometry2, typename Strategy>
struct comparable_distance_strategy2_type<Geometry1, Geometry2, Strategy, false>
{
typedef Strategy type;
};
template
<
typename Geometry1, typename Geometry2, typename Strategy,
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
>
struct comparable_distance_strategy_type
: strategy::distance::services::comparable_type
<
typename comparable_distance_strategy2_type
<
Geometry1, Geometry2, Strategy
>::type
>
{};
template <typename Geometry1, typename Geometry2, typename Strategy>
struct comparable_distance_strategy_type<Geometry1, Geometry2, Strategy, true>
: comparable_distance_strategy_type<Geometry2, Geometry1, Strategy, false>
{};
template <typename Geometry1, typename Geometry2, typename Strategy>
struct comparable_distance_result
: strategy::distance::services::return_type
<
typename strategy::distance::services::comparable_type
<
Strategy
>::type,
typename comparable_distance_strategy_type<Geometry1, Geometry2, Strategy>::type,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type
>
@@ -53,20 +89,68 @@ struct comparable_distance_result<Geometry1, Geometry2, default_strategy>
<
Geometry1,
Geometry2,
typename detail::distance::default_strategy
typename strategies::distance::services::default_strategy
<
Geometry1, Geometry2
>::type
>
{};
} // namespace resolve_strategy
namespace resolve_variant
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template <typename Geometry1, typename Geometry2, typename Strategy>
template <typename Strategy = geometry::default_strategy>
struct more_precise_comparable_distance_result
{
template <typename Curr, typename Next>
struct predicate
: std::is_same
<
typename resolve_strategy::comparable_distance_result
<
typename util::sequence_element<0, Curr>::type,
typename util::sequence_element<1, Curr>::type,
Strategy
>::type,
typename geometry::select_most_precise
<
typename resolve_strategy::comparable_distance_result
<
typename util::sequence_element<0, Curr>::type,
typename util::sequence_element<1, Curr>::type,
Strategy
>::type,
typename resolve_strategy::comparable_distance_result
<
typename util::sequence_element<0, Next>::type,
typename util::sequence_element<1, Next>::type,
Strategy
>::type
>::type
>
{};
};
}} // namespace detail::distance
#endif //DOXYGEN_NO_DETAIL
namespace resolve_dynamic
{
template
<
typename Geometry1, typename Geometry2, typename Strategy,
bool IsDynamicOrCollection = util::is_dynamic_geometry<Geometry1>::value
|| util::is_dynamic_geometry<Geometry2>::value
|| util::is_geometry_collection<Geometry1>::value
|| util::is_geometry_collection<Geometry2>::value
>
struct comparable_distance_result
: resolve_strategy::comparable_distance_result
<
@@ -76,95 +160,29 @@ struct comparable_distance_result
>
{};
template
<
typename Geometry1,
BOOST_VARIANT_ENUM_PARAMS(typename T),
typename Strategy
>
struct comparable_distance_result
<
Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy
>
template <typename Geometry1, typename Geometry2, typename Strategy>
struct comparable_distance_result<Geometry1, Geometry2, Strategy, true>
{
// A set of all variant type combinations that are compatible and
// implemented
typedef typename util::combine_if<
typename boost::mpl::vector1<Geometry1>,
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
boost::mpl::always<boost::mpl::true_>
>::type possible_input_types;
// Select the most precise distance strategy result type
// for all variant type combinations.
// TODO: We should ignore the combinations that are not valid
// but is_implemented is not ready for prime time.
using selected_types = typename detail::select_geometry_types
<
Geometry1, Geometry2,
detail::distance::more_precise_comparable_distance_result<Strategy>::template predicate
>::type;
// The (possibly variant) result type resulting from these combinations
typedef typename compress_variant<
typename transform_variant<
possible_input_types,
resolve_strategy::comparable_distance_result<
boost::mpl::first<boost::mpl::_>,
boost::mpl::second<boost::mpl::_>,
Strategy
>,
boost::mpl::back_inserter<boost::mpl::vector0<> >
>::type
>::type type;
using type = typename resolve_strategy::comparable_distance_result
<
typename util::sequence_element<0, selected_types>::type,
typename util::sequence_element<1, selected_types>::type,
Strategy
>::type;
};
// Distance arguments are commutative
template
<
BOOST_VARIANT_ENUM_PARAMS(typename T),
typename Geometry2,
typename Strategy
>
struct comparable_distance_result
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
Geometry2,
Strategy
> : public comparable_distance_result
<
Geometry2, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy
>
{};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy>
struct comparable_distance_result
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
Strategy
>
{
// A set of all variant type combinations that are compatible and
// implemented
typedef typename util::combine_if
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
boost::mpl::always<boost::mpl::true_>
>::type possible_input_types;
// The (possibly variant) result type resulting from these combinations
typedef typename compress_variant<
typename transform_variant<
possible_input_types,
resolve_strategy::comparable_distance_result<
boost::mpl::first<boost::mpl::_>,
boost::mpl::second<boost::mpl::_>,
Strategy
>,
boost::mpl::back_inserter<boost::mpl::vector0<> >
>::type
>::type type;
};
} // namespace resolve_variant
} // namespace resolve_dynamic
/*!
@@ -178,7 +196,7 @@ template
typename Strategy = void
>
struct comparable_distance_result
: resolve_variant::comparable_distance_result
: resolve_dynamic::comparable_distance_result
<
Geometry1, Geometry2, Strategy
>

View File

@@ -4,9 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -21,16 +22,15 @@
#define BOOST_GEOMETRY_STRATEGIES_COMPARE_HPP
#include <algorithm>
#include <cstddef>
#include <functional>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/min.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/util/math.hpp>
@@ -70,6 +70,24 @@ struct equal_to
}
};
struct equals_epsilon
{
template <typename T1, typename T2>
static inline bool apply(T1 const& l, T2 const& r)
{
return math::equals(l, r);
}
};
struct equals_exact
{
template <typename T1, typename T2>
static inline bool apply(T1 const& l, T2 const& r)
{
return l == r;
}
};
#ifndef DOXYGEN_NO_DETAIL
namespace detail
@@ -79,6 +97,7 @@ namespace detail
template
<
typename ComparePolicy,
typename EqualsPolicy,
std::size_t Dimension,
std::size_t DimensionCount
>
@@ -92,11 +111,12 @@ struct compare_loop
typename geometry::coordinate_type<Point2>::type const&
cright = geometry::get<Dimension>(right);
if (math::equals(cleft, cright))
if (EqualsPolicy::apply(cleft, cright))
{
return compare_loop
<
ComparePolicy,
EqualsPolicy,
Dimension + 1, DimensionCount
>::apply(left, right);
}
@@ -110,9 +130,10 @@ struct compare_loop
template
<
typename ComparePolicy,
typename EqualsPolicy,
std::size_t DimensionCount
>
struct compare_loop<ComparePolicy, DimensionCount, DimensionCount>
struct compare_loop<ComparePolicy, EqualsPolicy, DimensionCount, DimensionCount>
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& , Point2 const& )
@@ -125,9 +146,10 @@ struct compare_loop<ComparePolicy, DimensionCount, DimensionCount>
template
<
typename EqualsPolicy,
std::size_t DimensionCount
>
struct compare_loop<strategy::compare::equal_to, DimensionCount, DimensionCount>
struct compare_loop<strategy::compare::equal_to, EqualsPolicy, DimensionCount, DimensionCount>
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& , Point2 const& )
@@ -145,6 +167,7 @@ struct compare_loop<strategy::compare::equal_to, DimensionCount, DimensionCount>
template
<
typename ComparePolicy,
typename EqualsPolicy,
int Dimension = -1
>
struct cartesian
@@ -154,7 +177,7 @@ struct cartesian
{
return compare::detail::compare_loop
<
ComparePolicy, Dimension, Dimension + 1
ComparePolicy, EqualsPolicy, Dimension, Dimension + 1
>::apply(left, right);
}
};
@@ -162,9 +185,10 @@ struct cartesian
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
template
<
typename ComparePolicy
typename ComparePolicy,
typename EqualsPolicy
>
struct cartesian<ComparePolicy, -1>
struct cartesian<ComparePolicy, EqualsPolicy, -1>
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right)
@@ -172,12 +196,10 @@ struct cartesian<ComparePolicy, -1>
return compare::detail::compare_loop
<
ComparePolicy,
EqualsPolicy,
0,
boost::mpl::min
<
geometry::dimension<Point1>,
geometry::dimension<Point2>
>::type::value
((std::min)(geometry::dimension<Point1>::value,
geometry::dimension<Point2>::value))
>::apply(left, right);
}
};
@@ -190,6 +212,7 @@ namespace services
template
<
typename ComparePolicy,
typename EqualsPolicy,
typename Point1,
typename Point2 = Point1,
int Dimension = -1,
@@ -198,19 +221,23 @@ template
>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false,
NOT_IMPLEMENTED_FOR_THESE_TYPES,
(types<CSTag1, CSTag2>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for these types.",
CSTag1, CSTag2);
};
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy<ComparePolicy, Point1, Point2, Dimension, cartesian_tag, cartesian_tag>
template
<
typename ComparePolicy,
typename EqualsPolicy,
typename Point1,
typename Point2,
int Dimension
>
struct default_strategy<ComparePolicy, EqualsPolicy, Point1, Point2, Dimension, cartesian_tag, cartesian_tag>
{
typedef compare::cartesian<ComparePolicy, Dimension> type;
typedef compare::cartesian<ComparePolicy, EqualsPolicy, Dimension> type;
};

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// 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-2020.
// Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -20,15 +20,14 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
#include <vector>
#include <iterator>
#include <type_traits>
#include <vector>
#include <boost/concept_check.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/util/parameter_type_of.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/segment.hpp>
@@ -37,6 +36,8 @@
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/util/parameter_type_of.hpp>
namespace boost { namespace geometry { namespace concepts
{
@@ -87,14 +88,14 @@ private :
>::type tag;
static const bool is_correct_strategy_tag =
boost::is_same<tag, strategy_tag_distance_point_point>::value
|| boost::is_same<tag, strategy_tag_distance_point_box>::value
|| boost::is_same<tag, strategy_tag_distance_box_box>::value;
std::is_same<tag, strategy_tag_distance_point_point>::value
|| std::is_same<tag, strategy_tag_distance_point_box>::value
|| std::is_same<tag, strategy_tag_distance_box_box>::value;
BOOST_MPL_ASSERT_MSG
((is_correct_strategy_tag),
INCORRECT_STRATEGY_TAG,
(types<tag>));
BOOST_GEOMETRY_STATIC_ASSERT(
is_correct_strategy_tag,
"Incorrect Strategy tag.",
Strategy, tag);
// 5) must implement apply with arguments
Strategy* str = 0;
@@ -161,13 +162,13 @@ private :
// 2) must define meta-function "tag"
typedef typename services::tag<Strategy>::type tag;
BOOST_MPL_ASSERT_MSG
((boost::is_same
<
tag, strategy_tag_distance_point_segment
>::value),
INCORRECT_STRATEGY_TAG,
(types<tag>));
BOOST_GEOMETRY_STATIC_ASSERT(
(std::is_same
<
tag, strategy_tag_distance_point_segment
>::value),
"Incorrect Strategy tag.",
Strategy, tag);
// 3) must define meta-function "return_type"
typedef typename services::return_type

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020, Oracle and/or its affiliates.
// 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.
@@ -14,8 +18,9 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
#include <vector>
#include <iterator>
#include <type_traits>
#include <vector>
#include <boost/concept_check.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -54,12 +59,12 @@ private :
ApplyMethod
>::type parameter_types;
typedef typename boost::mpl::if_
typedef std::conditional_t
<
ft::is_member_function_pointer<ApplyMethod>,
boost::mpl::int_<1>,
boost::mpl::int_<0>
>::type base_index;
ft::is_member_function_pointer<ApplyMethod>::value,
std::integral_constant<int, 1>,
std::integral_constant<int, 0>
> base_index;
BOOST_CONCEPT_ASSERT
(

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018 Oracle and/or its affiliates.
// This file was modified by Oracle on 2018-2020.
// Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -19,11 +19,13 @@
#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
#include <type_traits>
#include <boost/concept_check.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -31,6 +33,8 @@
#include <boost/geometry/geometries/concepts/box_concept.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/util/parameter_type_of.hpp>
@@ -38,22 +42,72 @@ namespace boost { namespace geometry { namespace concepts
{
namespace detail
{
template
<
typename Point, typename Geometry, typename Strategy,
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
>
struct relate_strategy_dispatch
{
using type = decltype(std::declval<Strategy>().relate(
std::declval<Point>(), std::declval<Geometry>()));
};
template <typename Point, typename Geometry, typename Strategy>
struct relate_strategy_dispatch<Point, Geometry, Strategy, false>
{
using type = Strategy;
};
template
<
typename Point, typename Geometry, typename Strategy,
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
>
struct within_strategy_dispatch
{
using type = decltype(std::declval<Strategy>().within(
std::declval<Point>(), std::declval<Geometry>()));
};
template <typename Point, typename Geometry, typename Strategy>
struct within_strategy_dispatch<Point, Geometry, Strategy, false>
{
using type = Strategy;
};
} // namespace detail
/*!
\brief Checks strategy for within (point-in-polygon)
\ingroup within
*/
template <typename Strategy>
template <typename Point, typename Polygonal, typename Strategy>
class WithinStrategyPolygonal
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
typedef typename geometry::point_type<Polygonal>::type point_of_segment;
// 0)
typedef typename concepts::detail::relate_strategy_dispatch
<
Point, Polygonal, Strategy
>::type strategy_type;
// 1) must define state_type
typedef typename Strategy::state_type state_type;
typedef typename strategy_type::state_type state_type;
struct checker
{
template <typename ApplyMethod, typename ResultMethod>
static void apply(ApplyMethod const&, ResultMethod const& )
static void apply(ApplyMethod, ResultMethod)
{
typedef typename parameter_type_of
<
@@ -76,28 +130,28 @@ class WithinStrategyPolygonal
);
// CHECK: return types (result: int, apply: bool)
BOOST_MPL_ASSERT_MSG
BOOST_GEOMETRY_STATIC_ASSERT
(
(boost::is_same
(std::is_same
<
bool, typename boost::function_types::result_type<ApplyMethod>::type
>::type::value),
WRONG_RETURN_TYPE_OF_APPLY
, (bool)
>::value),
"Wrong return type of apply().",
bool, ApplyMethod
);
BOOST_MPL_ASSERT_MSG
BOOST_GEOMETRY_STATIC_ASSERT
(
(boost::is_same
(std::is_same
<
int, typename boost::function_types::result_type<ResultMethod>::type
>::type::value),
WRONG_RETURN_TYPE_OF_RESULT
, (int)
>::value),
"Wrong return type of result().",
int, ResultMethod
);
// CHECK: calling method apply and result
Strategy const* str = 0;
strategy_type const* str = 0;
state_type* st = 0;
point_type const* p = 0;
segment_point_type const* sp = 0;
@@ -113,7 +167,8 @@ class WithinStrategyPolygonal
public :
BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
{
checker::apply(&Strategy::apply, &Strategy::result);
checker::apply(&strategy_type::template apply<Point, point_of_segment>,
&strategy_type::result);
}
#endif
};
@@ -123,10 +178,16 @@ class WithinStrategyPointBox
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
// 0)
typedef typename concepts::detail::within_strategy_dispatch
<
Point, Box, Strategy
>::type strategy_type;
struct checker
{
template <typename ApplyMethod>
static void apply(ApplyMethod const&)
static void apply(ApplyMethod)
{
typedef typename parameter_type_of
<
@@ -149,20 +210,20 @@ class WithinStrategyPointBox
);
// CHECK: return types (apply: bool)
BOOST_MPL_ASSERT_MSG
BOOST_GEOMETRY_STATIC_ASSERT
(
(boost::is_same
(std::is_same
<
bool,
typename boost::function_types::result_type<ApplyMethod>::type
>::type::value),
WRONG_RETURN_TYPE
, (bool)
>::value),
"Wrong return type of apply().",
bool, ApplyMethod
);
// CHECK: calling method apply
Strategy const* str = 0;
strategy_type const* str = 0;
point_type const* p = 0;
box_type const* bx = 0;
@@ -176,16 +237,22 @@ class WithinStrategyPointBox
public :
BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
{
checker::apply(&Strategy::template apply<Point, Box>);
checker::apply(&strategy_type::template apply<Point, Box>);
}
#endif
};
template <typename Strategy>
template <typename Box1, typename Box2, typename Strategy>
class WithinStrategyBoxBox
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
// 0)
typedef typename concepts::detail::within_strategy_dispatch
<
Box1, Box2, Strategy
>::type strategy_type;
struct checker
{
template <typename ApplyMethod>
@@ -212,20 +279,20 @@ class WithinStrategyBoxBox
);
// CHECK: return types (apply: bool)
BOOST_MPL_ASSERT_MSG
BOOST_GEOMETRY_STATIC_ASSERT
(
(boost::is_same
(std::is_same
<
bool,
typename boost::function_types::result_type<ApplyMethod>::type
>::type::value),
WRONG_RETURN_TYPE
, (bool)
>::value),
"Wrong return type of apply().",
bool, ApplyMethod
);
// CHECK: calling method apply
Strategy const* str = 0;
strategy_type const* str = 0;
box_type1 const* b1 = 0;
box_type2 const* b2 = 0;
@@ -239,7 +306,7 @@ class WithinStrategyBoxBox
public :
BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
{
checker::apply(&Strategy::apply);
checker::apply(&strategy_type::template apply<Box1, Box2>);
}
#endif
};
@@ -270,7 +337,7 @@ template
>
struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
{
BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Strategy>) );
BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Geometry1, Geometry2, Strategy>) );
};
@@ -283,7 +350,7 @@ struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strateg
template <typename Geometry1, typename Geometry2, typename Strategy>
struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
{
BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Strategy>) );
BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Geometry1, Geometry2, Strategy>) );
};

View File

@@ -0,0 +1,77 @@
// Boost.Geometry
// Copyright (c) 2020-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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/convex_hull/services.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace convex_hull
{
template <typename CalculationType = void>
class cartesian : public strategies::detail::cartesian_base
{
public:
template <typename Geometry1, typename Geometry2>
static auto relate(Geometry1 const&, Geometry2 const&,
std::enable_if_t
<
util::is_pointlike<Geometry1>::value
&& util::is_pointlike<Geometry2>::value
> * = nullptr)
{
return strategy::within::cartesian_point_point();
}
static auto side()
{
using side_strategy_type
= strategy::side::side_robust<CalculationType>;
return side_strategy_type();
}
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::cartesian
<
ComparePolicy,
EqualsPolicy,
-1
>;
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, cartesian_tag>
{
using type = strategies::convex_hull::cartesian<>;
};
} // namespace services
}} // namespace strategies::convex_hull
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP

View File

@@ -0,0 +1,92 @@
// Boost.Geometry
// Copyright (c) 2020-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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_GEOGRAPHIC_HPP
#include <boost/geometry/strategies/convex_hull/services.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace convex_hull
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic : public strategies::detail::geographic_base<Spheroid>
{
using base_t = strategies::detail::geographic_base<Spheroid>;
public:
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
template <typename Geometry1, typename Geometry2>
static auto relate(Geometry1 const&, Geometry2 const&,
std::enable_if_t
<
util::is_pointlike<Geometry1>::value
&& util::is_pointlike<Geometry2>::value
> * = nullptr)
{
return strategy::within::spherical_point_point();
}
auto side() const
{
return strategy::side::geographic
<
FormulaPolicy,
Spheroid,
CalculationType
>(base_t::m_spheroid);
}
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::spherical
<
ComparePolicy,
EqualsPolicy,
-1
>;
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, geographic_tag>
{
using type = strategies::convex_hull::geographic<>;
};
} // namespace services
}} // namespace strategies::convex_hull
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,49 @@
// Boost.Geometry
// Copyright (c) 2020, 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_CONVEX_HULL_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/mpl/assert.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace convex_hull {
namespace services
{
template
<
typename Geometry,
typename CSTag = typename geometry::cs_tag<Geometry>::type
>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM
, (types<Geometry, CSTag>)
);
};
} // namespace services
}} // namespace strategies::convex_hull
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_SERVICES_HPP

View File

@@ -0,0 +1,74 @@
// Boost.Geometry
// Copyright (c) 2020-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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_SPHERICAL_HPP
#include <boost/geometry/strategies/convex_hull/services.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace convex_hull
{
template <typename CalculationType = void>
class spherical : public strategies::detail::spherical_base<void>
{
public:
template <typename Geometry1, typename Geometry2>
static auto relate(Geometry1 const&, Geometry2 const&,
std::enable_if_t
<
util::is_pointlike<Geometry1>::value
&& util::is_pointlike<Geometry2>::value
> * = nullptr)
{
return strategy::within::spherical_point_point();
}
static auto side()
{
return strategy::side::spherical_side_formula<CalculationType>();
}
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::spherical
<
ComparePolicy,
EqualsPolicy,
-1
>;
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, spherical_equatorial_tag>
{
using type = strategies::convex_hull::spherical<>;
};
} // namespace services
}} // namespace strategies::convex_hull
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_SPHERICAL_HPP

View File

@@ -4,9 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2017-2020.
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -19,10 +18,10 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
#define BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/tag_cast.hpp>
@@ -78,11 +77,9 @@ template
>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THESE_TYPES
, (types<GeometryContained, GeometryContaining>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for these types.",
GeometryContained, GeometryContaining);
};

View File

@@ -1,41 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020, Oracle and/or its affiliates.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// 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_DEFAULT_AREA_RESULT_HPP
#define BOOST_GEOMETRY_STRATEGIES_DEFAULT_AREA_RESULT_HPP
#include <boost/geometry/strategies/area_result.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
{
/*!
\brief Meta-function defining return type of area function, using the default strategy
\ingroup area
\note The strategy defines the return-type (so this situation is different
from length, where distance is sqr/sqrt, but length always squared)
*/
template <typename Geometry>
struct default_area_result
: area_result<Geometry>
{};
}} // namespace boost::geometry
#include <boost/geometry/algorithms/default_area_result.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_DEFAULT_AREA_RESULT_HPP

View File

@@ -4,10 +4,10 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, 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 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.
@@ -19,13 +19,11 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_DEFAULT_LENGTH_RESULT_HPP
#define BOOST_GEOMETRY_STRATEGIES_DEFAULT_LENGTH_RESULT_HPP
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/select_geometry_type.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/compress_variant.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/util/transform_variant.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
@@ -35,39 +33,38 @@ namespace boost { namespace geometry
namespace resolve_strategy
{
template <typename Geometry>
struct default_length_result
{
typedef typename select_most_precise
<
typename coordinate_type<Geometry>::type,
long double
>::type type;
};
// NOTE: The implementation was simplified greately preserving the old
// behavior. In general case the result types of Strategies should be
// taken into account.
// It would probably be enough to use distance_result and
// default_distance_result here.
} // namespace resolve_strategy
namespace resolve_variant
namespace resolve_dynamic
{
template <typename Sequence>
struct default_length_result_impl;
template <typename ...Geometries>
struct default_length_result_impl<util::type_sequence<Geometries...>>
{
using type = typename select_most_precise
<
typename coordinate_type<Geometries>::type...,
long double
>::type;
};
template <typename Geometry>
struct default_length_result
: resolve_strategy::default_length_result<Geometry>
: default_length_result_impl<typename detail::geometry_types<Geometry>::type>
{};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct default_length_result<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
typedef typename compress_variant<
typename transform_variant<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
resolve_strategy::default_length_result<boost::mpl::placeholders::_>
>::type
>::type type;
};
} // namespace resolve_variant
} // namespace resolve_dynamic
/*!
@@ -80,7 +77,7 @@ struct default_length_result<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
*/
template <typename Geometry>
struct default_length_result
: resolve_variant::default_length_result<Geometry>
: resolve_dynamic::default_length_result<Geometry>
{};

View File

@@ -1,7 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017, Oracle and/or its affiliates.
// Copyright (c) 2017-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
@@ -11,7 +10,7 @@
#define BOOST_GEOMETRY_STRATEGIES_DENSIFY_HPP
#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
@@ -26,11 +25,9 @@ namespace services
template <typename CSTag>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_CS
, (types<CSTag>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this coordinate system.",
CSTag);
};
} // namespace services

View File

@@ -0,0 +1,66 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DENSIFY_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_DENSIFY_CARTESIAN_HPP
#include <boost/geometry/strategies/cartesian/densify.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/densify/services.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace densify
{
template <typename CalculationType = void>
struct cartesian
: public strategies::detail::cartesian_base
{
template <typename Geometry>
static auto densify(Geometry const&)
{
return strategy::densify::cartesian<CalculationType>();
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, cartesian_tag>
{
using type = strategies::densify::cartesian<>;
};
template <typename CT>
struct strategy_converter<strategy::densify::cartesian<CT> >
{
static auto get(strategy::densify::cartesian<CT> const&)
{
return strategies::densify::cartesian<CT>();
}
};
} // namespace services
}} // namespace strategies::densify
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DENSIFY_CARTESIAN_HPP

View File

@@ -0,0 +1,81 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DENSIFY_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_DENSIFY_GEOGRAPHIC_HPP
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/densify/services.hpp>
#include <boost/geometry/strategies/geographic/densify.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace densify
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public strategies::detail::geographic_base<Spheroid>
{
using base_t = strategies::detail::geographic_base<Spheroid>;
public:
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
template <typename Geometry>
auto densify(Geometry const&) const
{
return strategy::densify::geographic
<
FormulaPolicy, Spheroid, CalculationType
>(base_t::m_spheroid);
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, geographic_tag>
{
using type = strategies::densify::geographic<>;
};
template <typename FP, typename S, typename CT>
struct strategy_converter<strategy::densify::geographic<FP, S, CT> >
{
static auto get(strategy::densify::geographic<FP, S, CT> const& s)
{
return strategies::densify::geographic<FP, S, CT>(s.model());
}
};
} // namespace services
}} // namespace strategies::densify
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DENSIFY_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,54 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DENSIFY_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_DENSIFY_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace densify
{
namespace services
{
template
<
typename Geometry,
typename CSTag = typename geometry::cs_tag<Geometry>::type
>
struct default_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Geometry's coordinate systems.",
Geometry, CSTag);
};
template <typename Strategy>
struct strategy_converter
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
} // namespace services
}} // namespace strategies::densify
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DENSIFY_SERVICES_HPP

View File

@@ -0,0 +1,81 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DENSIFY_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_DENSIFY_SPHERICAL_HPP
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/densify/services.hpp>
#include <boost/geometry/strategies/spherical/densify.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace densify
{
template
<
typename RadiusTypeOrSphere = double,
typename CalculationType = void
>
class spherical
: public strategies::detail::spherical_base<RadiusTypeOrSphere>
{
using base_t = strategies::detail::spherical_base<RadiusTypeOrSphere>;
public:
spherical() = default;
template <typename RadiusOrSphere>
explicit spherical(RadiusOrSphere const& radius_or_sphere)
: base_t(radius_or_sphere)
{}
template <typename Geometry>
auto densify(Geometry const&) const
{
return strategy::densify::spherical
<
typename base_t::radius_type, CalculationType
>(base_t::radius());
}
};
namespace services
{
template <typename Geometry>
struct default_strategy<Geometry, spherical_equatorial_tag>
{
using type = strategies::densify::spherical<>;
};
template <typename R, typename CT>
struct strategy_converter<strategy::densify::spherical<R, CT> >
{
static auto get(strategy::densify::spherical<R, CT> const& s)
{
return strategies::densify::spherical<R, CT>(s.radius());
}
};
} // namespace services
}} // namespace strategies::densify
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DENSIFY_SPHERICAL_HPP

View File

@@ -0,0 +1,145 @@
// Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DETAIL_HPP
#define BOOST_GEOMETRY_STRATEGIES_DETAIL_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/spherical/get_radius.hpp>
#include <boost/geometry/srs/sphere.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
struct umbrella_strategy {};
struct not_implemented {};
template <typename Strategy>
struct is_umbrella_strategy
{
static const bool value = std::is_base_of<umbrella_strategy, Strategy>::value;
};
struct cartesian_base : umbrella_strategy
{
typedef cartesian_tag cs_tag;
};
template <typename RadiusTypeOrSphere>
class spherical_base : umbrella_strategy
{
protected:
typedef typename strategy_detail::get_radius
<
RadiusTypeOrSphere
>::type radius_type;
public:
typedef spherical_tag cs_tag;
spherical_base()
: m_radius(1.0)
{}
template <typename RadiusOrSphere>
explicit spherical_base(RadiusOrSphere const& radius_or_sphere)
: m_radius(strategy_detail::get_radius
<
RadiusOrSphere
>::apply(radius_or_sphere))
{}
srs::sphere<radius_type> model() const
{
return srs::sphere<radius_type>(m_radius);
}
protected:
radius_type const& radius() const
{
return m_radius;
}
radius_type m_radius;
};
template <>
class spherical_base<void> : umbrella_strategy
{
protected:
typedef double radius_type;
public:
typedef spherical_tag cs_tag;
srs::sphere<radius_type> model() const
{
return srs::sphere<radius_type>(1.0);
}
protected:
radius_type radius() const
{
return 1.0;
}
};
template <typename Spheroid>
class geographic_base : umbrella_strategy
{
public:
typedef geographic_tag cs_tag;
geographic_base()
: m_spheroid()
{}
explicit geographic_base(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
Spheroid model() const
{
return m_spheroid;
}
protected:
Spheroid m_spheroid;
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
} // namespace strategies
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DETAIL_HPP

View File

@@ -0,0 +1,79 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_CARTESIAN_HPP
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/discrete_distance/services.hpp>
#include <boost/geometry/strategies/distance/comparable.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace discrete_distance
{
template <typename CalculationType = void>
struct cartesian
: public strategies::detail::cartesian_base
{
template <typename Geometry1, typename Geometry2>
static auto distance(Geometry1 const&, Geometry2 const&,
distance::detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr)
{
return strategy::distance::pythagoras<CalculationType>();
}
};
namespace services
{
template <typename Geometry1, typename Geometry2>
struct default_strategy<Geometry1, Geometry2, cartesian_tag, cartesian_tag>
{
using type = strategies::discrete_distance::cartesian<>;
};
template <typename CT>
struct strategy_converter<strategy::distance::pythagoras<CT> >
{
static auto get(strategy::distance::pythagoras<CT> const&)
{
return strategies::discrete_distance::cartesian<CT>();
}
};
template <typename CT>
struct strategy_converter<strategy::distance::comparable::pythagoras<CT> >
{
static auto get(strategy::distance::comparable::pythagoras<CT> const&)
{
return strategies::distance::detail::make_comparable(
strategies::discrete_distance::cartesian<CT>());
}
};
} // namespace services
}} // namespace strategies::discrete_distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_CARTESIAN_HPP

View File

@@ -0,0 +1,115 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_GEOGRAPHIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_GEOGRAPHIC_HPP
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/discrete_distance/services.hpp>
#include <boost/geometry/strategies/distance/comparable.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
// TODO - for backwards compatibility, remove?
#include <boost/geometry/strategies/geographic/distance_andoyer.hpp>
#include <boost/geometry/strategies/geographic/distance_thomas.hpp>
#include <boost/geometry/strategies/geographic/distance_vincenty.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace discrete_distance
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public strategies::detail::geographic_base<Spheroid>
{
using base_t = strategies::detail::geographic_base<Spheroid>;
public:
geographic() = default;
explicit geographic(Spheroid const& spheroid)
: base_t(spheroid)
{}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
distance::detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::geographic
<
FormulaPolicy, Spheroid, CalculationType
>(base_t::m_spheroid);
}
};
namespace services
{
template <typename Geometry1, typename Geometry2>
struct default_strategy<Geometry1, Geometry2, geographic_tag, geographic_tag>
{
using type = strategies::discrete_distance::geographic<>;
};
template <typename FP, typename S, typename CT>
struct strategy_converter<strategy::distance::geographic<FP, S, CT> >
{
static auto get(strategy::distance::geographic<FP, S, CT> const& s)
{
return strategies::discrete_distance::geographic<FP, S, CT>(s.model());
}
};
// TODO - for backwards compatibility, remove?
template <typename S, typename CT>
struct strategy_converter<strategy::distance::andoyer<S, CT> >
{
static auto get(strategy::distance::andoyer<S, CT> const& s)
{
return strategies::discrete_distance::geographic<strategy::andoyer, S, CT>(s.model());
}
};
// TODO - for backwards compatibility, remove?
template <typename S, typename CT>
struct strategy_converter<strategy::distance::thomas<S, CT> >
{
static auto get(strategy::distance::thomas<S, CT> const& s)
{
return strategies::discrete_distance::geographic<strategy::thomas, S, CT>(s.model());
}
};
// TODO - for backwards compatibility, remove?
template <typename S, typename CT>
struct strategy_converter<strategy::distance::vincenty<S, CT> >
{
static auto get(strategy::distance::vincenty<S, CT> const& s)
{
return strategies::discrete_distance::geographic<strategy::vincenty, S, CT>(s.model());
}
};
} // namespace services
}} // namespace strategies::discrete_distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_GEOGRAPHIC_HPP

View File

@@ -0,0 +1,56 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_SERVICES_HPP
#define BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_SERVICES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace discrete_distance
{
namespace services
{
template
<
typename Geometry1,
typename Geometry2,
typename CSTag1 = typename geometry::cs_tag<Geometry1>::type,
typename CSTag2 = typename geometry::cs_tag<Geometry2>::type
>
struct default_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for these Geometries' coordinate systems.",
Geometry1, Geometry2, CSTag1, CSTag2);
};
template <typename Strategy>
struct strategy_converter
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
} // namespace services
}} // namespace strategies::discrete_distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_SERVICES_HPP

View File

@@ -0,0 +1,93 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_SPHERICAL_HPP
#define BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_SPHERICAL_HPP
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/discrete_distance/services.hpp>
#include <boost/geometry/strategies/distance/comparable.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace discrete_distance
{
template
<
typename RadiusTypeOrSphere = double,
typename CalculationType = void
>
class spherical
: public strategies::detail::spherical_base<RadiusTypeOrSphere>
{
using base_t = strategies::detail::spherical_base<RadiusTypeOrSphere>;
public:
spherical() = default;
template <typename RadiusOrSphere>
explicit spherical(RadiusOrSphere const& radius_or_sphere)
: base_t(radius_or_sphere)
{}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
distance::detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::haversine
<
typename base_t::radius_type, CalculationType
>(base_t::radius());
}
};
namespace services
{
template <typename Geometry1, typename Geometry2>
struct default_strategy<Geometry1, Geometry2, spherical_equatorial_tag, spherical_equatorial_tag>
{
using type = strategies::discrete_distance::spherical<>;
};
template <typename R, typename CT>
struct strategy_converter<strategy::distance::haversine<R, CT> >
{
static auto get(strategy::distance::haversine<R, CT> const& s)
{
return strategies::discrete_distance::spherical<R, CT>(s.radius());
}
};
template <typename R, typename CT>
struct strategy_converter<strategy::distance::comparable::haversine<R, CT> >
{
static auto get(strategy::distance::comparable::haversine<R, CT> const& s)
{
return strategies::distance::detail::make_comparable(
strategies::discrete_distance::spherical<R, CT>(s.radius()));
}
};
} // namespace services
}} // namespace strategies::discrete_distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DISCRETE_DISTANCE_SPHERICAL_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Copyright (c) 2017-2020, 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
@@ -12,16 +12,14 @@
#define BOOST_GEOMETRY_STRATEGIES_DISJOINT_HPP
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/relate.hpp>
#include <boost/geometry/strategy/relate.hpp>
namespace boost { namespace geometry { namespace strategy { namespace disjoint

View File

@@ -4,10 +4,10 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, 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 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.
@@ -20,9 +20,8 @@
#define BOOST_GEOMETRY_STRATEGIES_DISTANCE_HPP
#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/strategies/tags.hpp>
@@ -34,36 +33,43 @@ namespace strategy { namespace distance { namespace services
{
template <typename Strategy> struct tag {};
template <typename Strategy> struct tag
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
template <typename Strategy, typename P1, typename P2>
struct return_type
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy, P1, P2>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy, P1, P2);
};
template <typename Strategy> struct comparable_type
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
template <typename Strategy> struct get_comparable
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
template <typename Strategy, typename P1, typename P2>
struct result_from_distance {};
struct result_from_distance
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy, P1, P2);
};
@@ -94,11 +100,9 @@ template
>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE_COMBINATION
, (types<Point1, Point2, CsTag1, CsTag2>)
);
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Point type combination.",
Point1, Point2, CsTag1, CsTag2);
};

View File

@@ -0,0 +1,238 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_BACKWARD_COMPATIBILITY_HPP
#define BOOST_GEOMETRY_STRATEGIES_DISTANCE_BACKWARD_COMPATIBILITY_HPP
#include <boost/geometry/strategies/distance/cartesian.hpp>
#include <boost/geometry/strategies/distance/comparable.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/strategies/distance/geographic.hpp>
#include <boost/geometry/strategies/distance/spherical.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace distance
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template
<
typename Strategy,
typename CSTag,
typename StrategyTag = typename strategy::distance::services::tag<Strategy>::type
>
struct custom_strategy
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Strategy.",
Strategy);
};
// NOTES:
// - There is no guarantee that any of the custom strategies are compatible with other
// strategies.
// - In many cases it is not possible to pass the custom strategy into other strategies.
// - The old backward compatibility code creating default Pt/Seg strategy from custom
// Pt/Pt strategy worked the same way. The custom strategy is default-created.
// - There are two versions of algorithm for Polyseg/Box, one for Seg/Box strategy the
// other one for Pt/Seg strategy. However there is only one version of algorithm for
// Seg/Box taking Seg/Box strategy.
// - Geographic strategies are default-created which means WGS84 spheroid is used.
// - Currently only Pt/Pt custom strategies are supported because this is what the old
// backward compatibility code was addressing.
template <typename Strategy>
struct custom_strategy<Strategy, cartesian_tag, strategy_tag_distance_point_point>
: cartesian<>
{
custom_strategy(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
{
return m_strategy;
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::projected_point<void, Strategy>();
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::pythagoras_point_box<>();
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::cartesian_segment_box<void, Strategy>();
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::pythagoras_box_box<>();
}
private:
Strategy const& m_strategy;
};
template <typename Strategy>
struct custom_strategy<Strategy, spherical_tag, strategy_tag_distance_point_point>
: detail::spherical<void, void>
{
custom_strategy(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
{
return m_strategy;
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::cross_track<void, Strategy>(m_strategy);
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::cross_track_point_box<void, Strategy>(m_strategy);
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::spherical_segment_box<void, Strategy>(m_strategy);
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::cross_track_box_box<void, Strategy>(m_strategy);
}
private:
Strategy const& m_strategy;
};
template <typename Strategy>
struct custom_strategy<Strategy, geographic_tag, strategy_tag_distance_point_point>
: geographic<>
{
custom_strategy(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
{
return m_strategy;
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::geographic_cross_track<>();
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::geographic_cross_track_point_box<>();
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::geographic_segment_box<>();
}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const&, Geometry2 const&,
enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
{
return strategy::distance::geographic_cross_track_box_box<>();
}
private:
Strategy const& m_strategy;
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
namespace services
{
template <typename Geometry1, typename Geometry2, typename Strategy>
struct custom_strategy_converter<Geometry1, Geometry2, Strategy, cartesian_tag, cartesian_tag>
{
static auto get(Strategy const& strategy)
{
return detail::custom_strategy<Strategy, cartesian_tag>(strategy);
}
};
template <typename Geometry1, typename Geometry2, typename Strategy>
struct custom_strategy_converter<Geometry1, Geometry2, Strategy, spherical_equatorial_tag, spherical_equatorial_tag>
{
static auto get(Strategy const& strategy)
{
return detail::custom_strategy<Strategy, spherical_tag>(strategy);
}
};
template <typename Geometry1, typename Geometry2, typename Strategy>
struct custom_strategy_converter<Geometry1, Geometry2, Strategy, geographic_tag, geographic_tag>
{
static auto get(Strategy const& strategy)
{
return detail::custom_strategy<Strategy, geographic_tag>(strategy);
}
};
} // namespace services
}} // namespace strategies::distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_BACKWARD_COMPATIBILITY_HPP

View File

@@ -0,0 +1,175 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_DISTANCE_CARTESIAN_HPP
//#include <boost/geometry/strategies/cartesian/azimuth.hpp>
#include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_segment_box.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/distance/comparable.hpp>
#include <boost/geometry/strategies/distance/detail.hpp>
#include <boost/geometry/strategies/distance/services.hpp>
//#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/relate/cartesian.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace distance
{
template <typename CalculationType = void>
struct cartesian
: public strategies::relate::cartesian<CalculationType>
{
template <typename Geometry1, typename Geometry2>
static auto distance(Geometry1 const&, Geometry2 const&,
detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr)
{
return strategy::distance::pythagoras<CalculationType>();
}
template <typename Geometry1, typename Geometry2>
static auto distance(Geometry1 const&, Geometry2 const&,
detail::enable_if_ps_t<Geometry1, Geometry2> * = nullptr)
{
return strategy::distance::projected_point
<
CalculationType,
strategy::distance::pythagoras<CalculationType>
>();
}
template <typename Geometry1, typename Geometry2>
static auto distance(Geometry1 const&, Geometry2 const&,
detail::enable_if_pb_t<Geometry1, Geometry2> * = nullptr)
{
return strategy::distance::pythagoras_point_box<CalculationType>();
}
template <typename Geometry1, typename Geometry2>
static auto distance(Geometry1 const&, Geometry2 const&,
detail::enable_if_sb_t<Geometry1, Geometry2> * = nullptr)
{
return strategy::distance::cartesian_segment_box
<
CalculationType,
strategy::distance::pythagoras<CalculationType>
>();
}
template <typename Geometry1, typename Geometry2>
static auto distance(Geometry1 const&, Geometry2 const&,
detail::enable_if_bb_t<Geometry1, Geometry2> * = nullptr)
{
return strategy::distance::pythagoras_box_box<CalculationType>();
}
};
namespace services
{
template <typename Geometry1, typename Geometry2>
struct default_strategy<Geometry1, Geometry2, cartesian_tag, cartesian_tag>
{
using type = strategies::distance::cartesian<>;
};
template <typename CT>
struct strategy_converter<strategy::distance::pythagoras<CT> >
{
template <typename S>
static auto get(S const&)
{
return strategies::distance::cartesian<CT>();
}
};
template <typename CT, typename PPS>
struct strategy_converter<strategy::distance::projected_point<CT, PPS> >
: strategy_converter<PPS>
{};
template <typename CT>
struct strategy_converter<strategy::distance::pythagoras_point_box<CT> >
{
static auto get(strategy::distance::pythagoras_point_box<CT> const&)
{
return strategies::distance::cartesian<CT>();
}
};
template <typename CT, typename PPS>
struct strategy_converter<strategy::distance::cartesian_segment_box<CT, PPS> >
: strategy_converter<PPS>
{};
template <typename CT>
struct strategy_converter<strategy::distance::pythagoras_box_box<CT> >
{
static auto get(strategy::distance::pythagoras_box_box<CT> const&)
{
return strategies::distance::cartesian<CT>();
}
};
template <typename CT>
struct strategy_converter<strategy::distance::comparable::pythagoras<CT> >
{
template <typename S>
static auto get(S const&)
{
return strategies::distance::detail::make_comparable(
strategies::distance::cartesian<CT>());
}
};
template <typename CT>
struct strategy_converter<strategy::distance::comparable::pythagoras_point_box<CT> >
{
static auto get(strategy::distance::comparable::pythagoras_point_box<CT> const&)
{
return strategies::distance::detail::make_comparable(
strategies::distance::cartesian<CT>());
}
};
template <typename CT>
struct strategy_converter<strategy::distance::comparable::pythagoras_box_box<CT> >
{
static auto get(strategy::distance::comparable::pythagoras_box_box<CT> const&)
{
return strategies::distance::detail::make_comparable(
strategies::distance::cartesian<CT>());
}
};
} // namespace services
}} // namespace strategies::distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_CARTESIAN_HPP

View File

@@ -0,0 +1,63 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_HPP
#define BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/strategies/distance.hpp>
namespace boost { namespace geometry
{
namespace strategies { namespace distance
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename Strategies>
struct comparable
: public Strategies
{
comparable() = default;
explicit comparable(Strategies const& strategies)
: Strategies(strategies)
{}
template <typename Geometry1, typename Geometry2>
auto distance(Geometry1 const& g1, Geometry2 const& g2) const
{
return strategy::distance::services::get_comparable
<
decltype(Strategies::distance(g1, g2))
>::apply(Strategies::distance(g1, g2));
}
};
template <typename Strategies>
inline comparable<Strategies> make_comparable(Strategies const& strategies)
{
return comparable<Strategies>(strategies);
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace strategies::distance
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_HPP

Some files were not shown because too many files have changed in this diff Show More