From 2c1992c45cbdbefa0d85ea67a311b8270c67fe94 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 18 Aug 2023 12:55:59 -0700 Subject: [PATCH] Add command line option to enable or disable overzooming --- README.md | 5 +++++ clip.cpp | 9 +++++++-- man/tippecanoe.1 | 7 +++++++ tile-join.cpp | 47 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index bd2ab600..1b79a193 100644 --- a/README.md +++ b/README.md @@ -767,6 +767,11 @@ The options are: * `-f` or `--force`: Remove *out.mbtiles* if it already exists. * `-r` or `--read-from`: list of input mbtiles to read from. +### Overzooming + + * `--overzoom`: If one of the source tilesets has a larger maxzoom than the others, scale up tiles from the tilesets with the lower maxzooms so they will all have the same maxzoom in the output tileset. + * `--buffer=`_pixels_ or `-b` _pixels_: Set the size of the tile buffer in the overzoomed tiles. + ### Tileset description and attribution * `-A` *attribution* or `--attribution=`*attribution*: Set the attribution string. diff --git a/clip.cpp b/clip.cpp index b73b8449..1abc3129 100644 --- a/clip.cpp +++ b/clip.cpp @@ -586,9 +586,14 @@ std::string overzoom(std::string s, int oz, int ox, int oy, int nz, int nx, int for (auto const &layer : tile.layers) { mvt_layer outlayer = mvt_layer(); + int det = detail; + if (det <= 0) { + det = std::round(log(layer.extent) / log(2)); + } + outlayer.name = layer.name; outlayer.version = layer.version; - outlayer.extent = 1LL << detail; + outlayer.extent = 1LL << det; for (auto const &feature : layer.features) { mvt_feature outfeature; @@ -636,7 +641,7 @@ std::string overzoom(std::string s, int oz, int ox, int oy, int nz, int nx, int // Scale to output tile extent - to_tile_scale(geom, nz, detail); + to_tile_scale(geom, nz, det); // Clean geometries diff --git a/man/tippecanoe.1 b/man/tippecanoe.1 index 3efc6846..ab72feb2 100644 --- a/man/tippecanoe.1 +++ b/man/tippecanoe.1 @@ -968,6 +968,13 @@ The options are: .IP \(bu 2 \fB\fC\-r\fR or \fB\fC\-\-read\-from\fR: list of input mbtiles to read from. .RE +.SS Overzooming +.RS +.IP \(bu 2 +\fB\fC\-\-overzoom\fR: If one of the source tilesets has a larger maxzoom than the others, scale up tiles from the tilesets with the lower maxzooms so they will all have the same maxzoom in the output tileset. +.IP \(bu 2 +\fB\fC\-\-buffer=\fR\fIpixels\fP or \fB\fC\-b\fR \fIpixels\fP: Set the size of the tile buffer in the overzoomed tiles. +.RE .SS Tileset description and attribution .RS .IP \(bu 2 diff --git a/tile-join.cpp b/tile-join.cpp index b72cd9e4..ece54815 100644 --- a/tile-join.cpp +++ b/tile-join.cpp @@ -53,6 +53,9 @@ int minzoom = 0; std::map renames; bool exclude_all = false; +bool want_overzoom = false; +int buffer = 5; + bool progress_time() { return false; } @@ -571,7 +574,7 @@ std::string retrieve_overzoom(struct reader *r, zxy tile) { } if (source.size() != 0) { - std::string ret = overzoom(source, parent_tile.z, parent_tile.x, parent_tile.y, tile.z, tile.x, tile.y, 12, 5, std::set()); + std::string ret = overzoom(source, parent_tile.z, parent_tile.x, parent_tile.y, tile.z, tile.x, tile.y, -1, buffer, std::set()); return ret; } @@ -601,17 +604,18 @@ void *join_worker(void *v) { for (auto ai = a->inputs.begin(); ai != a->inputs.end(); ++ai) { mvt_tile tile; - for (struct reader *r = a->readers; r != NULL; r = r->next) { - if (r->maxzoom_so_far < ai->first.z) { - // if this reader did not produce any tiles at this zoom level, - // and is not ready to produce any tiles at this zoom level, - // it is a candidate for overzooming this tile from whatever - // zoom level it did produce last. + if (want_overzoom) { + for (struct reader *r = a->readers; r != NULL; r = r->next) { + if (r->maxzoom_so_far < ai->first.z) { + // if this reader did not produce any tiles at this zoom level, + // and is not ready to produce any tiles at this zoom level, + // it is a candidate for overzooming this tile from whatever + // zoom level it did produce last. - // printf("overzooming %lld/%lld/%lld from zoom %d in %s\n", ai->first.z, ai->first.x, ai->first.y, r->maxzoom_so_far, r->name.c_str()); - std::string overzoomed = retrieve_overzoom(r, ai->first); - if (overzoomed.size() != 0) { - ai->second.push_back(overzoomed); + std::string overzoomed = retrieve_overzoom(r, ai->first); + if (overzoomed.size() != 0) { + ai->second.push_back(overzoomed); + } } } } @@ -958,8 +962,10 @@ void decode(struct reader *readers, std::map &layer if (sqlite3_step(r->stmt) == SQLITE_ROW) { int maxz = min(sqlite3_column_int(r->stmt, 0), maxzoom); - if (st->maxzoom >= 0 && maxz != st->maxzoom) { - fprintf(stderr, "Warning: mismatched maxzooms: %d in %s vs previous %d\n", maxz, r->name.c_str(), st->maxzoom); + if (!want_overzoom) { + if (st->maxzoom >= 0 && maxz != st->maxzoom) { + fprintf(stderr, "Warning: mismatched maxzooms: %d in %s vs previous %d\n", maxz, r->name.c_str(), st->maxzoom); + } } st->maxzoom = max(st->maxzoom, maxz); @@ -1117,6 +1123,8 @@ int main(int argc, char **argv) { {"output", required_argument, 0, 'o'}, {"output-to-directory", required_argument, 0, 'e'}, {"force", no_argument, 0, 'f'}, + {"overzoom", no_argument, 0, 'O'}, + {"buffer", required_argument, 0, 'b'}, {"if-matched", no_argument, 0, 'i'}, {"attribution", required_argument, 0, 'A'}, {"name", required_argument, 0, 'n'}, @@ -1182,6 +1190,14 @@ int main(int argc, char **argv) { force = 1; break; + case 'O': + want_overzoom = true; + break; + + case 'b': + buffer = atoi(optarg); + break; + case 'i': ifmatched = 1; break; @@ -1338,6 +1354,11 @@ int main(int argc, char **argv) { exit(EXIT_ARGS); } + if (buffer < 0) { + fprintf(stderr, "%s: buffer cannot be less than 0\n", argv[0]); + exit(EXIT_ARGS); + } + if (out_mbtiles != NULL) { if (force) { unlink(out_mbtiles);