From 150e3663e1e982bcf341fe35f13002d9a6093684 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Fri, 13 Jan 2017 14:59:11 -0800 Subject: [PATCH] Pass the index, sequence, and extent through the prefilter when needed --- decode.cpp | 2 +- geojson.cpp | 2 ++ plugin.cpp | 66 +++++++++++++++++++++++++++++++++++++------------- tile.cpp | 2 +- write_json.cpp | 43 +++++++++++++++++++++++++++++--- write_json.hpp | 2 +- 6 files changed, 93 insertions(+), 24 deletions(-) diff --git a/decode.cpp b/decode.cpp index 49a66dc..3dbb1ec 100644 --- a/decode.cpp +++ b/decode.cpp @@ -63,7 +63,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) { within = 0; } - layer_to_geojson(stdout, layer, z, x, y, true, false); + layer_to_geojson(stdout, layer, z, x, y, true, false, 0, 0, 0); if (describe) { printf("] }\n"); diff --git a/geojson.cpp b/geojson.cpp index 1a9733a..2e6a83b 100644 --- a/geojson.cpp +++ b/geojson.cpp @@ -317,6 +317,8 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje if (additional[A_DROP_DENSEST_AS_NEEDED] || additional[A_CALCULATE_FEATURE_DENSITY] || additional[A_INCREASE_GAMMA_AS_NEEDED] || uses_gamma) { sf.index = bbox_index; + } else { + sf.index = 0; } if (inline_meta) { diff --git a/plugin.cpp b/plugin.cpp index bb8ba00..1703211 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -51,7 +51,7 @@ void *run_writer(void *a) { } for (size_t i = 0; i < wa->layers->size(); i++) { - layer_to_geojson(fp, (*(wa->layers))[i], wa->z, wa->x, wa->y, false, true); + layer_to_geojson(fp, (*(wa->layers))[i], wa->z, wa->x, wa->y, false, true, 0, 0, 0); } if (fclose(fp) != 0) { @@ -369,27 +369,59 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std:: } if (dv.size() > 0) { - std::string layername = "unknown"; - json_object *tippecanoe = json_hash_get(j, "tippecanoe"); - json_object *layer = NULL; - if (tippecanoe != NULL) { - layer = json_hash_get(tippecanoe, "layer"); - if (layer != NULL && layer->type == JSON_STRING) { - layername = std::string(layer->string); - } - } - sf.t = mb_geometry[t]; sf.segment = tiling_seg; sf.geometry = dv; - sf.seq = 0; // XXX - sf.index = 0; // XXX - sf.bbox[0] = sf.bbox[1] = sf.bbox[2] = sf.bbox[3] = 0; // XXX - sf.extent = 0; // XXX - sf.m = 0; // XXX - sf.metapos = 0; // XXX + sf.seq = 0; + sf.index = 0; + sf.bbox[0] = sf.bbox[1] = LLONG_MAX; + sf.bbox[2] = sf.bbox[3] = LLONG_MIN; + sf.extent = 0; + sf.m = 0; + sf.metapos = 0; sf.has_id = false; + std::string layername = "unknown"; + json_object *tippecanoe = json_hash_get(j, "tippecanoe"); + if (tippecanoe != NULL) { + json_object *layer = json_hash_get(tippecanoe, "layer"); + if (layer != NULL && layer->type == JSON_STRING) { + layername = std::string(layer->string); + } + + json_object *index = json_hash_get(tippecanoe, "index"); + if (index != NULL && index->type == JSON_NUMBER) { + sf.index = index->number; + } + + json_object *sequence = json_hash_get(tippecanoe, "sequence"); + if (sequence != NULL && sequence->type == JSON_NUMBER) { + sf.seq = sequence->number; + } + + json_object *extent = json_hash_get(tippecanoe, "extent"); + if (extent != NULL && sequence->type == JSON_NUMBER) { + sf.extent = extent->number; + } + } + + for (size_t i = 0; i < dv.size(); i++) { + if (dv[i].op == VT_MOVETO || dv[i].op == VT_LINETO) { + if (dv[i].x < sf.bbox[0]) { + sf.bbox[0] = dv[i].x; + } + if (dv[i].y < sf.bbox[1]) { + sf.bbox[1] = dv[i].y; + } + if (dv[i].x > sf.bbox[2]) { + sf.bbox[2] = dv[i].x; + } + if (dv[i].y > sf.bbox[3]) { + sf.bbox[3] = dv[i].y; + } + } + } + json_object *id = json_hash_get(j, "id"); if (id != NULL) { sf.id = atoll(id->string); diff --git a/tile.cpp b/tile.cpp index e003f60..3d6e115 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1374,7 +1374,7 @@ void *run_prefilter(void *v) { decode_meta(sf.m, sf.keys, sf.values, rpa->stringpool + rpa->pool_off[sf.segment], tmp_layer, tmp_feature); tmp_layer.features.push_back(tmp_feature); - layer_to_geojson(rpa->prefilter_fp, tmp_layer, 0, 0, 0, false, true); + layer_to_geojson(rpa->prefilter_fp, tmp_layer, 0, 0, 0, false, true, sf.index, sf.seq, sf.extent); } if (fclose(rpa->prefilter_fp) != 0) { diff --git a/write_json.cpp b/write_json.cpp index ebcbd55..4060182 100644 --- a/write_json.cpp +++ b/write_json.cpp @@ -24,7 +24,7 @@ struct lonlat { } }; -void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name) { +void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, unsigned long long index, long long sequence, long long extent) { for (size_t f = 0; f < layer.features.size(); f++) { mvt_feature const &feat = layer.features[f]; @@ -38,9 +38,44 @@ void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, fprintf(fp, ", \"id\": %llu", feat.id); } - if (name) { - fprintf(fp, ", \"tippecanoe\": { \"layer\": "); - fprintq(fp, layer.name.c_str()); + if (name || index != 0 || sequence != 0 || extent != 0) { + bool need_comma = false; + + fprintf(fp, ", \"tippecanoe\": { "); + + if (name) { + if (need_comma) { + fprintf(fp, ", "); + } + fprintf(fp, "\"layer\": "); + fprintq(fp, layer.name.c_str()); + need_comma = true; + } + + if (index != 0) { + if (need_comma) { + fprintf(fp, ", "); + } + fprintf(fp, "\"index\": %llu", index); + need_comma = true; + } + + if (sequence != 0) { + if (need_comma) { + fprintf(fp, ", "); + } + fprintf(fp, "\"sequence\": %lld", sequence); + need_comma = true; + } + + if (extent != 0) { + if (need_comma) { + fprintf(fp, ", "); + } + fprintf(fp, "\"extent\": %lld", extent); + need_comma = true; + } + fprintf(fp, " }"); } diff --git a/write_json.hpp b/write_json.hpp index c7f1b2a..20b6a89 100644 --- a/write_json.hpp +++ b/write_json.hpp @@ -1,2 +1,2 @@ -void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name); +void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, unsigned long long index, long long sequence, long long extent); void fprintq(FILE *f, const char *s);