Skip to content

Commit

Permalink
Treat tiny polygon holes as dust again, but accumulated separately now
Browse files Browse the repository at this point in the history
  • Loading branch information
e-n-f committed Aug 25, 2023
1 parent 39ad95e commit f294e2a
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 9 deletions.
30 changes: 25 additions & 5 deletions geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
const double pixel = (1LL << (32 - detail - z)) * (double) tiny_polygon_size;
bool includes_real = false;
Expand Down Expand Up @@ -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
// 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) || (area < 0 && -area <= pixel * pixel && !included_last_outer)) {
// printf("area is only %f vs %lld so using square\n", area, pixel * pixel);

*accum_area += area;
Expand All @@ -243,10 +243,30 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
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
// 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 {
// printf("area is %f so keeping instead of %lld\n", area, pixel * pixel);

Expand Down
2 changes: 1 addition & 1 deletion geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 simple_clip_poly(drawvec &geom, int z, int buffer);
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);
drawvec clip_lines(drawvec &geom, int z, long long buffer);
drawvec stairstep(drawvec &geom, int z, int detail);
Expand Down
2 changes: 1 addition & 1 deletion overzoom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern char *optarg;
extern int optind;

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;

Expand Down
4 changes: 2 additions & 2 deletions tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1914,7 +1914,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
int line_detail;
for (line_detail = detail; line_detail >= min_detail || line_detail == detail; line_detail--, oprogress = 0) {
long long count = 0;
double accum_area = 0;
double accum_area = 0, accum_hole = 0;

double fraction_accum = 0;

Expand Down Expand Up @@ -2185,7 +2185,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
bool reduced = false;
if (sf.t == VT_POLYGON) {
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) {
strategy->tiny_polygons++;
}
Expand Down

0 comments on commit f294e2a

Please sign in to comment.