Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine FlatGeobuf polygon layers into one layer #5674

Merged
merged 1 commit into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hoot-core/src/main/cpp/hoot/core/io/FlatGeobufWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class FlatGeobufWriter : public OgrMultifileWriter
const char* _getDriverName() const override { return "FlatGeobuf"; };
QString _getFileExtension() const override { return ".fgb"; }
OgrOptions _getOptions() const override;
OGRwkbGeometryType _getPolygonGeometryType() const override { return OGRwkbGeometryType::wkbPolygon; }
bool _convertPolygons() const override { return true; }

};

Expand Down
30 changes: 20 additions & 10 deletions hoot-core/src/main/cpp/hoot/core/io/OgrMultifileWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <ogr_geometry.h>

// GEOS
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/LineString.h>
#include <geos/geom/Polygon.h>

Expand Down Expand Up @@ -298,7 +299,7 @@ void OgrMultifileWriter::writePoints(const ConstOsmMapPtr& map, const QString& p

void OgrMultifileWriter::writePolygons(const ConstOsmMapPtr& map, const QString& path)
{
_setupDataset(map, path, _getPolygonGeometryType(), ElementType::Unknown);
_setupDataset(map, path, wkbMultiPolygon, ElementType::Unknown);

const WayMap& ways = map->getWays();
for (auto it = ways.begin(); it != ways.end(); ++it)
Expand All @@ -309,15 +310,6 @@ void OgrMultifileWriter::writePolygons(const ConstOsmMapPtr& map, const QString&
_writeWayPolygon(map, way);
}

// For polygon only file types a multipolygon file needs to be written
if (_getPolygonGeometryType() == OGRwkbGeometryType::wkbPolygon)
{
_cleanupDataset();
QString multipolyPath = path;
multipolyPath.replace("Polygons" + _getFileExtension(), "MultiPolygons" + _getFileExtension());
_setupDataset(map, multipolyPath, OGRwkbGeometryType::wkbMultiPolygon, ElementType::Unknown);
}

const RelationMap& relations = map->getRelations();
for (auto it = relations.begin(); it != relations.end(); ++it)
{
Expand All @@ -344,6 +336,9 @@ void OgrMultifileWriter::_writeRelationPolygon(const ConstOsmMapPtr& map, const
return;
}

// Convert the polygon to a multipolygon if needed (FlagGeobuf cannot combine polygons and multipolygons in the same layer)
geometry = _polyToMultipoly(geometry);

std::string wkt = geometry->toString();
const char* t = wkt.data();
OGRGeometry* geom;
Expand Down Expand Up @@ -383,6 +378,9 @@ void OgrMultifileWriter::_writeWayPolygon(const ConstOsmMapPtr& map, const WayPt
return;
}

// Convert the polygon to a multipolygon if needed (FlagGeobuf cannot combine polygons and multipolygons in the same layer)
p = _polyToMultipoly(p);

std::string wkt = p->toString();
const char* t = wkt.data();
OGRGeometry* geom;
Expand All @@ -408,4 +406,16 @@ void OgrMultifileWriter::_writeWayPolygon(const ConstOsmMapPtr& map, const WayPt
OGRFeature::DestroyFeature(poFeature);
}

std::shared_ptr<geos::geom::Geometry> OgrMultifileWriter::_polyToMultipoly(const std::shared_ptr<geos::geom::Geometry>& geometry) const
{
std::shared_ptr<geos::geom::Geometry> multi = geometry;
if (_convertPolygons() && geometry->getGeometryTypeId() == GeometryTypeId::GEOS_POLYGON)
{
// Convert the single polygon to a multipolygon
std::vector<geos::geom::Geometry*>* single = new std::vector<geos::geom::Geometry*>({ geometry->clone().release() });
multi.reset(geos::geom::GeometryFactory::getDefaultInstance()->createMultiPolygon(single));
}
return multi;
}

}
3 changes: 2 additions & 1 deletion hoot-core/src/main/cpp/hoot/core/io/OgrMultifileWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,15 @@ class OgrMultifileWriter : public OsmMapWriter, public Configurable
virtual const char* _getDriverName() const = 0;
virtual QString _getFileExtension() const = 0;
virtual OgrOptions _getOptions() const = 0;
virtual OGRwkbGeometryType _getPolygonGeometryType() const = 0;
virtual bool _convertPolygons() const = 0;

void _writeRelationPolygon(const ConstOsmMapPtr& map, const RelationPtr& relation) const;
void _writeWayPolygon(const ConstOsmMapPtr& map, const WayPtr& way) const;

void _setupDataset(const ConstOsmMapPtr& map, const QString& path, OGRwkbGeometryType geometry_type, ElementType element_type);
OGRFeature* _createFeature(const Tags& tags, double circular_error) const;
void _cleanupDataset();
std::shared_ptr<geos::geom::Geometry> _polyToMultipoly(const std::shared_ptr<geos::geom::Geometry>& geometry) const;
};

}
Expand Down
2 changes: 1 addition & 1 deletion hoot-core/src/main/cpp/hoot/core/io/ShapefileWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class ShapefileWriter : public OgrMultifileWriter
const char* _getDriverName() const override { return "ESRI Shapefile"; };
QString _getFileExtension() const override { return ".shp"; }
OgrOptions _getOptions() const override;
OGRwkbGeometryType _getPolygonGeometryType() const override { return OGRwkbGeometryType::wkbMultiPolygon; }
bool _convertPolygons() const override { return false; }

};

Expand Down