Skip to content

Commit

Permalink
Progress in the direction of polygon clipping
Browse files Browse the repository at this point in the history
  • Loading branch information
e-n-f committed Nov 22, 2024
1 parent f9ec00d commit 9c4c952
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
71 changes: 71 additions & 0 deletions clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,71 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try
return ret;
}

drawvec clip_poly(drawvec &geom, drawvec const &bounds) {
printf("initial: %zu\n", geom.size());
geom = remove_noop(geom, VT_POLYGON, 0);
mapbox::geometry::multi_polygon<long long> result;

{
mapbox::geometry::wagyu::wagyu<long long> wagyu;

for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_MOVETO) {
mapbox::geometry::linear_ring<long long> lr;
lr.push_back(mapbox::geometry::point<long long>(geom[i].x, geom[i].y));

size_t j;
for (j = i + 1; j < geom.size(); j++) {
if (geom[j].op != VT_LINETO) {
break;
}
lr.push_back(mapbox::geometry::point<long long>(geom[j].x, geom[j].y));
}

if (lr.size() >= 4) {
wagyu.add_ring(lr);
}

i = j - 1;
}
}

for (size_t i = 0; i < bounds.size(); i++) {
if (bounds[i].op == VT_MOVETO) {
mapbox::geometry::linear_ring<long long> lr;
lr.push_back(mapbox::geometry::point<long long>(bounds[i].x, bounds[i].y));

size_t j;
for (j = i + 1; j < bounds.size(); j++) {
if (bounds[j].op != VT_LINETO) {
break;
}
lr.push_back(mapbox::geometry::point<long long>(bounds[j].x, bounds[j].y));
}

if (lr.size() >= 4) {
wagyu.add_ring(lr, mapbox::geometry::wagyu::polygon_type_clip);
}

i = j - 1;
}
}

try {
result.clear();
wagyu.execute(mapbox::geometry::wagyu::clip_type_union, result, mapbox::geometry::wagyu::fill_type_positive, mapbox::geometry::wagyu::fill_type_positive);
} catch (std::runtime_error &e) {
fprintf(stderr, "Internal error: Polygon clipping failed\n");
exit(EXIT_IMPOSSIBLE);
}
}

drawvec ret;
decode_clipped(result, ret, 1);
printf("after: %zu\n", ret.size());
return ret;
}

void to_tile_scale(drawvec &geom, int z, int detail) {
if (32 - detail - z < 0) {
for (size_t i = 0; i < geom.size(); i++) {
Expand Down Expand Up @@ -1093,6 +1158,7 @@ clipbbox parse_clip_poly(std::string arg) {
out.maxy = LLONG_MIN;
for (auto const &d : parsed_geometry.second) {
if (d.op == VT_MOVETO || d.op == VT_LINETO) {
printf("%lld,%lld\n", d.x, d.y);
if (d.x < out.minx) {
out.minx = d.x;
}
Expand Down Expand Up @@ -1914,11 +1980,16 @@ std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int
}

// Clip to user-specified bounding boxes.
// Bounding box clip first, to reduce complexity of the full clip.
// But don't clip here if we are binning, because we need to bin points in the buffer
if (bins.size() == 0) {
for (auto &c : clipbboxes) {
if (t == VT_POLYGON) {
printf("clip to %lld,%lld %lld,%lld\n", c.minx, c.miny, c.maxx, c.maxy);
geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false);
if (c.dv.size() > 0) {
geom = clip_poly(geom, c.dv);
}
} else if (t == VT_LINE) {
geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy);
} else if (t == VT_POINT) {
Expand Down
4 changes: 2 additions & 2 deletions read_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ std::pair<int, drawvec> parse_geometry(json_object *geometry, json_pull *jp, jso
dv[i].y -= scale * y;

// scale to tile
dv[i].x = std::round(dv[i].x * extent / (double) scale);
dv[i].y = std::round(dv[i].y * extent / (double) scale);
dv[i].x = std::round(dv[i].x * (extent / (double) scale));
dv[i].y = std::round(dv[i].y * (extent / (double) scale));
}

if (mb_geometry[t] == VT_POLYGON) {
Expand Down

0 comments on commit 9c4c952

Please sign in to comment.