From bc2f243f0b0da665715476aaba7c3eacb0fd0196 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Mon, 1 Jun 2015 15:01:46 -0700 Subject: [PATCH] Add a command line option to specify the minimum allowed tile extent --- README.md | 1 + geojson.c | 16 +++++++++++++--- man/tippecanoe.1 | 2 ++ tile.cc | 7 +++---- tile.h | 2 +- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2022810..d26a7ef 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ Options * -Z _zoom_: Lowest (minzoom) zoom level (default 0) * -d _detail_: Detail at base zoom level (default 26-basezoom, ~0.5m, for tile resolution of 4096 if -z14) * -D _detail_: Detail at lower zoom levels (default 10, for tile resolution of 1024) + * -m _detail_: Minimum detail that it will try if tiles are too big at regular detail (default 7) * -b _pixels_: Buffer size where features are duplicated from adjacent tiles (default 5) ### Properties diff --git a/geojson.c b/geojson.c index 830cd41..aa98a2f 100644 --- a/geojson.c +++ b/geojson.c @@ -23,6 +23,7 @@ int low_detail = 10; int full_detail = -1; +int min_detail = 7; #define GEOM_POINT 0 /* array of positions */ #define GEOM_MULTIPOINT 1 /* array of arrays of positions */ @@ -256,7 +257,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, prevent); + long long len = write_tile(&geom, metabase, file_bbox, z, x, y, z == maxzoom ? full_detail : low_detail, min_detail, maxzoom, file_keys, layernames, outdb, droprate, buffer, fname, sub, minzoom, maxzoom, todo, geomstart, along, gamma, nlayers, prevent); if (len < 0) { return i - 1; @@ -974,7 +975,7 @@ int main(int argc, char **argv) { prevent[i] = 0; } - while ((i = getopt(argc, argv, "l:n:z:Z:d:D:o:x:y:r:b:fXt:g:p:v")) != -1) { + while ((i = getopt(argc, argv, "l:n:z:Z:d:D:m:o:x:y:r:b:fXt:g:p:v")) != -1) { switch (i) { case 'n': name = optarg; @@ -1000,6 +1001,10 @@ int main(int argc, char **argv) { low_detail = atoi(optarg); break; + case 'm': + min_detail = atoi(optarg); + break; + case 'o': outdir = optarg; break; @@ -1051,7 +1056,7 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); 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] [-p rcfs] [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] [-m min-detail] [-x excluded-field ...] [-y included-field ...] [-X] [-r droprate] [-b buffer] [-t tmpdir] [-p rcfs] [file.json ...]\n", argv[0]); exit(EXIT_FAILURE); } } @@ -1068,6 +1073,11 @@ int main(int argc, char **argv) { full_detail = 26 - maxzoom; } + if (full_detail < min_detail || low_detail < min_detail) { + fprintf(stderr, "%s: Full detail and low detail must be at least minimum detail\n", argv[0]); + exit(EXIT_FAILURE); + } + if (outdir == NULL) { fprintf(stderr, "%s: must specify -o out.mbtiles\n", argv[0]); exit(EXIT_FAILURE); diff --git a/man/tippecanoe.1 b/man/tippecanoe.1 index 734eb3c..17d4ddf 100644 --- a/man/tippecanoe.1 +++ b/man/tippecanoe.1 @@ -76,6 +76,8 @@ it encounters. .IP \(bu 2 \-D \fIdetail\fP: Detail at lower zoom levels (default 10, for tile resolution of 1024) .IP \(bu 2 +\-m \fIdetail\fP: Minimum detail that it will try if tiles are too big at regular detail (default 7) +.IP \(bu 2 \-b \fIpixels\fP: Buffer size where features are duplicated from adjacent tiles (default 5) .RE .SS Properties diff --git a/tile.cc b/tile.cc index b1ffff9..c070859 100644 --- a/tile.cc +++ b/tile.cc @@ -25,7 +25,6 @@ extern "C" { } #define CMD_BITS 3 -#define MIN_DETAIL 7 // https://github.com/mapbox/mapnik-vector-tile/blob/master/src/vector_tile_compression.hpp static inline int compress(std::string const& input, std::string& output) { @@ -350,14 +349,14 @@ 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, char *prevent) { +long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int min_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; char *og = *geoms; - for (line_detail = detail; line_detail >= MIN_DETAIL || line_detail == detail; line_detail--) { + for (line_detail = detail; line_detail >= min_detail || line_detail == detail; line_detail--) { GOOGLE_PROTOBUF_VERIFY_VERSION; struct pool keys1[nlayers], values1[nlayers]; @@ -675,7 +674,7 @@ long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, u 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) { + if (line_detail == min_detail || !evaluated) { evaluated = true; #if 0 evaluate(features[0], metabase, file_keys[0], layername, line_detail, compressed.size()); // XXX layer diff --git a/tile.h b/tile.h index 84c13e2..3193231 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, char *prevent); +long long write_tile(char **geom, char *metabase, 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[4], int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, char *prevent);