Skip to content

Commit

Permalink
Add a helper method to manage the tile layer's key-value constant pool
Browse files Browse the repository at this point in the history
  • Loading branch information
e-n-f committed Apr 25, 2016
1 parent 2dea1d1 commit 7bb4c7d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 84 deletions.
1 change: 1 addition & 0 deletions decode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <sqlite3.h>
#include <string>
#include <vector>
#include <map>
#include <zlib.h>
#include <math.h>
#include <fcntl.h>
Expand Down
54 changes: 54 additions & 0 deletions mvt.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <zlib.h>
#include "mvt.hh"
#include "protozero/pbf_reader.hpp"
Expand Down Expand Up @@ -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<std::string, size_t>(layer.keys[i], i));
}
for (size_t i = 0; i < layer.values.size(); i++) {
layer.value_map.insert(std::pair<mvt_value, size_t>(layer.values[i], i));
}

layers.push_back(layer);
break;
}
Expand Down Expand Up @@ -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<std::string, size_t>::iterator ki = key_map.find(key);
std::map<mvt_value, size_t>::iterator vi = value_map.find(value);

if (ki == key_map.end()) {
ko = keys.size();
keys.push_back(key);
key_map.insert(std::pair<std::string, size_t>(key, ko));
} else {
ko = ki->second;
}

if (vi == value_map.end()) {
vo = values.size();
values.push_back(value);
value_map.insert(std::pair<mvt_value, size_t>(value, vo));
} else {
vo = vi->second;
}

feature.tags.push_back(ko);
feature.tags.push_back(vo);
}
12 changes: 12 additions & 0 deletions mvt.hh
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
struct mvt_value;
struct mvt_layer;

enum mvt_operation {
mvt_moveto = 1,
mvt_lineto = 2,
Expand Down Expand Up @@ -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 {
Expand All @@ -54,6 +59,13 @@ struct mvt_layer {
std::vector<std::string> keys;
std::vector<mvt_value> 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<std::string, size_t> key_map;
std::map<mvt_value, size_t> value_map;
};

struct mvt_tile {
Expand Down
93 changes: 9 additions & 84 deletions tile-join.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> feature_tags;
mvt_feature outfeature;
int matched = 0;

for (int t = 0; t + 1 < feat.tags.size(); t += 2) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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)) {
Expand All @@ -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);
} else {
char *copy = strdup(sjoinkey);
if (copy == NULL) {
perror("Out of memory");
exit(EXIT_FAILURE);
}
k = pool(&keys, copy, VT_STRING);
}

if (is_pooled(&values, sjoinval, type)) {
v = pool(&values, sjoinval, type);
mvt_value outval;
if (type == VT_STRING) {
outval.type = mvt_string;
outval.string_value = joinval;
} else {
char *copy = strdup(sjoinval);
if (copy == NULL) {
perror("Out of memory");
exit(EXIT_FAILURE);
}
v = pool(&values, copy, type);
outval.type = mvt_double;
outval.numeric_value.double_value = atof(joinval.c_str());
}

feature_tags.push_back(k->n);
feature_tags.push_back(v->n);
outlayer.tag(outfeature, joinkey, outval);
}
}
}
Expand All @@ -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);
}

Expand Down

0 comments on commit 7bb4c7d

Please sign in to comment.