1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. 6 7 // This file was modified by Oracle on 2014-2020. 8 // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates. 9 10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 11 12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 14 15 // Use, modification and distribution is subject to the Boost Software License, 16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 17 // http://www.boost.org/LICENSE_1_0.txt) 18 19 #ifndef BOOST_GEOMETRY_CORE_POINT_ORDER_HPP 20 #define BOOST_GEOMETRY_CORE_POINT_ORDER_HPP 21 22 23 #include <boost/range/value_type.hpp> 24 25 #include <boost/geometry/core/ring_type.hpp> 26 #include <boost/geometry/core/static_assert.hpp> 27 #include <boost/geometry/core/tag.hpp> 28 #include <boost/geometry/core/tags.hpp> 29 #include <boost/geometry/util/type_traits_std.hpp> 30 31 namespace boost { namespace geometry 32 { 33 34 /*! 35 \brief Enumerates options for the order of points within polygons 36 \ingroup enum 37 \details The enumeration order_selector describes options for the order of 38 points within a polygon. Polygons can be ordered either clockwise or 39 counterclockwise. The specific order of a polygon type is defined by the 40 point_order metafunction. The point_order metafunction defines a value, 41 which is one of the values enumerated in the order_selector 42 43 \qbk{ 44 [heading See also] 45 [link geometry.reference.core.point_order The point_order metafunction] 46 } 47 */ 48 enum order_selector 49 { 50 /// Points are ordered clockwise 51 clockwise = 1, 52 /// Points are ordered counter clockwise 53 counterclockwise = 2, 54 /// Points might be stored in any order, algorithms will determine it on the 55 /// fly (not yet supported) 56 order_undetermined = 0 57 }; 58 59 namespace traits 60 { 61 62 /*! 63 \brief Traits class indicating the order of contained points within a 64 ring or (multi)polygon, clockwise, counter clockwise or not known. 65 \ingroup traits 66 \tparam Ring ring 67 */ 68 template <typename Ring> 69 struct point_order 70 { 71 static const order_selector value = clockwise; 72 }; 73 74 75 } // namespace traits 76 77 78 #ifndef DOXYGEN_NO_DETAIL 79 namespace detail { namespace point_order 80 { 81 82 struct clockwise 83 { 84 static const order_selector value = geometry::clockwise; 85 }; 86 87 88 }} // namespace detail::point_order 89 #endif // DOXYGEN_NO_DETAIL 90 91 92 93 #ifndef DOXYGEN_NO_DISPATCH 94 namespace core_dispatch 95 { 96 97 template <typename Tag, typename Geometry> 98 struct point_order 99 { 100 BOOST_GEOMETRY_STATIC_ASSERT_FALSE( 101 "Not implemented for this Geometry type.", 102 Geometry); 103 }; 104 105 template <typename Point> 106 struct point_order<point_tag, Point> 107 : public detail::point_order::clockwise {}; 108 109 template <typename Segment> 110 struct point_order<segment_tag, Segment> 111 : public detail::point_order::clockwise {}; 112 113 114 template <typename Box> 115 struct point_order<box_tag, Box> 116 : public detail::point_order::clockwise {}; 117 118 template <typename LineString> 119 struct point_order<linestring_tag, LineString> 120 : public detail::point_order::clockwise {}; 121 122 123 template <typename Ring> 124 struct point_order<ring_tag, Ring> 125 { 126 static const order_selector value 127 = geometry::traits::point_order<Ring>::value; 128 }; 129 130 // Specialization for polygon: the order is the order of its rings 131 template <typename Polygon> 132 struct point_order<polygon_tag, Polygon> 133 { 134 static const order_selector value = core_dispatch::point_order 135 < 136 ring_tag, 137 typename ring_type<polygon_tag, Polygon>::type 138 >::value ; 139 }; 140 141 template <typename MultiPoint> 142 struct point_order<multi_point_tag, MultiPoint> 143 : public detail::point_order::clockwise {}; 144 145 template <typename MultiLinestring> 146 struct point_order<multi_linestring_tag, MultiLinestring> 147 : public detail::point_order::clockwise {}; 148 149 150 // Specialization for multi_polygon: the order is the order of its polygons 151 template <typename MultiPolygon> 152 struct point_order<multi_polygon_tag, MultiPolygon> 153 { 154 static const order_selector value = core_dispatch::point_order 155 < 156 polygon_tag, 157 typename boost::range_value<MultiPolygon>::type 158 >::value ; 159 }; 160 161 } // namespace core_dispatch 162 #endif // DOXYGEN_NO_DISPATCH 163 164 165 /*! 166 \brief \brief_meta{value, point order (clockwise\, counterclockwise), 167 \meta_geometry_type} 168 \tparam Geometry \tparam_geometry 169 \ingroup core 170 171 \qbk{[include reference/core/point_order.qbk]} 172 */ 173 template <typename Geometry> 174 struct point_order 175 { 176 static const order_selector value = core_dispatch::point_order 177 < 178 typename tag<Geometry>::type, 179 typename util::remove_cptrref<Geometry>::type 180 >::value; 181 }; 182 183 }} // namespace boost::geometry 184 185 #endif // BOOST_GEOMETRY_CORE_POINT_ORDER_HPP 186