boat
C++23 geospatial library
Loading...
Searching...
No Matches
wkb.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef BOAT_GEOMETRY_WKB_HPP
4#define BOAT_GEOMETRY_WKB_HPP
5
6#include <array>
7#include <boat/blob.hpp>
9#include <cstdint>
10
11namespace boat {
12namespace geometry::detail {
13
14constexpr auto endians = std::array{std::endian::big, std::endian::little};
15constexpr auto native = static_cast<uint8_t>(
16 std::ranges::find(endians, std::endian::native) - endians.begin());
17static_assert(native < endians.size());
18
19constexpr auto read = overloaded{
20 []<class T>(this auto&& self, blob_view& wkb, T& g, std::endian e) -> void {
21 if constexpr (point<T>)
22 g.x(get<double>(wkb, e)), g.y(get<double>(wkb, e));
23 else
24 for (uint32_t i{}, n = get<uint32_t>(wkb, e); i < n; ++i)
25 if constexpr (multi<T>)
26 self(wkb, g.emplace_back());
27 else if constexpr (polygon<T>)
28 self(wkb, i ? g.inners().emplace_back() : g.outer(), e);
29 else
30 self(wkb, g.emplace_back(), e);
31 },
32 []<class T>(this auto&& self, blob_view& wkb, T& g) -> void {
33 auto e = endians.at(get<uint8_t>(wkb));
34 auto i = get<uint32_t>(wkb, e) - 1;
35 if constexpr (dynamic<T>) {
36 variant_emplace(g, i);
37 std::visit([&](auto& g) { self(wkb, g, e); }, g);
38 }
39 else {
40 check(i == variant_index_v<T>, "wkb");
41 self(wkb, g = {}, e);
42 }
43 }};
44
45constexpr auto write = overloaded{
46 []<class T>(this auto&& self, T const& g, blob& wkb, auto) -> void {
47 if constexpr (point<T>)
48 wkb << g.x() << g.y();
49 else if constexpr (polygon<T>) {
50 wkb << static_cast<uint32_t>(1 + g.inners().size());
51 self(g.outer(), wkb, std::ignore);
52 for (auto& item : g.inners())
53 self(item, wkb, std::ignore);
54 }
55 else {
56 wkb << static_cast<uint32_t>(g.size());
57 for (auto& item : g)
58 if constexpr (multi<T>)
59 self(item, wkb);
60 else
61 self(item, wkb, std::ignore);
62 }
63 },
64 []<class T>(this auto&& self, T const& g, blob& wkb) -> void {
65 if constexpr (dynamic<T>)
66 std::visit([&](auto& g) { self(g, wkb); }, g);
67 else {
68 wkb << native << static_cast<uint32_t>(variant_index_v<T> + 1);
69 self(g, wkb, std::ignore);
70 }
71 }};
72
73} // namespace geometry::detail
74
77{
78 geometry::detail::read(wkb, geom);
79 return wkb;
80}
81
83blob& operator<<(blob& wkb, geometry::ogc99 auto const& geom)
84{
85 geometry::detail::write(geom, wkb);
86 return wkb;
87}
88
89} // namespace boat
90
91#endif // BOAT_GEOMETRY_WKB_HPP
Definition vocabulary.hpp:121
constexpr auto variant_index_v
Definition vocabulary.hpp:124
Definition blob.hpp:12
decltype(auto) operator<<(O &&out, I const &in)
Arithmetic values are appended in native byte order.
Definition blob.hpp:44
decltype(auto) operator>>(I &&in, O &out)
Arithmetic reads use native byte order and advance the view.
Definition blob.hpp:29
T get(blob_view &in)
Definition blob.hpp:54
Definition blob.hpp:14
Definition blob.hpp:19