helper_geometry.hpp 4.4 KB

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