From 6a2e80769e4cbe1fc4f6e1915682c26f386a1b26 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Fri, 16 Dec 2016 12:20:57 -0800 Subject: [PATCH] Choose a deeper initial tile than 0/0/0 if one contains all the features --- CHANGELOG.md | 5 +++ main.cpp | 100 +++++++++++++++++++++++++++++++-------------------- version.hpp | 2 +- 3 files changed, 67 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6232f8..b63981b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.16.1 + +* Choose a deeper starting tile than 0/0/0 if there is one that contains + all the features + ## 1.16.0 * Switch from Clipper to Wagyu for polygon topology correction diff --git a/main.cpp b/main.cpp index ca4bd86..30cc4a7 100644 --- a/main.cpp +++ b/main.cpp @@ -943,7 +943,58 @@ void radix(struct reader *reader, int nreaders, FILE *geomfile, int geomfd, FILE } } -int read_input(std::vector &sources, char *fname, const char *layername, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, std::set *exclude, std::set *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma) { +void choose_first_zoom(long long *file_bbox, struct reader *reader, unsigned *iz, unsigned *ix, unsigned *iy, int minzoom, int buffer) { + for (size_t i = 0; i < CPUS; i++) { + if (reader[i].file_bbox[0] < file_bbox[0]) { + file_bbox[0] = reader[i].file_bbox[0]; + } + if (reader[i].file_bbox[1] < file_bbox[1]) { + file_bbox[1] = reader[i].file_bbox[1]; + } + if (reader[i].file_bbox[2] > file_bbox[2]) { + file_bbox[2] = reader[i].file_bbox[2]; + } + if (reader[i].file_bbox[3] > file_bbox[3]) { + file_bbox[3] = reader[i].file_bbox[3]; + } + } + + // If the bounding box extends off the plane on either side, + // a feature wrapped across the date line, so the width of the + // bounding box is the whole world. + if (file_bbox[0] < 0) { + file_bbox[0] = 0; + file_bbox[2] = (1LL << 32) - 1; + } + if (file_bbox[2] > (1LL << 32) - 1) { + file_bbox[0] = 0; + file_bbox[2] = (1LL << 32) - 1; + } + if (file_bbox[1] < 0) { + file_bbox[1] = 0; + } + if (file_bbox[3] > (1LL << 32) - 1) { + file_bbox[3] = (1LL << 32) - 1; + } + + for (ssize_t z = minzoom; z >= 0; z--) { + long long shift = 1LL << (32 - z); + + long long left = (file_bbox[0] - buffer * shift / 256) / shift; + long long top = (file_bbox[1] - buffer * shift / 256) / shift; + long long right = (file_bbox[2] + buffer * shift / 256) / shift; + long long bottom = (file_bbox[3] + buffer * shift / 256) / shift; + + if (left == right && top == bottom) { + *iz = z; + *ix = left; + *iy = top; + break; + } + } +} + +int read_input(std::vector &sources, char *fname, const char *layername, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, std::set *exclude, std::set *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox) { int ret = EXIT_SUCCESS; struct reader reader[CPUS]; @@ -1462,12 +1513,15 @@ int read_input(std::vector &sources, char *fname, const char *layername, } unlink(geomname); + unsigned iz = 0, ix = 0, iy = 0; + choose_first_zoom(file_bbox, reader, &iz, &ix, &iy, minzoom, buffer); + long long geompos = 0; /* initial tile is 0/0/0 */ - serialize_int(geomfile, 0, &geompos, fname); - serialize_uint(geomfile, 0, &geompos, fname); - serialize_uint(geomfile, 0, &geompos, fname); + serialize_int(geomfile, iz, &geompos, fname); + serialize_uint(geomfile, ix, &geompos, fname); + serialize_uint(geomfile, iy, &geompos, fname); radix(reader, CPUS, geomfile, geomfd, indexfile, indexfd, tmpdir, &geompos, maxzoom, basezoom, droprate, gamma); @@ -1759,40 +1813,6 @@ int read_input(std::vector &sources, char *fname, const char *layername, midlat = (maxlat + minlat) / 2; midlon = (maxlon + minlon) / 2; - long long file_bbox[4] = {UINT_MAX, UINT_MAX, 0, 0}; - for (size_t i = 0; i < CPUS; i++) { - if (reader[i].file_bbox[0] < file_bbox[0]) { - file_bbox[0] = reader[i].file_bbox[0]; - } - if (reader[i].file_bbox[1] < file_bbox[1]) { - file_bbox[1] = reader[i].file_bbox[1]; - } - if (reader[i].file_bbox[2] > file_bbox[2]) { - file_bbox[2] = reader[i].file_bbox[2]; - } - if (reader[i].file_bbox[3] > file_bbox[3]) { - file_bbox[3] = reader[i].file_bbox[3]; - } - } - - // If the bounding box extends off the plane on either side, - // a feature wrapped across the date line, so the width of the - // bounding box is the whole world. - if (file_bbox[0] < 0) { - file_bbox[0] = 0; - file_bbox[2] = (1LL << 32) - 1; - } - if (file_bbox[2] > (1LL << 32) - 1) { - file_bbox[0] = 0; - file_bbox[2] = (1LL << 32) - 1; - } - if (file_bbox[1] < 0) { - file_bbox[1] = 0; - } - if (file_bbox[3] > (1LL << 32) - 1) { - file_bbox[3] = (1LL << 32) - 1; - } - tile2lonlat(file_bbox[0], file_bbox[1], 32, &minlon, &maxlat); tile2lonlat(file_bbox[2], file_bbox[3], 32, &maxlon, &minlat); @@ -2230,7 +2250,9 @@ int main(int argc, char **argv) { sources.push_back(src); } - ret = read_input(sources, name ? name : outdir, layer, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0); + long long file_bbox[4] = {UINT_MAX, UINT_MAX, 0, 0}; + + ret = read_input(sources, name ? name : outdir, layer, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox); mbtiles_close(outdb, argv); diff --git a/version.hpp b/version.hpp index 9123a80..3780171 100644 --- a/version.hpp +++ b/version.hpp @@ -1 +1 @@ -#define VERSION "tippecanoe v1.16.0\n" +#define VERSION "tippecanoe v1.16.1\n"