mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Add -zg option to automatically choose an appropriate maxzoom
This commit is contained in:
@@ -1006,7 +1006,7 @@ void choose_first_zoom(long long *file_bbox, struct reader *reader, unsigned *iz
|
||||
}
|
||||
}
|
||||
|
||||
int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, const char *outdir, std::set<std::string> *exclude, std::set<std::string> *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, const char *description) {
|
||||
int read_input(std::vector<source> &sources, char *fname, int &maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, const char *outdir, std::set<std::string> *exclude, std::set<std::string> *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, const char *description, bool guess_maxzoom) {
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
struct reader reader[CPUS];
|
||||
@@ -1555,15 +1555,75 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (basezoom < 0 || droprate < 0) {
|
||||
struct index *map = (struct index *) mmap(NULL, indexpos, PROT_READ, MAP_PRIVATE, indexfd, 0);
|
||||
if (map == MAP_FAILED) {
|
||||
perror("mmap index for basezoom");
|
||||
struct index *map = (struct index *) mmap(NULL, indexpos, PROT_READ, MAP_PRIVATE, indexfd, 0);
|
||||
if (map == MAP_FAILED) {
|
||||
perror("mmap index for basezoom");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
madvise(map, indexpos, MADV_SEQUENTIAL);
|
||||
madvise(map, indexpos, MADV_WILLNEED);
|
||||
long long indices = indexpos / sizeof(struct index);
|
||||
bool fix_dropping = false;
|
||||
|
||||
if (guess_maxzoom) {
|
||||
double sum = 0;
|
||||
size_t count = 0;
|
||||
|
||||
long long progress = -1;
|
||||
long long ip;
|
||||
for (ip = 0; ip < indices; ip++) {
|
||||
if (map[ip].index != map[ip - 1].index) {
|
||||
count++;
|
||||
sum += log(map[ip].index - map[ip - 1].index);
|
||||
}
|
||||
|
||||
long long nprogress = 100 * ip / indices;
|
||||
if (nprogress != progress) {
|
||||
progress = nprogress;
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Maxzoom: %lld%% \r", progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
// Geometric mean is appropriate because distances between features
|
||||
// are typically lognormally distributed
|
||||
double avg = exp(sum / count);
|
||||
|
||||
// Convert approximately from tile units to feet
|
||||
double dist_ft = sqrt(avg) / 33;
|
||||
double want = dist_ft / 250;
|
||||
|
||||
maxzoom = ceil(log(360 / (.00000274 * want)) / log(2) - full_detail);
|
||||
if (maxzoom < 0) {
|
||||
maxzoom = 0;
|
||||
}
|
||||
if (maxzoom > MAX_ZOOM) {
|
||||
maxzoom = MAX_ZOOM;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Choosing a maxzoom of -z%d for features about %d feet apart\n", maxzoom, (int) ceil(dist_ft));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Can't guess maxzoom (-zg) without at least two distinct feature locations\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
madvise(map, indexpos, MADV_SEQUENTIAL);
|
||||
madvise(map, indexpos, MADV_WILLNEED);
|
||||
|
||||
if (maxzoom < minzoom) {
|
||||
fprintf(stderr, "Can't use %d for maxzoom because minzoom is %d\n", maxzoom, minzoom);
|
||||
maxzoom = minzoom;
|
||||
}
|
||||
|
||||
fix_dropping = true;
|
||||
|
||||
if (basezoom == -1) {
|
||||
basezoom = maxzoom;
|
||||
}
|
||||
}
|
||||
|
||||
if (basezoom < 0 || droprate < 0) {
|
||||
struct tile {
|
||||
unsigned x;
|
||||
unsigned y;
|
||||
@@ -1583,7 +1643,6 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
|
||||
|
||||
long long progress = -1;
|
||||
|
||||
long long indices = indexpos / sizeof(struct index);
|
||||
long long ip;
|
||||
for (ip = 0; ip < indices; ip++) {
|
||||
unsigned xx, yy;
|
||||
@@ -1724,6 +1783,10 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
|
||||
}
|
||||
}
|
||||
|
||||
fix_dropping = true;
|
||||
}
|
||||
|
||||
if (fix_dropping) {
|
||||
// Fix up the minzooms for features, now that we really know the base zoom
|
||||
// and drop rate.
|
||||
|
||||
@@ -1743,7 +1806,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
|
||||
struct drop_state ds[maxzoom + 1];
|
||||
prep_drop_states(ds, maxzoom, basezoom, droprate);
|
||||
|
||||
for (ip = 0; ip < indices; ip++) {
|
||||
for (long long ip = 0; ip < indices; ip++) {
|
||||
if (ip > 0 && map[ip].start != map[ip - 1].end) {
|
||||
fprintf(stderr, "Mismatched index at %lld: %lld vs %lld\n", ip, map[ip].start, map[ip].end);
|
||||
}
|
||||
@@ -1752,10 +1815,11 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
|
||||
}
|
||||
|
||||
munmap(geom, geomst.st_size);
|
||||
madvise(map, indexpos, MADV_DONTNEED);
|
||||
munmap(map, indexpos);
|
||||
}
|
||||
|
||||
madvise(map, indexpos, MADV_DONTNEED);
|
||||
munmap(map, indexpos);
|
||||
|
||||
if (close(indexfd) != 0) {
|
||||
perror("close sorted index");
|
||||
}
|
||||
@@ -1889,6 +1953,7 @@ int main(int argc, char **argv) {
|
||||
const char *tmpdir = "/tmp";
|
||||
const char *attribution = NULL;
|
||||
std::vector<source> sources;
|
||||
bool guess_maxzoom = false;
|
||||
|
||||
std::set<std::string> exclude, include;
|
||||
int exclude_all = 0;
|
||||
@@ -2017,7 +2082,12 @@ int main(int argc, char **argv) {
|
||||
} break;
|
||||
|
||||
case 'z':
|
||||
maxzoom = atoi(optarg);
|
||||
if (strcmp(optarg, "g") == 0) {
|
||||
maxzoom = MAX_ZOOM;
|
||||
guess_maxzoom = true;
|
||||
} else {
|
||||
maxzoom = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
@@ -2217,9 +2287,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Need two checks: one for geometry representation, the other for
|
||||
// index traversal when guessing base zoom and drop rate
|
||||
if (maxzoom > 32 - full_detail) {
|
||||
maxzoom = 32 - full_detail;
|
||||
fprintf(stderr, "Highest supported zoom with detail %d is %d\n", full_detail, maxzoom);
|
||||
if (!guess_maxzoom) {
|
||||
if (maxzoom > 32 - full_detail) {
|
||||
maxzoom = 32 - full_detail;
|
||||
fprintf(stderr, "Highest supported zoom with detail %d is %d\n", full_detail, maxzoom);
|
||||
}
|
||||
}
|
||||
if (maxzoom > MAX_ZOOM) {
|
||||
maxzoom = MAX_ZOOM;
|
||||
@@ -2232,13 +2304,17 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if (basezoom == -1) {
|
||||
basezoom = maxzoom;
|
||||
if (!guess_maxzoom) {
|
||||
basezoom = maxzoom;
|
||||
}
|
||||
}
|
||||
|
||||
geometry_scale = 32 - (full_detail + maxzoom);
|
||||
if (geometry_scale < 0) {
|
||||
geometry_scale = 0;
|
||||
fprintf(stderr, "Full detail + maxzoom > 32, so you are asking for more detail than is available.\n");
|
||||
if (!guess_maxzoom) {
|
||||
fprintf(stderr, "Full detail + maxzoom > 32, so you are asking for more detail than is available.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if ((basezoom < 0 || droprate < 0) && (gamma < 0)) {
|
||||
@@ -2290,7 +2366,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
long long file_bbox[4] = {UINT_MAX, UINT_MAX, 0, 0};
|
||||
|
||||
ret = read_input(sources, name ? name : out_mbtiles ? out_mbtiles : out_directory, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, out_directory, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, description);
|
||||
ret = read_input(sources, name ? name : out_mbtiles ? out_mbtiles : out_directory, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, out_directory, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, description, guess_maxzoom);
|
||||
|
||||
if (outdb != NULL) {
|
||||
mbtiles_close(outdb, argv);
|
||||
|
||||
Reference in New Issue
Block a user