Skip to content

Commit

Permalink
Create a multipolygon for all polygons so they can be in one layer to…
Browse files Browse the repository at this point in the history
…gether. (#5674)
  • Loading branch information
bmarchant authored Jun 19, 2023
1 parent 10cc50b commit 5476d99
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 13 deletions.
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

0 comments on commit 5476d99

Please sign in to comment.