1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2015, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 6 7 // Licensed under the Boost Software License version 1.0. 8 // http://www.boost.org/users/license.html 9 10 #ifndef BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP 11 #define BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP 12 13 #include <boost/geometry/core/cs.hpp> 14 #include <boost/geometry/core/coordinate_dimension.hpp> 15 #include <boost/geometry/core/coordinate_type.hpp> 16 #include <boost/geometry/core/point_type.hpp> 17 #include <boost/geometry/core/tag.hpp> 18 #include <boost/geometry/core/tags.hpp> 19 20 #include <boost/geometry/geometries/box.hpp> 21 #include <boost/geometry/geometries/point.hpp> 22 23 #include <boost/geometry/algorithms/not_implemented.hpp> 24 25 26 namespace boost { namespace geometry 27 { 28 29 namespace detail { namespace helper_geometries 30 { 31 32 template <typename Geometry, typename CS_Tag = typename cs_tag<Geometry>::type> 33 struct default_units 34 { 35 typedef typename coordinate_system<Geometry>::type::units type; 36 }; 37 38 // The Cartesian coordinate system does not define the type units. 39 // For that reason the generic implementation for default_units cannot be used 40 // and specialization needs to be defined. 41 // Moreover, it makes sense to define the units for the Cartesian 42 // coordinate system to be radians, as this way a Cartesian point can 43 // potentially be used in algorithms taking non-Cartesian strategies 44 // and work as if it was as point in the non-Cartesian coordinate 45 // system with radian units. 46 template <typename Geometry> 47 struct default_units<Geometry, cartesian_tag> 48 { 49 typedef radian type; 50 }; 51 52 53 template <typename Units, typename CS_Tag> 54 struct cs_tag_to_coordinate_system 55 { 56 typedef cs::cartesian type; 57 }; 58 59 template <typename Units> 60 struct cs_tag_to_coordinate_system<Units, spherical_equatorial_tag> 61 { 62 typedef cs::spherical_equatorial<Units> type; 63 }; 64 65 template <typename Units> 66 struct cs_tag_to_coordinate_system<Units, spherical_tag> 67 { 68 typedef cs::spherical<Units> type; 69 }; 70 71 template <typename Units> 72 struct cs_tag_to_coordinate_system<Units, geographic_tag> 73 { 74 typedef cs::geographic<Units> type; 75 }; 76 77 78 template 79 < 80 typename Point, 81 typename NewCoordinateType, 82 typename NewUnits, 83 typename CS_Tag = typename cs_tag<Point>::type 84 > 85 struct helper_point 86 { 87 typedef model::point 88 < 89 NewCoordinateType, 90 dimension<Point>::value, 91 typename cs_tag_to_coordinate_system<NewUnits, CS_Tag>::type 92 > type; 93 }; 94 95 96 }} // detail::helper_geometries 97 98 99 namespace detail_dispatch 100 { 101 102 103 template 104 < 105 typename Geometry, 106 typename NewCoordinateType, 107 typename NewUnits, 108 typename Tag = typename tag<Geometry>::type> 109 struct helper_geometry : not_implemented<Geometry> 110 {}; 111 112 113 template <typename Point, typename NewCoordinateType, typename NewUnits> 114 struct helper_geometry<Point, NewCoordinateType, NewUnits, point_tag> 115 { 116 typedef typename detail::helper_geometries::helper_point 117 < 118 Point, NewCoordinateType, NewUnits 119 >::type type; 120 }; 121 122 123 template <typename Box, typename NewCoordinateType, typename NewUnits> 124 struct helper_geometry<Box, NewCoordinateType, NewUnits, box_tag> 125 { 126 typedef model::box 127 < 128 typename helper_geometry 129 < 130 typename point_type<Box>::type, NewCoordinateType, NewUnits 131 >::type 132 > type; 133 }; 134 135 136 } // detail_dispatch 137 138 139 // Meta-function that provides a new helper geometry of the same kind as 140 // the input geometry and the same coordinate system type, 141 // but with a possibly different coordinate type and coordinate system units 142 template 143 < 144 typename Geometry, 145 typename NewCoordinateType = typename coordinate_type<Geometry>::type, 146 typename NewUnits = typename detail::helper_geometries::default_units 147 < 148 Geometry 149 >::type 150 > 151 struct helper_geometry 152 { 153 typedef typename detail_dispatch::helper_geometry 154 < 155 Geometry, NewCoordinateType, NewUnits 156 >::type type; 157 }; 158 159 160 }} // namespace boost::geometry 161 162 #endif // BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP 163