Add --split-complex-polygons option

This commit is contained in:
Eric Fischer 2019-08-02 11:44:07 -07:00
parent df9fa602bd
commit de2037a479
6 changed files with 14 additions and 4 deletions

View File

@ -503,6 +503,7 @@ the same layer, enclose them in an `all` expression so they will all be evaluate
* `-pw` or `--use-source-polygon-winding`: Instead of respecting GeoJSON polygon ring order, use the original polygon winding in the source data to distinguish inner (clockwise) and outer (counterclockwise) polygon rings.
* `-pW` or `--reverse-source-polygon-winding`: Instead of respecting GeoJSON polygon ring order, use the opposite of the original polygon winding in the source data to distinguish inner (counterclockwise) and outer (clockwise) polygon rings.
* `--clip-bounding-box=`*minlon*`,`*minlat*`,`*maxlon*`,`*maxlat*: Clip all features to the specified bounding box.
* `--split-complex-polygons=`*limit*`: Subdivide polygons with more than *limit* vertices into multiple features.
### Setting or disabling tile size limits

View File

@ -975,16 +975,16 @@ drawvec fix_polygon(drawvec &geom) {
return out;
}
std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms) {
std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms, size_t n) {
while (1) {
bool again = false;
std::vector<drawvec> out;
for (size_t i = 0; i < geoms.size(); i++) {
if (geoms[i].size() > 700) {
if (geoms[i].size() > n) {
static bool warned = false;
if (!warned) {
fprintf(stderr, "Warning: splitting up polygon with more than 700 sides\n");
fprintf(stderr, "Warning: splitting up polygon with more than %zu sides\n", n);
warned = true;
}

View File

@ -71,7 +71,7 @@ int quick_check(long long *bbox, int z, long long buffer);
drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain, drawvec const &shared_nodes);
drawvec reorder_lines(drawvec &geom);
drawvec fix_polygon(drawvec &geom);
std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms);
std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms, size_t n);
void check_polygon(drawvec &geom);
double get_area(drawvec &geom, size_t i, size_t j);
double get_mp_area(drawvec &geom);

View File

@ -77,6 +77,7 @@ size_t max_tile_features = 200000;
int cluster_distance = 0;
long justx = -1, justy = -1;
std::string attribute_for_id = "";
size_t polygon_split = 0;
int prevent[256];
int additional[256];
@ -2596,6 +2597,7 @@ int main(int argc, char **argv) {
{"use-source-polygon-winding", no_argument, &prevent[P_USE_SOURCE_POLYGON_WINDING], 1},
{"reverse-source-polygon-winding", no_argument, &prevent[P_REVERSE_SOURCE_POLYGON_WINDING], 1},
{"clip-bounding-box", required_argument, 0, '~'},
{"split-complex-polygons", required_argument, 0, '~'},
{"Filtering tile contents", 0, 0, 0},
{"prefilter", required_argument, 0, 'C'},
@ -2695,6 +2697,8 @@ int main(int argc, char **argv) {
fprintf(stderr, "%s: Can't parse bounding box --%s=%s\n", argv[0], opt, optarg);
exit(EXIT_FAILURE);
}
} else if (strcmp(opt, "split-complex-polygons") == 0) {
polygon_split = atoi(optarg);
} else if (strcmp(opt, "use-attribute-for-id") == 0) {
attribute_for_id = optarg;
} else {

View File

@ -48,6 +48,7 @@ extern size_t max_tile_size;
extern size_t max_tile_features;
extern int cluster_distance;
extern std::string attribute_for_id;
extern size_t polygon_split;
int mkstemp_cloexec(char *name);
FILE *fopen_oflag(const char *name, const char *mode, int oflag);

View File

@ -493,6 +493,10 @@ void *partial_feature_worker(void *v) {
std::vector<drawvec> geoms;
geoms.push_back(geom);
if (t == VT_POLYGON && polygon_split > 0) {
geoms = chop_polygon(geoms, polygon_split);
}
if (t == VT_POLYGON) {
// Scaling may have made the polygon degenerate.
// Give Clipper a chance to try to fix it.