mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-05 09:55:41 +02:00
Treat tiny polygon holes as dust again, but accumulated separately now
This commit is contained in:
+25
-5
@@ -186,7 +186,7 @@ void check_polygon(drawvec &geom) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area, serial_feature *this_feature, serial_feature *tiny_feature) {
|
drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area, double *accum_hole, 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;
|
||||||
bool includes_real = false;
|
bool includes_real = false;
|
||||||
@@ -222,7 +222,7 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
|
|||||||
// 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) || (area < 0 && -area <= pixel * pixel && !included_last_outer)) {
|
||||||
// printf("area is only %f vs %lld so using square\n", area, pixel * pixel);
|
// printf("area is only %f vs %lld so using square\n", area, pixel * pixel);
|
||||||
|
|
||||||
*accum_area += area;
|
*accum_area += area;
|
||||||
@@ -243,10 +243,30 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
|
|||||||
included_last_outer = false;
|
included_last_outer = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is a tiny hole, and we have a real outer ring that we can cut it out of,
|
||||||
|
// so accumulate some hole, and if we have enough to be worth cutting, cut it out.
|
||||||
|
//
|
||||||
|
// these hole areas are accumulated separately rather than just decrementing
|
||||||
|
// the accumulated area, because otherwise it is possible to accumulate enough
|
||||||
|
// negative area to lose entire outer rings in the process of getting back up to 0.
|
||||||
|
else if (area < 0 && -area <= pixel * pixel && included_last_outer) {
|
||||||
|
*accum_hole -= area;
|
||||||
|
if (*accum_hole > pixel * pixel) {
|
||||||
|
// XXX use centroid;
|
||||||
|
|
||||||
|
out.push_back(draw(VT_MOVETO, geom[i].x - pixel / 2, geom[i].y - pixel / 2));
|
||||||
|
out.push_back(draw(VT_LINETO, geom[i].x - pixel / 2 + pixel, geom[i].y - pixel / 2));
|
||||||
|
out.push_back(draw(VT_LINETO, geom[i].x - pixel / 2 + pixel, geom[i].y - pixel / 2 + pixel));
|
||||||
|
out.push_back(draw(VT_LINETO, geom[i].x - pixel / 2, geom[i].y - pixel / 2 + pixel));
|
||||||
|
out.push_back(draw(VT_LINETO, geom[i].x - pixel / 2, geom[i].y - pixel / 2));
|
||||||
|
includes_dust = true;
|
||||||
|
|
||||||
|
*accum_hole -= pixel * pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// i.e., this ring is large enough that it gets to represent itself
|
// i.e., this ring is large enough that it gets to represent itself
|
||||||
// or it is a tiny hole out of a real polygon, which we are still treating
|
|
||||||
// as a real geometry because otherwise we can accumulate enough tiny holes
|
|
||||||
// that we will drop the next several outer rings getting back up to 0.
|
|
||||||
else {
|
else {
|
||||||
// printf("area is %f so keeping instead of %lld\n", area, pixel * pixel);
|
// printf("area is %f so keeping instead of %lld\n", area, pixel * pixel);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -66,7 +66,7 @@ drawvec clip_point(drawvec &geom, int z, long long buffer);
|
|||||||
drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip);
|
drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip);
|
||||||
drawvec simple_clip_poly(drawvec &geom, int z, int buffer);
|
drawvec simple_clip_poly(drawvec &geom, int z, int buffer);
|
||||||
drawvec close_poly(drawvec &geom);
|
drawvec close_poly(drawvec &geom);
|
||||||
drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area, serial_feature *this_feature, serial_feature *tiny_feature);
|
drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area, double *accum_hole, serial_feature *this_feature, serial_feature *tiny_feature);
|
||||||
int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax);
|
int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax);
|
||||||
drawvec clip_lines(drawvec &geom, int z, long long buffer);
|
drawvec clip_lines(drawvec &geom, int z, long long buffer);
|
||||||
drawvec stairstep(drawvec &geom, int z, int detail);
|
drawvec stairstep(drawvec &geom, int z, int detail);
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ extern char *optarg;
|
|||||||
extern int optind;
|
extern int optind;
|
||||||
|
|
||||||
int detail = 12; // tippecanoe-style: mvt extent == 1 << detail
|
int detail = 12; // tippecanoe-style: mvt extent == 1 << detail
|
||||||
int buffer = 5; // tippecanoe-style: mvt buffer == extent * buffer / 256;
|
int buffer = 5; // tippecanoe-style: mvt buffer == extent * buffer / 256;
|
||||||
|
|
||||||
std::set<std::string> keep;
|
std::set<std::string> keep;
|
||||||
|
|
||||||
|
|||||||
@@ -1914,7 +1914,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
|
|||||||
int line_detail;
|
int line_detail;
|
||||||
for (line_detail = detail; line_detail >= min_detail || line_detail == detail; line_detail--, oprogress = 0) {
|
for (line_detail = detail; line_detail >= min_detail || line_detail == detail; line_detail--, oprogress = 0) {
|
||||||
long long count = 0;
|
long long count = 0;
|
||||||
double accum_area = 0;
|
double accum_area = 0, accum_hole = 0;
|
||||||
|
|
||||||
double fraction_accum = 0;
|
double fraction_accum = 0;
|
||||||
|
|
||||||
@@ -2185,7 +2185,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
|
|||||||
bool reduced = false;
|
bool reduced = false;
|
||||||
if (sf.t == VT_POLYGON) {
|
if (sf.t == VT_POLYGON) {
|
||||||
if (!prevent[P_TINY_POLYGON_REDUCTION] && !additional[A_GRID_LOW_ZOOMS]) {
|
if (!prevent[P_TINY_POLYGON_REDUCTION] && !additional[A_GRID_LOW_ZOOMS]) {
|
||||||
sf.geometry = reduce_tiny_poly(sf.geometry, z, line_detail, &reduced, &accum_area, &sf, &tiny_feature);
|
sf.geometry = reduce_tiny_poly(sf.geometry, z, line_detail, &reduced, &accum_area, &accum_hole, &sf, &tiny_feature);
|
||||||
if (reduced) {
|
if (reduced) {
|
||||||
strategy->tiny_polygons++;
|
strategy->tiny_polygons++;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user