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