Handle indeterminate length FlatGeobuf headers, linestring geometries [#2]

This commit is contained in:
Brandon Liu
2022-03-27 19:13:22 +08:00
parent b350a8dda7
commit 33a9aef758
3 changed files with 30 additions and 17 deletions
+28 -15
View File
@@ -36,7 +36,7 @@ uint64_t PackedRTreeSize(const uint64_t numItems, const uint16_t nodeSize)
return numNodes * sizeof(NodeItem); return numNodes * sizeof(NodeItem);
} }
drawvec readPolygon(const FlatGeobuf::Geometry *geometry) { drawvec readLinePart(const FlatGeobuf::Geometry *geometry) {
auto xy = geometry->xy(); auto xy = geometry->xy();
auto ends = geometry->ends(); auto ends = geometry->ends();
size_t current_end = 0; size_t current_end = 0;
@@ -56,14 +56,17 @@ drawvec readPolygon(const FlatGeobuf::Geometry *geometry) {
} }
drawvec readGeometry(const FlatGeobuf::Geometry *geometry, FlatGeobuf::GeometryType h_geometry_type) { drawvec readGeometry(const FlatGeobuf::Geometry *geometry, FlatGeobuf::GeometryType h_geometry_type) {
if (h_geometry_type == FlatGeobuf::GeometryType::LineString) {
if (h_geometry_type == FlatGeobuf::GeometryType::Polygon) { } else if (h_geometry_type == FlatGeobuf::GeometryType::MultiLineString) {
return readPolygon(geometry); return readLinePart(geometry); // TODO fixme
} if (h_geometry_type == FlatGeobuf::GeometryType::Polygon) {
return readLinePart(geometry);
} else if (h_geometry_type == FlatGeobuf::GeometryType::MultiPolygon) { } else if (h_geometry_type == FlatGeobuf::GeometryType::MultiPolygon) {
// if it is a GeometryCollection, parse Parts, ignore XY // if it is a GeometryCollection, parse Parts, ignore XY
drawvec dv; drawvec dv;
for (size_t part = 0; part < geometry->parts()->size(); part++) { for (size_t part = 0; part < geometry->parts()->size(); part++) {
drawvec dv2 = readPolygon(geometry->parts()->Get(part)); drawvec dv2 = readLinePart(geometry->parts()->Get(part));
for (size_t k = 0; k < dv2.size(); k++) { for (size_t k = 0; k < dv2.size(); k++) {
dv.push_back(dv2[k]); dv.push_back(dv2[k]);
} }
@@ -76,7 +79,7 @@ drawvec readGeometry(const FlatGeobuf::Geometry *geometry, FlatGeobuf::GeometryT
} }
} }
void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *src, int layer, std::string layername) { void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *src, size_t len, int layer, std::string layername) {
auto header_size = flatbuffers::GetPrefixedSize((const uint8_t *)src + 8); auto header_size = flatbuffers::GetPrefixedSize((const uint8_t *)src + 8);
auto header = FlatGeobuf::GetSizePrefixedHeader(src + 8); auto header = FlatGeobuf::GetSizePrefixedHeader(src + 8);
auto features_count = header->features_count(); auto features_count = header->features_count();
@@ -90,28 +93,38 @@ void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *
h_column_types.push_back(header->columns()->Get(i)->type()); h_column_types.push_back(header->columns()->Get(i)->type());
} }
auto index_size = PackedRTreeSize(features_count,node_size);
auto h_geometry_type = header->geometry_type(); auto h_geometry_type = header->geometry_type();
int drawvec_type = -1;
switch (h_geometry_type) { switch (h_geometry_type) {
case FlatGeobuf::GeometryType::Unknown :
case FlatGeobuf::GeometryType::Point : case FlatGeobuf::GeometryType::Point :
case FlatGeobuf::GeometryType::LineString :
case FlatGeobuf::GeometryType::Polygon :
case FlatGeobuf::GeometryType::MultiPoint : case FlatGeobuf::GeometryType::MultiPoint :
case FlatGeobuf::GeometryType::MultiLineString : drawvec_type = 1;
case FlatGeobuf::GeometryType::MultiPolygon :
case FlatGeobuf::GeometryType::GeometryCollection :
break; break;
case FlatGeobuf::GeometryType::LineString :
case FlatGeobuf::GeometryType::MultiLineString :
drawvec_type = 2;
break;
case FlatGeobuf::GeometryType::Polygon :
case FlatGeobuf::GeometryType::MultiPolygon :
drawvec_type = 3;
break;
case FlatGeobuf::GeometryType::Unknown :
case FlatGeobuf::GeometryType::GeometryCollection :
default: default:
fprintf(stderr, "flatgeobuf has unsupported geometry type %u\n", (unsigned int)h_geometry_type); fprintf(stderr, "flatgeobuf has unsupported geometry type %u\n", (unsigned int)h_geometry_type);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int index_size = 0;
if (node_size > 0) {
index_size = PackedRTreeSize(features_count,node_size);
}
const char* start = src + 8 + 4 + header_size + index_size; const char* start = src + 8 + 4 + header_size + index_size;
for (size_t i = 0; i < features_count; i++) {
while (start < src + len) {
serial_feature sf; serial_feature sf;
auto my_sst = &(*sst)[0]; auto my_sst = &(*sst)[0];
@@ -130,7 +143,7 @@ void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *
sf.feature_minzoom = false; sf.feature_minzoom = false;
sf.seq = (*my_sst->layer_seq); sf.seq = (*my_sst->layer_seq);
sf.geometry = dv; sf.geometry = dv;
sf.t = 3; sf.t = drawvec_type;
vector<string> full_keys; vector<string> full_keys;
vector<serial_val> full_values; vector<serial_val> full_values;
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef FLATGEOBUF_HPP #ifndef FLATGEOBUF_HPP
#define FLATGEOBUF_HPP #define FLATGEOBUF_HPP
void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *s, int layer, std::string layername); void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *s, size_t len, int layer, std::string layername);
#endif #endif
+1 -1
View File
@@ -1403,7 +1403,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
sst[i].attribute_types = attribute_types; sst[i].attribute_types = attribute_types;
} }
parse_flatgeobuf(&sst, map, layer, sources[layer].layer); parse_flatgeobuf(&sst, map, st.st_size, layer, sources[layer].layer);
for (size_t i = 0; i < CPUS; i++) { for (size_t i = 0; i < CPUS; i++) {
dist_sum += dist_sums[i]; dist_sum += dist_sums[i];