Add an option to exclude tiles that are entirely covered by a polygon

This commit is contained in:
Eric Fischer 2019-10-23 17:38:01 -07:00
parent ec00ac2516
commit 4ce6265423
5 changed files with 3861 additions and 0 deletions

View File

@ -490,6 +490,7 @@ the same layer, enclose them in an `all` expression so they will all be evaluate
* `-b` _pixels_ or `--buffer=`_pixels_: Buffer size where features are duplicated from adjacent tiles. Units are "screen pixels"—1/256th of the tile width or height. (default 5)
* `-pc` or `--no-clipping`: Don't clip features to the size of the tile. If a feature overlaps the tile's bounds or buffer at all, it is included completely. Be careful: this can produce very large tilesets, especially with large polygons.
* `-pD` or `--no-duplication`: As with `--no-clipping`, each feature is included intact instead of cut to tile boundaries. In addition, it is included only in a single tile per zoom level rather than potentially in multiple copies. Clients of the tileset must check adjacent tiles (possibly some distance away) to ensure they have all features.
* `-pF` or `--remove-filled`: Do not generate tiles that consist entirely of polygons that cover the entire extent of the tile. This is primarily useful for preventing the generation of large number of water or land cover tiles.
### Reordering features within each tile

View File

@ -2579,6 +2579,7 @@ int main(int argc, char **argv) {
{"buffer", required_argument, 0, 'b'},
{"no-clipping", no_argument, &prevent[P_CLIPPING], 1},
{"no-duplication", no_argument, &prevent[P_DUPLICATION], 1},
{"remove-filled", no_argument, &prevent[P_FILLED], 1},
{"Reordering features within each tile", 0, 0, 0},
{"preserve-input-order", no_argument, &prevent[P_INPUT_ORDER], 1},

View File

@ -30,6 +30,7 @@
#define P_SIMPLIFY_LOW ((int) 'S')
#define P_SIMPLIFY_SHARED_NODES ((int) 'n')
#define P_FEATURE_LIMIT ((int) 'f')
#define P_FILLED ((int) 'F')
#define P_KILOBYTE_LIMIT ((int) 'k')
#define P_DYNAMIC_DROP ((int) 'd')
#define P_INPUT_ORDER ((int) 'i')

File diff suppressed because one or more lines are too long

View File

@ -2126,6 +2126,55 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
}
}
bool remove_filled = false;
if (prevent[P_FILLED]) {
remove_filled = true;
for (size_t i = 0; i < partials.size(); i++) {
if (partials[i].t != VT_POLYGON ||
partials[i].geoms.size() != 1 ||
partials[i].geoms[0].size() != 5) {
remove_filled = false;
break;
}
// It is a polygon with four sides.
// Are they all outside the tile boundary?
for (size_t j = 0; j + 1 < partials[i].geoms[0].size(); j++) {
if (partials[i].geoms[0][j].x == partials[i].geoms[0][j + 1].x &&
(partials[i].geoms[0][j].x < 0 || partials[i].geoms[0][j].x > partials[i].extent)) {
// vertical line, outside the edge of the tile
if (!((partials[i].geoms[0][j].y < 0 &&
partials[i].geoms[0][j + 1].y > partials[i].extent) ||
(partials[i].geoms[0][j + 1].y < 0 &&
partials[i].geoms[0][j].y > partials[i].extent))) {
remove_filled = false;
break;
}
} else if (partials[i].geoms[0][j].y == partials[i].geoms[0][j + 1].y &&
(partials[i].geoms[0][j].y < 0 || partials[i].geoms[0][j].y > partials[i].extent)) {
// horizontal line, outside the edge of the tile
if (!((partials[i].geoms[0][j].x < 0 &&
partials[i].geoms[0][j + 1].x > partials[i].extent) ||
(partials[i].geoms[0][j + 1].x < 0 &&
partials[i].geoms[0][j].x > partials[i].extent))) {
remove_filled = false;
break;
}
} else {
remove_filled = false;
break;
}
}
}
}
if (remove_filled) {
partials.clear();
}
for (size_t i = 0; i < partials.size(); i++) {
std::vector<drawvec> &pgeoms = partials[i].geoms;
signed char t = partials[i].t;