Skip to content

Commit

Permalink
Fix polygon pruning
Browse files Browse the repository at this point in the history
  • Loading branch information
kleunen committed May 3, 2021
1 parent 4ca85c8 commit 57c7695
Showing 1 changed file with 40 additions and 26 deletions.
66 changes: 40 additions & 26 deletions src/output_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,17 @@ Geometry buildWayGeometry(OSMStore &osmStore, OutputObject const &oo, const Tile

case OutputGeometryType::POLYGON:
{
auto const &mp = osmStore.retrieve<mmap::multi_polygon_t>(oo.handle);
auto const &input = osmStore.retrieve<mmap::multi_polygon_t>(oo.handle);

Polygon clippingPolygon;
geom::convert(bbox.clippingBox, clippingPolygon);
if (!geom::intersects(mp, clippingPolygon)) { return MultiPolygon(); }
if (!geom::intersects(input, clippingPolygon)) { return MultiPolygon(); }

MultiPolygon mp;
Polygon extendPolygon;
geom::convert(bbox.getExtendBox(), extendPolygon);
geom::intersection(input, extendPolygon, mp);

MultiPolygon out;
for(auto const &p: mp) {
Polygon newp;
Expand All @@ -125,40 +130,49 @@ Geometry buildWayGeometry(OSMStore &osmStore, OutputObject const &oo, const Tile
}

std::size_t start_index = 0;
for(std::size_t j = 0; j < p.outer().size() - 1; ++j) {
if (geom::within(p.outer()[start_index], bbox.clippingBox)) {
start_index = j;
break;
}
}

geom::append(newp.outer(), p.outer[start_index]);
for(std::size_t j = 1; j < p.outer.size() - 1; ++j) {
std::size_t i = (start_index + j) % p.outer.size();
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) {
geom::append(newp.outer(), p.outer()[start_index]);
geom::append(newp.outer(), p.outer()[start_index + 1]);
for(std::size_t j = 2; j < p.outer().size() - 1; ++j) {
std::size_t i = (start_index + j) % (p.outer().size() - 1);
auto prev_2 = newp.outer()[newp.outer().size() - 2];
auto prev_1 = newp.outer()[newp.outer().size() - 1];

bool remove_point =
!geom::within(prev_2, bbox.clippingBox) && !geom::within(prev_1, bbox.clippingBox) && !geom::within(p.outer()[i], bbox.clippingBox);

if(remove_point) {
// Check if 3 points are locally convex
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] });
(p.outer()[i].x() - prev_2.x()) * (prev_1.y() - prev_2.y()) -
(prev_1.x() - prev_2.x()) * (p.outer()[i].y() - prev_2.y());

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

if(!intersects)
if(!intersects) {
newp.outer()[newp.outer().size() - 1] = p.outer()[i];
continue;
}
}
}
}

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

newp.inners().reserve(p.inners.size());
for(auto const &inner: p.inners) {
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);
Expand Down

0 comments on commit 57c7695

Please sign in to comment.