From 40418113728bdefdc8109231a1ab3bc919bdfa60 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Fri, 10 Apr 2015 11:36:30 -0700 Subject: [PATCH] Add flags to disable simplification/coalescing/limits when unwanted --- README.md | 8 ++++++++ geojson.c | 28 +++++++++++++++++++++------- tile.cc | 12 ++++++------ tile.h | 2 +- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index a941de31..4f120b9c 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,14 @@ Options * -r rate: Rate at which dots are dropped at lower zoom levels (default 2.5) * -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 less + + * -ps: Don't simplify lines + * -pr: Don't reverse the direction of lines to make them coalesce better + * -pc: Don't coalesce features with the same properties + * -pf: Don't limit tiles to 200,000 features + * -pk: Don't limit tiles to 500K bytes + Example ------- diff --git a/geojson.c b/geojson.c index 377aeff2..86b1b2eb 100644 --- a/geojson.c +++ b/geojson.c @@ -194,7 +194,7 @@ struct pool_val *deserialize_string(char **f, struct pool *p, int type) { return ret; } -int traverse_zooms(int geomfd[4], off_t geom_size[4], char *metabase, unsigned *file_bbox, 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) { +int traverse_zooms(int geomfd[4], off_t geom_size[4], char *metabase, unsigned *file_bbox, 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) { int i; for (i = 0; i <= maxzoom; i++) { long long most = 0; @@ -255,7 +255,7 @@ int traverse_zooms(int geomfd[4], off_t geom_size[4], char *metabase, unsigned * // fprintf(stderr, "%d/%u/%u\n", z, x, y); - long long len = write_tile(&geom, metabase, file_bbox, z, x, y, z == maxzoom ? full_detail : low_detail, maxzoom, file_keys, layernames, outdb, droprate, buffer, fname, sub, minzoom, maxzoom, todo, geomstart, along, gamma, nlayers); + long long len = write_tile(&geom, metabase, file_bbox, z, x, y, z == maxzoom ? full_detail : low_detail, maxzoom, file_keys, layernames, outdb, droprate, buffer, fname, sub, minzoom, maxzoom, todo, geomstart, along, gamma, nlayers, prevent); if (len < 0) { return i - 1; @@ -361,7 +361,7 @@ static void merge(struct merge *merges, int nmerges, unsigned char *map, FILE *f } } -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) { +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) { int ret = EXIT_SUCCESS; char metaname[strlen(tmpdir) + strlen("/meta.XXXXXXXX") + 1]; @@ -885,7 +885,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\n", seq, (long long) geomst.st_size, (long long) metast.st_size); - int written = traverse_zooms(fd, size, meta, file_bbox, file_keys, &midx, &midy, layernames, maxzoom, minzoom, outdb, droprate, buffer, fname, tmpdir, gamma, nlayers); + int written = traverse_zooms(fd, size, meta, file_bbox, file_keys, &midx, &midy, layernames, maxzoom, minzoom, outdb, droprate, buffer, fname, tmpdir, gamma, nlayers, prevent); if (maxzoom != written) { fprintf(stderr, "\n\n\n*** NOTE TILES ONLY COMPLETE THROUGH ZOOM %d ***\n\n\n", written); @@ -949,13 +949,18 @@ int main(int argc, char **argv) { double gamma = 0; int buffer = 5; const char *tmpdir = "/tmp"; + char prevent[256]; struct pool exclude, include; pool_init(&exclude, 0); pool_init(&include, 0); int exclude_all = 0; - while ((i = getopt(argc, argv, "l:n:z:Z:d:D:o:x:y:r:b:fXt:g:")) != -1) { + for (i = 0; i < 256; i++) { + prevent[i] = 0; + } + + while ((i = getopt(argc, argv, "l:n:z:Z:d:D:o:x:y:r:b:fXt:g:p:")) != -1) { switch (i) { case 'n': name = optarg; @@ -1018,8 +1023,17 @@ int main(int argc, char **argv) { gamma = atof(optarg); break; + case 'p': + { + char *cp; + for (cp = optarg; *cp != '\0'; cp++) { + prevent[*cp & 0xFF] = 1; + } + } + break; + default: - fprintf(stderr, "Usage: %s -o out.mbtiles [-n name] [-l layername] [-z maxzoom] [-Z minzoom] [-d detail] [-D lower-detail] [-x excluded-field ...] [-y included-field ...] [-X] [-r droprate] [-b buffer] [-t tmpdir] [file.json]\n", argv[0]); + fprintf(stderr, "Usage: %s -o out.mbtiles [-n name] [-l layername] [-z maxzoom] [-Z minzoom] [-d detail] [-D lower-detail] [-x excluded-field ...] [-y included-field ...] [-X] [-r droprate] [-b buffer] [-t tmpdir] [-p rcfs] [file.json ...]\n", argv[0]); exit(EXIT_FAILURE); } } @@ -1043,7 +1057,7 @@ int main(int argc, char **argv) { sqlite3 *outdb = mbtiles_open(outdir, argv); 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); + ret = read_json(argc - optind, argv + optind, name ? name : outdir, layer, maxzoom, minzoom, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, prevent); mbtiles_close(outdb, argv); return ret; diff --git a/tile.cc b/tile.cc index 4a48f99f..c2412ba5 100644 --- a/tile.cc +++ b/tile.cc @@ -348,7 +348,7 @@ void evaluate(std::vector &features, char *metabase, struct pool *file } #endif -long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE *geomfile[4], int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers) { +long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE *geomfile[4], int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, char *prevent) { int line_detail; static bool evaluated = false; double oprogress = 0; @@ -555,7 +555,7 @@ long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, u geom = reduce_tiny_poly(geom, z, line_detail, &reduced, &accum_area); } - if (t == VT_LINE || t == VT_POLYGON) { + if ((t == VT_LINE || t == VT_POLYGON) && !prevent['s' & 0xFF]) { if (!reduced) { geom = simplify_lines(geom, z, line_detail); } @@ -567,7 +567,7 @@ long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, u } #endif - if (t == VT_LINE) { + if (t == VT_LINE && !prevent['r' & 0xFF]) { geom = reorder_lines(geom); } @@ -620,7 +620,7 @@ long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, u fprintf(stderr, "\nfeature out of order\n"); } - if (out.size() > 0 && out[y].geom.size() + features[j][x].geom.size() < 20000 && coalcmp(&features[j][x], &out[y]) == 0 && features[j][x].type != VT_POINT) { + if (!prevent['c' & 0xFF] && out.size() > 0 && out[y].geom.size() + features[j][x].geom.size() < 20000 && coalcmp(&features[j][x], &out[y]) == 0 && features[j][x].type != VT_POINT) { unsigned z; for (z = 0; z < features[j][x].geom.size(); z++) { out[y].geom.push_back(features[j][x].geom[z]); @@ -646,7 +646,7 @@ long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, u } if (totalsize > 0) { - if (totalsize > 200000) { + if (totalsize > 200000 && !prevent['f' & 0xFF]) { fprintf(stderr, "tile %d/%u/%u has %lld features, >200000 \n", z, tx, ty, totalsize); fprintf(stderr, "Try using -z to set a higher base zoom level.\n"); return -1; @@ -666,7 +666,7 @@ long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, u tile.SerializeToString(&s); compress(s, compressed); - if (compressed.size() > 500000) { + if (compressed.size() > 500000 && !prevent['k' & 0xFF]) { fprintf(stderr, "tile %d/%u/%u size is %lld with detail %d, >500000 \n", z, tx, ty, (long long) compressed.size(), line_detail); if (line_detail == MIN_DETAIL || !evaluated) { diff --git a/tile.h b/tile.h index 0ab429bf..84c13e23 100644 --- a/tile.h +++ b/tile.h @@ -25,4 +25,4 @@ void deserialize_uint(char **f, unsigned *n); void deserialize_byte(char **f, signed char *n); struct pool_val *deserialize_string(char **f, struct pool *p, int type); -long long write_tile(char **geom, char *metabase, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE *geomfile[4], int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers); +long long write_tile(char **geom, char *metabase, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE *geomfile[4], int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, char *prevent);