Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:12

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2017-2022 Oracle and/or its affiliates.
0004 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0005 
0006 // Use, modification and distribution is subject to the Boost Software License,
0007 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0008 // http://www.boost.org/LICENSE_1_0.txt)
0009 
0010 
0011 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP
0012 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP
0013 
0014 
0015 #include <boost/geometry/algorithms/detail/covered_by/implementation.hpp>
0016 #include <boost/geometry/core/tags.hpp>
0017 #include <boost/geometry/iterators/point_iterator.hpp>
0018 
0019 
0020 namespace boost { namespace geometry
0021 {
0022 
0023 
0024 #ifndef DOXYGEN_NO_DETAIL
0025 namespace detail { namespace overlay
0026 {
0027 
0028 
0029 template
0030 <
0031     typename Geometry,
0032     typename Tag = typename geometry::tag<Geometry>::type
0033 >
0034 struct points_range
0035 {
0036     typedef geometry::point_iterator<Geometry const> iterator_type;
0037 
0038     explicit points_range(Geometry const& geometry)
0039         : m_geometry(geometry)
0040     {}
0041 
0042     iterator_type begin() const
0043     {
0044         return geometry::points_begin(m_geometry);
0045     }
0046 
0047     iterator_type end() const
0048     {
0049         return geometry::points_end(m_geometry);
0050     }
0051 
0052     Geometry const& m_geometry;
0053 };
0054 // Specialized because point_iterator doesn't support boxes
0055 template <typename Box>
0056 struct points_range<Box, box_tag>
0057 {
0058     typedef typename geometry::point_type<Box>::type point_type;
0059     typedef const point_type * iterator_type;
0060 
0061     explicit points_range(Box const& box)
0062     {
0063         detail::assign_box_corners(box,
0064             m_corners[0], m_corners[1], m_corners[2], m_corners[3]);
0065     }
0066 
0067     iterator_type begin() const
0068     {
0069         return m_corners;
0070     }
0071 
0072     iterator_type end() const
0073     {
0074         return m_corners + 4;
0075     }
0076 
0077     point_type m_corners[4];
0078 };
0079 
0080 template
0081 <
0082     typename Geometry,
0083     typename Tag = typename geometry::tag<Geometry>::type
0084 >
0085 struct point_in_geometry_helper
0086 {
0087     template <typename Point, typename Strategy>
0088     static inline int apply(Point const& point, Geometry const& geometry,
0089                             Strategy const& strategy)
0090     {
0091         return detail::within::point_in_geometry(point, geometry, strategy);
0092     }
0093 };
0094 // Specialized because point_in_geometry doesn't support Boxes
0095 template <typename Box>
0096 struct point_in_geometry_helper<Box, box_tag>
0097 {
0098     template <typename Point, typename Strategy>
0099     static inline int apply(Point const& point, Box const& box,
0100                             Strategy const& strategy)
0101     {
0102         return geometry::covered_by(point, box, strategy) ? 1 : -1;
0103     }
0104 };
0105 
0106 // This function returns
0107 // when it finds a point of geometry1 inside or outside geometry2
0108 template <typename Geometry1, typename Geometry2, typename Strategy>
0109 static inline int range_in_geometry(Geometry1 const& geometry1,
0110                                     Geometry2 const& geometry2,
0111                                     Strategy const& strategy,
0112                                     bool skip_first = false)
0113 {
0114     int result = 0;
0115     points_range<Geometry1> points(geometry1);
0116     typedef typename points_range<Geometry1>::iterator_type iterator_type;
0117     iterator_type const end = points.end();
0118     iterator_type it = points.begin();
0119     if (it == end)
0120     {
0121         return result;
0122     }
0123     else if (skip_first)
0124     {
0125         ++it;
0126     }
0127 
0128     for ( ; it != end; ++it)
0129     {
0130         result = point_in_geometry_helper<Geometry2>::apply(*it, geometry2, strategy);
0131         if (result != 0)
0132         {
0133             return result;
0134         }
0135     }
0136     // all points contained entirely by the boundary
0137     return result;
0138 }
0139 
0140 // This function returns if first_point1 is inside or outside geometry2 or
0141 // when it finds a point of geometry1 inside or outside geometry2
0142 template <typename Point1, typename Geometry1, typename Geometry2, typename Strategy>
0143 inline int range_in_geometry(Point1 const& first_point1,
0144                              Geometry1 const& geometry1,
0145                              Geometry2 const& geometry2,
0146                              Strategy const& strategy)
0147 {
0148     // check a point on border of geometry1 first
0149     int result = point_in_geometry_helper<Geometry2>::apply(first_point1, geometry2, strategy);
0150     if (result == 0)
0151     {
0152         // if a point is on boundary of geometry2
0153         // check points of geometry1 until point inside/outside is found
0154         // NOTE: skip first point because it should be already tested above
0155         result = range_in_geometry(geometry1, geometry2, strategy, true);
0156     }
0157     return result;
0158 }
0159 
0160 
0161 }} // namespace detail::overlay
0162 #endif // DOXYGEN_NO_DETAIL
0163 
0164 
0165 }} // namespace boost::geometry
0166 
0167 
0168 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP