polygon.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. // Copyright (c) 2014-2018 Adam Wulkiewicz, Lodz, Poland.
  6. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  7. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  8. // Use, modification and distribution is subject to the Boost Software License,
  9. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #ifndef BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP
  12. #define BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP
  13. #include <memory>
  14. #include <vector>
  15. #include <boost/concept/assert.hpp>
  16. #include <boost/geometry/core/exterior_ring.hpp>
  17. #include <boost/geometry/core/interior_rings.hpp>
  18. #include <boost/geometry/core/point_type.hpp>
  19. #include <boost/geometry/core/ring_type.hpp>
  20. #include <boost/geometry/geometries/concepts/point_concept.hpp>
  21. #include <boost/geometry/geometries/ring.hpp>
  22. #include <boost/config.hpp>
  23. #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
  24. #include <initializer_list>
  25. #endif
  26. namespace boost { namespace geometry
  27. {
  28. namespace model
  29. {
  30. /*!
  31. \brief The polygon contains an outer ring and zero or more inner rings.
  32. \ingroup geometries
  33. \tparam Point point type
  34. \tparam ClockWise true for clockwise direction,
  35. false for CounterClockWise direction
  36. \tparam Closed true for closed polygons (last point == first point),
  37. false open points
  38. \tparam PointList container type for points,
  39. for example std::vector, std::deque
  40. \tparam RingList container type for inner rings,
  41. for example std::vector, std::deque
  42. \tparam PointAlloc container-allocator-type, for the points
  43. \tparam RingAlloc container-allocator-type, for the rings
  44. \note The container collecting the points in the rings can be different
  45. from the container collecting the inner rings. They all default to vector.
  46. \qbk{[include reference/geometries/polygon.qbk]}
  47. \qbk{before.synopsis,
  48. [heading Model of]
  49. [link geometry.reference.concepts.concept_polygon Polygon Concept]
  50. }
  51. */
  52. template
  53. <
  54. typename Point,
  55. bool ClockWise = true,
  56. bool Closed = true,
  57. template<typename, typename> class PointList = std::vector,
  58. template<typename, typename> class RingList = std::vector,
  59. template<typename> class PointAlloc = std::allocator,
  60. template<typename> class RingAlloc = std::allocator
  61. >
  62. class polygon
  63. {
  64. BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
  65. public:
  66. // Member types
  67. typedef Point point_type;
  68. typedef ring<Point, ClockWise, Closed, PointList, PointAlloc> ring_type;
  69. typedef RingList<ring_type , RingAlloc<ring_type > > inner_container_type;
  70. inline ring_type const& outer() const { return m_outer; }
  71. inline inner_container_type const& inners() const { return m_inners; }
  72. inline ring_type& outer() { return m_outer; }
  73. inline inner_container_type & inners() { return m_inners; }
  74. #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
  75. // default constructor definition is required only
  76. // if the constructor taking std::initializer_list is defined
  77. /// \constructor_default{polygon}
  78. inline polygon()
  79. : m_outer()
  80. , m_inners()
  81. {}
  82. /// \constructor_initializer_list{polygon}
  83. inline polygon(std::initializer_list<ring_type> l)
  84. : m_outer(l.size() > 0 ? *l.begin() : ring_type())
  85. , m_inners(l.size() > 0 ? l.begin() + 1 : l.begin(), l.end())
  86. {}
  87. // Commented out for now in order to support Boost.Assign
  88. // Without this assignment operator first the object should be created
  89. // from initializer list, then it shoudl be moved.
  90. //// Without this workaround in MSVC the assignment operator is ambiguous
  91. //#ifndef BOOST_MSVC
  92. // /// \assignment_initializer_list{polygon}
  93. // inline polygon & operator=(std::initializer_list<ring_type> l)
  94. // {
  95. // if ( l.size() > 0 )
  96. // {
  97. // m_outer = *l.begin();
  98. // m_inners.assign(l.begin() + 1, l.end());
  99. // }
  100. // else
  101. // {
  102. // m_outer.clear();
  103. // m_inners.clear();
  104. // }
  105. // return *this;
  106. // }
  107. //#endif
  108. #endif
  109. /// Utility method, clears outer and inner rings
  110. inline void clear()
  111. {
  112. m_outer.clear();
  113. m_inners.clear();
  114. }
  115. private:
  116. ring_type m_outer;
  117. inner_container_type m_inners;
  118. };
  119. } // namespace model
  120. #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
  121. namespace traits
  122. {
  123. template
  124. <
  125. typename Point,
  126. bool ClockWise, bool Closed,
  127. template<typename, typename> class PointList,
  128. template<typename, typename> class RingList,
  129. template<typename> class PointAlloc,
  130. template<typename> class RingAlloc
  131. >
  132. struct tag
  133. <
  134. model::polygon
  135. <
  136. Point, ClockWise, Closed,
  137. PointList, RingList, PointAlloc, RingAlloc
  138. >
  139. >
  140. {
  141. typedef polygon_tag type;
  142. };
  143. template
  144. <
  145. typename Point,
  146. bool ClockWise, bool Closed,
  147. template<typename, typename> class PointList,
  148. template<typename, typename> class RingList,
  149. template<typename> class PointAlloc,
  150. template<typename> class RingAlloc
  151. >
  152. struct ring_const_type
  153. <
  154. model::polygon
  155. <
  156. Point, ClockWise, Closed,
  157. PointList, RingList, PointAlloc, RingAlloc
  158. >
  159. >
  160. {
  161. typedef typename model::polygon
  162. <
  163. Point, ClockWise, Closed,
  164. PointList, RingList,
  165. PointAlloc, RingAlloc
  166. >::ring_type const& type;
  167. };
  168. template
  169. <
  170. typename Point,
  171. bool ClockWise, bool Closed,
  172. template<typename, typename> class PointList,
  173. template<typename, typename> class RingList,
  174. template<typename> class PointAlloc,
  175. template<typename> class RingAlloc
  176. >
  177. struct ring_mutable_type
  178. <
  179. model::polygon
  180. <
  181. Point, ClockWise, Closed,
  182. PointList, RingList, PointAlloc, RingAlloc
  183. >
  184. >
  185. {
  186. typedef typename model::polygon
  187. <
  188. Point, ClockWise, Closed,
  189. PointList, RingList,
  190. PointAlloc, RingAlloc
  191. >::ring_type& type;
  192. };
  193. template
  194. <
  195. typename Point,
  196. bool ClockWise, bool Closed,
  197. template<typename, typename> class PointList,
  198. template<typename, typename> class RingList,
  199. template<typename> class PointAlloc,
  200. template<typename> class RingAlloc
  201. >
  202. struct interior_const_type
  203. <
  204. model::polygon
  205. <
  206. Point, ClockWise, Closed,
  207. PointList, RingList,
  208. PointAlloc, RingAlloc
  209. >
  210. >
  211. {
  212. typedef typename model::polygon
  213. <
  214. Point, ClockWise, Closed,
  215. PointList, RingList,
  216. PointAlloc, RingAlloc
  217. >::inner_container_type const& type;
  218. };
  219. template
  220. <
  221. typename Point,
  222. bool ClockWise, bool Closed,
  223. template<typename, typename> class PointList,
  224. template<typename, typename> class RingList,
  225. template<typename> class PointAlloc,
  226. template<typename> class RingAlloc
  227. >
  228. struct interior_mutable_type
  229. <
  230. model::polygon
  231. <
  232. Point, ClockWise, Closed,
  233. PointList, RingList,
  234. PointAlloc, RingAlloc
  235. >
  236. >
  237. {
  238. typedef typename model::polygon
  239. <
  240. Point, ClockWise, Closed,
  241. PointList, RingList,
  242. PointAlloc, RingAlloc
  243. >::inner_container_type& type;
  244. };
  245. template
  246. <
  247. typename Point,
  248. bool ClockWise, bool Closed,
  249. template<typename, typename> class PointList,
  250. template<typename, typename> class RingList,
  251. template<typename> class PointAlloc,
  252. template<typename> class RingAlloc
  253. >
  254. struct exterior_ring
  255. <
  256. model::polygon
  257. <
  258. Point, ClockWise, Closed,
  259. PointList, RingList, PointAlloc, RingAlloc
  260. >
  261. >
  262. {
  263. typedef model::polygon
  264. <
  265. Point, ClockWise, Closed,
  266. PointList, RingList,
  267. PointAlloc, RingAlloc
  268. > polygon_type;
  269. static inline typename polygon_type::ring_type& get(polygon_type& p)
  270. {
  271. return p.outer();
  272. }
  273. static inline typename polygon_type::ring_type const& get(
  274. polygon_type const& p)
  275. {
  276. return p.outer();
  277. }
  278. };
  279. template
  280. <
  281. typename Point,
  282. bool ClockWise, bool Closed,
  283. template<typename, typename> class PointList,
  284. template<typename, typename> class RingList,
  285. template<typename> class PointAlloc,
  286. template<typename> class RingAlloc
  287. >
  288. struct interior_rings
  289. <
  290. model::polygon
  291. <
  292. Point, ClockWise, Closed,
  293. PointList, RingList,
  294. PointAlloc, RingAlloc
  295. >
  296. >
  297. {
  298. typedef model::polygon
  299. <
  300. Point, ClockWise, Closed, PointList, RingList,
  301. PointAlloc, RingAlloc
  302. > polygon_type;
  303. static inline typename polygon_type::inner_container_type& get(
  304. polygon_type& p)
  305. {
  306. return p.inners();
  307. }
  308. static inline typename polygon_type::inner_container_type const& get(
  309. polygon_type const& p)
  310. {
  311. return p.inners();
  312. }
  313. };
  314. } // namespace traits
  315. #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
  316. }} // namespace boost::geometry
  317. #endif // BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP