3#ifndef BOAT_GEOMETRY_TRANSFORM_HPP
4#define BOAT_GEOMETRY_TRANSFORM_HPP
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>
18namespace srs = boost::geometry::srs;
22constexpr bool is_srs_spec = std::is_constructible_v<srs::projection<>, T>;
32 specialized<T, srs::projection> || specialized<T, srs::transformation>;
34static auto const lonlat = srs::proj4{
" +proj=lonlat +datum=WGS84 +no_defs"};
39 return srs::proj4{concat(
40 " +proj=ortho +x_0=0 +y_0=0 +units=m +no_defs +a=",
41 numbers::earth::equatorial_radius,
43 numbers::earth::polar_radius,
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");
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);
65 return srs::transformation<>(a, b);
74template <projection_or_transformation T>
77 return boost::geometry::strategy::transform::srs_forward_transformer<T>{v};
80template <projection_or_transformation T>
83 return boost::geometry::strategy::transform::srs_inverse_transformer<T>{v};
87 boost::geometry::strategy::transform::matrix_transformer<double, 2, 2>;
94template <tagged T1, same_tag<T1> T2,
class Strategy>
95bool transform(T1
const& geom1, T2& geom2, Strategy
const& strategy)
99 return boost::geometry::transform(a, b = {}, strategy);
101 [](
this auto&& self,
multi auto const& a,
multi auto& b) ->
bool {
103 for (
auto const& v : a)
104 if (!self(v, b.emplace_back()))
108 [](
this auto&& self,
dynamic auto const& a,
dynamic auto& b) ->
bool {
109 auto vis = [&]<
class T>(T const& v) {
112 return std::visit(vis, a);
119 return [=]<
tagged T>(T a) {
121 return (... && (b = std::move(a),
transform(b, a, strategies)))
122 ? std::optional{std::move(a)}
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