polygon.hpp 9.0 KB

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