diff --git a/src/base.jl b/src/base.jl index b84be69..483eca7 100644 --- a/src/base.jl +++ b/src/base.jl @@ -153,3 +153,33 @@ GeoInterface.trait(fc::MaybeArrayFeatureCollection) = _is_array_featurecollectio GeoInterface.nfeature(::FeatureCollectionTrait, fc::MaybeArrayFeatureCollection) = _is_array_featurecollection(fc) ? Base.length(fc) : nothing GeoInterface.getfeature(::FeatureCollectionTrait, fc::MaybeArrayFeatureCollection, i::Integer) = _is_array_featurecollection(fc) ? fc[i] : nothing GeoInterface.geometrycolumns(fc::MaybeArrayFeatureCollection) = _is_array_featurecollection(fc) ? (:geometry,) : nothing + +# Extents.Extent as RectangleTrait +GeoInterface.isgeometry(::Type{Extent{(:X, :Y), V}}) where V <:Tuple = true +GeoInterface.isgeometry(::Type{Extent{(:X, :Y, :Z), V}}) where V <:Tuple = true +GeoInterface.isgeometry(::Type{Extent{(:X, :Y, :Z, :M), V}}) where V <:Tuple = true +GeoInterface.geomtrait(::Extents.Extent) = RectangleTrait() +GeoInterface.ncoord(::RectangleTrait, geom::Extent{(:X, :Y)}) = 2 +GeoInterface.ncoord(::RectangleTrait, geom::Extent{(:X, :Y, :Z)}) = 3 +GeoInterface.ncoord(::RectangleTrait, geom::Extent{(:X, :Y, :Z, :M)}) = 4 +GeoInterface.ngeom(::RectangleTrait, geom::Extents.Extent) = 1 # Rectangle has one ring +function GeoInterface.getgeom(::RectangleTrait, geom::Extents.Extent{(:X, :Y)}, i::Integer) + i == 1 || throw(BoundsError(geom, i)) + + x_bounds = geom.X + y_bounds = geom.Y + + corners = [ + (x_bounds[1], y_bounds[1]), # bottom-left + (x_bounds[2], y_bounds[1]), # bottom-right + (x_bounds[2], y_bounds[2]), # top-right + (x_bounds[1], y_bounds[2]), # top-left + (x_bounds[1], y_bounds[1]) # close the ring + ] + # Wrap the corners in a LinearRing + return GeoInterface.LinearRing(corners) +end + +function GeoInterface.getgeom(::RectangleTrait, geom::Extents.Extent, i::Integer) + throw(ArgumentError("Extents with dimension other than XY are not supported as RectangleTrait geometries")) +end diff --git a/test/test_primitives.jl b/test/test_primitives.jl index 2eff930..8b34e64 100644 --- a/test/test_primitives.jl +++ b/test/test_primitives.jl @@ -542,3 +542,26 @@ Extents.extent(::ExtentPolygon) = Extent(X=(1, 2), Y=(3, 4)) @test isnothing(GeoInterface.extent(1)) @test isnothing(GeoInterface.extent(nothing, 1)) end + +@testset "Extent as RectangleTrait" begin + # Create an extent + extent = Extent(X=(1.0, 3.0), Y=(2.0, 4.0)) + + @test GeoInterface.isgeometry(extent) + @test GeoInterface.geomtrait(extent) isa RectangleTrait + @test GeoInterface.ncoord(extent) == 2 + @test GeoInterface.ngeom(extent) == 1 + + ring = GeoInterface.getgeom(extent, 1) + @test GeoInterface.geomtrait(ring) isa LinearRingTrait + @test GeoInterface.npoint(ring) == 5 # 4 corners + closing point + @inferred GeoInterface.getpoint(extent) + corners = collect(GeoInterface.getpoint(extent)) + @test corners[1] == (1.0, 2.0) # bottom-left + @test corners[2] == (3.0, 2.0) # bottom-right + @test corners[3] == (3.0, 4.0) # top-right + @test corners[4] == (1.0, 4.0) # top-left + @test corners[5] == (1.0, 2.0) # closed ring + + @test testgeometry(extent) +end