point_on_border.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // This file was modified by Oracle on 2017-2022.
  6. // Modifications copyright (c) 2017-2022 Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.Dimension. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
  14. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
  15. #include <cstddef>
  16. #include <boost/range/begin.hpp>
  17. #include <boost/range/end.hpp>
  18. #include <boost/static_assert.hpp>
  19. #include <boost/geometry/algorithms/assign.hpp>
  20. #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
  21. #include <boost/geometry/algorithms/detail/equals/point_point.hpp>
  22. #include <boost/geometry/core/tags.hpp>
  23. #include <boost/geometry/core/point_type.hpp>
  24. #include <boost/geometry/core/ring_type.hpp>
  25. #include <boost/geometry/geometries/concepts/check.hpp>
  26. #include <boost/geometry/util/condition.hpp>
  27. #include <boost/geometry/views/detail/indexed_point_view.hpp>
  28. namespace boost { namespace geometry
  29. {
  30. #ifndef DOXYGEN_NO_DETAIL
  31. namespace detail { namespace point_on_border
  32. {
  33. struct get_point
  34. {
  35. template <typename Destination, typename Source>
  36. static inline bool apply(Destination& destination, Source const& source)
  37. {
  38. detail::conversion::convert_point_to_point(source, destination);
  39. return true;
  40. }
  41. };
  42. struct point_on_range
  43. {
  44. // Version with iterator
  45. template<typename Point, typename Iterator>
  46. static inline bool apply(Point& point, Iterator begin, Iterator end)
  47. {
  48. if (begin == end)
  49. {
  50. return false;
  51. }
  52. detail::conversion::convert_point_to_point(*begin, point);
  53. return true;
  54. }
  55. // Version with range
  56. template<typename Point, typename Range>
  57. static inline bool apply(Point& point, Range const& range)
  58. {
  59. return apply(point, boost::begin(range), boost::end(range));
  60. }
  61. };
  62. struct point_on_polygon
  63. {
  64. template<typename Point, typename Polygon>
  65. static inline bool apply(Point& point, Polygon const& polygon)
  66. {
  67. return point_on_range::apply(point, exterior_ring(polygon));
  68. }
  69. };
  70. struct point_on_segment_or_box
  71. {
  72. template<typename Point, typename SegmentOrBox>
  73. static inline bool apply(Point& point, SegmentOrBox const& segment_or_box)
  74. {
  75. detail::indexed_point_view<SegmentOrBox const, 0> view(segment_or_box);
  76. detail::conversion::convert_point_to_point(view, point);
  77. return true;
  78. }
  79. };
  80. template <typename Policy>
  81. struct point_on_multi
  82. {
  83. template<typename Point, typename MultiGeometry>
  84. static inline bool apply(Point& point, MultiGeometry const& multi)
  85. {
  86. // Take a point on the first multi-geometry
  87. // (i.e. the first that is not empty)
  88. for (auto it = boost::begin(multi); it != boost::end(multi); ++it)
  89. {
  90. if (Policy::apply(point, *it))
  91. {
  92. return true;
  93. }
  94. }
  95. return false;
  96. }
  97. };
  98. }} // namespace detail::point_on_border
  99. #endif // DOXYGEN_NO_DETAIL
  100. #ifndef DOXYGEN_NO_DISPATCH
  101. namespace dispatch
  102. {
  103. template <typename GeometryTag>
  104. struct point_on_border
  105. {};
  106. template <>
  107. struct point_on_border<point_tag>
  108. : detail::point_on_border::get_point
  109. {};
  110. template <>
  111. struct point_on_border<segment_tag>
  112. : detail::point_on_border::point_on_segment_or_box
  113. {};
  114. template <>
  115. struct point_on_border<linestring_tag>
  116. : detail::point_on_border::point_on_range
  117. {};
  118. template <>
  119. struct point_on_border<ring_tag>
  120. : detail::point_on_border::point_on_range
  121. {};
  122. template <>
  123. struct point_on_border<polygon_tag>
  124. : detail::point_on_border::point_on_polygon
  125. {};
  126. template <>
  127. struct point_on_border<box_tag>
  128. : detail::point_on_border::point_on_segment_or_box
  129. {};
  130. template <>
  131. struct point_on_border<multi_point_tag>
  132. : detail::point_on_border::point_on_range
  133. {};
  134. template <>
  135. struct point_on_border<multi_polygon_tag>
  136. : detail::point_on_border::point_on_multi
  137. <
  138. detail::point_on_border::point_on_polygon
  139. >
  140. {};
  141. template <>
  142. struct point_on_border<multi_linestring_tag>
  143. : detail::point_on_border::point_on_multi
  144. <
  145. detail::point_on_border::point_on_range
  146. >
  147. {};
  148. } // namespace dispatch
  149. #endif // DOXYGEN_NO_DISPATCH
  150. // TODO: We should probably rename this utility because it can return point
  151. // which is in the interior of a geometry (for PointLike and LinearRings).
  152. /*!
  153. \brief Take point on a border
  154. \ingroup overlay
  155. \tparam Geometry geometry type. This also defines the type of the output point
  156. \param point to assign
  157. \param geometry geometry to take point from
  158. \return TRUE if successful, else false.
  159. It is only false if polygon/line have no points
  160. \note for a polygon, it is always a point on the exterior ring
  161. */
  162. template <typename Point, typename Geometry>
  163. inline bool point_on_border(Point& point, Geometry const& geometry)
  164. {
  165. concepts::check<Point>();
  166. concepts::check<Geometry const>();
  167. return dispatch::point_on_border
  168. <
  169. typename tag<Geometry>::type
  170. >::apply(point, geometry);
  171. }
  172. }} // namespace boost::geometry
  173. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP