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. 8 // Modifications copyright (c) 2014 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/mpl/assert.hpp> 24 #include <boost/range/value_type.hpp> 25 26 #include <boost/geometry/core/ring_type.hpp> 27 #include <boost/geometry/core/tag.hpp> 28 #include <boost/geometry/core/tags.hpp> 29 #include <boost/geometry/util/bare_type.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_MPL_ASSERT_MSG 101 ( 102 false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE 103 , (types<Geometry>) 104 ); 105 }; 106 107 template <typename Point> 108 struct point_order<point_tag, Point> 109 : public detail::point_order::clockwise {}; 110 111 template <typename Segment> 112 struct point_order<segment_tag, Segment> 113 : public detail::point_order::clockwise {}; 114 115 116 template <typename Box> 117 struct point_order<box_tag, Box> 118 : public detail::point_order::clockwise {}; 119 120 template <typename LineString> 121 struct point_order<linestring_tag, LineString> 122 : public detail::point_order::clockwise {}; 123 124 125 template <typename Ring> 126 struct point_order<ring_tag, Ring> 127 { 128 static const order_selector value 129 = geometry::traits::point_order<Ring>::value; 130 }; 131 132 // Specialization for polygon: the order is the order of its rings 133 template <typename Polygon> 134 struct point_order<polygon_tag, Polygon> 135 { 136 static const order_selector value = core_dispatch::point_order 137 < 138 ring_tag, 139 typename ring_type<polygon_tag, Polygon>::type 140 >::value ; 141 }; 142 143 template <typename MultiPoint> 144 struct point_order<multi_point_tag, MultiPoint> 145 : public detail::point_order::clockwise {}; 146 147 template <typename MultiLinestring> 148 struct point_order<multi_linestring_tag, MultiLinestring> 149 : public detail::point_order::clockwise {}; 150 151 152 // Specialization for multi_polygon: the order is the order of its polygons 153 template <typename MultiPolygon> 154 struct point_order<multi_polygon_tag, MultiPolygon> 155 { 156 static const order_selector value = core_dispatch::point_order 157 < 158 polygon_tag, 159 typename boost::range_value<MultiPolygon>::type 160 >::value ; 161 }; 162 163 } // namespace core_dispatch 164 #endif // DOXYGEN_NO_DISPATCH 165 166 167 /*! 168 \brief \brief_meta{value, point order (clockwise\, counterclockwise), 169 \meta_geometry_type} 170 \tparam Geometry \tparam_geometry 171 \ingroup core 172 173 \qbk{[include reference/core/point_order.qbk]} 174 */ 175 template <typename Geometry> 176 struct point_order 177 { 178 static const order_selector value = core_dispatch::point_order 179 < 180 typename tag<Geometry>::type, 181 typename util::bare_type<Geometry>::type 182 >::value; 183 }; 184 185 }} // namespace boost::geometry 186 187 #endif // BOOST_GEOMETRY_CORE_POINT_ORDER_HPP 188