3#ifndef BOAT_GEOMETRY_WKB_HPP
4#define BOAT_GEOMETRY_WKB_HPP
12namespace geometry::detail {
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());
19constexpr auto read = overloaded{
20 []<
class T>(this auto&& self, blob_view& wkb, T& g, std::endian e) ->
void {
21 if constexpr (point<T>)
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);
30 self(wkb, g.emplace_back(), e);
32 []<
class T>(this auto&& self, blob_view& wkb, T& g) ->
void {
35 if constexpr (dynamic<T>) {
36 variant_emplace(g, i);
37 std::visit([&](
auto& g) { self(wkb, g, e); }, g);
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);
56 wkb << static_cast<uint32_t>(g.size());
58 if constexpr (multi<T>)
61 self(item, wkb, std::ignore);
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);
69 self(g, wkb, std::ignore);
78 geometry::detail::read(wkb, geom);
85 geometry::detail::write(geom, wkb);
Definition vocabulary.hpp:121
constexpr auto variant_index_v
Definition vocabulary.hpp:124
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