mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-05 01:45:41 +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 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;
|
drawvec out;
|
||||||
const double pixel = (1LL << (32 - detail - z)) * (double) tiny_polygon_size;
|
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 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,
|
// 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
|
// 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
|
// 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
|
// cut out of, so we are just subtracting its area from the tiny polygon
|
||||||
// rather than trying to deal with it geometrically
|
// 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;
|
*accum_area += area;
|
||||||
*reduced_away = true;
|
*reduced_away = true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user