From 2fa2f3bc706e2659b6464258c033be4481417000 Mon Sep 17 00:00:00 2001 From: Maarten Pronk Date: Thu, 1 Jan 2026 16:59:06 +0100 Subject: [PATCH 1/3] Fix for empty geometries. --- src/fallbacks.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fallbacks.jl b/src/fallbacks.jl index 8dbda50..2b84fdb 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -43,7 +43,7 @@ getexterior(t::AbstractPolygonTrait, geom) = getring(t, geom, 1) nhole(t::AbstractPolygonTrait, geom) = nring(t, geom) - 1 gethole(t::AbstractPolygonTrait, geom) = (getgeom(t, geom, i) for i in 2:ngeom(t, geom)) gethole(t::AbstractPolygonTrait, geom, i) = getring(t, geom, i + 1) -npoint(t::AbstractPolygonTrait, geom) = sum(npoint(p) for p in getring(t, geom)) +npoint(t::AbstractPolygonTrait, geom) = sum(npoint(p) for p in getring(t, geom); init=0) getpoint(t::AbstractPolygonTrait, geom) = flatten((p for p in getpoint(r)) for r in getring(t, geom)) ## MultiPoint @@ -55,16 +55,16 @@ getpoint(t::AbstractMultiPointTrait, geom, i) = getgeom(t, geom, i) nlinestring(t::AbstractMultiCurveTrait, geom) = ngeom(t, geom) getlinestring(t::AbstractMultiCurveTrait, geom) = getgeom(t, geom) getlinestring(t::AbstractMultiCurveTrait, geom, i) = getgeom(t, geom, i) -npoint(t::AbstractMultiCurveTrait, geom) = sum(npoint(ls) for ls in getgeom(t, geom)) +npoint(t::AbstractMultiCurveTrait, geom) = sum(npoint(ls) for ls in getgeom(t, geom); init=0) getpoint(t::AbstractMultiCurveTrait, geom) = flatten((p for p in getpoint(ls)) for ls in getgeom(t, geom)) ## MultiPolygon npolygon(t::AbstractMultiPolygonTrait, geom) = ngeom(t, geom) getpolygon(t::AbstractMultiPolygonTrait, geom) = getgeom(t, geom) getpolygon(t::AbstractMultiPolygonTrait, geom, i) = getgeom(t, geom, i) -nring(t::AbstractMultiPolygonTrait, geom) = sum(nring(p) for p in getpolygon(t, geom)) +nring(t::AbstractMultiPolygonTrait, geom) = sum(nring(p)::Int for p in getpolygon(t, geom); init=0) getring(t::AbstractMultiPolygonTrait, geom) = flatten((r for r in getring(p)) for p in getpolygon(t, geom)) -npoint(t::AbstractMultiPolygonTrait, geom) = sum(npoint(r) for r in getring(t, geom)) +npoint(t::AbstractMultiPolygonTrait, geom) = sum(npoint(r)::Int for r in getring(t, geom); init=0) getpoint(t::AbstractMultiPolygonTrait, geom) = flatten((p for p in getpoint(r)) for r in getring(t, geom)) ## Surface @@ -130,6 +130,7 @@ function calc_extent(t::AbstractPointTrait, geom) end end function calc_extent(t::AbstractGeometryTrait, geom) + isempty(t, geom) && return nothing points = getpoint(t, geom) X = extrema(p -> x(p), points) Y = extrema(p -> y(p), points) From 2974a6878925c7b447917ed47d6cda6522096da3 Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Fri, 2 Jan 2026 17:33:41 +0100 Subject: [PATCH 2/3] Add test for empty polygon geometry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests that npoint and nring return 0 for empty polygons, verifying the init=0 fix works correctly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- test/test_primitives.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/test_primitives.jl b/test/test_primitives.jl index 49901c3..2eff930 100644 --- a/test/test_primitives.jl +++ b/test/test_primitives.jl @@ -8,6 +8,7 @@ struct MyPoint end struct MyEmptyPoint end struct MyCurve end struct MyPolygon end +struct MyEmptyPolygon end struct MyTriangle end struct MyMultiPoint end struct MyMultiCurve end @@ -46,6 +47,12 @@ GeoInterface.ngeom(::PolygonTrait, geom::MyPolygon) = 2 GeoInterface.getgeom(::PolygonTrait, geom::MyPolygon, i) = MyCurve() GeoInterface.ncoord(t::PolygonTrait, geom::MyPolygon) = 2 +GeoInterface.isgeometry(::Type{MyEmptyPolygon}) = true +GeoInterface.geomtrait(::MyEmptyPolygon) = PolygonTrait() +GeoInterface.ngeom(::PolygonTrait, geom::MyEmptyPolygon) = 0 +GeoInterface.getgeom(::PolygonTrait, geom::MyEmptyPolygon, i) = nothing +GeoInterface.isempty(::PolygonTrait, geom::MyEmptyPolygon) = true + GeoInterface.isgeometry(::Type{MyTriangle}) = true GeoInterface.geomtrait(::MyTriangle) = TriangleTrait() GeoInterface.ngeom(::TriangleTrait, geom::MyTriangle) = 3 @@ -173,6 +180,11 @@ GeoInterface.crs(::RasterTrait, ::Raster) = GeoFormatTypes.EPSG(4326) @test GeoInterface.nring(geom) == 1 @test GeoInterface.nhole(geom) == 0 @test GeoInterface.npoint(geom) == 3 + + geom = MyEmptyPolygon() + @test GeoInterface.isempty(geom) + @test GeoInterface.nring(geom) == 0 + @test GeoInterface.npoint(geom) == 0 end @testset "MultiPoint" begin From 37be44a435c08ed99aae4d1c02f3394c36d1e3d5 Mon Sep 17 00:00:00 2001 From: Maarten Pronk Date: Sat, 3 Jan 2026 13:29:06 +0100 Subject: [PATCH 3/3] Remove typehint. --- src/fallbacks.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fallbacks.jl b/src/fallbacks.jl index 2b84fdb..c79caa8 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -62,9 +62,9 @@ getpoint(t::AbstractMultiCurveTrait, geom) = flatten((p for p in getpoint(ls)) f npolygon(t::AbstractMultiPolygonTrait, geom) = ngeom(t, geom) getpolygon(t::AbstractMultiPolygonTrait, geom) = getgeom(t, geom) getpolygon(t::AbstractMultiPolygonTrait, geom, i) = getgeom(t, geom, i) -nring(t::AbstractMultiPolygonTrait, geom) = sum(nring(p)::Int for p in getpolygon(t, geom); init=0) +nring(t::AbstractMultiPolygonTrait, geom) = sum(nring(p) for p in getpolygon(t, geom); init=0) getring(t::AbstractMultiPolygonTrait, geom) = flatten((r for r in getring(p)) for p in getpolygon(t, geom)) -npoint(t::AbstractMultiPolygonTrait, geom) = sum(npoint(r)::Int for r in getring(t, geom); init=0) +npoint(t::AbstractMultiPolygonTrait, geom) = sum(npoint(r) for r in getring(t, geom); init=0) getpoint(t::AbstractMultiPolygonTrait, geom) = flatten((p for p in getpoint(r)) for r in getring(t, geom)) ## Surface