Add basezoom parameter for dot-dropping, independent of maxzoom

This commit is contained in:
Eric Fischer 2015-12-15 11:56:49 -08:00
parent 3b8a5d42dd
commit 7372a2c4bc
4 changed files with 30 additions and 22 deletions

View File

@ -66,8 +66,9 @@ Options
### Zoom levels and resolution ### Zoom levels and resolution
* -z _zoom_: Base (maxzoom) zoom level (default 14) * -z _zoom_: Max zoom level (default 14)
* -Z _zoom_: Lowest (minzoom) zoom level (default 0) * -Z _zoom_: Lowest (minzoom) zoom level (default 0)
* -B _zoom_: Base zoom, the level at which point data is complete (default maxzoom)
* -d _detail_: Detail at base zoom level (default 12, for tile resolution of 4096) * -d _detail_: Detail at base zoom level (default 12, for tile resolution of 4096)
* -D _detail_: Detail at lower zoom levels (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) * -m _detail_: Minimum detail that it will try if tiles are too big at regular detail (default 7)
@ -142,7 +143,7 @@ coordinated with the base zoom level and dot-dropping rate. You can use this she
calculate the appropriate marker-width at high zoom levels to match the fraction of dots calculate the appropriate marker-width at high zoom levels to match the fraction of dots
that were dropped at low zoom levels. that were dropped at low zoom levels.
If you used `-z` to change the base zoom level or `-r` to change the If you used `-B` or `-z` to change the base zoom level or `-r` to change the
dot-dropping rate, replace them in the `basezoom` and `rate` below. dot-dropping rate, replace them in the `basezoom` and `rate` below.
awk 'BEGIN { awk 'BEGIN {
@ -167,7 +168,9 @@ Geometric simplifications
At every zoom level, line and polygon features are subjected to Douglas-Peucker At every zoom level, line and polygon features are subjected to Douglas-Peucker
simplification to the resolution of the tile. simplification to the resolution of the tile.
For point features, it drops 1/2.5 of the dots for each zoom level above the base. For point features, it drops 1/2.5 of the dots for each zoom level above the
point base zoom (which is normally the same as the `-z` max zoom, but can be
a different zoom specified with `-B` if you have precise but sparse data).
I don't know why 2.5 is the appropriate number, but the densities of many different I don't know why 2.5 is the appropriate number, but the densities of many different
data sets fall off at about this same rate. You can use -r to specify a different rate. data sets fall off at about this same rate. You can use -r to specify a different rate.

View File

@ -437,7 +437,7 @@ long long addpool(struct memfile *poolfile, struct memfile *treefile, char *s, c
return off; return off;
} }
int serialize_geometry(json_object *geometry, json_object *properties, const char *reading, json_pull *jp, long long *seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, const char *fname, int maxzoom, int layer, double droprate, long long *file_bbox, json_object *tippecanoe) { int serialize_geometry(json_object *geometry, json_object *properties, const char *reading, json_pull *jp, long long *seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, const char *fname, int maxzoom, int basezoom, int layer, double droprate, long long *file_bbox, json_object *tippecanoe) {
json_object *geometry_type = json_hash_get(geometry, "type"); json_object *geometry_type = json_hash_get(geometry, "type");
if (geometry_type == NULL) { if (geometry_type == NULL) {
static int warned = 0; static int warned = 0;
@ -587,7 +587,7 @@ int serialize_geometry(json_object *geometry, json_object *properties, const cha
if (r == 0) { if (r == 0) {
r = .00000001; r = .00000001;
} }
minzoom = maxzoom - floor(log(r) / -log(droprate)); minzoom = basezoom - floor(log(r) / -log(droprate));
} }
serialize_byte(geomfile, minzoom, geompos, fname); serialize_byte(geomfile, minzoom, geompos, fname);
@ -626,7 +626,7 @@ int serialize_geometry(json_object *geometry, json_object *properties, const cha
return 1; return 1;
} }
void parse_json(json_pull *jp, const char *reading, long long *seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, char *fname, int maxzoom, int layer, double droprate, long long *file_bbox) { void parse_json(json_pull *jp, const char *reading, long long *seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, char *fname, int maxzoom, int basezoom, int layer, double droprate, long long *file_bbox) {
long long found_hashes = 0; long long found_hashes = 0;
long long found_features = 0; long long found_features = 0;
long long found_geometries = 0; long long found_geometries = 0;
@ -691,7 +691,7 @@ void parse_json(json_pull *jp, const char *reading, long long *seq, long long *m
} }
found_geometries++; found_geometries++;
serialize_geometry(j, NULL, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, NULL); serialize_geometry(j, NULL, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, basezoom, layer, droprate, file_bbox, NULL);
json_free(j); json_free(j);
continue; continue;
} }
@ -726,10 +726,10 @@ void parse_json(json_pull *jp, const char *reading, long long *seq, long long *m
if (geometries != NULL) { if (geometries != NULL) {
int g; int g;
for (g = 0; g < geometries->length; g++) { for (g = 0; g < geometries->length; g++) {
serialize_geometry(geometries->array[g], properties, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, tippecanoe); serialize_geometry(geometries->array[g], properties, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, basezoom, layer, droprate, file_bbox, tippecanoe);
} }
} else { } else {
serialize_geometry(geometry, properties, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, tippecanoe); serialize_geometry(geometry, properties, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, basezoom, layer, droprate, file_bbox, tippecanoe);
} }
json_free(j); json_free(j);
@ -738,7 +738,7 @@ void parse_json(json_pull *jp, const char *reading, long long *seq, long long *m
} }
} }
int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, char *prevent, char *additional) { int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, char *prevent, char *additional) {
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
char metaname[strlen(tmpdir) + strlen("/meta.XXXXXXXX") + 1]; char metaname[strlen(tmpdir) + strlen("/meta.XXXXXXXX") + 1];
@ -866,7 +866,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
layer = source; layer = source;
} }
parse_json(jp, reading, &seq, &metapos, &geompos, &indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox); parse_json(jp, reading, &seq, &metapos, &geompos, &indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, basezoom, layer, droprate, file_bbox);
json_end(jp); json_end(jp);
fclose(fp); fclose(fp);
@ -1138,7 +1138,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
fprintf(stderr, "%lld features, %lld bytes of geometry, %lld bytes of metadata, %lld bytes of string pool\n", seq, (long long) geomst.st_size, (long long) metast.st_size, poolfile->off); fprintf(stderr, "%lld features, %lld bytes of geometry, %lld bytes of metadata, %lld bytes of string pool\n", seq, (long long) geomst.st_size, (long long) metast.st_size, poolfile->off);
} }
int written = traverse_zooms(fd, size, meta, stringpool, file_keys, &midx, &midy, layernames, maxzoom, minzoom, outdb, droprate, buffer, fname, tmpdir, gamma, nlayers, prevent, additional, full_detail, low_detail, min_detail); int written = traverse_zooms(fd, size, meta, stringpool, file_keys, &midx, &midy, layernames, maxzoom, minzoom, basezoom, outdb, droprate, buffer, fname, tmpdir, gamma, nlayers, prevent, additional, full_detail, low_detail, min_detail);
if (maxzoom != written) { if (maxzoom != written) {
fprintf(stderr, "\n\n\n*** NOTE TILES ONLY COMPLETE THROUGH ZOOM %d ***\n\n\n", written); fprintf(stderr, "\n\n\n*** NOTE TILES ONLY COMPLETE THROUGH ZOOM %d ***\n\n\n", written);
@ -1224,6 +1224,7 @@ int main(int argc, char **argv) {
char *outdir = NULL; char *outdir = NULL;
int maxzoom = 14; int maxzoom = 14;
int minzoom = 0; int minzoom = 0;
int basezoom = -1;
int force = 0; int force = 0;
double droprate = 2.5; double droprate = 2.5;
double gamma = 0; double gamma = 0;
@ -1242,7 +1243,7 @@ int main(int argc, char **argv) {
additional[i] = 0; additional[i] = 0;
} }
while ((i = getopt(argc, argv, "l:n:z:Z:d:D:m:o:x:y:r:b:fXt:g:p:vqa:")) != -1) { while ((i = getopt(argc, argv, "l:n:z:Z:d:D:m:o:x:y:r:b:fXt:g:p:vqa:B:")) != -1) {
switch (i) { switch (i) {
case 'n': case 'n':
name = optarg; name = optarg;
@ -1260,6 +1261,10 @@ int main(int argc, char **argv) {
minzoom = atoi(optarg); minzoom = atoi(optarg);
break; break;
case 'B':
basezoom = atoi(optarg);
break;
case 'd': case 'd':
full_detail = atoi(optarg); full_detail = atoi(optarg);
break; break;
@ -1332,7 +1337,7 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
default: default:
fprintf(stderr, "Usage: %s -o out.mbtiles [-n name] [-l layername] [-z maxzoom] [-Z minzoom] [-d detail] [-D lower-detail] [-m min-detail] [-x excluded-field ...] [-y included-field ...] [-X] [-r droprate] [-b buffer] [-t tmpdir] [-a rco] [-p sfkld] [-q] [file.json ...]\n", argv[0]); fprintf(stderr, "Usage: %s -o out.mbtiles [-n name] [-l layername] [-z maxzoom] [-Z minzoom] [-B basezoom] [-d detail] [-D lower-detail] [-m min-detail] [-x excluded-field ...] [-y included-field ...] [-X] [-r droprate] [-b buffer] [-t tmpdir] [-a rco] [-p sfkld] [-q] [file.json ...]\n", argv[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -1342,6 +1347,10 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (basezoom < 0) {
basezoom = maxzoom;
}
if (full_detail <= 0) { if (full_detail <= 0) {
full_detail = 12; full_detail = 12;
} }
@ -1365,7 +1374,7 @@ int main(int argc, char **argv) {
sqlite3 *outdb = mbtiles_open(outdir, argv); sqlite3 *outdb = mbtiles_open(outdir, argv);
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
ret = read_json(argc - optind, argv + optind, name ? name : outdir, layer, maxzoom, minzoom, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, prevent, additional); ret = read_json(argc - optind, argv + optind, name ? name : outdir, layer, maxzoom, minzoom, basezoom, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, prevent, additional);
mbtiles_close(outdb, argv); mbtiles_close(outdb, argv);

View File

@ -906,8 +906,6 @@ struct write_tile_args {
int buffer; int buffer;
const char *fname; const char *fname;
FILE **geomfile; FILE **geomfile;
int file_minzoom;
int file_maxzoom;
double todo; double todo;
volatile long long *along; volatile long long *along;
double gamma; double gamma;
@ -999,7 +997,7 @@ void *run_thread(void *vargs) {
return NULL; return NULL;
} }
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail) { int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail) {
int i; int i;
for (i = 0; i <= maxzoom; i++) { for (i = 0; i <= maxzoom; i++) {
long long most = 0; long long most = 0;
@ -1098,7 +1096,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo
args[thread].metabase = metabase; args[thread].metabase = metabase;
args[thread].stringpool = stringpool; args[thread].stringpool = stringpool;
args[thread].min_detail = min_detail; args[thread].min_detail = min_detail;
args[thread].basezoom = maxzoom; // XXX rename? args[thread].basezoom = basezoom;
args[thread].file_keys = file_keys; // locked with var_lock args[thread].file_keys = file_keys; // locked with var_lock
args[thread].layernames = layernames; args[thread].layernames = layernames;
args[thread].outdb = outdb; // locked with db_lock args[thread].outdb = outdb; // locked with db_lock
@ -1106,8 +1104,6 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo
args[thread].buffer = buffer; args[thread].buffer = buffer;
args[thread].fname = fname; args[thread].fname = fname;
args[thread].geomfile = sub + thread * (TEMP_FILES / threads); args[thread].geomfile = sub + thread * (TEMP_FILES / threads);
args[thread].file_minzoom = minzoom;
args[thread].file_maxzoom = maxzoom;
args[thread].todo = todo; args[thread].todo = todo;
args[thread].along = &along; // locked with var_lock args[thread].along = &along; // locked with var_lock
args[thread].gamma = gamma; args[thread].gamma = gamma;

2
tile.h
View File

@ -27,7 +27,7 @@ struct pool_val *deserialize_string(char **f, struct pool *p, int type);
long long write_tile(char **geom, char *metabase, char *stringpool, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int min_detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, char *prevent, char *additional); long long write_tile(char **geom, char *metabase, char *stringpool, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int min_detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, char *prevent, char *additional);
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail); int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail);
extern unsigned initial_x, initial_y; extern unsigned initial_x, initial_y;
extern int geometry_scale; extern int geometry_scale;