mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-02-02 01:08:14 +00:00
Merge pull request #426 from mapbox/extend-zooms
Add an option to increase maxzoom if features are still being dropped
This commit is contained in:
commit
240ccbd219
@ -1,3 +1,7 @@
|
||||
## 1.19.1
|
||||
|
||||
* Add an option to increase maxzoom if features are still being dropped
|
||||
|
||||
## 1.19.0
|
||||
|
||||
* Tile-join can merge and create directories, not only mbtiles
|
||||
|
@ -135,6 +135,9 @@ than at all newlines.
|
||||
* `-z` _zoom_ or `--maximum-zoom=`_zoom_: Maxzoom: the highest zoom level for which tiles are generated (default 14)
|
||||
* `-zg` or `--maximum-zoom=g`: Guess what is probably a reasonable maxzoom based on the spacing of features.
|
||||
* `-Z` _zoom_ or `--minimum-zoom=`_zoom_: Minzoom: the lowest zoom level for which tiles are generated (default 0)
|
||||
* `-ae` or `--extend-zooms-if-still-dropping`: Increase the maxzoom if features are still being dropped at that zoom level.
|
||||
The detail and simplification options that ordinarily apply only to the maximum zoom level will apply both to the originally
|
||||
specified maximum zoom and to any levels added beyond that.
|
||||
|
||||
### Tile resolution
|
||||
|
||||
@ -393,12 +396,12 @@ tile-join
|
||||
=========
|
||||
|
||||
Tile-join is a tool for joining new attributes from a CSV file to features
|
||||
that have already been tiled with tippecanoe. It reads the tiles from an
|
||||
that have already been tiled with tippecanoe. It reads the tiles from an
|
||||
existing .mbtiles file or a directory of tiles, matches them against the
|
||||
records of the CSV, and writes out a new tileset.
|
||||
|
||||
If you specify multiple source mbtiles files or source directories of tiles,
|
||||
all the sources are read and their combined contents are written to the new
|
||||
all the sources are read and their combined contents are written to the new
|
||||
mbtiles output. If they define the same layers or the same tiles, the layers
|
||||
or tiles are merged.
|
||||
|
||||
|
3
main.cpp
3
main.cpp
@ -75,8 +75,6 @@ size_t TEMP_FILES;
|
||||
long long MAX_FILES;
|
||||
static long long diskfree;
|
||||
|
||||
#define MAX_ZOOM 24
|
||||
|
||||
struct reader {
|
||||
int metafd;
|
||||
int poolfd;
|
||||
@ -2090,6 +2088,7 @@ int main(int argc, char **argv) {
|
||||
{"Zoom levels", 0, 0, 0},
|
||||
{"maximum-zoom", required_argument, 0, 'z'},
|
||||
{"minimum-zoom", required_argument, 0, 'Z'},
|
||||
{"extend-zooms-if-still-dropping", no_argument, &additional[A_EXTEND_ZOOMS], 1},
|
||||
|
||||
{"Tile resolution", 0, 0, 0},
|
||||
{"full-detail", required_argument, 0, 'd'},
|
||||
|
2
main.hpp
2
main.hpp
@ -16,3 +16,5 @@ extern size_t CPUS;
|
||||
extern size_t TEMP_FILES;
|
||||
|
||||
extern size_t max_tile_size;
|
||||
|
||||
#define MAX_ZOOM 24
|
||||
|
@ -48,6 +48,24 @@ The GeoJSON features need not be wrapped in a FeatureCollection.
|
||||
You can concatenate multiple GeoJSON features or files together,
|
||||
and it will parse out the features and ignore whatever other objects
|
||||
it encounters.
|
||||
.SH Docker Image
|
||||
.PP
|
||||
A tippecanoe Docker image can be built from source and executed as a task to
|
||||
automatically install dependencies and allow tippecanoe to run on any system
|
||||
supported by Docker.
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
$ docker build \-t tippecanoe:latest .
|
||||
$ docker run \-it \-\-rm \\
|
||||
\-v /tiledata:/data \\
|
||||
tippecanoe:latest \\
|
||||
tippecanoe \-\-output=/data/output.mbtiles /data/example.geojson
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
The commands above will build a Docker image from the source and compile the
|
||||
latest version. The image supports all tippecanoe flags and options.
|
||||
.SH Options
|
||||
.PP
|
||||
There are a lot of options. A lot of the time you won't want to use any of them
|
||||
@ -126,6 +144,10 @@ than at all newlines.
|
||||
\fB\fC\-zg\fR or \fB\fC\-\-maximum\-zoom=g\fR: Guess what is probably a reasonable maxzoom based on the spacing of features.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-Z\fR \fIzoom\fP or \fB\fC\-\-minimum\-zoom=\fR\fIzoom\fP: Minzoom: the lowest zoom level for which tiles are generated (default 0)
|
||||
.IP \(bu 2
|
||||
\fB\fC\-ae\fR or \fB\fC\-\-extend\-zooms\-if\-still\-dropping\fR: Increase the maxzoom if features are still being dropped at that zoom level.
|
||||
The detail and simplification options that ordinarily apply only to the maximum zoom level will apply both to the originally
|
||||
specified maximum zoom and to any levels added beyond that.
|
||||
.RE
|
||||
.SS Tile resolution
|
||||
.RS
|
||||
@ -431,20 +453,27 @@ Check out some examples of maps made with tippecanoe \[la]MADE_WITH.md\[ra]
|
||||
The name is a joking reference \[la]http://en.wikipedia.org/wiki/Tippecanoe_and_Tyler_Too\[ra] to a "tiler" for making map tiles.
|
||||
.SH tile\-join
|
||||
.PP
|
||||
Tile\-join is a tool for joining new attributes from a CSV file to features that
|
||||
have already been tiled with tippecanoe. It reads the tiles from an existing .mbtiles
|
||||
file, matches them against the records of the CSV, and writes out a new tileset.
|
||||
Tile\-join is a tool for joining new attributes from a CSV file to features
|
||||
that have already been tiled with tippecanoe. It reads the tiles from an
|
||||
existing .mbtiles file or a directory of tiles, matches them against the
|
||||
records of the CSV, and writes out a new tileset.
|
||||
.PP
|
||||
If you specify multiple source mbtiles files, they are all read and their combined
|
||||
contents are written to the new mbtiles output. If they define the same layers or
|
||||
the same tiles, the layers or tiles are merged.
|
||||
If you specify multiple source mbtiles files or source directories of tiles,
|
||||
all the sources are read and their combined contents are written to the new
|
||||
mbtiles output. If they define the same layers or the same tiles, the layers
|
||||
or tiles are merged.
|
||||
.PP
|
||||
You can use the \fB\fC\-e\fR flag to output a directory of tiles rather than a
|
||||
\&.mbtiles file.
|
||||
.PP
|
||||
The options are:
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fC\-o\fR \fIout.mbtiles\fP: Write the new tiles to the specified .mbtiles file
|
||||
\fB\fC\-o\fR \fIout.mbtiles\fP: Write the new tiles to the specified .mbtiles file.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-f\fR: Remove \fIout.mbtiles\fP if it already exists
|
||||
\fB\fC\-e\fR \fIdirectory\fP: Write the new tiles to the specified directory instead of to an mbtiles file.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-f\fR: Remove \fIout.mbtiles\fP if it already exists.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-c\fR \fImatch\fP\fB\fC\&.csv\fR: Use \fImatch\fP\fB\fC\&.csv\fR as the source for new attributes to join to the features. The first line of the file should be the key names; the other lines are values. The first column is the one to match against the existing features; the other columns are the new data to add.
|
||||
.IP \(bu 2
|
||||
@ -454,6 +483,8 @@ The options are:
|
||||
.IP \(bu 2
|
||||
\fB\fC\-pk\fR: Don't skip tiles larger than 500K.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-pC\fR: Don't compress the PBF vector tile data.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-l\fR \fIlayer\fP: Include the named layer in the output. You can specify multiple \fB\fC\-l\fR options to keep multiple layers. If you don't specify, they will all be retained.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-L\fR \fIlayer\fP: Remove the named layer from the output. You can specify multiple \fB\fC\-L\fR options to remove multiple layers.
|
||||
|
@ -14,6 +14,7 @@
|
||||
#define A_DROP_SMALLEST_AS_NEEDED ((int) 'n')
|
||||
#define A_GRID_LOW_ZOOMS ((int) 'L')
|
||||
#define A_DETECT_WRAPAROUND ((int) 'w')
|
||||
#define A_EXTEND_ZOOMS ((int) 'e')
|
||||
|
||||
#define P_SIMPLIFY ((int) 's')
|
||||
#define P_SIMPLIFY_LOW ((int) 'S')
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
39
tile.cpp
39
tile.cpp
@ -254,7 +254,7 @@ static int is_integer(const char *s, long long *v) {
|
||||
}
|
||||
|
||||
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int line_detail, int *within, long long *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, int m, std::vector<long long> &metakeys, std::vector<long long> &metavals, bool has_id, unsigned long long id, unsigned long long index, long long extent) {
|
||||
if (geom.size() > 0 && nextzoom <= maxzoom) {
|
||||
if (geom.size() > 0 && (nextzoom <= maxzoom || additional[A_EXTEND_ZOOMS])) {
|
||||
int xo, yo;
|
||||
int span = 1 << (nextzoom - z);
|
||||
|
||||
@ -1221,6 +1221,8 @@ struct write_tile_args {
|
||||
long long minextent_out;
|
||||
double fraction;
|
||||
double fraction_out;
|
||||
bool still_dropping;
|
||||
int wrote_zoom;
|
||||
};
|
||||
|
||||
long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *stringpool, int z, unsigned tx, unsigned ty, int detail, int min_detail, int basezoom, sqlite3 *outdb, const char *outdir, double droprate, int buffer, const char *fname, FILE **geomfile, int minzoom, int maxzoom, double todo, volatile long long *along, long long alongminus, double gamma, int child_shards, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, volatile int *running, double simplification, std::vector<std::map<std::string, layermap_entry>> *layermaps, std::vector<std::vector<std::string>> *layer_unmaps, size_t pass, size_t passes, unsigned long long mingap, long long minextent, double fraction, write_tile_args *arg) {
|
||||
@ -1791,6 +1793,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
|
||||
if (gamma > arg->gamma_out) {
|
||||
arg->gamma_out = gamma;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
@ -1800,9 +1803,14 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
continue;
|
||||
} else if (additional[A_DROP_DENSEST_AS_NEEDED]) {
|
||||
mingap_fraction = mingap_fraction * 200000.0 / totalsize * 0.90;
|
||||
mingap = choose_mingap(indices, mingap_fraction);
|
||||
unsigned long long mg = choose_mingap(indices, mingap_fraction);
|
||||
if (mg <= mingap) {
|
||||
mg = mingap * 1.5;
|
||||
}
|
||||
mingap = mg;
|
||||
if (mingap > arg->mingap_out) {
|
||||
arg->mingap_out = mingap;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Going to try keeping the sparsest %0.2f%% of the features to make it fit\n", mingap_fraction * 100.0);
|
||||
@ -1816,6 +1824,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
minextent = m;
|
||||
if (minextent > arg->minextent_out) {
|
||||
arg->minextent_out = minextent;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Going to try keeping the biggest %0.2f%% of the features to make it fit\n", minextent_fraction * 100.0);
|
||||
@ -1830,6 +1839,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
}
|
||||
if (additional[A_DROP_FRACTION_AS_NEEDED] && fraction < arg->fraction_out) {
|
||||
arg->fraction_out = fraction;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
line_detail++; // to keep it the same when the loop decrements it
|
||||
continue;
|
||||
@ -1868,6 +1878,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
|
||||
if (gamma > arg->gamma_out) {
|
||||
arg->gamma_out = gamma;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
@ -1876,9 +1887,14 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
line_detail++; // to keep it the same when the loop decrements it
|
||||
} else if (additional[A_DROP_DENSEST_AS_NEEDED]) {
|
||||
mingap_fraction = mingap_fraction * max_tile_size / compressed.size() * 0.90;
|
||||
mingap = choose_mingap(indices, mingap_fraction);
|
||||
unsigned long long mg = choose_mingap(indices, mingap_fraction);
|
||||
if (mg <= mingap) {
|
||||
mg = mingap * 1.5;
|
||||
}
|
||||
mingap = mg;
|
||||
if (mingap > arg->mingap_out) {
|
||||
arg->mingap_out = mingap;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Going to try keeping the sparsest %0.2f%% of the features to make it fit\n", mingap_fraction * 100.0);
|
||||
@ -1891,6 +1907,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
minextent = m;
|
||||
if (minextent > arg->minextent_out) {
|
||||
arg->minextent_out = minextent;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Going to try keeping the biggest %0.2f%% of the features to make it fit\n", minextent_fraction * 100.0);
|
||||
@ -1908,6 +1925,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
|
||||
}
|
||||
if (additional[A_DROP_FRACTION_AS_NEEDED] && fraction < arg->fraction_out) {
|
||||
arg->fraction_out = fraction;
|
||||
arg->still_dropping = true;
|
||||
}
|
||||
line_detail++; // to keep it the same when the loop decrements it
|
||||
}
|
||||
@ -1982,6 +2000,8 @@ void *run_thread(void *vargs) {
|
||||
deserialize_uint_io(geom, &x, &geompos);
|
||||
deserialize_uint_io(geom, &y, &geompos);
|
||||
|
||||
arg->wrote_zoom = z;
|
||||
|
||||
// fprintf(stderr, "%d/%u/%u\n", z, x, y);
|
||||
|
||||
long long len = write_tile(geom, &geompos, arg->metabase, arg->stringpool, z, x, y, z == arg->maxzoom ? arg->full_detail : arg->low_detail, arg->min_detail, arg->basezoom, arg->outdb, arg->outdir, arg->droprate, arg->buffer, arg->fname, arg->geomfile, arg->minzoom, arg->maxzoom, arg->todo, arg->along, geompos, arg->gamma, arg->child_shards, arg->meta_off, arg->pool_off, arg->initial_x, arg->initial_y, arg->running, arg->simplification, arg->layermaps, arg->layer_unmaps, arg->pass, arg->passes, arg->mingap, arg->minextent, arg->fraction, arg);
|
||||
@ -2049,7 +2069,7 @@ void *run_thread(void *vargs) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, const char *outdir, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, double simplification, std::vector<std::map<std::string, layermap_entry>> &layermaps) {
|
||||
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, int &maxzoom, int minzoom, int basezoom, sqlite3 *outdb, const char *outdir, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, double simplification, std::vector<std::map<std::string, layermap_entry>> &layermaps) {
|
||||
// Table to map segment and layer number back to layer name
|
||||
std::vector<std::vector<std::string>> layer_unmaps;
|
||||
for (size_t seg = 0; seg < layermaps.size(); seg++) {
|
||||
@ -2222,6 +2242,8 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo
|
||||
args[thread].running = &running;
|
||||
args[thread].pass = pass;
|
||||
args[thread].passes = 2 - start;
|
||||
args[thread].wrote_zoom = -1;
|
||||
args[thread].still_dropping = false;
|
||||
|
||||
if (pthread_create(&pthreads[thread], NULL, run_thread, &args[thread]) != 0) {
|
||||
perror("pthread_create");
|
||||
@ -2252,6 +2274,15 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo
|
||||
if (args[thread].fraction_out < zoom_fraction) {
|
||||
zoom_fraction = args[thread].fraction_out;
|
||||
}
|
||||
|
||||
// Zoom counter might be lower than reality if zooms are being skipped
|
||||
if (args[thread].wrote_zoom > i) {
|
||||
i = args[thread].wrote_zoom;
|
||||
}
|
||||
|
||||
if (additional[A_EXTEND_ZOOMS] && i == maxzoom && args[thread].still_dropping && maxzoom < MAX_ZOOM) {
|
||||
maxzoom++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
2
tile.hpp
2
tile.hpp
@ -1,5 +1,5 @@
|
||||
long long write_tile(char **geom, char *metabase, char *stringpool, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int min_detail, int basezoom, sqlite3 *outdb, const char *outdir, double droprate, int buffer, const char *fname, FILE **geomfile, int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers);
|
||||
|
||||
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, const char *outdir, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, double simplification, std::vector<std::map<std::string, layermap_entry> > &layermap);
|
||||
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, int &maxzoom, int minzoom, int basezoom, sqlite3 *outdb, const char *outdir, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, double simplification, std::vector<std::map<std::string, layermap_entry> > &layermap);
|
||||
|
||||
int manage_gap(unsigned long long index, unsigned long long *previndex, double scale, double gamma, double *gap);
|
||||
|
@ -1 +1 @@
|
||||
#define VERSION "tippecanoe v1.19.0\n"
|
||||
#define VERSION "tippecanoe v1.19.1\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user