mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Limit decay into polygon dust to reasonably compact polygons
This commit is contained in:
+25
-1
@@ -176,6 +176,18 @@ void check_polygon(drawvec &geom) {
|
||||
}
|
||||
}
|
||||
|
||||
double get_perimeter(const drawvec &geom, size_t i, size_t j) {
|
||||
double perimeter = 0;
|
||||
|
||||
for (size_t k = i; k + 1 < j; k++) {
|
||||
double dx = geom[k].x - geom[k + 1].x;
|
||||
double dy = geom[k].y - geom[k + 1].y;
|
||||
perimeter += sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
return perimeter;
|
||||
}
|
||||
|
||||
drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *still_needs_simplification, bool *reduced_away, double *accum_area, serial_feature *this_feature, serial_feature *tiny_feature) {
|
||||
drawvec out;
|
||||
const double pixel = (1LL << (32 - detail - z)) * (double) tiny_polygon_size;
|
||||
@@ -196,6 +208,17 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *still_needs_sim
|
||||
}
|
||||
|
||||
double area = get_area(geom, i, j);
|
||||
double schwartzberg = 1;
|
||||
|
||||
if (area != 0) {
|
||||
// polygon compactness measure
|
||||
// https://fisherzachary.github.io/public/r-output.html
|
||||
// Schwartzberg, Joseph E. 1965. “Reapportionment, gerrymanders, and the notion of compactness”.
|
||||
// In: Minn. L. Rev. 50, 443.
|
||||
|
||||
double perimeter = get_perimeter(geom, i, j);
|
||||
schwartzberg = 1 / (perimeter / (2 * M_PI * sqrt(std::fabs(area) / M_PI)));
|
||||
}
|
||||
|
||||
// XXX There is an ambiguity here: If the area of a ring is 0 and it is followed by holes,
|
||||
// we don't know whether the area-0 ring was a hole too or whether it was the outer ring
|
||||
@@ -213,7 +236,8 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *still_needs_sim
|
||||
// OR it is an inner ring and we haven't output an outer ring for it to be
|
||||
// cut out of, so we are just subtracting its area from the tiny polygon
|
||||
// rather than trying to deal with it geometrically
|
||||
if ((area > 0 && area <= pixel * pixel) || (area < 0 && !included_last_outer)) {
|
||||
if ((area > 0 && area <= pixel * pixel && schwartzberg > 0.3) ||
|
||||
(area < 0 && !included_last_outer)) {
|
||||
*accum_area += area;
|
||||
*reduced_away = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user