From 7a843145623b5b26b0b7f217f6d02c03dfdfac0c Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Mon, 8 Oct 2018 14:45:40 -0700 Subject: [PATCH] Introduce new list and hash container types for geometric attributes --- mvt.cpp | 59 +++++++++++++++++++++++++++++++++++--------------- mvt.hpp | 7 ++++-- tile-join.cpp | 4 ++-- write_json.cpp | 2 +- 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/mvt.cpp b/mvt.cpp index 74c35d9..7b402d1 100644 --- a/mvt.cpp +++ b/mvt.cpp @@ -415,7 +415,7 @@ bool mvt_tile::decode(std::string &message, bool &was_compressed) { for (size_t j = 0; j < geom.size(); j++) { if (geom[j].op == mvt_moveto || geom[j].op == mvt_lineto) { if (off < attr.size()) { - mvt_value v = layer.decode_property(attr, off); + mvt_value v = layer.decode_property(attr, off, true); off++; if (v.type == mvt_hash || v.type == mvt_list) { geom[j].attribute = v.string_value; @@ -915,7 +915,7 @@ void tag_object_v3(mvt_layer &layer, json_object *j, std::vector tv.type = mvt_string; tv.string_value = j->keys[i]->string; - layer.tag_v3_value(tv, onto); + onto.push_back(layer.tag_v3_key(tv.string_value)); tag_object_v3(layer, j->values[i], onto); } } else if (j->type == JSON_ARRAY) { @@ -1053,7 +1053,7 @@ void mvt_layer::reorder_values() { } } -mvt_value mvt_layer::decode_property(std::vector const &property, size_t &off) const { +mvt_value mvt_layer::decode_property(std::vector const &property, size_t &off, bool stringify_nested) const { int type = property[off] & 0x0F; mvt_value ret; @@ -1129,20 +1129,28 @@ mvt_value mvt_layer::decode_property(std::vector const &property, size_t len = property[off] >> 4; off++; - ret.string_value = "["; + if (stringify_nested) { + ret.string_value = "["; + } for (size_t i = 0; i < len; i++) { - mvt_value v1 = decode_property(property, off); + mvt_value v1 = decode_property(property, off, stringify_nested); off++; - ret.string_value.append(v1.toString()); + if (stringify_nested) { + ret.string_value.append(v1.toString()); - if (i + 1 < len) { - ret.string_value.push_back(','); + if (i + 1 < len) { + ret.string_value.push_back(','); + } + } else { + ret.list_value.push_back(v1); } } - ret.string_value.append("]"); + if (stringify_nested) { + ret.string_value.append("]"); + } off--; // so caller can increment return ret; @@ -1154,25 +1162,40 @@ mvt_value mvt_layer::decode_property(std::vector const &property, size_t len = property[off] >> 4; off++; - ret.string_value = "{"; + if (stringify_nested) { + ret.string_value = "{"; + } for (size_t i = 0; i < len; i++) { - mvt_value v1 = decode_property(property, off); + if (property[off] >= keys.size()) { + fprintf(stderr, "Out of bounds hash key reference\n"); + exit(EXIT_FAILURE); + } + + mvt_value v1; + v1.type = mvt_string; + v1.string_value = keys[property[off]]; off++; - mvt_value v2 = decode_property(property, off); + mvt_value v2 = decode_property(property, off, stringify_nested); off++; - ret.string_value.append(v1.toString()); - ret.string_value.append(":"); - ret.string_value.append(v2.toString()); + if (stringify_nested) { + ret.string_value.append(v1.toString()); + ret.string_value.append(":"); + ret.string_value.append(v2.toString()); - if (i + 1 < len) { - ret.string_value.push_back(','); + if (i + 1 < len) { + ret.string_value.push_back(','); + } + } else { + ret.hash_value.insert(std::pair(v1.string_value, v2)); } } - ret.string_value.append("}"); + if (stringify_nested) { + ret.string_value.append("}"); + } off--; // so caller can increment return ret; diff --git a/mvt.hpp b/mvt.hpp index d4ccd2a..864419c 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -94,7 +94,10 @@ enum mvt_value_type { struct mvt_value { mvt_value_type type; std::string string_value; - // std::vector list_value; + + std::vector list_value; + std::map hash_value; + union { float float_value; double double_value; @@ -147,7 +150,7 @@ struct mvt_layer { std::map value_map{}; std::map property_map{}; - mvt_value decode_property(std::vector const &property, size_t &off) const; + mvt_value decode_property(std::vector const &property, size_t &off, bool stringify_nested) const; void reorder_values(); }; diff --git a/tile-join.cpp b/tile-join.cpp index 53ad7a8..6a10085 100644 --- a/tile-join.cpp +++ b/tile-join.cpp @@ -151,7 +151,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map(key, val)); } @@ -226,7 +226,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map(key, val)); } diff --git a/write_json.cpp b/write_json.cpp index 8e13781..40a9180 100644 --- a/write_json.cpp +++ b/write_json.cpp @@ -448,7 +448,7 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y const char *key = layer.keys[feat.properties[t]].c_str(); t++; - mvt_value const &val = layer.decode_property(feat.properties, t); + mvt_value const &val = layer.decode_property(feat.properties, t, true); state.json_write_string(key); print_val(feat, layer, val, 0, state);