Add an option to dynamically increase gamma until tiles are small enough

This commit is contained in:
Eric Fischer 2016-10-24 12:29:36 -07:00
parent 1cfc58267e
commit 83e73e8840
5 changed files with 44 additions and 3 deletions

View File

@ -126,6 +126,7 @@ resolution is obtained than by using a smaller _maxzoom_ or _detail_.
* -ap or --drop-polygons: Let "dot" dropping at lower zooms apply to polygons too
* -ag or --calculate-feature-density: Add a new attribute, `tippecanoe_feature_density`, to each feature, to record how densely features are spaced in that area of the tile. You can use this attribute in the style to produce a glowing effect where points are densely packed. It can range from 0 in the sparsest areas to 255 in the densest.
* -ab or --detect-shared-borders: In the manner of [TopoJSON](https://github.com/mbostock/topojson/wiki/Introduction), detect borders that are shared between multiple polygons and simplify them identically in each polygon. This takes more time and memory than considering each polygon individually.
* -aG or --increase-gamma-as-needed: If a tile is too large, try to reduce it to under 500K by increasing the `-g` gamma
### Doing less

View File

@ -1911,6 +1911,7 @@ int main(int argc, char **argv) {
{"prefer-radix-sort", no_argument, &additional[A_PREFER_RADIX_SORT], 1},
{"calculate-feature-density", no_argument, &additional[A_CALCULATE_FEATURE_DENSITY], 1},
{"detect-shared-borders", no_argument, &additional[A_DETECT_SHARED_BORDERS], 1},
{"increase-gamma-as-needed", no_argument, &additional[A_INCREASE_GAMMA_AS_NEEDED], 1},
{"no-line-simplification", no_argument, &prevent[P_SIMPLIFY], 1},
{"simplify-only-low-zooms", no_argument, &prevent[P_SIMPLIFY_LOW], 1},

View File

@ -150,6 +150,8 @@ which may not be what you want.
\-ag or \-\-calculate\-feature\-density: Add a new attribute, \fB\fCtippecanoe_feature_density\fR, to each feature, to record how densely features are spaced in that area of the tile. You can use this attribute in the style to produce a glowing effect where points are densely packed. It can range from 0 in the sparsest areas to 255 in the densest.
.IP \(bu 2
\-ab or \-\-detect\-shared\-borders: In the manner of TopoJSON \[la]https://github.com/mbostock/topojson/wiki/Introduction\[ra], detect borders that are shared between multiple polygons and simplify them identically in each polygon. This takes more time and memory than considering each polygon individually.
.IP \(bu 2
\-aG or \-\-increase\-gamma\-as\-needed: If a tile is too large, try to reduce it to under 500K by increasing the \fB\fC\-g\fR gamma
.RE
.SS Doing less
.RS

View File

@ -7,6 +7,7 @@
#define A_DETECT_SHARED_BORDERS ((int) 'b')
#define A_PREFER_RADIX_SORT ((int) 'R')
#define A_CALCULATE_FEATURE_DENSITY ((int) 'g')
#define A_INCREASE_GAMMA_AS_NEEDED ((int) 'G')
#define P_SIMPLIFY ((int) 's')
#define P_SIMPLIFY_LOW ((int) 'S')

View File

@ -990,6 +990,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
static volatile double oprogress = 0;
bool first_time = true;
// This only loops if the tile data didn't fit, in which case the detail
// goes down and the progress indicator goes backward for the next try.
for (line_detail = detail; line_detail >= min_detail || line_detail == detail; line_detail--, oprogress = 0) {
@ -1177,7 +1178,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
unclipped_features++;
}
if (line_detail == detail && fraction == 1) { /* only write out the next zoom once, even if we retry */
if (first_time) { /* only write out the next zoom once, even if we retry */
rewrite(geom, z, nextzoom, maxzoom, bbox, tx, ty, buffer, line_detail, within, geompos, geomfile, fname, t, layer, metastart, feature_minzoom, child_shards, max_zoom_increment, original_seq, tippecanoe_minzoom, tippecanoe_maxzoom, segment, initial_x, initial_y, m, metakeys, metavals, has_id, id);
}
@ -1253,6 +1254,8 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
}
}
first_time = false;
if (additional[A_DETECT_SHARED_BORDERS]) {
find_common_edges(partials, z, line_detail, simplification, maxzoom);
}
@ -1473,8 +1476,30 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
if (totalsize > 0 && tile.layers.size() > 0) {
if (totalsize > 200000 && !prevent[P_FEATURE_LIMIT]) {
fprintf(stderr, "tile %d/%u/%u has %lld features, >200000 \n", z, tx, ty, totalsize);
fprintf(stderr, "Try using -B to set a higher base zoom level.\n");
return -1;
if (prevent[P_DYNAMIC_DROP]) {
fraction = fraction * 200000 / totalsize * 0.95;
if (!quiet) {
fprintf(stderr, "Going to try keeping %0.2f%% of the features to make it fit\n", fraction * 100);
}
line_detail++; // to keep it the same when the loop decrements it
continue;
} else if (additional[A_INCREASE_GAMMA_AS_NEEDED]) {
if (gamma < 1) {
gamma = 1;
} else {
gamma = gamma * 1.25;
}
if (!quiet) {
fprintf(stderr, "Going to try gamma of %0.3f to make it fit\n", gamma);
}
line_detail++; // to keep it the same when the loop decrements it
continue;
} else {
fprintf(stderr, "Try using -B (and --drop-lines or --drop-polygons if needed) to set a higher base zoom level.\n");
return -1;
}
}
std::string compressed = tile.encode();
@ -1493,6 +1518,17 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
fprintf(stderr, "Going to try keeping %0.2f%% of the features to make it fit\n", fraction * 100);
}
line_detail++; // to keep it the same when the loop decrements it
} else if (additional[A_INCREASE_GAMMA_AS_NEEDED]) {
if (gamma < 1) {
gamma = 1;
} else {
gamma = gamma * 1.25;
}
if (!quiet) {
fprintf(stderr, "Going to try gamma of %0.3f to make it fit\n", gamma);
}
line_detail++; // to keep it the same when the loop decrements it
}
} else {
if (pthread_mutex_lock(&db_lock) != 0) {