mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-13 10:48:08 +00:00
Added thirdparty: boost library
This commit is contained in:
Vendored
Executable
+28
@@ -0,0 +1,28 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_IMPLEMENTATION_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/distance/implementation.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/point_to_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/multipoint_to_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/linear_to_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/linear_or_areal_to_areal.hpp>
|
||||
//#include <boost/geometry/algorithms/detail/closest_points/linear_to_box.hpp>
|
||||
//#include <boost/geometry/algorithms/detail/closest_points/geometry_to_segment_or_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/segment_to_segment.hpp>
|
||||
//#include <boost/geometry/algorithms/detail/closest_points/segment_to_box.hpp>
|
||||
//#include <boost/geometry/algorithms/detail/closest_points/box_to_box.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/closest_points/cartesian.hpp>
|
||||
#include <boost/geometry/strategies/closest_points/geographic.hpp>
|
||||
#include <boost/geometry/strategies/closest_points/spherical.hpp>
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_IMPLEMENTATION_HPP
|
||||
Vendored
Executable
+225
@@ -0,0 +1,225 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_INTERFACE_HPP
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/closest_points.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/distance/interface.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/closest_points/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1,
|
||||
typename Tag2
|
||||
>
|
||||
struct closest_points
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
Tag1, Tag2, true
|
||||
>
|
||||
: closest_points<Geometry2, Geometry1, Tag2, Tag1, false>
|
||||
{
|
||||
template <typename Segment, typename Strategy>
|
||||
static inline void apply(Geometry1 const& g1, Geometry2 const& g2,
|
||||
Segment& shortest_seg, Strategy const& strategy)
|
||||
{
|
||||
closest_points
|
||||
<
|
||||
Geometry2, Geometry1, Tag2, Tag1, false
|
||||
>::apply(g2, g1, shortest_seg, strategy);
|
||||
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template<typename Strategy>
|
||||
struct closest_points
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Segment>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Segment& shortest_seg,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
dispatch::closest_points
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, shortest_seg, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct closest_points<default_strategy>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Segment>
|
||||
static inline void
|
||||
apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Segment& shortest_seg,
|
||||
default_strategy)
|
||||
{
|
||||
using strategy_type = typename strategies::closest_points::services::default_strategy
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type;
|
||||
|
||||
dispatch::closest_points
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, shortest_seg, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct closest_points
|
||||
{
|
||||
template <typename Segment, typename Strategy>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Segment& shortest_seg,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
resolve_strategy::closest_points
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, shortest_seg, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
//TODO: Add support for DG/GC
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief Calculate the closest points between two geometries \brief_strategy
|
||||
\ingroup closest_points
|
||||
\details
|
||||
\details The free function closest_points calculates the distance between two geometries \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Segment Any type fulfilling a Segment Concept
|
||||
\tparam Strategy \tparam_strategy{Closest Points}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param shortest_seg Output segment containing the closest points
|
||||
\param strategy \param_strategy{closest_points}
|
||||
\note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
|
||||
it may also be a point-segment strategy.
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
|
||||
\qbk{
|
||||
|
||||
[heading Example]
|
||||
[closest_points_strategy]
|
||||
[closest_points_strategy_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.distance distance]
|
||||
}
|
||||
*/
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Segment, typename Strategy>
|
||||
inline void closest_points(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Segment& shortest_seg,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
detail::throw_on_empty_input(geometry1);
|
||||
detail::throw_on_empty_input(geometry2);
|
||||
|
||||
resolve_variant::closest_points
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, shortest_seg, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Compute the closest points between two geometries.
|
||||
\ingroup closest_points
|
||||
\details The free function closest_points calculates the closest points between two geometries. \details_default_strategy
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Segment Any type fulfilling a Segment Concept
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param shortest_seg Output segment containing the closest points
|
||||
|
||||
\qbk{
|
||||
|
||||
[heading Example]
|
||||
[closest_points]
|
||||
[closest_points_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.distance distance]
|
||||
}
|
||||
*/
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Segment>
|
||||
inline void closest_points(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Segment& shortest_seg)
|
||||
{
|
||||
closest_points(geometry1, geometry2, shortest_seg, default_strategy());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_INTERFACE_HPP
|
||||
Vendored
Executable
+261
@@ -0,0 +1,261 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_LINEAR_OR_AREAL_TO_AREAL_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_LINEAR_OR_AREAL_TO_AREAL_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/closest_points/linear_to_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace closest_points
|
||||
{
|
||||
|
||||
struct linear_to_areal
|
||||
{
|
||||
template <typename Linear, typename Areal, typename Segment, typename Strategies>
|
||||
static inline void apply(Linear const& linear,
|
||||
Areal const& areal,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using most_precise_type = typename select_coordinate_type<Linear, Areal>::type;
|
||||
|
||||
using point_type = typename std::conditional
|
||||
<
|
||||
std::is_same<typename coordinate_type<Linear>::type, most_precise_type>::value,
|
||||
typename point_type<Linear>::type,
|
||||
typename point_type<Areal>::type
|
||||
>::type;
|
||||
|
||||
using linestring_type = geometry::model::linestring<point_type>;
|
||||
|
||||
/* TODO: currently intersection does not support some cases of tupled input
|
||||
* such as linestring - multipolygon
|
||||
* this could be implemented directly with dynamic geometries
|
||||
using polygon_type = geometry::model::polygon<point_type>;
|
||||
std::tuple
|
||||
<
|
||||
geometry::model::multi_point<point_type>,
|
||||
geometry::model::multi_linestring<linestring_type>,
|
||||
geometry::model::multi_polygon<polygon_type>
|
||||
> tp;
|
||||
bool intersect_tp = geometry::intersection(linear, areal, tp, strategies);
|
||||
*/
|
||||
|
||||
geometry::model::multi_point<point_type> mp_out;
|
||||
geometry::intersection(linear, areal, mp_out, strategies);
|
||||
|
||||
if (! boost::empty(mp_out))
|
||||
{
|
||||
set_segment_from_points::apply(*boost::begin(mp_out),
|
||||
*boost::begin(mp_out),
|
||||
shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
// if there are no intersection points then check if the linear geometry
|
||||
// (or part of it) is inside the areal and return any point of this part
|
||||
geometry::model::multi_linestring<linestring_type> ln_out;
|
||||
geometry::intersection(linear, areal, ln_out, strategies);
|
||||
|
||||
if (! boost::empty(ln_out))
|
||||
{
|
||||
set_segment_from_points::apply(*boost::begin(*boost::begin(ln_out)),
|
||||
*boost::begin(*boost::begin(ln_out)),
|
||||
shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
linear_to_linear::apply(linear, areal, shortest_seg, strategies, false);
|
||||
}
|
||||
};
|
||||
|
||||
struct areal_to_linear
|
||||
{
|
||||
template <typename Linear, typename Areal, typename Segment, typename Strategies>
|
||||
static inline void apply(Areal const& areal,
|
||||
Linear const& linear,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
linear_to_areal::apply(linear, areal, shortest_seg, strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
struct segment_to_areal
|
||||
{
|
||||
template <typename Segment, typename Areal, typename OutSegment, typename Strategies>
|
||||
static inline void apply(Segment const& segment,
|
||||
Areal const& areal,
|
||||
OutSegment& shortest_seg,
|
||||
Strategies const& strategies,
|
||||
bool = false)
|
||||
{
|
||||
using linestring_type = geometry::model::linestring<typename point_type<Segment>::type>;
|
||||
linestring_type linestring;
|
||||
convert(segment, linestring);
|
||||
linear_to_areal::apply(linestring, areal, shortest_seg, strategies);
|
||||
}
|
||||
};
|
||||
|
||||
struct areal_to_segment
|
||||
{
|
||||
template <typename Areal, typename Segment, typename OutSegment, typename Strategies>
|
||||
static inline void apply(Areal const& areal,
|
||||
Segment const& segment,
|
||||
OutSegment& shortest_seg,
|
||||
Strategies const& strategies,
|
||||
bool = false)
|
||||
{
|
||||
segment_to_areal::apply(segment, areal, shortest_seg, strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
struct areal_to_areal
|
||||
{
|
||||
template <typename Areal1, typename Areal2, typename Segment, typename Strategies>
|
||||
static inline void apply(Areal1 const& areal1,
|
||||
Areal2 const& areal2,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using most_precise_type = typename select_coordinate_type<Areal1, Areal2>::type;
|
||||
|
||||
using point_type = typename std::conditional
|
||||
<
|
||||
std::is_same<typename coordinate_type<Areal1>::type, most_precise_type>::value,
|
||||
typename point_type<Areal1>::type,
|
||||
typename point_type<Areal2>::type
|
||||
>::type;
|
||||
|
||||
using linestring_type = geometry::model::linestring<point_type>;
|
||||
using polygon_type = geometry::model::polygon<point_type>;
|
||||
|
||||
/* TODO: currently intersection does not support tupled input
|
||||
* this should be implemented directly with dynamic geometries
|
||||
*/
|
||||
|
||||
geometry::model::multi_point<point_type> mp_out;
|
||||
geometry::intersection(areal1, areal2, mp_out, strategies);
|
||||
|
||||
if (! boost::empty(mp_out))
|
||||
{
|
||||
set_segment_from_points::apply(*boost::begin(mp_out),
|
||||
*boost::begin(mp_out),
|
||||
shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
// if there are no intersection points then the linear geometry (or part of it)
|
||||
// is inside the areal; return any point of this part
|
||||
geometry::model::multi_linestring<linestring_type> ln_out;
|
||||
geometry::intersection(areal1, areal2, ln_out, strategies);
|
||||
|
||||
if (! boost::empty(ln_out))
|
||||
{
|
||||
set_segment_from_points::apply(*boost::begin(*boost::begin(ln_out)),
|
||||
*boost::begin(*boost::begin(ln_out)),
|
||||
shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
geometry::model::multi_polygon<polygon_type> pl_out;
|
||||
geometry::intersection(areal1, areal2, pl_out, strategies);
|
||||
|
||||
if (! boost::empty(pl_out))
|
||||
{
|
||||
set_segment_from_points::apply(
|
||||
*boost::begin(boost::geometry::exterior_ring(*boost::begin(pl_out))),
|
||||
*boost::begin(boost::geometry::exterior_ring(*boost::begin(pl_out))),
|
||||
shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
linear_to_linear::apply(areal1, areal2, shortest_seg, strategies, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::closest_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Linear, typename Areal>
|
||||
struct closest_points
|
||||
<
|
||||
Linear, Areal,
|
||||
linear_tag, areal_tag,
|
||||
false
|
||||
>
|
||||
: detail::closest_points::linear_to_areal
|
||||
{};
|
||||
|
||||
template <typename Areal, typename Linear>
|
||||
struct closest_points
|
||||
<
|
||||
Areal, Linear,
|
||||
areal_tag, linear_tag,
|
||||
false
|
||||
>
|
||||
: detail::closest_points::areal_to_linear
|
||||
{};
|
||||
|
||||
template <typename Segment, typename Areal>
|
||||
struct closest_points
|
||||
<
|
||||
Segment, Areal,
|
||||
segment_tag, areal_tag,
|
||||
false
|
||||
>
|
||||
: detail::closest_points::segment_to_areal
|
||||
{};
|
||||
|
||||
template <typename Areal, typename Segment>
|
||||
struct closest_points
|
||||
<
|
||||
Areal, Segment,
|
||||
areal_tag, segment_tag,
|
||||
false
|
||||
>
|
||||
: detail::closest_points::areal_to_segment
|
||||
{};
|
||||
|
||||
template <typename Areal1, typename Areal2>
|
||||
struct closest_points
|
||||
<
|
||||
Areal1, Areal2,
|
||||
areal_tag, areal_tag,
|
||||
false
|
||||
>
|
||||
: detail::closest_points::areal_to_areal
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_LINEAR_OR_AREAL_TO_AREAL_HPP
|
||||
Vendored
Executable
+155
@@ -0,0 +1,155 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_LINEAR_TO_LINEAR_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_LINEAR_TO_LINEAR_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/closest_points/range_to_geometry_rtree.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/num_points.hpp>
|
||||
#include <boost/geometry/algorithms/num_segments.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/point_iterator.hpp>
|
||||
#include <boost/geometry/iterators/segment_iterator.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace closest_points
|
||||
{
|
||||
|
||||
|
||||
struct linear_to_linear
|
||||
{
|
||||
template <typename Linear1, typename Linear2, typename Segment, typename Strategies>
|
||||
static inline void apply(Linear1 const& linear1,
|
||||
Linear2 const& linear2,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies,
|
||||
bool = false)
|
||||
{
|
||||
if (geometry::num_points(linear1) == 1)
|
||||
{
|
||||
dispatch::closest_points
|
||||
<
|
||||
typename point_type<Linear1>::type,
|
||||
Linear2
|
||||
>::apply(*points_begin(linear1), linear2, shortest_seg, strategies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (geometry::num_points(linear2) == 1)
|
||||
{
|
||||
dispatch::closest_points
|
||||
<
|
||||
typename point_type<Linear2>::type,
|
||||
Linear1
|
||||
>::apply(*points_begin(linear2), linear1, shortest_seg, strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (geometry::num_segments(linear1) < geometry::num_segments(linear2))
|
||||
{
|
||||
point_or_segment_range_to_geometry_rtree::apply(
|
||||
geometry::segments_begin(linear2),
|
||||
geometry::segments_end(linear2),
|
||||
linear1,
|
||||
shortest_seg,
|
||||
strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
point_or_segment_range_to_geometry_rtree::apply(
|
||||
geometry::segments_begin(linear1),
|
||||
geometry::segments_end(linear1),
|
||||
linear2,
|
||||
shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
struct segment_to_linear
|
||||
{
|
||||
template <typename Segment, typename Linear, typename OutSegment, typename Strategies>
|
||||
static inline void apply(Segment const& segment,
|
||||
Linear const& linear,
|
||||
OutSegment& shortest_seg,
|
||||
Strategies const& strategies,
|
||||
bool = false)
|
||||
{
|
||||
using linestring_type = geometry::model::linestring
|
||||
<typename point_type<Segment>::type>;
|
||||
linestring_type linestring;
|
||||
convert(segment, linestring);
|
||||
linear_to_linear::apply(linestring, linear, shortest_seg, strategies);
|
||||
}
|
||||
};
|
||||
|
||||
struct linear_to_segment
|
||||
{
|
||||
template <typename Linear, typename Segment, typename OutSegment, typename Strategies>
|
||||
static inline void apply(Linear const& linear,
|
||||
Segment const& segment,
|
||||
OutSegment& shortest_seg,
|
||||
Strategies const& strategies,
|
||||
bool = false)
|
||||
{
|
||||
segment_to_linear::apply(segment, linear, shortest_seg, strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::closest_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Linear1, typename Linear2>
|
||||
struct closest_points
|
||||
<
|
||||
Linear1, Linear2,
|
||||
linear_tag, linear_tag,
|
||||
false
|
||||
> : detail::closest_points::linear_to_linear
|
||||
{};
|
||||
|
||||
template <typename Segment, typename Linear>
|
||||
struct closest_points
|
||||
<
|
||||
Segment, Linear,
|
||||
segment_tag, linear_tag,
|
||||
false
|
||||
> : detail::closest_points::segment_to_linear
|
||||
{};
|
||||
|
||||
template <typename Linear, typename Segment>
|
||||
struct closest_points
|
||||
<
|
||||
Linear, Segment,
|
||||
linear_tag, segment_tag,
|
||||
false
|
||||
> : detail::closest_points::linear_to_segment
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_LINEAR_TO_LINEAR_HPP
|
||||
Vendored
Executable
+327
@@ -0,0 +1,327 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_MULTIPOINT_TO_GEOMETRY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_MULTIPOINT_TO_GEOMETRY_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/range/size.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/range_to_geometry_rtree.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/closest_points.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/linestring.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace closest_points
|
||||
{
|
||||
|
||||
|
||||
struct multipoint_to_multipoint
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiPoint1,
|
||||
typename MultiPoint2,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(MultiPoint1 const& multipoint1,
|
||||
MultiPoint2 const& multipoint2,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
if (boost::size(multipoint1) < boost::size(multipoint2))
|
||||
{
|
||||
point_or_segment_range_to_geometry_rtree::apply(
|
||||
boost::begin(multipoint2),
|
||||
boost::end(multipoint2),
|
||||
multipoint1,
|
||||
shortest_seg,
|
||||
strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
return;
|
||||
}
|
||||
point_or_segment_range_to_geometry_rtree::apply(
|
||||
boost::begin(multipoint1),
|
||||
boost::end(multipoint1),
|
||||
multipoint2,
|
||||
shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
struct multipoint_to_linear
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiPoint,
|
||||
typename Linear,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(MultiPoint const& multipoint,
|
||||
Linear const& linear,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
point_or_segment_range_to_geometry_rtree::apply(
|
||||
boost::begin(multipoint),
|
||||
boost::end(multipoint),
|
||||
linear,
|
||||
shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
struct linear_to_multipoint
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Linear,
|
||||
typename MultiPoint,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Linear const& linear,
|
||||
MultiPoint const& multipoint,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
multipoint_to_linear::apply(multipoint, linear, shortest_seg, strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
struct segment_to_multipoint
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Segment,
|
||||
typename MultiPoint,
|
||||
typename OutSegment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Segment const& segment,
|
||||
MultiPoint const& multipoint,
|
||||
OutSegment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using linestring_type = geometry::model::linestring
|
||||
<
|
||||
typename point_type<Segment>::type
|
||||
>;
|
||||
linestring_type linestring;
|
||||
convert(segment, linestring);
|
||||
multipoint_to_linear::apply(multipoint, linestring, shortest_seg, strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
struct multipoint_to_segment
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiPoint,
|
||||
typename Segment,
|
||||
typename OutSegment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(MultiPoint const& multipoint,
|
||||
Segment const& segment,
|
||||
OutSegment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using linestring_type = geometry::model::linestring
|
||||
<
|
||||
typename point_type<Segment>::type
|
||||
>;
|
||||
linestring_type linestring;
|
||||
convert(segment, linestring);
|
||||
multipoint_to_linear::apply(multipoint, linestring, shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct multipoint_to_areal
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
template <typename Areal, typename Strategies>
|
||||
struct covered_by_areal
|
||||
{
|
||||
covered_by_areal(Areal const& areal, Strategies const& strategy)
|
||||
: m_areal(areal), m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
inline bool operator()(Point const& point) const
|
||||
{
|
||||
return geometry::covered_by(point, m_areal, m_strategy);
|
||||
}
|
||||
|
||||
Areal const& m_areal;
|
||||
Strategies const& m_strategy;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiPoint,
|
||||
typename Areal,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(MultiPoint const& multipoint,
|
||||
Areal const& areal,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
covered_by_areal<Areal, Strategies> predicate(areal, strategies);
|
||||
|
||||
auto it = std::find_if(
|
||||
boost::begin(multipoint),
|
||||
boost::end(multipoint),
|
||||
predicate);
|
||||
|
||||
if (it != boost::end(multipoint))
|
||||
{
|
||||
return set_segment_from_points::apply(*it, *it, shortest_seg);
|
||||
|
||||
}
|
||||
|
||||
point_or_segment_range_to_geometry_rtree::apply(
|
||||
boost::begin(multipoint),
|
||||
boost::end(multipoint),
|
||||
areal,
|
||||
shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
struct areal_to_multipoint
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Areal,
|
||||
typename MultiPoint,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Areal const& areal,
|
||||
MultiPoint const& multipoint,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
multipoint_to_areal::apply(multipoint, areal, shortest_seg, strategies);
|
||||
detail::closest_points::swap_segment_points::apply(shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::closest_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2>
|
||||
struct closest_points
|
||||
<
|
||||
MultiPoint1, MultiPoint2,
|
||||
multi_point_tag, multi_point_tag,
|
||||
false
|
||||
> : detail::closest_points::multipoint_to_multipoint
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename Linear>
|
||||
struct closest_points
|
||||
<
|
||||
MultiPoint, Linear,
|
||||
multi_point_tag, linear_tag,
|
||||
false
|
||||
> : detail::closest_points::multipoint_to_linear
|
||||
{};
|
||||
|
||||
|
||||
template <typename Linear, typename MultiPoint>
|
||||
struct closest_points
|
||||
<
|
||||
Linear, MultiPoint,
|
||||
linear_tag, multi_point_tag,
|
||||
false
|
||||
> : detail::closest_points::linear_to_multipoint
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename Segment>
|
||||
struct closest_points
|
||||
<
|
||||
MultiPoint, Segment,
|
||||
multi_point_tag, segment_tag,
|
||||
false
|
||||
> : detail::closest_points::multipoint_to_segment
|
||||
{};
|
||||
|
||||
|
||||
template <typename Segment, typename MultiPoint>
|
||||
struct closest_points
|
||||
<
|
||||
Segment, MultiPoint,
|
||||
segment_tag, multi_point_tag,
|
||||
false
|
||||
> : detail::closest_points::segment_to_multipoint
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename Areal>
|
||||
struct closest_points
|
||||
<
|
||||
MultiPoint, Areal,
|
||||
multi_point_tag, areal_tag,
|
||||
false
|
||||
> : detail::closest_points::multipoint_to_areal
|
||||
{};
|
||||
|
||||
|
||||
template <typename Areal, typename MultiPoint>
|
||||
struct closest_points
|
||||
<
|
||||
Areal, MultiPoint,
|
||||
areal_tag, multi_point_tag,
|
||||
false
|
||||
> : detail::closest_points::areal_to_multipoint
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_MULTIPOINT_TO_GEOMETRY_HPP
|
||||
Vendored
Executable
+456
@@ -0,0 +1,456 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_POINT_TO_GEOMETRY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_POINT_TO_GEOMETRY_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/strategy_utils.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/closest_points.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/radian_access.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
#include <boost/geometry/strategies/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace closest_points
|
||||
{
|
||||
|
||||
struct point_to_point
|
||||
{
|
||||
template <typename P1, typename P2, typename Segment, typename Strategies>
|
||||
static inline void apply(P1 const& p1, P2 const& p2,
|
||||
Segment& shortest_seg, Strategies const&)
|
||||
{
|
||||
set_segment_from_points::apply(p1, p2, shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
struct point_to_segment
|
||||
{
|
||||
template <typename Point, typename Segment, typename OutputSegment, typename Strategies>
|
||||
static inline void apply(Point const& point, Segment const& segment,
|
||||
OutputSegment& shortest_seg, Strategies const& strategies)
|
||||
{
|
||||
typename point_type<Segment>::type p[2];
|
||||
geometry::detail::assign_point_from_index<0>(segment, p[0]);
|
||||
geometry::detail::assign_point_from_index<1>(segment, p[1]);
|
||||
|
||||
boost::ignore_unused(strategies);
|
||||
|
||||
auto closest_point = strategies.closest_points(point, segment)
|
||||
.apply(point, p[0], p[1]);
|
||||
|
||||
set_segment_from_points::apply(point, closest_point, shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
struct point_to_box
|
||||
{
|
||||
template<typename Point, typename Box, typename Strategies>
|
||||
static inline auto apply(Point const& point, Box const& box,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
boost::ignore_unused(strategies);
|
||||
return strategies.closest_points(point, box).apply(point, box);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
template <closure_selector Closure>
|
||||
class point_to_range
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename Point, typename Range, typename Segment, typename Strategies>
|
||||
static inline void apply(Point const& point, Range const& range,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using point_to_point_range = detail::closest_feature::point_to_point_range
|
||||
<
|
||||
Point, Range, Closure
|
||||
>;
|
||||
|
||||
if (boost::size(range) == 0)
|
||||
{
|
||||
set_segment_from_points::apply(point, point, shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
closest_points::creturn_t<Point, Range, Strategies> cd_min;
|
||||
|
||||
auto comparable_distance = strategy::distance::services::get_comparable
|
||||
<
|
||||
decltype(strategies.distance(point, range))
|
||||
>::apply(strategies.distance(point, range));
|
||||
|
||||
auto closest_segment = point_to_point_range::apply(point,
|
||||
boost::begin(range),
|
||||
boost::end(range),
|
||||
comparable_distance,
|
||||
cd_min);
|
||||
|
||||
auto closest_point = strategies.closest_points(point, range)
|
||||
.apply(point, *closest_segment.first, *closest_segment.second);
|
||||
|
||||
set_segment_from_points::apply(point, closest_point, shortest_seg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<closure_selector Closure>
|
||||
struct point_to_ring
|
||||
{
|
||||
template <typename Point, typename Ring, typename Segment, typename Strategies>
|
||||
static inline auto apply(Point const& point,
|
||||
Ring const& ring,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
if (within::within_point_geometry(point, ring, strategies))
|
||||
{
|
||||
set_segment_from_points::apply(point, point, shortest_seg);
|
||||
}
|
||||
else
|
||||
{
|
||||
point_to_range
|
||||
<
|
||||
closure<Ring>::value
|
||||
>::apply(point, ring, shortest_seg, strategies);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <closure_selector Closure>
|
||||
class point_to_polygon
|
||||
{
|
||||
template <typename Polygon>
|
||||
struct distance_to_interior_rings
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename InteriorRingIterator,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Point const& point,
|
||||
InteriorRingIterator first,
|
||||
InteriorRingIterator last,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using per_ring = point_to_range<Closure>;
|
||||
|
||||
for (InteriorRingIterator it = first; it != last; ++it)
|
||||
{
|
||||
if (within::within_point_geometry(point, *it, strategies))
|
||||
{
|
||||
// the point is inside a polygon hole, so its distance
|
||||
// to the polygon is its distance to the polygon's
|
||||
// hole boundary
|
||||
per_ring::apply(point, *it, shortest_seg, strategies);
|
||||
return;
|
||||
}
|
||||
}
|
||||
set_segment_from_points::apply(point, point, shortest_seg);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename InteriorRings,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Point const& point, InteriorRings const& interior_rings,
|
||||
Segment& shortest_seg, Strategies const& strategies)
|
||||
{
|
||||
apply(point,
|
||||
boost::begin(interior_rings),
|
||||
boost::end(interior_rings),
|
||||
shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Polygon,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Point const& point,
|
||||
Polygon const& polygon,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using per_ring = point_to_range<Closure>;
|
||||
|
||||
if (! within::covered_by_point_geometry(point, exterior_ring(polygon),
|
||||
strategies))
|
||||
{
|
||||
// the point is outside the exterior ring, so its distance
|
||||
// to the polygon is its distance to the polygon's exterior ring
|
||||
per_ring::apply(point, exterior_ring(polygon), shortest_seg, strategies);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check interior rings
|
||||
distance_to_interior_rings<Polygon>::apply(point,
|
||||
interior_rings(polygon),
|
||||
shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiGeometry,
|
||||
bool CheckCoveredBy = std::is_same
|
||||
<
|
||||
typename tag<MultiGeometry>::type, multi_polygon_tag
|
||||
>::value
|
||||
>
|
||||
class point_to_multigeometry
|
||||
{
|
||||
private:
|
||||
using geometry_to_range = detail::closest_feature::geometry_to_range;
|
||||
|
||||
public:
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Point const& point,
|
||||
MultiGeometry const& multigeometry,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using selector_type = distance::iterator_selector<MultiGeometry const>;
|
||||
|
||||
closest_points::creturn_t<Point, MultiGeometry, Strategies> cd;
|
||||
|
||||
auto comparable_distance = strategy::distance::services::get_comparable
|
||||
<
|
||||
decltype(strategies.distance(point, multigeometry))
|
||||
>::apply(strategies.distance(point, multigeometry));
|
||||
|
||||
typename selector_type::iterator_type it_min
|
||||
= geometry_to_range::apply(point,
|
||||
selector_type::begin(multigeometry),
|
||||
selector_type::end(multigeometry),
|
||||
comparable_distance,
|
||||
cd);
|
||||
|
||||
dispatch::closest_points
|
||||
<
|
||||
Point,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename selector_type::iterator_type
|
||||
>::value_type
|
||||
>::apply(point, *it_min, shortest_seg, strategies);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// this is called only for multipolygons, hence the change in the
|
||||
// template parameter name MultiGeometry to MultiPolygon
|
||||
template <typename MultiPolygon>
|
||||
struct point_to_multigeometry<MultiPolygon, true>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(Point const& point,
|
||||
MultiPolygon const& multipolygon,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
if (within::covered_by_point_geometry(point, multipolygon, strategies))
|
||||
{
|
||||
set_segment_from_points::apply(point, point, shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
return point_to_multigeometry
|
||||
<
|
||||
MultiPolygon, false
|
||||
>::apply(point, multipolygon, shortest_seg, strategies);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::closest_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename P1, typename P2>
|
||||
struct closest_points
|
||||
<
|
||||
P1, P2, point_tag, point_tag, false
|
||||
> : detail::closest_points::point_to_point
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
struct closest_points
|
||||
<
|
||||
Point, Linestring, point_tag, linestring_tag, false
|
||||
> : detail::closest_points::point_to_range<closed>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Ring>
|
||||
struct closest_points
|
||||
<
|
||||
Point, Ring, point_tag, ring_tag, false
|
||||
> : detail::closest_points::point_to_ring
|
||||
<
|
||||
closure<Ring>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Polygon>
|
||||
struct closest_points
|
||||
<
|
||||
Point, Polygon, point_tag, polygon_tag, false
|
||||
> : detail::closest_points::point_to_polygon
|
||||
<
|
||||
closure<Polygon>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Segment>
|
||||
struct closest_points
|
||||
<
|
||||
Point, Segment, point_tag, segment_tag, false
|
||||
> : detail::closest_points::point_to_segment
|
||||
{};
|
||||
|
||||
/*
|
||||
template <typename Point, typename Box>
|
||||
struct closest_points
|
||||
<
|
||||
Point, Box, point_tag, box_tag,
|
||||
strategy_tag_distance_point_box, false
|
||||
> : detail::closest_points::point_to_box<Point, Box>
|
||||
{};
|
||||
*/
|
||||
|
||||
template<typename Point, typename MultiPoint>
|
||||
struct closest_points
|
||||
<
|
||||
Point, MultiPoint, point_tag, multi_point_tag, false
|
||||
> : detail::closest_points::point_to_multigeometry<MultiPoint>
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point, typename MultiLinestring>
|
||||
struct closest_points
|
||||
<
|
||||
Point, MultiLinestring, point_tag, multi_linestring_tag, false
|
||||
> : detail::closest_points::point_to_multigeometry<MultiLinestring>
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point, typename MultiPolygon>
|
||||
struct closest_points
|
||||
<
|
||||
Point, MultiPolygon, point_tag, multi_polygon_tag, false
|
||||
> : detail::closest_points::point_to_multigeometry<MultiPolygon>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Linear>
|
||||
struct closest_points
|
||||
<
|
||||
Point, Linear, point_tag, linear_tag, false
|
||||
> : closest_points
|
||||
<
|
||||
Point, Linear,
|
||||
point_tag, typename tag<Linear>::type, false
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Areal>
|
||||
struct closest_points
|
||||
<
|
||||
Point, Areal, point_tag, areal_tag, false
|
||||
> : closest_points
|
||||
<
|
||||
Point, Areal,
|
||||
point_tag, typename tag<Areal>::type, false
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_POINT_TO_GEOMETRY_HPP
|
||||
Vendored
Executable
+110
@@ -0,0 +1,110 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_RANGE_TO_GEOMETRY_RTREE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_RANGE_TO_GEOMETRY_RTREE_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/strategy_utils.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/closest_points.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/detail/has_one_element.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace closest_points
|
||||
{
|
||||
|
||||
class point_or_segment_range_to_geometry_rtree
|
||||
{
|
||||
public:
|
||||
|
||||
template
|
||||
<
|
||||
typename PointOrSegmentIterator,
|
||||
typename Geometry,
|
||||
typename Segment,
|
||||
typename Strategies
|
||||
>
|
||||
static inline void apply(PointOrSegmentIterator first,
|
||||
PointOrSegmentIterator last,
|
||||
Geometry const& geometry,
|
||||
Segment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
typedef typename std::iterator_traits
|
||||
<
|
||||
PointOrSegmentIterator
|
||||
>::value_type point_or_segment_type;
|
||||
|
||||
typedef distance::iterator_selector<Geometry const> selector_type;
|
||||
|
||||
typedef detail::closest_feature::range_to_range_rtree range_to_range;
|
||||
|
||||
BOOST_GEOMETRY_ASSERT( first != last );
|
||||
|
||||
//TODO: Is this special case needed?
|
||||
//if ( detail::has_one_element(first, last) )
|
||||
//{
|
||||
// dispatch::closest_points
|
||||
// <
|
||||
// point_or_segment_type, Geometry
|
||||
// >::apply(*first, geometry, shortest_seg, strategies);
|
||||
//}
|
||||
|
||||
closest_points::creturn_t<point_or_segment_type, Geometry, Strategies> cd;
|
||||
|
||||
std::pair
|
||||
<
|
||||
point_or_segment_type,
|
||||
typename selector_type::iterator_type
|
||||
> closest_features
|
||||
= range_to_range::apply(first,
|
||||
last,
|
||||
selector_type::begin(geometry),
|
||||
selector_type::end(geometry),
|
||||
strategies,
|
||||
cd);
|
||||
dispatch::closest_points
|
||||
<
|
||||
point_or_segment_type,
|
||||
typename std::iterator_traits
|
||||
<
|
||||
typename selector_type::iterator_type
|
||||
>::value_type
|
||||
>::apply(closest_features.first,
|
||||
*closest_features.second,
|
||||
shortest_seg,
|
||||
strategies);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::closest_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_RANGE_TO_GEOMETRY_RTREE_HPP
|
||||
Vendored
Executable
+145
@@ -0,0 +1,145 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_SEGMENT_TO_SEGMENT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_SEGMENT_TO_SEGMENT_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/strategy_utils.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/closest_points.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
#include <boost/geometry/strategies/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/condition.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace closest_points
|
||||
{
|
||||
|
||||
|
||||
|
||||
// compute segment-segment closest-points
|
||||
class segment_to_segment
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename Segment1, typename Segment2, typename OutputSegment, typename Strategies>
|
||||
static inline void apply(Segment1 const& segment1, Segment2 const& segment2,
|
||||
OutputSegment& shortest_seg,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using intersection_return_type = segment_intersection_points
|
||||
<
|
||||
typename point_type<Segment1>::type
|
||||
>;
|
||||
|
||||
using intersection_policy = policies::relate::segments_intersection_points
|
||||
<
|
||||
intersection_return_type
|
||||
>;
|
||||
|
||||
detail::segment_as_subrange<Segment1> sub_range1(segment1);
|
||||
detail::segment_as_subrange<Segment2> sub_range2(segment2);
|
||||
auto is = strategies.relate().apply(sub_range1, sub_range2,
|
||||
intersection_policy());
|
||||
if (is.count > 0)
|
||||
{
|
||||
set_segment_from_points::apply(is.intersections[0],
|
||||
is.intersections[0],
|
||||
shortest_seg);
|
||||
return;
|
||||
}
|
||||
|
||||
typename point_type<Segment1>::type p[2];
|
||||
detail::assign_point_from_index<0>(segment1, p[0]);
|
||||
detail::assign_point_from_index<1>(segment1, p[1]);
|
||||
|
||||
typename point_type<Segment2>::type q[2];
|
||||
detail::assign_point_from_index<0>(segment2, q[0]);
|
||||
detail::assign_point_from_index<1>(segment2, q[1]);
|
||||
|
||||
auto cp0 = strategies.closest_points(q[0], segment1).apply(q[0], p[0], p[1]);
|
||||
auto cp1 = strategies.closest_points(q[1], segment1).apply(q[1], p[0], p[1]);
|
||||
auto cp2 = strategies.closest_points(p[0], segment2).apply(p[0], q[0], q[1]);
|
||||
auto cp3 = strategies.closest_points(p[1], segment2).apply(p[1], q[0], q[1]);
|
||||
|
||||
closest_points::creturn_t<Segment1, Segment2, Strategies> d[4];
|
||||
|
||||
auto const cds = strategies::distance::detail::make_comparable(strategies)
|
||||
.distance(detail::dummy_point(), detail::dummy_point());
|
||||
|
||||
d[0] = cds.apply(cp0, q[0]);
|
||||
d[1] = cds.apply(cp1, q[1]);
|
||||
d[2] = cds.apply(p[0], cp2);
|
||||
d[3] = cds.apply(p[1], cp3);
|
||||
|
||||
std::size_t imin = std::distance(boost::addressof(d[0]), std::min_element(d, d + 4));
|
||||
|
||||
switch (imin)
|
||||
{
|
||||
case 0:
|
||||
set_segment_from_points::apply(cp0, q[0], shortest_seg);
|
||||
return;
|
||||
case 1:
|
||||
set_segment_from_points::apply(cp1, q[1], shortest_seg);
|
||||
return;
|
||||
case 2:
|
||||
set_segment_from_points::apply(p[0], cp2, shortest_seg);
|
||||
return;
|
||||
default:
|
||||
set_segment_from_points::apply(p[1], cp3, shortest_seg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::closest_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// segment-segment
|
||||
template <typename Segment1, typename Segment2>
|
||||
struct closest_points
|
||||
<
|
||||
Segment1, Segment2, segment_tag, segment_tag, false
|
||||
> : detail::closest_points::segment_to_segment
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_SEGMENT_TO_SEGMENT_HPP
|
||||
Vendored
Executable
+69
@@ -0,0 +1,69 @@
|
||||
// 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_ALGORITHMS_DETAIL_CLOSEST_POINTS_UTILITIES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_UTILITIES_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
#include <boost/geometry/util/algorithm.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace detail { namespace closest_points
|
||||
{
|
||||
|
||||
struct set_segment_from_points
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Segment>
|
||||
static inline void apply(Point1 const& p1, Point2 const& p2, Segment& segment)
|
||||
{
|
||||
assign_point_to_index<0>(p1, segment);
|
||||
assign_point_to_index<1>(p2, segment);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct swap_segment_points
|
||||
{
|
||||
template <typename Segment>
|
||||
static inline void apply(Segment& segment)
|
||||
{
|
||||
geometry::detail::for_each_dimension<Segment>([&](auto index)
|
||||
{
|
||||
auto temp = get<0,index>(segment);
|
||||
set<0,index>(segment, get<1,index>(segment));
|
||||
set<1,index>(segment, temp);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategies>
|
||||
using distance_strategy_t = decltype(
|
||||
std::declval<Strategies>().distance(std::declval<Geometry1>(), std::declval<Geometry2>()));
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategies>
|
||||
using creturn_t = typename strategy::distance::services::return_type
|
||||
<
|
||||
typename strategy::distance::services::comparable_type
|
||||
<
|
||||
distance_strategy_t<Geometry1, Geometry2, Strategies>
|
||||
>::type,
|
||||
typename point_type<Geometry1>::type,
|
||||
typename point_type<Geometry2>::type
|
||||
>::type;
|
||||
|
||||
|
||||
}} // namespace detail::closest_points
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif //BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_UTILITIES_HPP
|
||||
Reference in New Issue
Block a user