[geos-commits] [SCM] GEOS branch main updated. ee89eae8faa1e8bf82c98d30ce35a3328e3d57ae
git at osgeo.org
git at osgeo.org
Wed Apr 1 08:53:42 PDT 2026
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".
The branch, main has been updated
via ee89eae8faa1e8bf82c98d30ce35a3328e3d57ae (commit)
from 1a8eb16b2c90598d71fd6e469c79ec0ce6bba33e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ee89eae8faa1e8bf82c98d30ce35a3328e3d57ae
Author: Daniel Baston <dbaston at gmail.com>
Date: Wed Apr 1 11:53:19 2026 -0400
GeometryFactory: add createSurface method (#1416)
diff --git a/include/geos/geom/GeometryFactory.h b/include/geos/geom/GeometryFactory.h
index 4b5dba01f..d58b4dfe7 100644
--- a/include/geos/geom/GeometryFactory.h
+++ b/include/geos/geom/GeometryFactory.h
@@ -308,6 +308,15 @@ public:
std::unique_ptr<CurvePolygon> createCurvePolygon(std::unique_ptr<Curve>&& shell,
std::vector<std::unique_ptr<Curve>> && holes) const;
+
+ /// Construct a Surface, taking ownership of given arguments
+ /// If arguments are LinearRings, a Polygon will be returned.
+ /// Otherwise, a CurvePolygon will be returned.
+ std::unique_ptr<Surface> createSurface(std::unique_ptr<Curve>&& shell) const;
+
+ std::unique_ptr<Surface> createSurface(std::unique_ptr<Curve>&& shell,
+ std::vector<std::unique_ptr<Curve>> && holes) const;
+
/// Construct an EMPTY LineString
std::unique_ptr<LineString> createLineString(std::size_t coordinateDimension = 2) const;
std::unique_ptr<LineString> createLineString(bool hasZ, bool hasM) const;
diff --git a/src/geom/GeometryFactory.cpp b/src/geom/GeometryFactory.cpp
index 152dd39a2..93dc39f61 100644
--- a/src/geom/GeometryFactory.cpp
+++ b/src/geom/GeometryFactory.cpp
@@ -635,6 +635,42 @@ const
return std::unique_ptr<CurvePolygon>(new CurvePolygon(std::move(shell), std::move(holes), *this));
}
+/* public */
+std::unique_ptr<Surface>
+GeometryFactory::createSurface(std::unique_ptr<Curve> && shell)
+const
+{
+ if (shell->getGeometryTypeId() == GEOS_LINEARRING) {
+ std::unique_ptr<LinearRing> shellLR(detail::down_cast<LinearRing*>(shell.release()));
+ return createPolygon(std::move(shellLR));
+ }
+
+ return createCurvePolygon(std::move(shell));
+}
+
+/* public */
+std::unique_ptr<Surface>
+GeometryFactory::createSurface(std::unique_ptr<Curve> && shell, std::vector<std::unique_ptr<Curve>> && holes)
+const
+{
+ const bool returnPolygon = shell->getGeometryTypeId() == GEOS_LINEARRING && std::all_of(holes.begin(), holes.end(), [](const auto& hole) {
+ return hole->getGeometryTypeId() == GEOS_LINEARRING;
+ });
+
+ if (returnPolygon) {
+ std::unique_ptr<LinearRing> shellLR(detail::down_cast<LinearRing*>(shell.release()));
+
+ std::vector<std::unique_ptr<LinearRing>> holesLR(holes.size());
+ for (std::size_t i = 0; i < holes.size(); i++) {
+ holesLR[i].reset(detail::down_cast<LinearRing*>(holes[i].release()));
+ }
+
+ return createPolygon(std::move(shellLR), std::move(holesLR));
+ }
+
+ return createCurvePolygon(std::move(shell), std::move(holes));
+}
+
/*public*/
std::unique_ptr<LineString>
GeometryFactory::createLineString(std::size_t coordinateDimension) const
diff --git a/tests/unit/geom/GeometryFactoryTest.cpp b/tests/unit/geom/GeometryFactoryTest.cpp
index a0773b21b..7e80d6703 100644
--- a/tests/unit/geom/GeometryFactoryTest.cpp
+++ b/tests/unit/geom/GeometryFactoryTest.cpp
@@ -1455,5 +1455,63 @@ void object::test<41>
}
}
+template<>
+template<>
+void object::test<42>
+() {
+ set_test_name("createSurface");
+ using geos::geom::GEOS_POLYGON;
+ using geos::geom::GEOS_CURVEPOLYGON;
+ using geos::geom::Curve;
+
+ // LinearRing
+ {
+ auto shell = reader_.read<Curve>("LINEARRING (0 0, 1 0, 1 1, 0 0)");
+ ensure_equals(factory_->createSurface(std::move(shell))->getGeometryTypeId(), GEOS_POLYGON);
+ }
+
+ // LineString
+ {
+ auto shell = reader_.read<Curve>("LINESTRING (0 0, 1 0, 1 1, 0 0)");
+ ensure_equals(factory_->createSurface(std::move(shell))->getGeometryTypeId(), GEOS_CURVEPOLYGON);
+ }
+
+ // CompoundCurve, linear
+ {
+ auto shell = reader_.read<Curve>("COMPOUNDCURVE ((0 0, 1 0, 1 1, 0 0))");
+ ensure_equals(factory_->createSurface(std::move(shell))->getGeometryTypeId(), GEOS_CURVEPOLYGON);
+ }
+
+ // CircularString
+ {
+ auto shell = reader_.read<Curve>("CIRCULARSTRING (-1 0, 0 1, 1 0, 0 -1, -1 0)");
+ ensure_equals(factory_->createSurface(std::move(shell))->getGeometryTypeId(), GEOS_CURVEPOLYGON);
+ }
+
+ // CompoundCurve, curved
+ {
+ auto shell = reader_.read<Curve>("COMPOUNDCURVE (CIRCULARSTRING (0 0, 1 1, 2 0), (2 0, 0 0))");
+ ensure_equals(factory_->createSurface(std::move(shell))->getGeometryTypeId(), GEOS_CURVEPOLYGON);
+ }
+
+ // LinearRing shell, LinearRing hole
+ {
+ auto shell = reader_.read<Curve>("LINEARRING (0 0, 10 0, 10 10, 0 10, 0 0)");
+ auto hole = reader_.read<Curve>("LINEARRING (5 5, 7 5, 7 7, 5 7, 5 5)");
+ std::vector<std::unique_ptr<Curve>> holes;
+ holes.push_back(std::move(hole));
+ ensure_equals(factory_->createSurface(std::move(shell), std::move(holes))->getGeometryTypeId(), GEOS_POLYGON);
+ }
+
+ // LinearRing shell, CompoundCurve hole
+ {
+ auto shell = reader_.read<Curve>("LINEARRING (0 0, 10 0, 10 10, 0 10, 0 0)");
+ auto hole = reader_.read<Curve>("COMPOUNDCURVE ((5 5, 7 5, 7 7, 5 7, 5 5))");
+ std::vector<std::unique_ptr<Curve>> holes;
+ holes.push_back(std::move(hole));
+ ensure_equals(factory_->createSurface(std::move(shell), std::move(holes))->getGeometryTypeId(), GEOS_CURVEPOLYGON);
+ }
+
+}
} // namespace tut
-----------------------------------------------------------------------
Summary of changes:
include/geos/geom/GeometryFactory.h | 9 +++++
src/geom/GeometryFactory.cpp | 36 ++++++++++++++++++++
tests/unit/geom/GeometryFactoryTest.cpp | 58 +++++++++++++++++++++++++++++++++
3 files changed, 103 insertions(+)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list