Add the ability to inline metadata with geometry

This commit is contained in:
Eric Fischer
2016-05-10 16:46:45 -07:00
parent f920c05c75
commit 3655a54d22
4 changed files with 102 additions and 52 deletions
+59 -29
View File
@@ -57,7 +57,7 @@ bool draws_something(drawvec &geom) {
return false;
}
int metacmp(int m1, char **meta1, char *stringpool1, int m2, char **meta2, char *stringpool2);
int metacmp(int m1, const std::vector<long long> &keys1, const std::vector<long long> &values1, char *stringpool1, int m2, const std::vector<long long> &keys2, const std::vector<long long> &values2, char *stringpool2);
int coalindexcmp(const struct coalesce *c1, const struct coalesce *c2);
static int is_integer(const char *s, long long *v);
@@ -71,6 +71,8 @@ struct coalesce {
unsigned long long index2;
bool coalesced;
long long original_seq;
std::vector<long long> keys;
std::vector<long long> values;
bool operator<(const coalesce &o) const {
int cmp = coalindexcmp(this, &o);
@@ -97,10 +99,7 @@ int coalcmp(const void *v1, const void *v2) {
return cmp;
}
char *m1 = c1->meta;
char *m2 = c2->meta;
return metacmp(c1->m, &m1, c1->stringpool, c2->m, &m2, c2->stringpool);
return metacmp(c1->m, c1->keys, c1->values, c1->stringpool, c2->m, c2->keys, c2->values, c2->stringpool);
}
int coalindexcmp(const struct coalesce *c1, const struct coalesce *c2) {
@@ -123,10 +122,7 @@ int coalindexcmp(const struct coalesce *c1, const struct coalesce *c2) {
return cmp;
}
mvt_value retrieve_string(char **f, char *stringpool, int *otype) {
long long off;
deserialize_long_long(f, &off);
mvt_value retrieve_string(long long off, char *stringpool, int *otype) {
int type = stringpool[off];
char *s = stringpool + off + 1;
@@ -160,18 +156,18 @@ mvt_value retrieve_string(char **f, char *stringpool, int *otype) {
return tv;
}
void decode_meta(int m, char **meta, char *stringpool, mvt_layer &layer, mvt_feature &feature) {
void decode_meta(int m, std::vector<long long> &metakeys, std::vector<long long> &metavals, char *stringpool, mvt_layer &layer, mvt_feature &feature) {
int i;
for (i = 0; i < m; i++) {
int otype;
mvt_value key = retrieve_string(meta, stringpool, NULL);
mvt_value value = retrieve_string(meta, stringpool, &otype);
mvt_value key = retrieve_string(metakeys[i], stringpool, NULL);
mvt_value value = retrieve_string(metavals[i], stringpool, &otype);
layer.tag(feature, key.string_value, value);
}
}
int metacmp(int m1, char **meta1, char *stringpool1, int m2, char **meta2, char *stringpool2) {
int metacmp(int m1, const std::vector<long long> &keys1, const std::vector<long long> &values1, char *stringpool1, int m2, const std::vector<long long> &keys2, const std::vector<long long> &values2, char *stringpool2) {
// XXX
// Ideally this would make identical features compare the same lexically
// even if their attributes were declared in different orders in different instances.
@@ -179,8 +175,8 @@ int metacmp(int m1, char **meta1, char *stringpool1, int m2, char **meta2, char
int i;
for (i = 0; i < m1 && i < m2; i++) {
mvt_value key1 = retrieve_string(meta1, stringpool1, NULL);
mvt_value key2 = retrieve_string(meta2, stringpool2, NULL);
mvt_value key1 = retrieve_string(keys1[i], stringpool1, NULL);
mvt_value key2 = retrieve_string(keys2[i], stringpool2, NULL);
if (key1.string_value < key2.string_value) {
return -1;
@@ -188,13 +184,11 @@ int metacmp(int m1, char **meta1, char *stringpool1, int m2, char **meta2, char
return 1;
}
long long off1;
deserialize_long_long(meta1, &off1);
long long off1 = values1[i];
int type1 = stringpool1[off1];
char *s1 = stringpool1 + off1 + 1;
long long off2;
deserialize_long_long(meta2, &off2);
long long off2 = values2[i];
int type2 = stringpool2[off2];
char *s2 = stringpool2 + off2 + 1;
@@ -265,7 +259,7 @@ struct sll {
}
};
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int line_detail, int *within, long long *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, int m) {
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int line_detail, int *within, long long *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, int m, std::vector<long long> &metakeys, std::vector <long long> &metavals) {
if (geom.size() > 0 && nextzoom <= maxzoom) {
int xo, yo;
int span = 1 << (nextzoom - z);
@@ -347,8 +341,6 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
serialize_int(geomfile[j], tippecanoe_maxzoom, geompos, fname);
}
serialize_int(geomfile[j], segment, &geompos[j], fname);
serialize_long_long(geomfile[j], metastart, &geompos[j], fname);
serialize_int(geomfile[j], m, &geompos[j], fname);
long long wx = initial_x[segment], wy = initial_y[segment];
for (size_t u = 0; u < geom.size(); u++) {
@@ -363,6 +355,16 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
}
serialize_byte(geomfile[j], VT_END, &geompos[j], fname);
serialize_int(geomfile[j], m, &geompos[j], fname);
serialize_long_long(geomfile[j], metastart, &geompos[j], fname);
if (metastart < 0) {
for (int i = 0; i < m; i++) {
serialize_long_long(geomfile[j], metakeys[i], &geompos[j], fname);
serialize_long_long(geomfile[j], metavals[i], &geompos[j], fname);
}
}
serialize_byte(geomfile[j], feature_minzoom, &geompos[j], fname);
}
}
@@ -386,6 +388,8 @@ struct partial {
int *prevent;
int *additional;
int maxzoom;
std::vector<long long> keys;
std::vector<long long> values;
};
struct partial_arg {
@@ -649,15 +653,37 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
int segment;
deserialize_int_io(geoms, &segment, geompos_in);
long long metastart;
int m;
deserialize_long_long_io(geoms, &metastart, geompos_in);
deserialize_int_io(geoms, &m, geompos_in);
char *meta = metabase + metastart + meta_off[segment];
long long bbox[4];
drawvec geom = decode_geometry(geoms, geompos_in, z, tx, ty, line_detail, bbox, initial_x[segment], initial_y[segment]);
long long metastart;
int m;
deserialize_int_io(geoms, &m, geompos_in);
deserialize_long_long_io(geoms, &metastart, geompos_in);
char *meta = NULL;
std::vector<long long> metakeys, metavals;
if (metastart >= 0) {
meta = metabase + metastart + meta_off[segment];
for (int i = 0; i < m; i++) {
long long k, v;
deserialize_long_long(&meta, &k);
deserialize_long_long(&meta, &v);
metakeys.push_back(k);
metavals.push_back(v);
}
} else {
for (int i = 0; i < m; i++) {
long long k, v;
deserialize_long_long_io(geoms, &k, geompos_in);
deserialize_long_long_io(geoms, &v, geompos_in);
metakeys.push_back(k);
metavals.push_back(v);
}
}
signed char feature_minzoom;
deserialize_byte_io(geoms, &feature_minzoom, geompos_in);
@@ -752,7 +778,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
}
if (line_detail == detail && fraction == 1) { /* only write out the next zoom once, even if we retry */
rewrite(geom, z, nextzoom, maxzoom, bbox, tx, ty, buffer, line_detail, within, geompos, geomfile, fname, t, layer, metastart, feature_minzoom, child_shards, max_zoom_increment, original_seq, tippecanoe_minzoom, tippecanoe_maxzoom, segment, initial_x, initial_y, m);
rewrite(geom, z, nextzoom, maxzoom, bbox, tx, ty, buffer, line_detail, within, geompos, geomfile, fname, t, layer, metastart, feature_minzoom, child_shards, max_zoom_increment, original_seq, tippecanoe_minzoom, tippecanoe_maxzoom, segment, initial_x, initial_y, m, metakeys, metavals);
}
if (z < minzoom) {
@@ -818,6 +844,8 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
p.prevent = prevent;
p.additional = additional;
p.maxzoom = maxzoom;
p.keys = metakeys;
p.values = metavals;
partials.push_back(p);
}
}
@@ -876,6 +904,8 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
c.m = partials[i].m;
c.meta = partials[i].meta;
c.stringpool = stringpool + pool_off[partials[i].segment];
c.keys = partials[i].keys;
c.values = partials[i].values;
features[layer].push_back(c);
}
@@ -967,7 +997,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
feature.geometry = to_feature(features[k][x].geom);
count += features[k][x].geom.size();
decode_meta(features[k][x].m, &features[k][x].meta, features[k][x].stringpool, layer, feature);
decode_meta(features[k][x].m, features[k][x].keys, features[k][x].values, features[k][x].stringpool, layer, feature);
layer.features.push_back(feature);
}