Skip to content

Commit

Permalink
Prune polygon to area within tile bounding box
Browse files Browse the repository at this point in the history
  • Loading branch information
kleunen committed May 1, 2021
1 parent b9ce0c7 commit 035c1a7
Showing 1 changed file with 65 additions and 15 deletions.
80 changes: 65 additions & 15 deletions src/output_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ Geometry buildWayGeometry(OSMStore &osmStore, OutputObject const &oo, const Tile

case OutputGeometryType::LINESTRING:
{
MultiLinestring out;
auto const &ls = osmStore.retrieve<mmap::linestring_t>(oo.handle);

MultiLinestring out;
if(ls.empty())
return out;

Expand All @@ -95,6 +95,7 @@ Geometry buildWayGeometry(OSMStore &osmStore, OutputObject const &oo, const Tile
out.push_back(std::move(current_ls));
current_ls.clear();
}

geom::append(current_ls, ls[i]);
}

Expand All @@ -109,23 +110,72 @@ Geometry buildWayGeometry(OSMStore &osmStore, OutputObject const &oo, const Tile
auto const &mp = osmStore.retrieve<mmap::multi_polygon_t>(oo.handle);

Polygon clippingPolygon;

geom::convert(bbox.clippingBox, clippingPolygon);
if (!geom::intersects(mp, clippingPolygon)) { return MultiPolygon(); }
if (geom::within(mp, clippingPolygon)) {
MultiPolygon out;
boost::geometry::assign(out, mp);
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;
if(geom::within(p.outer, clippingPolygon)) {
boost::geometry::assign(newp, p);
out.push_back(newp);
continue;
}

for(auto const &inner: p.inners) {
if(!inner.empty()) {
Ring ring;
geom::append(ring, inner[0]);
for(std::size_t i = 1; i < inner.size(); ++i) {
if(geom::within(inner[i], bbox.clippingBox)) {
geom::append(ring, inner[i]);
continue;
}

std::size_t next_i = (i + 1) % inner.size();
Linestring ls({ ring.back(), inner[next_i] });

if(!geom::within(ls, inner) || geom::intersects(ls, bbox.clippingBox)) {
geom::append(ring, inner[i]);
}
}

if(ring.size() >= 3) {
newp.inners().resize(newp.inners().size() + 1);
boost::geometry::assign(newp.inners().back(), ring);
}
}
}

Ring outer_ring;
geom::append(outer_ring, p.outer[0]);
for(std::size_t i = 1; i < p.outer.size(); ++i) {
if(geom::within(p.outer[i], bbox.clippingBox)) {
geom::append(outer_ring, p.outer[i]);
continue;
}

std::size_t next_i = (i + 1) % p.outer.size();
Linestring ls({ outer_ring.back(), p.outer[next_i] });
if(!geom::within(ls, p.outer)) {
geom::append(outer_ring, p.outer[i]);
continue;
}

bool intersects = geom::intersects(ls, bbox.clippingBox);
for(auto const &inner: newp.inners()) {
intersects |= geom::intersects(ls, inner);
}

if(intersects) {
geom::append(outer_ring, p.outer[i]);
}
}

boost::geometry::assign(newp.outer(), outer_ring);
out.push_back(newp);
}

return out;
}

default:
Expand Down

0 comments on commit 035c1a7

Please sign in to comment.