Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:43

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
0004 // Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
0005 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
0006 
0007 // This file was modified by Oracle on 2014-2021.
0008 // Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
0009 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0010 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0011 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0012 
0013 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0014 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0015 
0016 // Use, modification and distribution is subject to the Boost Software License,
0017 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0018 // http://www.boost.org/LICENSE_1_0.txt)
0019 
0020 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
0021 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
0022 
0023 
0024 #include <type_traits>
0025 
0026 #include <boost/concept_check.hpp>
0027 #include <boost/core/ignore_unused.hpp>
0028 
0029 #include <boost/geometry/core/access.hpp>
0030 #include <boost/geometry/core/point_type.hpp>
0031 
0032 #include <boost/geometry/algorithms/convert.hpp>
0033 #include <boost/geometry/arithmetic/arithmetic.hpp>
0034 #include <boost/geometry/arithmetic/dot_product.hpp>
0035 
0036 #include <boost/geometry/strategies/tags.hpp>
0037 #include <boost/geometry/strategies/distance.hpp>
0038 #include <boost/geometry/strategies/default_distance_result.hpp>
0039 #include <boost/geometry/strategies/cartesian/closest_points_pt_seg.hpp>
0040 #include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
0041 #include <boost/geometry/strategies/cartesian/point_in_point.hpp>
0042 #include <boost/geometry/strategies/cartesian/intersection.hpp>
0043 
0044 // Helper geometry (projected point on line)
0045 #include <boost/geometry/geometries/point.hpp>
0046 
0047 
0048 namespace boost { namespace geometry
0049 {
0050 
0051 
0052 namespace strategy { namespace distance
0053 {
0054 
0055 /*!
0056 \brief Strategy for distance point to segment
0057 \ingroup strategies
0058 \details Calculates distance using projected-point method, and (optionally) Pythagoras
0059 \author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
0060 \tparam CalculationType \tparam_calculation
0061 \tparam Strategy underlying point-point distance strategy
0062 \par Concepts for Strategy:
0063 - cartesian_distance operator(Point,Point)
0064 \note If the Strategy is a "comparable::pythagoras", this strategy
0065     automatically is a comparable projected_point strategy (so without sqrt)
0066 
0067 \qbk{
0068 [heading See also]
0069 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
0070 }
0071 
0072 */
0073 template
0074 <
0075     typename CalculationType = void,
0076     typename Strategy = pythagoras<CalculationType>
0077 >
0078 class projected_point
0079 {
0080 public:
0081     // The three typedefs below are necessary to calculate distances
0082     // from segments defined in integer coordinates.
0083 
0084     // Integer coordinates can still result in FP distances.
0085     // There is a division, which must be represented in FP.
0086     // So promote.
0087     template <typename Point, typename PointOfSegment>
0088     struct calculation_type
0089         : promote_floating_point
0090           <
0091               typename strategy::distance::services::return_type
0092                   <
0093                       Strategy,
0094                       Point,
0095                       PointOfSegment
0096                   >::type
0097           >
0098     {};
0099 
0100     template <typename Point, typename PointOfSegment>
0101     inline typename calculation_type<Point, PointOfSegment>::type
0102     apply(Point const& p, PointOfSegment const& p1, PointOfSegment const& p2) const
0103     {
0104         assert_dimension_equal<Point, PointOfSegment>();
0105 
0106         typedef typename calculation_type<Point, PointOfSegment>::type calculation_type;
0107 
0108         auto closest_point = closest_points::detail::compute_closest_point_to_segment
0109             <calculation_type>::apply(p, p1, p2);
0110 
0111         return Strategy().apply(p, closest_point);
0112     }
0113 
0114     template <typename CT>
0115     inline CT vertical_or_meridian(CT const& lat1, CT const& lat2) const
0116     {
0117         return lat1 - lat2;
0118     }
0119 
0120 };
0121 
0122 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0123 namespace services
0124 {
0125 
0126 template <typename CalculationType, typename Strategy>
0127 struct tag<projected_point<CalculationType, Strategy> >
0128 {
0129     typedef strategy_tag_distance_point_segment type;
0130 };
0131 
0132 
0133 template <typename CalculationType, typename Strategy, typename P, typename PS>
0134 struct return_type<projected_point<CalculationType, Strategy>, P, PS>
0135     : projected_point<CalculationType, Strategy>::template calculation_type<P, PS>
0136 {};
0137 
0138 
0139 
0140 template <typename CalculationType, typename Strategy>
0141 struct comparable_type<projected_point<CalculationType, Strategy> >
0142 {
0143     // Define a projected_point strategy with its underlying point-point-strategy
0144     // being comparable
0145     typedef projected_point
0146         <
0147             CalculationType,
0148             typename comparable_type<Strategy>::type
0149         > type;
0150 };
0151 
0152 
0153 template <typename CalculationType, typename Strategy>
0154 struct get_comparable<projected_point<CalculationType, Strategy> >
0155 {
0156     typedef typename comparable_type
0157         <
0158             projected_point<CalculationType, Strategy>
0159         >::type comparable_type;
0160 public :
0161     static inline comparable_type apply(projected_point<CalculationType, Strategy> const& )
0162     {
0163         return comparable_type();
0164     }
0165 };
0166 
0167 
0168 template <typename CalculationType, typename Strategy, typename P, typename PS>
0169 struct result_from_distance<projected_point<CalculationType, Strategy>, P, PS>
0170 {
0171 private :
0172     typedef typename return_type<projected_point<CalculationType, Strategy>, P, PS>::type return_type;
0173 public :
0174     template <typename T>
0175     static inline return_type apply(projected_point<CalculationType, Strategy> const& , T const& value)
0176     {
0177         Strategy s;
0178         return result_from_distance<Strategy, P, PS>::apply(s, value);
0179     }
0180 };
0181 
0182 
0183 // Get default-strategy for point-segment distance calculation
0184 // while still have the possibility to specify point-point distance strategy (PPS)
0185 // It is used in algorithms/distance.hpp where users specify PPS for distance
0186 // of point-to-segment or point-to-linestring.
0187 // Convenient for geographic coordinate systems especially.
0188 template <typename Point, typename PointOfSegment, typename Strategy>
0189 struct default_strategy
0190     <
0191         point_tag, segment_tag, Point, PointOfSegment,
0192         cartesian_tag, cartesian_tag, Strategy
0193     >
0194 {
0195     typedef strategy::distance::projected_point
0196         <
0197             void,
0198             std::conditional_t
0199                 <
0200                     std::is_void<Strategy>::value,
0201                     typename default_strategy
0202                         <
0203                             point_tag, point_tag, Point, PointOfSegment,
0204                             cartesian_tag, cartesian_tag
0205                         >::type,
0206                     Strategy
0207                 >
0208         > type;
0209 };
0210 
0211 template <typename PointOfSegment, typename Point, typename Strategy>
0212 struct default_strategy
0213     <
0214         segment_tag, point_tag, PointOfSegment, Point,
0215         cartesian_tag, cartesian_tag, Strategy
0216     >
0217 {
0218     typedef typename default_strategy
0219         <
0220             point_tag, segment_tag, Point, PointOfSegment,
0221             cartesian_tag, cartesian_tag, Strategy
0222         >::type type;
0223 };
0224 
0225 
0226 } // namespace services
0227 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0228 
0229 
0230 }} // namespace strategy::distance
0231 
0232 
0233 }} // namespace boost::geometry
0234 
0235 
0236 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP