From 7bb4c7dbe9ae5ee6ba7687f2cb4443f2c711bff6 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Mon, 25 Apr 2016 14:19:38 -0700 Subject: [PATCH] Add a helper method to manage the tile layer's key-value constant pool --- decode.cc | 1 + mvt.cc | 54 ++++++++++++++++++++++++++++++ mvt.hh | 12 +++++++ tile-join.cc | 93 +++++----------------------------------------------- 4 files changed, 76 insertions(+), 84 deletions(-) diff --git a/decode.cc b/decode.cc index 4a0aafa..8ea0712 100644 --- a/decode.cc +++ b/decode.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/mvt.cc b/mvt.cc index 1af00d9..f1c0357 100644 --- a/mvt.cc +++ b/mvt.cc @@ -1,6 +1,8 @@ #include +#include #include #include +#include #include #include "mvt.hh" #include "protozero/pbf_reader.hpp" @@ -232,6 +234,13 @@ bool mvt_tile::decode(std::string &message) { } } + for (size_t i = 0; i < layer.keys.size(); i++) { + layer.key_map.insert(std::pair(layer.keys[i], i)); + } + for (size_t i = 0; i < layer.values.size(); i++) { + layer.value_map.insert(std::pair(layer.values[i], i)); + } + layers.push_back(layer); break; } @@ -353,3 +362,48 @@ std::string mvt_tile::encode() { return compressed; } + +bool mvt_value::operator<(const mvt_value &o) const { + if (type < o.type) { + return true; + } + if (type == o.type) { + if ((type == mvt_string && string_value < o.string_value) || + (type == mvt_float && numeric_value.float_value < o.numeric_value.float_value) || + (type == mvt_double && numeric_value.double_value < o.numeric_value.double_value) || + (type == mvt_int && numeric_value.int_value < o.numeric_value.int_value) || + (type == mvt_uint && numeric_value.uint_value < o.numeric_value.uint_value) || + (type == mvt_sint && numeric_value.sint_value < o.numeric_value.sint_value) || + (type == mvt_bool && numeric_value.bool_value < o.numeric_value.bool_value)) { + return true; + } + } + + return false; +} + +void mvt_layer::tag(mvt_feature &feature, std::string key, mvt_value value) { + size_t ko, vo; + + std::map::iterator ki = key_map.find(key); + std::map::iterator vi = value_map.find(value); + + if (ki == key_map.end()) { + ko = keys.size(); + keys.push_back(key); + key_map.insert(std::pair(key, ko)); + } else { + ko = ki->second; + } + + if (vi == value_map.end()) { + vo = values.size(); + values.push_back(value); + value_map.insert(std::pair(value, vo)); + } else { + vo = vi->second; + } + + feature.tags.push_back(ko); + feature.tags.push_back(vo); +} diff --git a/mvt.hh b/mvt.hh index c2fb754..ce6361d 100644 --- a/mvt.hh +++ b/mvt.hh @@ -1,3 +1,6 @@ +struct mvt_value; +struct mvt_layer; + enum mvt_operation { mvt_moveto = 1, mvt_lineto = 2, @@ -45,6 +48,8 @@ struct mvt_value { long long sint_value; bool bool_value; } numeric_value; + + bool operator<(const mvt_value &o) const; }; struct mvt_layer { @@ -54,6 +59,13 @@ struct mvt_layer { std::vector keys; std::vector values; int extent; + + // Add a key-value pair to a feature, using this layer's constant pool + void tag(mvt_feature &feature, std::string key, mvt_value value); + + // For tracking the key-value constants already used in this layer + std::map key_map; + std::map value_map; }; struct mvt_tile { diff --git a/tile-join.cc b/tile-join.cc index 95cd03d..21d67c4 100644 --- a/tile-join.cc +++ b/tile-join.cc @@ -75,13 +75,9 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi *nlayers = ll + 1; } - struct pool keys, values; - pool_init(&keys, 0); - pool_init(&values, 0); - for (size_t f = 0; f < layer.features.size(); f++) { mvt_feature feat = layer.features[f]; - std::vector feature_tags; + mvt_feature outfeature; int matched = 0; for (int t = 0; t + 1 < feat.tags.size(); t += 2) { @@ -139,32 +135,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi pool(&((*file_keys)[ll]), copy, type); } - struct pool_val *k, *v; - - if (is_pooled(&keys, key, VT_STRING)) { - k = pool(&keys, key, VT_STRING); - } else { - char *copy = strdup(key); - if (copy == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } - k = pool(&keys, copy, VT_STRING); - } - - if (is_pooled(&values, value, type)) { - v = pool(&values, value, type); - } else { - char *copy = strdup(value); - if (copy == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } - v = pool(&values, copy, type); - } - - feature_tags.push_back(k->n); - feature_tags.push_back(v->n); + outlayer.tag(outfeature, layer.keys[feat.tags[t]], val); } if (header.size() > 0 && strcmp(key, header[0].c_str()) == 0) { @@ -188,7 +159,6 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi } const char *sjoinkey = joinkey.c_str(); - const char *sjoinval = joinval.c_str(); if (!is_pooled(exclude, sjoinkey, VT_STRING)) { if (!is_pooled(&((*file_keys)[ll]), sjoinkey, type)) { @@ -200,32 +170,16 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi pool(&((*file_keys)[ll]), copy, type); } - struct pool_val *k, *v; - - if (is_pooled(&keys, sjoinkey, VT_STRING)) { - k = pool(&keys, sjoinkey, VT_STRING); + mvt_value outval; + if (type == VT_STRING) { + outval.type = mvt_string; + outval.string_value = joinval; } else { - char *copy = strdup(sjoinkey); - if (copy == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } - k = pool(&keys, copy, VT_STRING); + outval.type = mvt_double; + outval.numeric_value.double_value = atof(joinval.c_str()); } - if (is_pooled(&values, sjoinval, type)) { - v = pool(&values, sjoinval, type); - } else { - char *copy = strdup(sjoinval); - if (copy == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } - v = pool(&values, copy, type); - } - - feature_tags.push_back(k->n); - feature_tags.push_back(v->n); + outlayer.tag(outfeature, joinkey, outval); } } } @@ -235,43 +189,14 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi } if (matched || !ifmatched) { - mvt_feature outfeature; outfeature.type = feat.type; outfeature.geometry = feat.geometry; - for (size_t i = 0; i < feature_tags.size(); i++) { - outfeature.tags.push_back(feature_tags[i]); - } - features_added++; outlayer.features.push_back(outfeature); } } - struct pool_val *pv; - for (pv = keys.head; pv != NULL; pv = pv->next) { - outlayer.keys.push_back(std::string(pv->s, strlen(pv->s))); - } - for (pv = values.head; pv != NULL; pv = pv->next) { - mvt_value tv; - - if (pv->type == VT_NUMBER) { - tv.type = mvt_double; - tv.numeric_value.double_value = atof(pv->s); - } else if (pv->type == VT_BOOLEAN) { - tv.type = mvt_bool; - tv.numeric_value.bool_value = (pv->s[0] == 't'); - } else { - tv.type = mvt_string; - tv.string_value = std::string(pv->s); - } - - outlayer.values.push_back(tv); - } - - pool_free_strings(&keys); - pool_free_strings(&values); - outtile.layers.push_back(outlayer); }