summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp')
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp87
1 files changed, 50 insertions, 37 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp b/boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp
index 82ab3d5d04..d462bb524d 100644
--- a/boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp
@@ -1,6 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2019 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2019-2021 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2022.
+// Modifications copyright (c) 2022 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
@@ -61,53 +65,48 @@ namespace detail_dispatch
template <typename CalculationType, typename CsTag>
struct get_distance_measure
- : not_implemented<CsTag>
+ : not_implemented<CsTag>
{};
template <typename CalculationType>
-struct get_distance_measure<CalculationType, cartesian_tag>
+struct get_distance_measure<CalculationType, spherical_tag>
{
- typedef detail::distance_measure<CalculationType> result_type;
+ // By default the distance measure is zero, no side difference
+ using result_type = detail::distance_measure<CalculationType>;
template <typename SegmentPoint, typename Point>
- static result_type apply(SegmentPoint const& p1, SegmentPoint const& p2,
- Point const& p)
+ static result_type apply(SegmentPoint const& , SegmentPoint const& ,
+ Point const& )
{
- // Get the distance measure / side value
- // It is not a real distance and purpose is
- // to detect small differences in collinearity
-
- typedef model::infinite_line<CalculationType> line_type;
- line_type const line = detail::make::make_infinite_line<CalculationType>(p1, p2);
- result_type result;
- result.measure = arithmetic::side_value(line, p);
+ const result_type result;
return result;
}
};
template <typename CalculationType>
-struct get_distance_measure<CalculationType, spherical_tag>
+struct get_distance_measure<CalculationType, geographic_tag>
+ : get_distance_measure<CalculationType, spherical_tag>
+{};
+
+template <typename CalculationType>
+struct get_distance_measure<CalculationType, cartesian_tag>
{
- typedef detail::distance_measure<CalculationType> result_type;
+ using result_type = detail::distance_measure<CalculationType>;
template <typename SegmentPoint, typename Point>
- static result_type apply(SegmentPoint const& , SegmentPoint const& ,
- Point const& )
+ static result_type apply(SegmentPoint const& p1, SegmentPoint const& p2,
+ Point const& p)
{
- // TODO, optional
+ // Get the distance measure / side value
+ // It is not a real distance and purpose is
+ // to detect small differences in collinearity
+ auto const line = detail::make::make_infinite_line<CalculationType>(p1, p2);
result_type result;
+ result.measure = arithmetic::side_value(line, p);
return result;
}
};
-template <typename CalculationType>
-struct get_distance_measure<CalculationType, geographic_tag>
- : get_distance_measure<CalculationType, spherical_tag> {};
-
-template <typename CalculationType>
-struct get_distance_measure<CalculationType, spherical_equatorial_tag>
- : get_distance_measure<CalculationType, spherical_tag> {};
-
} // namespace detail_dispatch
namespace detail
@@ -117,18 +116,32 @@ namespace detail
// 0 (absolutely 0, not even an epsilon) means collinear. Like side,
// a negative means that p is to the right of p1-p2. And a positive value
// means that p is to the left of p1-p2.
-
-template <typename SegmentPoint, typename Point>
-static distance_measure<typename select_coordinate_type<SegmentPoint, Point>::type>
-get_distance_measure(SegmentPoint const& p1, SegmentPoint const& p2, Point const& p)
+template <typename SegmentPoint, typename Point, typename Strategies>
+inline auto get_distance_measure(SegmentPoint const& p1, SegmentPoint const& p2, Point const& p,
+ Strategies const&)
{
- typedef typename geometry::cs_tag<Point>::type cs_tag;
- return detail_dispatch::get_distance_measure
- <
- typename select_coordinate_type<SegmentPoint, Point>::type,
- cs_tag
- >::apply(p1, p2, p);
+ using calc_t = typename select_coordinate_type<SegmentPoint, Point>::type;
+
+ // Verify equality, without using a tolerance
+ // (so don't use equals or equals_point_point)
+ // because it is about very tiny differences.
+ auto identical = [](const auto& point1, const auto& point2)
+ {
+ return geometry::get<0>(point1) == geometry::get<0>(point2)
+ && geometry::get<1>(point1) == geometry::get<1>(point2);
+ };
+ if (identical(p1, p) || identical(p2, p))
+ {
+ detail::distance_measure<calc_t> const result;
+ return result;
+ }
+
+ return detail_dispatch::get_distance_measure
+ <
+ calc_t,
+ typename Strategies::cs_tag
+ >::apply(p1, p2, p);
}
} // namespace detail