Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --split-complex-polygons option #778

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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'},
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down