Support GeometryCollections in geobuf

This commit is contained in:
Eric Fischer
2017-08-30 14:10:35 -07:00
parent 5c5fbe2617
commit f65faaf3da
+45 -22
View File
@@ -180,9 +180,16 @@ drawvec readMultiPolygon(std::vector<long long> &coords, std::vector<int> &lengt
return dv; return dv;
} }
drawvec readGeometry(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<std::string> &keys, int &type) { struct drawvec_type {
drawvec dv;
int type;
};
std::vector<drawvec_type> readGeometry(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<std::string> &keys) {
std::vector<drawvec_type> ret;
std::vector<long long> coords; std::vector<long long> coords;
std::vector<int> lengths; std::vector<int> lengths;
int type;
while (pbf.next()) { while (pbf.next()) {
switch (pbf.tag()) { switch (pbf.tag()) {
@@ -207,9 +214,13 @@ drawvec readGeometry(protozero::pbf_reader &pbf, size_t dim, double e, std::vect
} }
case 4: { case 4: {
int type2;
protozero::pbf_reader geometry_reader(pbf.get_message()); protozero::pbf_reader geometry_reader(pbf.get_message());
drawvec dv2 = readGeometry(geometry_reader, dim, e, keys, type2); std::vector<drawvec_type> dv2 = readGeometry(geometry_reader, dim, e, keys);
for (size_t i = 0; i < dv2.size(); i++) {
ret.push_back(dv2[i]);
}
break; break;
} }
@@ -218,37 +229,42 @@ drawvec readGeometry(protozero::pbf_reader &pbf, size_t dim, double e, std::vect
} }
} }
drawvec dv; drawvec_type dv;
if (type == POINT) { if (type == POINT) {
dv = readPoint(coords, lengths, dim, e); dv.dv = readPoint(coords, lengths, dim, e);
} else if (type == MULTIPOINT) { } else if (type == MULTIPOINT) {
dv = readLine(coords, lengths, dim, e, false); dv.dv = readLine(coords, lengths, dim, e, false);
} else if (type == LINESTRING) { } else if (type == LINESTRING) {
dv = readLine(coords, lengths, dim, e, false); dv.dv = readLine(coords, lengths, dim, e, false);
} else if (type == POLYGON) { } else if (type == POLYGON) {
dv = readMultiLine(coords, lengths, dim, e, true); dv.dv = readMultiLine(coords, lengths, dim, e, true);
} else if (type == MULTIPOLYGON) { } else if (type == MULTIPOLYGON) {
dv = readMultiPolygon(coords, lengths, dim, e); dv.dv = readMultiPolygon(coords, lengths, dim, e);
} }
type = type / 2 + 1; dv.type = type / 2 + 1;
return dv; ret.push_back(dv);
return ret;
} }
void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<std::string> &keys, struct serialization_state *sst, int layer, std::string layername) { void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<std::string> &keys, struct serialization_state *sst, int layer, std::string layername) {
drawvec dv; std::vector<drawvec_type> dv;
long long id = 0; long long id = 0;
bool has_id = false; bool has_id = false;
std::vector<serial_val> values; std::vector<serial_val> values;
int type = 0;
serial_feature sf;
std::map<std::string, serial_val> other; std::map<std::string, serial_val> other;
std::vector<std::string> full_keys;
std::vector<serial_val> full_values;
while (pbf.next()) { while (pbf.next()) {
switch (pbf.tag()) { switch (pbf.tag()) {
case 1: { case 1: {
protozero::pbf_reader geometry_reader(pbf.get_message()); protozero::pbf_reader geometry_reader(pbf.get_message());
dv = readGeometry(geometry_reader, dim, e, keys, type); std::vector<drawvec_type> dv2 = readGeometry(geometry_reader, dim, e, keys);
for (size_t i = 0; i < dv2.size(); i++) {
dv.push_back(dv2[i]);
}
break; break;
} }
@@ -291,8 +307,8 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
sf.full_keys.push_back(keys[properties[i]]); full_keys.push_back(keys[properties[i]]);
sf.full_values.push_back(values[properties[i + 1]]); full_values.push_back(values[properties[i + 1]]);
} }
values.clear(); values.clear();
@@ -329,6 +345,9 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
} }
} }
for (size_t i = 0; i < dv.size(); i++) {
serial_feature sf;
sf.layer = layer; sf.layer = layer;
sf.layername = layername; sf.layername = layername;
sf.segment = 0; // single thread sf.segment = 0; // single thread
@@ -338,8 +357,10 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
sf.has_tippecanoe_maxzoom = false; sf.has_tippecanoe_maxzoom = false;
sf.feature_minzoom = false; sf.feature_minzoom = false;
sf.seq = (*sst->layer_seq); sf.seq = (*sst->layer_seq);
sf.geometry = dv; sf.geometry = dv[i].dv;
sf.t = type; sf.t = dv[i].type;
sf.full_keys = full_keys;
sf.full_values = full_values;
sf.m = sf.full_values.size(); sf.m = sf.full_values.size();
auto tip = other.find("tippecanoe"); auto tip = other.find("tippecanoe");
@@ -366,6 +387,7 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
} }
serialize_feature(sst, sf); serialize_feature(sst, sf);
}
} }
void outBareGeometry(drawvec const &dv, int type, size_t dim, double e, std::vector<std::string> &keys, struct serialization_state *sst, int layer, std::string layername) { void outBareGeometry(drawvec const &dv, int type, size_t dim, double e, std::vector<std::string> &keys, struct serialization_state *sst, int layer, std::string layername) {
@@ -435,10 +457,11 @@ void parse_geobuf(struct serialization_state *sst, const char *src, size_t len,
} }
case 6: { case 6: {
int type;
protozero::pbf_reader geometry_reader(pbf.get_message()); protozero::pbf_reader geometry_reader(pbf.get_message());
drawvec dv = readGeometry(geometry_reader, dim, e, keys, type); std::vector<drawvec_type> dv = readGeometry(geometry_reader, dim, e, keys);
outBareGeometry(dv, type, dim, e, keys, sst, layer, layername); for (size_t i = 0; i < dv.size(); i++) {
outBareGeometry(dv[i].dv, dv[i].type, dim, e, keys, sst, layer, layername);
}
break; break;
} }