Merge pull request #79 from mapbox/rework-options

Change some defaults that keep tripping people up:
This commit is contained in:
Eric Fischer 2015-08-27 16:10:20 -07:00
commit 93b2687548
5 changed files with 54 additions and 31 deletions

View File

@ -61,12 +61,13 @@ Options
* -o _file_.mbtiles: Name the output file. * -o _file_.mbtiles: Name the output file.
* -f: Delete the mbtiles file if it already exists instead of giving an error * -f: Delete the mbtiles file if it already exists instead of giving an error
* -t _directory_: Put the temporary files in _directory_.
### Zoom levels and resolution ### Zoom levels and resolution
* -z _zoom_: Base (maxzoom) zoom level (default 14) * -z _zoom_: Base (maxzoom) zoom level (default 14)
* -Z _zoom_: Lowest (minzoom) zoom level (default 0) * -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 base zoom level (default 12 at -z14 or higher, or 13 at -z13 or lower. Detail beyond 13 has rendering problems with Mapbox GL.)
* -D _detail_: Detail at lower zoom levels (default 10, for tile resolution of 1024) * -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) * -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. Units are "screen pixels"--1/256th of the tile width or height. (default 5) * -b _pixels_: Buffer size where features are duplicated from adjacent tiles. Units are "screen pixels"--1/256th of the tile width or height. (default 5)
@ -82,15 +83,18 @@ Options
* -r _rate_: Rate at which dots are dropped at lower zoom levels (default 2.5) * -r _rate_: Rate at which dots are dropped at lower zoom levels (default 2.5)
* -g _gamma_: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number. * -g _gamma_: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number.
### Doing more
* -ac: Coalesce adjacent line and polygon features that have the same properties
* -ar: Try reversing the directions of lines to make them coalesce and compress better
* -ao: Reorder features to put ones with the same properties in sequence, to try to get them to coalesce
* -al: Let "dot" dropping at lower zooms apply to lines too
### Doing less ### Doing less
* -ps: Don't simplify lines * -ps: Don't simplify lines
* -pr: Don't reverse the direction of lines to make them coalesce better
* -pc: Don't coalesce features with the same properties
* -pf: Don't limit tiles to 200,000 features * -pf: Don't limit tiles to 200,000 features
* -pk: Don't limit tiles to 500K bytes * -pk: Don't limit tiles to 500K bytes
* -po: Don't reorder features to put the same properties in sequence
* -pl: Let "dot" simplification apply to lines too
* -pd: Dynamically drop some fraction of features from large tiles to keep them under the 500K size limit. It will probably look ugly at the tile boundaries. * -pd: Dynamically drop some fraction of features from large tiles to keep them under the 500K size limit. It will probably look ugly at the tile boundaries.
* -q: Work quietly instead of reporting progress * -q: Work quietly instead of reporting progress

View File

@ -562,7 +562,7 @@ int serialize_geometry(json_object *geometry, json_object *properties, const cha
return 1; return 1;
} }
int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, char *prevent) { int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, char *prevent, char *additional) {
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
char metaname[strlen(tmpdir) + strlen("/meta.XXXXXXXX") + 1]; char metaname[strlen(tmpdir) + strlen("/meta.XXXXXXXX") + 1];
@ -1001,7 +1001,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
fprintf(stderr, "%lld features, %lld bytes of geometry, %lld bytes of metadata, %lld bytes of string pool\n", seq, (long long) geomst.st_size, (long long) metast.st_size, poolfile->off); fprintf(stderr, "%lld features, %lld bytes of geometry, %lld bytes of metadata, %lld bytes of string pool\n", seq, (long long) geomst.st_size, (long long) metast.st_size, poolfile->off);
} }
int written = traverse_zooms(fd, size, meta, stringpool, file_bbox, file_keys, &midx, &midy, layernames, maxzoom, minzoom, outdb, droprate, buffer, fname, tmpdir, gamma, nlayers, prevent, full_detail, low_detail, min_detail); int written = traverse_zooms(fd, size, meta, stringpool, file_bbox, file_keys, &midx, &midy, layernames, maxzoom, minzoom, outdb, droprate, buffer, fname, tmpdir, gamma, nlayers, prevent, additional, full_detail, low_detail, min_detail);
if (maxzoom != written) { if (maxzoom != written) {
fprintf(stderr, "\n\n\n*** NOTE TILES ONLY COMPLETE THROUGH ZOOM %d ***\n\n\n", written); fprintf(stderr, "\n\n\n*** NOTE TILES ONLY COMPLETE THROUGH ZOOM %d ***\n\n\n", written);
@ -1073,6 +1073,7 @@ int main(int argc, char **argv) {
int buffer = 5; int buffer = 5;
const char *tmpdir = "/tmp"; const char *tmpdir = "/tmp";
char prevent[256]; char prevent[256];
char additional[256];
struct pool exclude, include; struct pool exclude, include;
pool_init(&exclude, 0); pool_init(&exclude, 0);
@ -1081,9 +1082,10 @@ int main(int argc, char **argv) {
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
prevent[i] = 0; prevent[i] = 0;
additional[i] = 0;
} }
while ((i = getopt(argc, argv, "l:n:z:Z:d:D:m:o:x:y:r:b:fXt:g:p:vq")) != -1) { while ((i = getopt(argc, argv, "l:n:z:Z:d:D:m:o:x:y:r:b:fXt:g:p:vqa:")) != -1) {
switch (i) { switch (i) {
case 'n': case 'n':
name = optarg; name = optarg;
@ -1161,12 +1163,19 @@ int main(int argc, char **argv) {
} }
} break; } break;
case 'a': {
char *cp;
for (cp = optarg; *cp != '\0'; cp++) {
additional[*cp & 0xFF] = 1;
}
} break;
case 'v': case 'v':
fprintf(stderr, VERSION); fprintf(stderr, VERSION);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
default: default:
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]); 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] [-a rco] [-p sfkld] [-q] [file.json ...]\n", argv[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -1177,8 +1186,13 @@ int main(int argc, char **argv) {
} }
if (full_detail <= 0) { if (full_detail <= 0) {
// ~0.5m accuracy at whatever zoom if (maxzoom >= 14) {
// 12 bits (4096 units) at z14 // ~0.5m accuracy at z14
full_detail = 12;
} else {
// as good as we can get without breaking GL
full_detail = 13;
}
full_detail = 26 - maxzoom; full_detail = 26 - maxzoom;
} }
@ -1202,7 +1216,7 @@ int main(int argc, char **argv) {
sqlite3 *outdb = mbtiles_open(outdir, argv); sqlite3 *outdb = mbtiles_open(outdir, argv);
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
ret = read_json(argc - optind, argv + optind, name ? name : outdir, layer, maxzoom, minzoom, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, prevent); ret = read_json(argc - optind, argv + optind, name ? name : outdir, layer, maxzoom, minzoom, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, prevent, additional);
mbtiles_close(outdb, argv); mbtiles_close(outdb, argv);

View File

@ -64,6 +64,8 @@ it encounters.
\-o \fIfile\fP\&.mbtiles: Name the output file. \-o \fIfile\fP\&.mbtiles: Name the output file.
.IP \(bu 2 .IP \(bu 2
\-f: Delete the mbtiles file if it already exists instead of giving an error \-f: Delete the mbtiles file if it already exists instead of giving an error
.IP \(bu 2
\-t \fIdirectory\fP: Put the temporary files in \fIdirectory\fP\&.
.RE .RE
.SS Zoom levels and resolution .SS Zoom levels and resolution
.RS .RS
@ -72,7 +74,7 @@ it encounters.
.IP \(bu 2 .IP \(bu 2
\-Z \fIzoom\fP: Lowest (minzoom) zoom level (default 0) \-Z \fIzoom\fP: Lowest (minzoom) zoom level (default 0)
.IP \(bu 2 .IP \(bu 2
\-d \fIdetail\fP: Detail at base zoom level (default 26\-basezoom, ~0.5m, for tile resolution of 4096 if \-z14) \-d \fIdetail\fP: Detail at base zoom level (default 12 at \-z14 or higher, or 13 at \-z13 or lower. Detail beyond 13 has rendering problems with Mapbox GL.)
.IP \(bu 2 .IP \(bu 2
\-D \fIdetail\fP: Detail at lower zoom levels (default 10, for tile resolution of 1024) \-D \fIdetail\fP: Detail at lower zoom levels (default 10, for tile resolution of 1024)
.IP \(bu 2 .IP \(bu 2
@ -96,23 +98,26 @@ it encounters.
.IP \(bu 2 .IP \(bu 2
\-g \fIgamma\fP: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number. \-g \fIgamma\fP: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number.
.RE .RE
.SS Doing more
.RS
.IP \(bu 2
\-ac: Coalesce adjacent line and polygon features that have the same properties
.IP \(bu 2
\-ar: Try reversing the directions of lines to make them coalesce and compress better
.IP \(bu 2
\-ao: Reorder features to put ones with the same properties in sequence, to try to get them to coalesce
.IP \(bu 2
\-al: Let "dot" dropping at lower zooms apply to lines too
.RE
.SS Doing less .SS Doing less
.RS .RS
.IP \(bu 2 .IP \(bu 2
\-ps: Don't simplify lines \-ps: Don't simplify lines
.IP \(bu 2 .IP \(bu 2
\-pr: Don't reverse the direction of lines to make them coalesce better
.IP \(bu 2
\-pc: Don't coalesce features with the same properties
.IP \(bu 2
\-pf: Don't limit tiles to 200,000 features \-pf: Don't limit tiles to 200,000 features
.IP \(bu 2 .IP \(bu 2
\-pk: Don't limit tiles to 500K bytes \-pk: Don't limit tiles to 500K bytes
.IP \(bu 2 .IP \(bu 2
\-po: Don't reorder features to put the same properties in sequence
.IP \(bu 2
\-pl: Let "dot" simplification apply to lines too
.IP \(bu 2
\-pd: Dynamically drop some fraction of features from large tiles to keep them under the 500K size limit. It will probably look ugly at the tile boundaries. \-pd: Dynamically drop some fraction of features from large tiles to keep them under the 500K size limit. It will probably look ugly at the tile boundaries.
.IP \(bu 2 .IP \(bu 2
\-q: Work quietly instead of reporting progress \-q: Work quietly instead of reporting progress
@ -167,7 +172,7 @@ I don't know why 2.5 is the appropriate number, but the densities of many differ
data sets fall off at about this same rate. You can use \-r to specify a different rate. data sets fall off at about this same rate. You can use \-r to specify a different rate.
.PP .PP
You can use the gamma option to thin out especially dense clusters of points. You can use the gamma option to thin out especially dense clusters of points.
For any area that where dots are closer than one pixel together (at whatever zoom level), For any area where dots are closer than one pixel together (at whatever zoom level),
a gamma of 3, for example, will reduce these clusters to the cube root of their original density. a gamma of 3, for example, will reduce these clusters to the cube root of their original density.
.PP .PP
For line features, it drops any features that are too small to draw at all. For line features, it drops any features that are too small to draw at all.

14
tile.cc
View File

@ -451,7 +451,7 @@ void rewrite(drawvec &geom, int z, int nextzoom, int file_maxzoom, long long *bb
} }
} }
long long write_tile(char **geoms, char *metabase, char *stringpool, 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, 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, char *stringpool, 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, int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, char *prevent, char *additional) {
int line_detail; int line_detail;
static bool evaluated = false; static bool evaluated = false;
double oprogress = 0; double oprogress = 0;
@ -580,7 +580,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, unsigned *f
continue; continue;
} }
if (gamma >= 0 && (t == VT_POINT || (prevent['l' & 0xFF] && t == VT_LINE))) { if (gamma >= 0 && (t == VT_POINT || (additional['l' & 0xFF] && t == VT_LINE))) {
seq++; seq++;
if (seq >= 0) { if (seq >= 0) {
seq -= interval; seq -= interval;
@ -645,7 +645,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, unsigned *f
} }
#endif #endif
if (t == VT_LINE && !prevent['r' & 0xFF]) { if (t == VT_LINE && additional['r' & 0xFF]) {
geom = reorder_lines(geom); geom = reorder_lines(geom);
} }
@ -687,7 +687,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, unsigned *f
} }
for (j = 0; j < nlayers; j++) { for (j = 0; j < nlayers; j++) {
if (!prevent['o' & 0xFF]) { if (additional['o' & 0xFF]) {
std::sort(features[j].begin(), features[j].end()); std::sort(features[j].begin(), features[j].end());
} }
@ -702,7 +702,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, unsigned *f
} }
#endif #endif
if (!prevent['c' & 0xFF] && out.size() > 0 && out[y].geom.size() + features[j][x].geom.size() < 20000 && coalcmp(&features[j][x], &out[y]) == 0 && features[j][x].type != VT_POINT) { if (additional['c' & 0xFF] && out.size() > 0 && out[y].geom.size() + features[j][x].geom.size() < 20000 && coalcmp(&features[j][x], &out[y]) == 0 && features[j][x].type != VT_POINT) {
unsigned z; unsigned z;
for (z = 0; z < features[j][x].geom.size(); z++) { for (z = 0; z < features[j][x].geom.size(); z++) {
out[y].geom.push_back(features[j][x].geom[z]); out[y].geom.push_back(features[j][x].geom[z]);
@ -794,7 +794,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, unsigned *f
return -1; return -1;
} }
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *file_bbox, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, int full_detail, int low_detail, int min_detail) { int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *file_bbox, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail) {
int i; int i;
for (i = 0; i <= maxzoom; i++) { for (i = 0; i <= maxzoom; i++) {
long long most = 0; long long most = 0;
@ -855,7 +855,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo
// fprintf(stderr, "%d/%u/%u\n", z, x, y); // fprintf(stderr, "%d/%u/%u\n", z, x, y);
long long len = write_tile(&geom, metabase, stringpool, 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); long long len = write_tile(&geom, metabase, stringpool, 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, additional);
if (len < 0) { if (len < 0) {
return i - 1; return i - 1;

4
tile.h
View File

@ -25,9 +25,9 @@ void deserialize_uint(char **f, unsigned *n);
void deserialize_byte(char **f, signed char *n); void deserialize_byte(char **f, signed char *n);
struct pool_val *deserialize_string(char **f, struct pool *p, int type); struct pool_val *deserialize_string(char **f, struct pool *p, int type);
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, struct pool **file_keys, char **layernames, sqlite3 *outdb, 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, char *prevent); 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, struct pool **file_keys, char **layernames, sqlite3 *outdb, 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, char *prevent, char *additional);
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *file_bbox, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, int full_detail, int low_detail, int min_detail); int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *file_bbox, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail);
extern unsigned initial_x, initial_y; extern unsigned initial_x, initial_y;
extern int geometry_scale; extern int geometry_scale;