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 | |