Skip to content

Commit 5a85ddc

Browse files
evetionasinghvi17claude
authored
Fix for empty geometries. (#209)
* Fix for empty geometries. * Add test for empty polygon geometry 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 <[email protected]> * Remove typehint. --------- Co-authored-by: Anshul Singhvi <[email protected]> Co-authored-by: Claude Opus 4.5 <[email protected]>
1 parent f427af4 commit 5a85ddc

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/fallbacks.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ getexterior(t::AbstractPolygonTrait, geom) = getring(t, geom, 1)
4343
nhole(t::AbstractPolygonTrait, geom) = nring(t, geom) - 1
4444
gethole(t::AbstractPolygonTrait, geom) = (getgeom(t, geom, i) for i in 2:ngeom(t, geom))
4545
gethole(t::AbstractPolygonTrait, geom, i) = getring(t, geom, i + 1)
46-
npoint(t::AbstractPolygonTrait, geom) = sum(npoint(p) for p in getring(t, geom))
46+
npoint(t::AbstractPolygonTrait, geom) = sum(npoint(p) for p in getring(t, geom); init=0)
4747
getpoint(t::AbstractPolygonTrait, geom) = flatten((p for p in getpoint(r)) for r in getring(t, geom))
4848

4949
## MultiPoint
@@ -55,16 +55,16 @@ getpoint(t::AbstractMultiPointTrait, geom, i) = getgeom(t, geom, i)
5555
nlinestring(t::AbstractMultiCurveTrait, geom) = ngeom(t, geom)
5656
getlinestring(t::AbstractMultiCurveTrait, geom) = getgeom(t, geom)
5757
getlinestring(t::AbstractMultiCurveTrait, geom, i) = getgeom(t, geom, i)
58-
npoint(t::AbstractMultiCurveTrait, geom) = sum(npoint(ls) for ls in getgeom(t, geom))
58+
npoint(t::AbstractMultiCurveTrait, geom) = sum(npoint(ls) for ls in getgeom(t, geom); init=0)
5959
getpoint(t::AbstractMultiCurveTrait, geom) = flatten((p for p in getpoint(ls)) for ls in getgeom(t, geom))
6060

6161
## MultiPolygon
6262
npolygon(t::AbstractMultiPolygonTrait, geom) = ngeom(t, geom)
6363
getpolygon(t::AbstractMultiPolygonTrait, geom) = getgeom(t, geom)
6464
getpolygon(t::AbstractMultiPolygonTrait, geom, i) = getgeom(t, geom, i)
65-
nring(t::AbstractMultiPolygonTrait, geom) = sum(nring(p) for p in getpolygon(t, geom))
65+
nring(t::AbstractMultiPolygonTrait, geom) = sum(nring(p) for p in getpolygon(t, geom); init=0)
6666
getring(t::AbstractMultiPolygonTrait, geom) = flatten((r for r in getring(p)) for p in getpolygon(t, geom))
67-
npoint(t::AbstractMultiPolygonTrait, geom) = sum(npoint(r) for r in getring(t, geom))
67+
npoint(t::AbstractMultiPolygonTrait, geom) = sum(npoint(r) for r in getring(t, geom); init=0)
6868
getpoint(t::AbstractMultiPolygonTrait, geom) = flatten((p for p in getpoint(r)) for r in getring(t, geom))
6969

7070
## Surface
@@ -130,6 +130,7 @@ function calc_extent(t::AbstractPointTrait, geom)
130130
end
131131
end
132132
function calc_extent(t::AbstractGeometryTrait, geom)
133+
isempty(t, geom) && return nothing
133134
points = getpoint(t, geom)
134135
X = extrema(p -> x(p), points)
135136
Y = extrema(p -> y(p), points)

test/test_primitives.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct MyPoint end
88
struct MyEmptyPoint end
99
struct MyCurve end
1010
struct MyPolygon end
11+
struct MyEmptyPolygon end
1112
struct MyTriangle end
1213
struct MyMultiPoint end
1314
struct MyMultiCurve end
@@ -46,6 +47,12 @@ GeoInterface.ngeom(::PolygonTrait, geom::MyPolygon) = 2
4647
GeoInterface.getgeom(::PolygonTrait, geom::MyPolygon, i) = MyCurve()
4748
GeoInterface.ncoord(t::PolygonTrait, geom::MyPolygon) = 2
4849

50+
GeoInterface.isgeometry(::Type{MyEmptyPolygon}) = true
51+
GeoInterface.geomtrait(::MyEmptyPolygon) = PolygonTrait()
52+
GeoInterface.ngeom(::PolygonTrait, geom::MyEmptyPolygon) = 0
53+
GeoInterface.getgeom(::PolygonTrait, geom::MyEmptyPolygon, i) = nothing
54+
GeoInterface.isempty(::PolygonTrait, geom::MyEmptyPolygon) = true
55+
4956
GeoInterface.isgeometry(::Type{MyTriangle}) = true
5057
GeoInterface.geomtrait(::MyTriangle) = TriangleTrait()
5158
GeoInterface.ngeom(::TriangleTrait, geom::MyTriangle) = 3
@@ -173,6 +180,11 @@ GeoInterface.crs(::RasterTrait, ::Raster) = GeoFormatTypes.EPSG(4326)
173180
@test GeoInterface.nring(geom) == 1
174181
@test GeoInterface.nhole(geom) == 0
175182
@test GeoInterface.npoint(geom) == 3
183+
184+
geom = MyEmptyPolygon()
185+
@test GeoInterface.isempty(geom)
186+
@test GeoInterface.nring(geom) == 0
187+
@test GeoInterface.npoint(geom) == 0
176188
end
177189

178190
@testset "MultiPoint" begin

0 commit comments

Comments
 (0)