Skip to content

Commit

Permalink
Fix WKT generation for polygons with islands.
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed May 10, 2019
1 parent 741e445 commit 966c506
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 34 deletions.
20 changes: 8 additions & 12 deletions filters/private/hexer/HexGrid.cpp
Expand Up @@ -368,27 +368,23 @@ void HexGrid::cleanPossibleRoot(Segment s, Path *p)
}
}

void HexGrid::toWKT(std::ostream& output) const
void HexGrid::toWKT(std::ostream& out) const
{
auto outputPath = [this,&output](size_t pathNum)
auto writePath = [this, &out](size_t pathNum)
{
Path *p = rootPaths()[pathNum];

output << "(";
p->toWKT(output);
output << ")";
rootPaths()[pathNum]->toWKT(out);
};

output << "MULTIPOLYGON (";
out << "MULTIPOLYGON (";

if (rootPaths().size())
outputPath(0);
writePath(0);
for (size_t pi = 1; pi < rootPaths().size(); ++pi)
{
output << ",";
outputPath(pi);
out << ",";
writePath(pi);
}
output << ")";
out << ")";
}

size_t HexGrid::densePointCount() const
Expand Down
65 changes: 47 additions & 18 deletions filters/private/hexer/Path.cpp
Expand Up @@ -66,34 +66,63 @@ vector<Point> Path::points() const
return points;
}

void Path::toWKT( std::ostream& output) const
void Path::writeRing(std::ostream& out) const
{
vector<Point> pts = points();

auto outputPoint = [&output](Point& p)
auto outputPoint = [&out](const Point& p)
{
output << p.m_x << " " << p.m_y;
out << p.m_x << " " << p.m_y;
};

output << "(";
const vector<Point>& pts = points();
assert(pts.size() > 2);
out << "(";
outputPoint(pts.front());
for (auto it = pts.begin() + 1; it != pts.end(); ++it)
{
out << ", ";
outputPoint(*it);
}
out << ")";
}

auto pi = pts.begin();
if (pi != pts.end())
outputPoint(*pi++);
for (; pi != pts.end(); ++pi)
// WKT (or GeoJSON) doesn't allow nesting of polygons. You can just have
// polygons and holes. Islands within the holes need to be described as
// separate polygons. To that end, we grather the islands from all holes
// and return them to be processed as separate polygons.
PathPtrList Path::writePolygon(std::ostream& out) const
{
PathPtrList islands;

out << "(";
writeRing(out);
const PathPtrList& paths = subPaths();
for (auto& p : paths)
{
output << ", ";
outputPoint(*pi);
out << ", ";
p->writeRing(out);
const PathPtrList& subs(p->subPaths());
islands.insert(islands.end(), subs.begin(), subs.end());
}
out << ")";
return islands;
}

output << ")";

vector<Path *> paths = subPaths();
for (size_t pi = 0; pi != paths.size(); ++pi)
void Path::toWKT(std::ostream& out) const
{
PathPtrList islands = writePolygon(out);

// See the note on writePolygon()
while (islands.size())
{
Path* p = paths[pi];
output <<",";
p->toWKT(output);
PathPtrList paths;
paths.swap(islands);
for (Path *p : paths)
{
out << ", ";
PathPtrList subIslands = p->writePolygon(out);
islands.insert(islands.end(), subIslands.begin(), subIslands.end());
}
}
}

Expand Down
13 changes: 9 additions & 4 deletions filters/private/hexer/Path.hpp
Expand Up @@ -49,6 +49,8 @@ enum Orientation
};

class HexGrid;
class Path;
using PathPtrList = std::vector<Path *>;

class Path
{
Expand All @@ -59,8 +61,8 @@ class Path

~Path()
{
for (std::vector<Path*>::size_type i = 0; i < m_children.size(); ++i)
delete m_children[i];
for (auto p : m_children)
delete p;
}

void push_back(const Segment& s)
Expand All @@ -85,7 +87,7 @@ class Path
Orientation orientation() const
{ return m_orientation; }
std::vector<Point> points() const;
std::vector<Path *> subPaths() const
PathPtrList subPaths() const
{ return m_children; }
void toWKT( std::ostream& output) const;

Expand All @@ -95,12 +97,15 @@ class Path
/// Parent path (NULL if root path)
Path *m_parent;
/// Children
std::vector<Path *> m_children;
PathPtrList m_children;
/// Orientation of path AT EXTRACTION - segments are ALWAYS ordered
/// clockwise.
Orientation m_orientation;
/// List of segments that make up the path.
std::vector<Segment> m_segs;

void writeRing(std::ostream& out) const;
PathPtrList writePolygon(std::ostream& out) const;
};

} //namespace hexer
Expand Down

0 comments on commit 966c506

Please sign in to comment.