boat
C++23 geospatial library
Loading...
Searching...
No Matches
transform.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef BOAT_GEOMETRY_TRANSFORM_HPP
4#define BOAT_GEOMETRY_TRANSFORM_HPP
5
6#include <boat/detail/numbers.hpp>
7#include <boat/detail/string.hpp>
9#include <boost/geometry/algorithms/transform.hpp>
10#include <boost/geometry/srs/epsg.hpp>
11#include <boost/geometry/srs/transformation.hpp>
12#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
13#include <boost/geometry/strategies/transform/srs_transformer.hpp>
14#include <optional>
15
16namespace boat::geometry {
17
18namespace srs = boost::geometry::srs;
19using srs_variant = std::variant<srs::epsg, srs::proj4>;
20
21template <class T>
22constexpr bool is_srs_spec = std::is_constructible_v<srs::projection<>, T>;
23
24template <class... Ts>
25constexpr bool is_srs_spec<std::variant<Ts...>> = (is_srs_spec<Ts> && ...);
26
27template <class T>
29
30template <class T>
32 specialized<T, srs::projection> || specialized<T, srs::transformation>;
33
34static auto const lonlat = srs::proj4{" +proj=lonlat +datum=WGS84 +no_defs"};
35
37inline auto ortho(geographic::point const& v)
38{
39 return srs::proj4{concat( //
40 " +proj=ortho +x_0=0 +y_0=0 +units=m +no_defs +a=",
41 numbers::earth::equatorial_radius,
42 " +b=",
43 numbers::earth::polar_radius,
44 " +lat_0=",
45 v.y(),
46 " +lon_0=",
47 v.x())};
48}
49
51inline srs_variant to_srs_variant(auto const& meta)
52{
53 return meta.epsg > 0 ? srs_variant{srs::epsg{meta.epsg}}
54 : !meta.proj4.empty() ? srs_variant{srs::proj4{meta.proj4}}
55 : throw std::runtime_error("no SRS");
56}
57
58auto transformation(srs_spec auto const& a, srs_spec auto const& b)
59{
60 if constexpr (specialized<decltype(a), std::variant>)
61 return std::visit([&](auto&& a) { return transformation(a, b); }, a);
62 else if constexpr (specialized<decltype(b), std::variant>)
63 return std::visit([&](auto&& b) { return transformation(a, b); }, b);
64 else
65 return srs::transformation<>(a, b);
66}
67
69auto transformation(srs_spec auto const& v)
70{
71 return transformation(lonlat, v);
72}
73
74template <projection_or_transformation T>
75auto srs_forward(T const& v)
76{
77 return boost::geometry::strategy::transform::srs_forward_transformer<T>{v};
78}
79
80template <projection_or_transformation T>
81auto srs_inverse(T const& v)
82{
83 return boost::geometry::strategy::transform::srs_inverse_transformer<T>{v};
84}
85
87 boost::geometry::strategy::transform::matrix_transformer<double, 2, 2>;
88
89inline auto mat_inverse(matrix const& v)
90{
91 return mat_forward{inverse(v)};
92}
93
94template <tagged T1, same_tag<T1> T2, class Strategy>
95bool transform(T1 const& geom1, T2& geom2, Strategy const& strategy)
96{
97 return overloaded{
98 [&](single auto const& a, single auto& b) {
99 return boost::geometry::transform(a, b = {}, strategy);
100 },
101 [](this auto&& self, multi auto const& a, multi auto& b) -> bool {
102 b = {};
103 for (auto const& v : a)
104 if (!self(v, b.emplace_back()))
105 b.pop_back();
106 return !b.empty();
107 },
108 [](this auto&& self, dynamic auto const& a, dynamic auto& b) -> bool {
109 auto vis = [&]<class T>(T const& v) {
110 return self(v, b.template emplace<variant_index_v<T>>());
111 };
112 return std::visit(vis, a);
113 }}(geom1, geom2);
114}
115
117auto transform(auto const&... strategies)
118{
119 return [=]<tagged T>(T a) {
120 T b;
121 return (... && (b = std::move(a), transform(b, a, strategies)))
122 ? std::optional{std::move(a)}
123 : std::nullopt;
124 };
125}
126
127} // namespace boat::geometry
128
129#endif // BOAT_GEOMETRY_TRANSFORM_HPP
Definition vocabulary.hpp:32
Definition vocabulary.hpp:38
Definition vocabulary.hpp:53
Definition transform.hpp:28
Definition vocabulary.hpp:26
Definition algorithm.hpp:10
constexpr bool is_srs_spec
Definition transform.hpp:22
bool transform(T1 const &geom1, T2 &geom2, Strategy const &strategy)
Definition transform.hpp:95
std::variant< srs::epsg, srs::proj4 > srs_variant
Definition transform.hpp:19
constexpr auto variant_index_v
Definition vocabulary.hpp:108
auto ortho(geographic::point const &v)
Orthographic SRS centered at v.
Definition transform.hpp:37
auto mat_inverse(matrix const &v)
Definition transform.hpp:89
boost::geometry::strategy::transform::matrix_transformer< double, 2, 2 > mat_forward
Definition transform.hpp:86
auto srs_forward(T const &v)
Definition transform.hpp:75
auto transformation(srs_spec auto const &a, srs_spec auto const &b)
Definition transform.hpp:58
auto srs_inverse(T const &v)
Definition transform.hpp:81
boost::qvm::mat< double, 3, 3 > matrix
Definition vocabulary.hpp:99
srs_variant to_srs_variant(auto const &meta)
Prefers a positive epsg code to proj4; throws if neither is available.
Definition transform.hpp:51
model::d2::point_xy< double, boost::geometry::cs::geographic< boost::geometry::degree > > point
Definition vocabulary.hpp:60