Merge pull request #185 from mapbox/line-polygons

Silently drop zero-area polygons instead of showing Clipper errors
This commit is contained in:
Eric Fischer
2016-03-10 17:31:47 -08:00
+34 -4
View File
@@ -241,6 +241,8 @@ static void decode_clipped(ClipperLib::PolyNode *t, drawvec &out) {
drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool clip) { drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool clip) {
ClipperLib::Clipper clipper(ClipperLib::ioStrictlySimple); ClipperLib::Clipper clipper(ClipperLib::ioStrictlySimple);
bool has_area = false;
for (unsigned i = 0; i < geom.size(); i++) { for (unsigned i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_MOVETO) { if (geom[i].op == VT_MOVETO) {
unsigned j; unsigned j;
@@ -250,6 +252,16 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool cl
} }
} }
double area = 0;
for (unsigned k = i; k < j; k++) {
area += (long double) geom[k].x * (long double) geom[i + ((k - i + 1) % (j - i))].y;
area -= (long double) geom[k].y * (long double) geom[i + ((k - i + 1) % (j - i))].x;
}
area = area / 2;
if (area != 0) {
has_area = true;
}
ClipperLib::Path path; ClipperLib::Path path;
drawvec tmp; drawvec tmp;
@@ -297,6 +309,11 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool cl
fprintf(stderr, "Polygon clip failed\n"); fprintf(stderr, "Polygon clip failed\n");
} }
} else { } else {
if (!has_area) {
drawvec out;
return out;
}
if (!clipper.Execute(ClipperLib::ctUnion, clipped)) { if (!clipper.Execute(ClipperLib::ctUnion, clipped)) {
fprintf(stderr, "Polygon clean failed\n"); fprintf(stderr, "Polygon clean failed\n");
} }
@@ -978,16 +995,29 @@ std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms) {
midx /= count; midx /= count;
midy /= count; midy /= count;
drawvec c1, c2;
if (maxy - miny > maxx - minx) { if (maxy - miny > maxx - minx) {
// printf("clipping y to %lld %lld %lld %lld\n", minx, miny, maxx, midy); // printf("clipping y to %lld %lld %lld %lld\n", minx, miny, maxx, midy);
out.push_back(simple_clip_poly(geoms[i], minx, miny, maxx, midy)); c1 = simple_clip_poly(geoms[i], minx, miny, maxx, midy);
// printf(" and %lld %lld %lld %lld\n", minx, midy, maxx, maxy); // printf(" and %lld %lld %lld %lld\n", minx, midy, maxx, maxy);
out.push_back(simple_clip_poly(geoms[i], minx, midy, maxx, maxy)); c2 = simple_clip_poly(geoms[i], minx, midy, maxx, maxy);
} else { } else {
// printf("clipping x to %lld %lld %lld %lld\n", minx, miny, midx, maxy); // printf("clipping x to %lld %lld %lld %lld\n", minx, miny, midx, maxy);
out.push_back(simple_clip_poly(geoms[i], minx, miny, midx, maxy)); c1 = simple_clip_poly(geoms[i], minx, miny, midx, maxy);
// printf(" and %lld %lld %lld %lld\n", midx, midy, maxx, maxy); // printf(" and %lld %lld %lld %lld\n", midx, midy, maxx, maxy);
out.push_back(simple_clip_poly(geoms[i], midx, miny, maxx, maxy)); c2 = simple_clip_poly(geoms[i], midx, miny, maxx, maxy);
}
if (c1.size() >= geoms[i].size()) {
fprintf(stderr, "Subdividing complex polygon failed\n");
} else {
out.push_back(c1);
}
if (c2.size() >= geoms[i].size()) {
fprintf(stderr, "Subdividing complex polygon failed\n");
} else {
out.push_back(c2);
} }
again = true; again = true;