Skip to content

Commit

Permalink
Correct pruning of polygons
Browse files Browse the repository at this point in the history
  • Loading branch information
kleunen committed May 2, 2021
1 parent 7407dce commit 2a96b59
Showing 1 changed file with 45 additions and 7 deletions.
52 changes: 45 additions & 7 deletions src/output_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,52 @@ Geometry buildWayGeometry(OSMStore &osmStore, OutputObject const &oo, const Tile
return out;
}

try {
MultiPolygon out;
geom::intersection(mp, clippingPolygon, out);
return out;
} catch (geom::overlay_invalid_input_exception &err) {
std::cout << "Couldn't clip polygon (self-intersection)" << std::endl;
return MultiPolygon(); // blank
MultiPolygon out;
for(auto const &p: mp) {
Polygon newp;
newp.outer().reserve(p.outer.size());

geom::append(newp.outer(), p.outer[0]);
for(std::size_t i = 1; i < p.outer.size(); ++i) {
std::size_t next_i = (i + 1) % p.outer.size();

bool keep_point =
geom::within(newp.outer().back(), bbox.clippingBox) ||
geom::within(p.outer[i], bbox.clippingBox) ||
geom::within(p.outer[next_i], bbox.clippingBox);

if(!keep_point) {
double det =
(p.outer[i].x() - newp.outer().back().x()) * (p.outer[next_i].y() * newp.outer().back().y()) -
(p.outer[next_i].x() - newp.outer().back().x()) * (p.outer[i].y() * newp.outer().back().y());

if(det < 0) {
Linestring ls({ newp.outer().back(), p.outer[next_i] });
bool intersects = geom::intersects(ls, bbox.clippingBox);
for(auto const &inner: p.inners) {
intersects |= geom::intersects(ls, inner);
}

if(!intersects)
continue;
}
}

geom::append(newp.outer(), p.outer[i]);
}

newp.inners().reserve(p.inners.size());
for(auto const &inner: p.inners) {
if(geom::within(inner, newp.outer())) {
newp.inners().resize(newp.inners().size() + 1);
boost::geometry::assign(newp.inners().back(), inner);
}
}

out.push_back(std::move(newp));
}

return out;
}

default:
Expand Down

0 comments on commit 2a96b59

Please sign in to comment.