19#ifndef OPENSWMM_GPKG_GEOMETRY_HPP
20#define OPENSWMM_GPKG_GEOMETRY_HPP
50inline void append_u8(std::vector<uint8_t>& buf, uint8_t v) {
54inline void append_u32(std::vector<uint8_t>& buf, uint32_t v) {
55 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&v),
56 reinterpret_cast<const uint8_t*
>(&v) + 4);
59inline void append_f64(std::vector<uint8_t>& buf,
double v) {
60 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&v),
61 reinterpret_cast<const uint8_t*
>(&v) + 8);
66 double min_x,
double min_y,
double max_x,
double max_y) {
77 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&srs_id),
78 reinterpret_cast<const uint8_t*
>(&srs_id) + 4);
93 buf.insert(buf.end(),
reinterpret_cast<const uint8_t*
>(&srs_id),
94 reinterpret_cast<const uint8_t*
>(&srs_id) + 4);
106inline std::vector<uint8_t>
encode_point(
double x,
double y, int32_t srs_id) {
107 std::vector<uint8_t> buf;
108 buf.reserve(8 + 32 + 21);
124 const std::vector<double>& ys,
127 std::vector<uint8_t> buf;
134 double min_x = xs[0], max_x = xs[0], min_y = ys[0], max_y = ys[0];
135 for (
size_t i = 1; i < xs.size(); ++i) {
136 min_x = std::min(min_x, xs[i]);
137 max_x = std::max(max_x, xs[i]);
138 min_y = std::min(min_y, ys[i]);
139 max_y = std::max(max_y, ys[i]);
141 std::vector<uint8_t> buf;
142 buf.reserve(8 + 32 + 9 + xs.size() * 16);
147 for (
size_t i = 0; i < xs.size(); ++i) {
160 const std::vector<double>& ys,
163 std::vector<uint8_t> buf;
171 bool closed = (xs.front() == xs.back() && ys.front() == ys.back());
172 uint32_t n_pts =
static_cast<uint32_t
>(xs.size()) + (closed ? 0 : 1);
174 double min_x = xs[0], max_x = xs[0], min_y = ys[0], max_y = ys[0];
175 for (
size_t i = 1; i < xs.size(); ++i) {
176 min_x = std::min(min_x, xs[i]);
177 max_x = std::max(max_x, xs[i]);
178 min_y = std::min(min_y, ys[i]);
179 max_y = std::max(max_y, ys[i]);
182 std::vector<uint8_t> buf;
183 buf.reserve(8 + 32 + 50 + n_pts * 16);
196 for (
size_t i = 0; i < xs.size(); ++i) {
217 const std::vector<double>& ys,
220 std::vector<uint8_t> buf;
228 bool closed = (xs.front() == xs.back() && ys.front() == ys.back());
229 uint32_t n_pts =
static_cast<uint32_t
>(xs.size()) + (closed ? 0 : 1);
231 double min_x = xs[0], max_x = xs[0], min_y = ys[0], max_y = ys[0];
232 for (
size_t i = 1; i < xs.size(); ++i) {
233 min_x = std::min(min_x, xs[i]);
234 max_x = std::max(max_x, xs[i]);
235 min_y = std::min(min_y, ys[i]);
236 max_y = std::max(max_y, ys[i]);
239 std::vector<uint8_t> buf;
240 buf.reserve(8 + 32 + 30 + n_pts * 16);
248 for (
size_t i = 0; i < xs.size(); ++i) {
264 double x = 0.0,
y = 0.0;
286 if (size < 8)
throw std::runtime_error(
"GeoPackage binary too short");
288 throw std::runtime_error(
"Invalid GeoPackage binary magic");
289 uint8_t flags = data[3];
290 std::memcpy(&srs_id, data + 4, 4);
292 int envelope_type = (flags >> 1) & 0x07;
293 size_t envelope_size = 0;
294 switch (envelope_type) {
295 case 0: envelope_size = 0;
break;
296 case 1: envelope_size = 32;
break;
297 case 2: envelope_size = 48;
break;
298 case 3: envelope_size = 48;
break;
299 case 4: envelope_size = 64;
break;
300 default:
throw std::runtime_error(
"Unknown envelope type");
302 return 8 + envelope_size;
306inline T
read_val(
const uint8_t* data,
size_t& offset) {
308 std::memcpy(&val, data + offset,
sizeof(T));
320 if (type !=
WKB_POINT)
throw std::runtime_error(
"Expected WKB POINT");
331 if (type !=
WKB_LINESTRING)
throw std::runtime_error(
"Expected WKB LINESTRING");
335 for (uint32_t i = 0; i < n; ++i) {
347 if (type !=
WKB_MULTIPOLYGON)
throw std::runtime_error(
"Expected WKB MULTIPOLYGON");
349 if (n_polys == 0)
return mp;
355 if (n_rings == 0)
return mp;
360 for (uint32_t i = 0; i < n_pts; ++i) {
Definition GpkgGeometry.hpp:48
void append_u32(std::vector< uint8_t > &buf, uint32_t v)
Definition GpkgGeometry.hpp:54
void write_gp_header_empty(std::vector< uint8_t > &buf, int32_t srs_id)
Definition GpkgGeometry.hpp:87
size_t parse_gp_header(const uint8_t *data, size_t size, int32_t &srs_id)
Definition GpkgGeometry.hpp:285
T read_val(const uint8_t *data, size_t &offset)
Definition GpkgGeometry.hpp:306
void append_u8(std::vector< uint8_t > &buf, uint8_t v)
Definition GpkgGeometry.hpp:50
void append_f64(std::vector< uint8_t > &buf, double v)
Definition GpkgGeometry.hpp:59
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:65
Definition ExternalContentReader.cpp:33
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:106
DecodedMultipolygon decode_multipolygon(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:342
DecodedPoint decode_point(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:315
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:216
constexpr uint8_t WKB_LITTLE_ENDIAN
Definition GpkgGeometry.hpp:38
DecodedLinestring decode_linestring(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:326
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:123
constexpr uint8_t GP_MAGIC_2
Definition GpkgGeometry.hpp:42
WkbType
Definition GpkgGeometry.hpp:30
@ WKB_POINT
Definition GpkgGeometry.hpp:31
@ WKB_POLYGON
Definition GpkgGeometry.hpp:33
@ WKB_MULTIPOLYGON
Definition GpkgGeometry.hpp:34
@ WKB_LINESTRING
Definition GpkgGeometry.hpp:32
constexpr uint8_t GP_MAGIC_1
Definition GpkgGeometry.hpp:41
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:159
double * y
Definition odesolve.c:28
Definition GpkgGeometry.hpp:268
std::vector< double > xs
Definition GpkgGeometry.hpp:269
std::vector< double > ys
Definition GpkgGeometry.hpp:269
int32_t srs_id
Definition GpkgGeometry.hpp:270
Definition GpkgGeometry.hpp:273
int32_t srs_id
Definition GpkgGeometry.hpp:276
std::vector< double > ys
Definition GpkgGeometry.hpp:275
std::vector< double > xs
Definition GpkgGeometry.hpp:275
Definition GpkgGeometry.hpp:263
double y
Definition GpkgGeometry.hpp:264
int32_t srs_id
Definition GpkgGeometry.hpp:265
double x
Definition GpkgGeometry.hpp:264