35#ifndef OPENSWMM_GPKG_GEOMETRY_HPP
36#define OPENSWMM_GPKG_GEOMETRY_HPP
66inline void append_u8(std::vector<uint8_t>& buf, uint8_t v) {
70inline void append_u32(std::vector<uint8_t>& buf, uint32_t v) {
71 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&v),
72 reinterpret_cast<const uint8_t*
>(&v) + 4);
75inline void append_f64(std::vector<uint8_t>& buf,
double v) {
76 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&v),
77 reinterpret_cast<const uint8_t*
>(&v) + 8);
82 double min_x,
double min_y,
double max_x,
double max_y) {
93 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&srs_id),
94 reinterpret_cast<const uint8_t*
>(&srs_id) + 4);
109 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&srs_id),
110 reinterpret_cast<const uint8_t*
>(&srs_id) + 4);
122inline std::vector<uint8_t>
encode_point(
double x,
double y, int32_t srs_id) {
123 std::vector<uint8_t> buf;
124 buf.reserve(8 + 32 + 21);
140 const std::vector<double>& ys,
143 std::vector<uint8_t> buf;
150 double min_x = xs[0], max_x = xs[0], min_y = ys[0], max_y = ys[0];
151 for (
size_t i = 1; i < xs.size(); ++i) {
152 min_x = std::min(min_x, xs[i]);
153 max_x = std::max(max_x, xs[i]);
154 min_y = std::min(min_y, ys[i]);
155 max_y = std::max(max_y, ys[i]);
157 std::vector<uint8_t> buf;
158 buf.reserve(8 + 32 + 9 + xs.size() * 16);
163 for (
size_t i = 0; i < xs.size(); ++i) {
176 const std::vector<double>& ys,
179 std::vector<uint8_t> buf;
187 bool closed = (xs.front() == xs.back() && ys.front() == ys.back());
188 uint32_t n_pts =
static_cast<uint32_t
>(xs.size()) + (closed ? 0 : 1);
190 double min_x = xs[0], max_x = xs[0], min_y = ys[0], max_y = ys[0];
191 for (
size_t i = 1; i < xs.size(); ++i) {
192 min_x = std::min(min_x, xs[i]);
193 max_x = std::max(max_x, xs[i]);
194 min_y = std::min(min_y, ys[i]);
195 max_y = std::max(max_y, ys[i]);
198 std::vector<uint8_t> buf;
199 buf.reserve(8 + 32 + 50 + n_pts * 16);
212 for (
size_t i = 0; i < xs.size(); ++i) {
233 const std::vector<double>& ys,
236 std::vector<uint8_t> buf;
244 bool closed = (xs.front() == xs.back() && ys.front() == ys.back());
245 uint32_t n_pts =
static_cast<uint32_t
>(xs.size()) + (closed ? 0 : 1);
247 double min_x = xs[0], max_x = xs[0], min_y = ys[0], max_y = ys[0];
248 for (
size_t i = 1; i < xs.size(); ++i) {
249 min_x = std::min(min_x, xs[i]);
250 max_x = std::max(max_x, xs[i]);
251 min_y = std::min(min_y, ys[i]);
252 max_y = std::max(max_y, ys[i]);
255 std::vector<uint8_t> buf;
256 buf.reserve(8 + 32 + 30 + n_pts * 16);
264 for (
size_t i = 0; i < xs.size(); ++i) {
280 double x = 0.0,
y = 0.0;
302 if (size < 8)
throw std::runtime_error(
"GeoPackage binary too short");
304 throw std::runtime_error(
"Invalid GeoPackage binary magic");
305 uint8_t flags = data[3];
306 std::memcpy(&srs_id, data + 4, 4);
308 int envelope_type = (flags >> 1) & 0x07;
309 size_t envelope_size = 0;
310 switch (envelope_type) {
311 case 0: envelope_size = 0;
break;
312 case 1: envelope_size = 32;
break;
313 case 2: envelope_size = 48;
break;
314 case 3: envelope_size = 48;
break;
315 case 4: envelope_size = 64;
break;
316 default:
throw std::runtime_error(
"Unknown envelope type");
318 return 8 + envelope_size;
322inline T
read_val(
const uint8_t* data,
size_t& offset) {
324 std::memcpy(&val, data + offset,
sizeof(T));
336 if (type !=
WKB_POINT)
throw std::runtime_error(
"Expected WKB POINT");
347 if (type !=
WKB_LINESTRING)
throw std::runtime_error(
"Expected WKB LINESTRING");
351 for (uint32_t i = 0; i < n; ++i) {
363 if (type !=
WKB_MULTIPOLYGON)
throw std::runtime_error(
"Expected WKB MULTIPOLYGON");
365 if (n_polys == 0)
return mp;
371 if (n_rings == 0)
return mp;
376 for (uint32_t i = 0; i < n_pts; ++i) {
Definition GpkgGeometry.hpp:64
void append_u32(std::vector< uint8_t > &buf, uint32_t v)
Definition GpkgGeometry.hpp:70
void write_gp_header_empty(std::vector< uint8_t > &buf, int32_t srs_id)
Definition GpkgGeometry.hpp:103
size_t parse_gp_header(const uint8_t *data, size_t size, int32_t &srs_id)
Definition GpkgGeometry.hpp:301
T read_val(const uint8_t *data, size_t &offset)
Definition GpkgGeometry.hpp:322
void append_u8(std::vector< uint8_t > &buf, uint8_t v)
Definition GpkgGeometry.hpp:66
void append_f64(std::vector< uint8_t > &buf, double v)
Definition GpkgGeometry.hpp:75
void write_gp_header(std::vector< uint8_t > &buf, int32_t srs_id, double min_x, double min_y, double max_x, double max_y)
Definition GpkgGeometry.hpp:81
Definition ExternalContentReader.cpp:49
std::vector< uint8_t > encode_point(double x, double y, int32_t srs_id)
Encode a POINT geometry in GeoPackage Binary format.
Definition GpkgGeometry.hpp:122
DecodedMultipolygon decode_multipolygon(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:358
DecodedPoint decode_point(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:331
std::vector< uint8_t > encode_polygon(const std::vector< double > &xs, const std::vector< double > &ys, int32_t srs_id)
Encode a POLYGON geometry (single ring) in GeoPackage Binary format.
Definition GpkgGeometry.hpp:232
constexpr uint8_t WKB_LITTLE_ENDIAN
Definition GpkgGeometry.hpp:54
DecodedLinestring decode_linestring(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:342
std::vector< uint8_t > encode_linestring(const std::vector< double > &xs, const std::vector< double > &ys, int32_t srs_id)
Encode a LINESTRING geometry in GeoPackage Binary format.
Definition GpkgGeometry.hpp:139
constexpr uint8_t GP_MAGIC_2
Definition GpkgGeometry.hpp:58
WkbType
Definition GpkgGeometry.hpp:46
@ WKB_POINT
Definition GpkgGeometry.hpp:47
@ WKB_POLYGON
Definition GpkgGeometry.hpp:49
@ WKB_MULTIPOLYGON
Definition GpkgGeometry.hpp:50
@ WKB_LINESTRING
Definition GpkgGeometry.hpp:48
constexpr uint8_t GP_MAGIC_1
Definition GpkgGeometry.hpp:57
std::vector< uint8_t > encode_multipolygon(const std::vector< double > &xs, const std::vector< double > &ys, int32_t srs_id)
Encode a MULTIPOLYGON geometry (single polygon, single ring) in GeoPackage Binary format.
Definition GpkgGeometry.hpp:175
double * y
Definition odesolve.c:28
Definition GpkgGeometry.hpp:284
std::vector< double > xs
Definition GpkgGeometry.hpp:285
std::vector< double > ys
Definition GpkgGeometry.hpp:285
int32_t srs_id
Definition GpkgGeometry.hpp:286
Definition GpkgGeometry.hpp:289
int32_t srs_id
Definition GpkgGeometry.hpp:292
std::vector< double > ys
Definition GpkgGeometry.hpp:291
std::vector< double > xs
Definition GpkgGeometry.hpp:291
Definition GpkgGeometry.hpp:279
double y
Definition GpkgGeometry.hpp:280
int32_t srs_id
Definition GpkgGeometry.hpp:281
double x
Definition GpkgGeometry.hpp:280