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) {
212 double x = 0.0,
y = 0.0;
234 if (
size < 8)
throw std::runtime_error(
"GeoPackage binary too short");
236 throw std::runtime_error(
"Invalid GeoPackage binary magic");
237 uint8_t flags =
data[3];
238 std::memcpy(&srs_id,
data + 4, 4);
240 int envelope_type = (flags >> 1) & 0x07;
241 size_t envelope_size = 0;
242 switch (envelope_type) {
243 case 0: envelope_size = 0;
break;
244 case 1: envelope_size = 32;
break;
245 case 2: envelope_size = 48;
break;
246 case 3: envelope_size = 48;
break;
247 case 4: envelope_size = 64;
break;
248 default:
throw std::runtime_error(
"Unknown envelope type");
250 return 8 + envelope_size;
256 std::memcpy(&val,
data + offset,
sizeof(T));
267 uint32_t type = detail::read_val<uint32_t>(blob.data(), offset);
268 if (type !=
WKB_POINT)
throw std::runtime_error(
"Expected WKB POINT");
269 pt.
x = detail::read_val<double>(blob.data(), offset);
270 pt.
y = detail::read_val<double>(blob.data(), offset);
278 uint32_t type = detail::read_val<uint32_t>(blob.data(), offset);
279 if (type !=
WKB_LINESTRING)
throw std::runtime_error(
"Expected WKB LINESTRING");
280 uint32_t n = detail::read_val<uint32_t>(blob.data(), offset);
283 for (uint32_t i = 0; i < n; ++i) {
284 ls.
xs[i] = detail::read_val<double>(blob.data(), offset);
285 ls.
ys[i] = detail::read_val<double>(blob.data(), offset);
294 uint32_t type = detail::read_val<uint32_t>(blob.data(), offset);
295 if (type !=
WKB_MULTIPOLYGON)
throw std::runtime_error(
"Expected WKB MULTIPOLYGON");
296 uint32_t n_polys = detail::read_val<uint32_t>(blob.data(), offset);
297 if (n_polys == 0)
return mp;
300 uint32_t poly_type = detail::read_val<uint32_t>(blob.data(), offset);
302 uint32_t n_rings = detail::read_val<uint32_t>(blob.data(), offset);
303 if (n_rings == 0)
return mp;
305 uint32_t n_pts = detail::read_val<uint32_t>(blob.data(), offset);
308 for (uint32_t i = 0; i < n_pts; ++i) {
309 mp.
xs[i] = detail::read_val<double>(blob.data(), offset);
310 mp.
ys[i] = detail::read_val<double>(blob.data(), offset);
int size
Definition XSectBatch.cpp:567
const double * data
Definition XSectBatch.cpp:567
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:233
T read_val(const uint8_t *data, size_t &offset)
Definition GpkgGeometry.hpp:254
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 GeoPackageInputPlugin.cpp:15
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:290
DecodedPoint decode_point(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:263
constexpr uint8_t WKB_LITTLE_ENDIAN
Definition GpkgGeometry.hpp:38
DecodedLinestring decode_linestring(const std::vector< uint8_t > &blob)
Definition GpkgGeometry.hpp:274
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:216
std::vector< double > xs
Definition GpkgGeometry.hpp:217
std::vector< double > ys
Definition GpkgGeometry.hpp:217
int32_t srs_id
Definition GpkgGeometry.hpp:218
Definition GpkgGeometry.hpp:221
int32_t srs_id
Definition GpkgGeometry.hpp:224
std::vector< double > ys
Definition GpkgGeometry.hpp:223
std::vector< double > xs
Definition GpkgGeometry.hpp:223
Definition GpkgGeometry.hpp:211
double y
Definition GpkgGeometry.hpp:212
int32_t srs_id
Definition GpkgGeometry.hpp:213
double x
Definition GpkgGeometry.hpp:212