Fill out layermaps when reading the output of the postfilter

This commit is contained in:
Eric Fischer 2016-12-12 15:12:41 -08:00
parent 57ff54e683
commit 5e7f718afc
4 changed files with 1821 additions and 13 deletions

View File

@ -8,13 +8,16 @@
#include <vector>
#include <string>
#include <map>
#include <set>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <cmath>
#include <sys/types.h>
#include <sys/wait.h>
#include <sqlite3.h>
#include "mvt.hpp"
#include "mbtiles.hpp"
#include "projection.hpp"
#include "geometry.hpp"
#include "serial.hpp"
@ -67,12 +70,14 @@ static std::vector<mvt_geometry> to_feature(drawvec &geom) {
return out;
}
mvt_layer parse_layer(int fd, unsigned z, unsigned x, unsigned y, mvt_layer const &olayer) {
mvt_layer parse_layer(int fd, unsigned z, unsigned x, unsigned y, mvt_layer const &olayer, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg) {
mvt_layer ret;
ret.name = olayer.name;
ret.version = olayer.version;
ret.extent = olayer.extent;
std::string layername = olayer.name;
FILE *f = fdopen(fd, "r");
if (f == NULL) {
perror("fdopen filter output");
@ -186,6 +191,8 @@ mvt_layer parse_layer(int fd, unsigned z, unsigned x, unsigned y, mvt_layer cons
feature.has_id = true;
}
std::map<std::string, layermap_entry> &layermap = (*layermaps)[tiling_seg];
for (size_t i = 0; i < properties->length; i++) {
int tp = -1;
std::string s;
@ -194,6 +201,27 @@ mvt_layer parse_layer(int fd, unsigned z, unsigned x, unsigned y, mvt_layer cons
if (tp >= 0) {
mvt_value v = stringified_to_mvt_value(tp, s.c_str());
ret.tag(feature, std::string(properties->keys[i]->string), v);
if (layermap.count(layername) == 0) {
layermap_entry lme = layermap_entry(layermap.size());
lme.minzoom = z;
lme.maxzoom = z;
layermap.insert(std::pair<std::string, layermap_entry>(layername, lme));
}
type_and_string tas;
tas.string = std::string(properties->keys[i]->string);
tas.type = tp;
auto fk = layermap.find(layername);
if (z < fk->second.minzoom) {
fk->second.minzoom = z;
}
if (z > fk->second.maxzoom) {
fk->second.maxzoom = z;
}
fk->second.file_keys.insert(tas);
}
}
@ -204,7 +232,10 @@ mvt_layer parse_layer(int fd, unsigned z, unsigned x, unsigned y, mvt_layer cons
}
json_end(jp);
fclose(f);
if (fclose(f) != 0) {
perror("fclose postfilter output");
exit(EXIT_FAILURE);
}
return ret;
}
@ -434,7 +465,7 @@ void setup_filter(const char *filter, int *write_to, int *read_from, pid_t *pid,
}
}
mvt_layer filter_layer(const char *filter, mvt_layer &layer, unsigned z, unsigned x, unsigned y) {
mvt_layer filter_layer(const char *filter, mvt_layer &layer, unsigned z, unsigned x, unsigned y, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg) {
int write_to, read_from;
pid_t pid;
setup_filter(filter, &write_to, &read_from, &pid, z, x, y);
@ -452,12 +483,7 @@ mvt_layer filter_layer(const char *filter, mvt_layer &layer, unsigned z, unsigne
exit(EXIT_FAILURE);
}
layer = parse_layer(read_from, z, x, y, layer);
if (close(read_from) != 0) {
perror("close output from filter");
exit(EXIT_FAILURE);
}
layer = parse_layer(read_from, z, x, y, layer, layermaps, tiling_seg);
while (1) {
int stat_loc;

View File

@ -1,3 +1,3 @@
mvt_layer filter_layer(const char *filter, mvt_layer &layer, unsigned z, unsigned x, unsigned y);
mvt_layer filter_layer(const char *filter, mvt_layer &layer, unsigned z, unsigned x, unsigned y, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg);
void setup_filter(const char *filter, int *write_to, int *read_from, pid_t *pid, unsigned z, unsigned x, unsigned y);
serial_feature parse_feature(json_pull *jp, unsigned z, unsigned x, unsigned y);

File diff suppressed because it is too large Load Diff

View File

@ -1176,6 +1176,7 @@ struct write_tile_args {
double fraction_out;
const char *prefilter;
const char *postfilter;
size_t tiling_seg;
};
bool clip_to_tile(serial_feature &sf, int z, long long buffer) {
@ -1381,7 +1382,7 @@ void *run_prefilter(void *v) {
return NULL;
}
long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *stringpool, int z, unsigned tx, unsigned ty, int detail, int min_detail, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int minzoom, int maxzoom, double todo, volatile long long *along, long long alongminus, double gamma, int child_shards, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, volatile int *running, double simplification, std::vector<std::map<std::string, layermap_entry>> *layermaps, std::vector<std::vector<std::string>> *layer_unmaps, size_t pass, size_t passes, unsigned long long mingap, long long minextent, double fraction, const char *prefilter, const char *postfilter, write_tile_args *arg) {
long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *stringpool, int z, unsigned tx, unsigned ty, int detail, int min_detail, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int minzoom, int maxzoom, double todo, volatile long long *along, long long alongminus, double gamma, int child_shards, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, volatile int *running, double simplification, std::vector<std::map<std::string, layermap_entry>> *layermaps, std::vector<std::vector<std::string>> *layer_unmaps, size_t tiling_seg, size_t pass, size_t passes, unsigned long long mingap, long long minextent, double fraction, const char *prefilter, const char *postfilter, write_tile_args *arg) {
int line_detail;
double merge_fraction = 1;
double mingap_fraction = 1;
@ -1825,7 +1826,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
}
if (postfilter != NULL) {
layer = filter_layer(postfilter, layer, z, tx, ty);
layer = filter_layer(postfilter, layer, z, tx, ty, layermaps, tiling_seg);
}
if (layer.features.size() > 0) {
@ -2054,7 +2055,7 @@ void *run_thread(void *vargs) {
// fprintf(stderr, "%d/%u/%u\n", z, x, y);
long long len = write_tile(geom, &geompos, arg->metabase, arg->stringpool, z, x, y, z == arg->maxzoom ? arg->full_detail : arg->low_detail, arg->min_detail, arg->basezoom, arg->outdb, arg->droprate, arg->buffer, arg->fname, arg->geomfile, arg->minzoom, arg->maxzoom, arg->todo, arg->along, geompos, arg->gamma, arg->child_shards, arg->meta_off, arg->pool_off, arg->initial_x, arg->initial_y, arg->running, arg->simplification, arg->layermaps, arg->layer_unmaps, arg->pass, arg->passes, arg->mingap, arg->minextent, arg->fraction, arg->prefilter, arg->postfilter, arg);
long long len = write_tile(geom, &geompos, arg->metabase, arg->stringpool, z, x, y, z == arg->maxzoom ? arg->full_detail : arg->low_detail, arg->min_detail, arg->basezoom, arg->outdb, arg->droprate, arg->buffer, arg->fname, arg->geomfile, arg->minzoom, arg->maxzoom, arg->todo, arg->along, geompos, arg->gamma, arg->child_shards, arg->meta_off, arg->pool_off, arg->initial_x, arg->initial_y, arg->running, arg->simplification, arg->layermaps, arg->layer_unmaps, arg->tiling_seg, arg->pass, arg->passes, arg->mingap, arg->minextent, arg->fraction, arg->prefilter, arg->postfilter, arg);
if (len < 0) {
int *err = &arg->err;
@ -2133,6 +2134,14 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo
}
}
// The existing layermaps are one table per input thread.
// We need to add another one per *tiling* thread so that it can be
// safely changed during tiling.
size_t layermaps_off = layermaps.size();
for (size_t i = 0; i < CPUS; i++) {
layermaps.push_back(std::map<std::string, layermap_entry>());
}
int i;
for (i = 0; i <= maxzoom; i++) {
long long most = 0;
@ -2286,6 +2295,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo
args[thread].initial_y = initial_y;
args[thread].layermaps = &layermaps;
args[thread].layer_unmaps = &layer_unmaps;
args[thread].tiling_seg = thread + layermaps_off;
args[thread].prefilter = prefilter;
args[thread].postfilter = postfilter;