Skip to content

Commit abcac34

Browse files
authored
Merge pull request #64 from JuliaGeo/features_fixes
2 parents 608717d + 94bb30a commit abcac34

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

src/base.jl

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,30 @@ GeoInterface.coordnames(::PointTrait, geom::NamedTuple{Keys,NTuple{N,T}}) where
2828

2929
# Default features using NamedTuple and AbstractArray
3030

31-
const NamedTupleFeature = NamedTuple{(:geometry, :properties)}
31+
# Any named tuple with a `:geometry` field is a feature
32+
_is_namedtuple_feature(::Type{<:NamedTuple{K}}) where K = :geometry in K
33+
_is_namedtuple_feature(nt::NamedTuple) = _is_namedtuple_feature(typeof(nt))
34+
35+
GeoInterface.isfeature(T::Type{<:NamedTuple}) = _is_namedtuple_feature(T)
36+
GeoInterface.trait(nt::NamedTuple) = _is_namedtuple_feature(nt) ? FeatureTrait() : nothing
37+
GeoInterface.geometry(nt::NamedTuple) = _is_namedtuple_feature(nt) ? nt.geometry : nothing
38+
GeoInterface.properties(nt::NamedTuple) = _is_namedtuple_feature(nt) ? _nt_properties(nt) : nothing
39+
40+
# Use Val to force constant propagation through `reduce`
41+
function _nt_properties(nt::NamedTuple{K}) where K
42+
keys = reduce(K; init=()) do acc, k
43+
k == :geometry ? acc : (acc..., k)
44+
end
45+
return NamedTuple{keys}(nt)
46+
end
3247

33-
GeoInterface.isfeature(::Type{<:NamedTupleFeature}) = true
34-
GeoInterface.trait(::NamedTupleFeature) = FeatureTrait()
35-
GeoInterface.geometry(f::NamedTupleFeature) = f.geometry
36-
GeoInterface.properties(f::NamedTupleFeature) = f.properties
48+
const MaybeArrayFeatureCollection = AbstractArray{<:NamedTuple}
3749

38-
const ArrayFeatureCollection = AbstractArray{<:NamedTupleFeature}
50+
_is_array_featurecollection(::Type{<:AbstractArray{T}}) where {T<:NamedTuple} = _is_namedtuple_feature(T)
51+
_is_array_featurecollection(A::AbstractArray{<:NamedTuple}) = _is_array_featurecollection(typeof(A))
3952

40-
GeoInterface.isfeaturecollection(::Type{<:ArrayFeatureCollection}) = true
41-
GeoInterface.trait(::ArrayFeatureCollection) = FeatureCollectionTrait()
42-
GeoInterface.nfeature(::FeatureCollectionTrait, fc::ArrayFeatureCollection) = Base.length(fc)
43-
GeoInterface.getfeature(::FeatureCollectionTrait, fc::ArrayFeatureCollection, i::Integer) = fc[i]
44-
GeoInterface.geometrycolumns(fc::ArrayFeatureCollection) = (:geometry,)
53+
GeoInterface.isfeaturecollection(T::Type{<:MaybeArrayFeatureCollection}) = _is_array_featurecollection(T)
54+
GeoInterface.trait(fc::MaybeArrayFeatureCollection) = _is_array_featurecollection(fc) ? FeatureCollectionTrait() : nothing
55+
GeoInterface.nfeature(::FeatureCollectionTrait, fc::MaybeArrayFeatureCollection) = _is_array_featurecollection(fc) ? Base.length(fc) : nothing
56+
GeoInterface.getfeature(::FeatureCollectionTrait, fc::MaybeArrayFeatureCollection, i::Integer) = _is_array_featurecollection(fc) ? fc[i] : nothing
57+
GeoInterface.geometrycolumns(fc::MaybeArrayFeatureCollection) = _is_array_featurecollection(fc) ? (:geometry,) : nothing

src/interface.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ Returns the object type, such as [`FeatureTrait`](@ref).
9292
For all `isgeometry` objects `trait` is the same as `geomtrait(obj)`,
9393
e.g. [`PointTrait`](@ref).
9494
"""
95-
# trait(geom::T) where T = isgeometry(T) ? geomtrait(geom) : nothing
9695
trait(geom) = geomtrait(geom)
9796

9897
# All types

src/types.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
"An AbstractTrait type for all geometries, features and feature collections."
2+
abstract type AbstractTrait end
13
"An AbstractGeometryTrait type for all geometries."
2-
abstract type AbstractGeometryTrait end
4+
abstract type AbstractGeometryTrait <: AbstractTrait end
35

46
"An AbstractGeometryCollectionTrait type for all geometrycollections."
57
abstract type AbstractGeometryCollectionTrait <: AbstractGeometryTrait end
@@ -82,11 +84,11 @@ struct MultiPolygonTrait <: AbstractMultiPolygonTrait end
8284

8385

8486
"An AbstractFeatureTrait for all features"
85-
abstract type AbstractFeatureTrait end
87+
abstract type AbstractFeatureTrait <: AbstractTrait end
8688
"A FeatureTrait holds `geometries`, `properties` and an `extent`"
8789
struct FeatureTrait <: AbstractFeatureTrait end
8890

8991
"An AbstractFeatureCollectionTrait for all feature collections"
90-
abstract type AbstractFeatureCollectionTrait end
92+
abstract type AbstractFeatureCollectionTrait <: AbstractTrait end
9193
"A FeatureCollectionTrait holds objects of `FeatureTrait` and an `extent`"
9294
struct FeatureCollectionTrait <: AbstractFeatureCollectionTrait end

test/test_primitives.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,9 @@ end
344344
end
345345

346346
@testset "NamedTupleFeature" begin
347-
feature = (; geometry=(1, 2), properties=(a="x", b="y"))
347+
feature = (; geometry=(1, 2), a="x", b="y", c="z")
348+
GeoInterface.geometry(feature) = (1, 2)
349+
@test GeoInterface.properties(feature) == (a="x", b="y", c="z")
348350
@test GeoInterface.testfeature(feature)
349351
@test GeoInterface.testfeaturecollection([feature, feature])
350352
end

0 commit comments

Comments
 (0)