From 668181724390850baceaf838a197e2ab808a502c Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Wed, 16 Dec 2015 12:13:24 -0800 Subject: [PATCH] Add an option to guess the drop rate --- README.md | 5 +++-- geojson.c | 48 +++++++++++++++++++++++++++++++++++++----------- man/tippecanoe.1 | 5 +++-- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 71b7d77..31cc9d0 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ Options * -z _zoom_: Maxzoom: the highest zoom level for which tiles are generated (default 14) * -Z _zoom_: Minzoom: the lowest zoom level for which tiles are generated (default 0) * -B _zoom_: Base zoom, the level at and above which all points are included in the tiles (default maxzoom). - If you use -Bg, it will guess a zoom level that will keep less than 50,000 features in the densest tile. + If you use -Bg, it will guess a zoom level that will keep at most 50,000 features in the densest tile. * -d _detail_: Detail at max zoom level (default 12, for tile resolution of 4096) * -D _detail_: Detail at lower zoom levels (default 12, for tile resolution of 4096) * -m _detail_: Minimum detail that it will try if tiles are too big at regular detail (default 7) @@ -83,7 +83,8 @@ Options ### Point simplification - * -r _rate_: Rate at which dots are dropped at zoom levels below basezoom (default 2.5) + * -r _rate_: Rate at which dots are dropped at zoom levels below basezoom (default 2.5). + If you use -rg, it will guess a drop rate that will keep at most 50,000 features in the densest tile. * -g _gamma_: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number. ### Doing more diff --git a/geojson.c b/geojson.c index 4a6f973..0750fcf 100644 --- a/geojson.c +++ b/geojson.c @@ -1046,7 +1046,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max exit(EXIT_FAILURE); } - if (basezoom < 0) { + if (basezoom < 0 || droprate < 0) { struct index *map = mmap(NULL, indexpos, PROT_READ, MAP_PRIVATE, indexfd, 0); if (map == MAP_FAILED) { perror("mmap"); @@ -1096,22 +1096,44 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max } } - basezoom = MAX_ZOOM; - int z; for (z = MAX_ZOOM; z >= 0; z--) { if (tile[z].count > max[z].count) { max[z] = tile[z]; } - - if (max[z].count < 50000) { - basezoom = z; - } - - // printf("%d/%u/%u %lld\n", z, max[z].x, max[z].y, max[z].count); } - fprintf(stderr, "Choosing a base zoom of -B%d to keep %lld features in tile %d/%u/%u.\n", basezoom, max[basezoom].count, basezoom, max[basezoom].x, max[basezoom].y); +#define MAX_FEATURES 50000 + + if (basezoom < 0) { + basezoom = MAX_ZOOM; + + for (z = MAX_ZOOM; z >= 0; z--) { + if (max[z].count < MAX_FEATURES) { + basezoom = z; + } + + // printf("%d/%u/%u %lld\n", z, max[z].x, max[z].y, max[z].count); + } + + fprintf(stderr, "Choosing a base zoom of -B%d to keep %lld features in tile %d/%u/%u.\n", basezoom, max[basezoom].count, basezoom, max[basezoom].x, max[basezoom].y); + } + + if (droprate < 0) { + droprate = 1; + + for (z = 0; z <= basezoom; z++) { + double interval = exp(log(droprate) * (basezoom - z)); + + if (max[z].count / interval >= MAX_FEATURES) { + interval = (long double) max[z].count / MAX_FEATURES; + droprate = exp(log(interval) / (basezoom - z)); + interval = exp(log(droprate) * (basezoom - z)); + + fprintf(stderr, "Choosing a drop rate of -r%f to keep %f features in tile %d/%u/%u.\n", droprate, max[z].count / interval, z, max[z].x, max[z].y); + } + } + } munmap(map, indexpos); } @@ -1375,7 +1397,11 @@ int main(int argc, char **argv) { break; case 'r': - droprate = atof(optarg); + if (strcmp(optarg, "g") == 0) { + droprate = -2; + } else { + droprate = atof(optarg); + } break; case 'b': diff --git a/man/tippecanoe.1 b/man/tippecanoe.1 index 6f677bd..65dc9ad 100644 --- a/man/tippecanoe.1 +++ b/man/tippecanoe.1 @@ -76,7 +76,7 @@ specified, the files are all merged into the single named layer. \-Z \fIzoom\fP: Minzoom: the lowest zoom level for which tiles are generated (default 0) .IP \(bu 2 \-B \fIzoom\fP: Base zoom, the level at and above which all points are included in the tiles (default maxzoom). -If you use \-Bg, it will guess a zoom level that will keep less than 50,000 features in the densest tile. +If you use \-Bg, it will guess a zoom level that will keep at most 50,000 features in the densest tile. .IP \(bu 2 \-d \fIdetail\fP: Detail at max zoom level (default 12, for tile resolution of 4096) .IP \(bu 2 @@ -98,7 +98,8 @@ If you use \-Bg, it will guess a zoom level that will keep less than 50,000 feat .SS Point simplification .RS .IP \(bu 2 -\-r \fIrate\fP: Rate at which dots are dropped at zoom levels below basezoom (default 2.5) +\-r \fIrate\fP: Rate at which dots are dropped at zoom levels below basezoom (default 2.5). +If you use \-rg, it will guess a drop rate that will keep at most 50,000 features in the densest tile. .IP \(bu 2 \-g \fIgamma\fP: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number. .RE