Skip to content

Commit

Permalink
Merge pull request #57 from JuliaGeo/feat/add-base-implementations
Browse files Browse the repository at this point in the history
Add implementations for Base types.
  • Loading branch information
evetion authored May 17, 2022
2 parents acf609b + e1b3d9b commit 70413dc
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 2 deletions.
14 changes: 14 additions & 0 deletions docs/src/guides/defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,17 @@ npoint(::QuadTrait, geom) = 4
npoint(::PentagonTrait, geom) = 5
npoint(::HexagonTrait, geom) = 6
```

# Implementations
GeoInterface is implemented for `NTuple`s, `NamedTuple`s and `AbstractVector`s to behave as Points. Note the `eltype` in all cases should be a `Real`. Only the keys `X`, `Y`, `Z`, and `M` are supported for `NamedTuple`s.

```julia
a = [1, 2, 3]
GeoInterface.x(a) == 1

b = (1, 2, 3)
GeoInterface.y(b) == 2

c = (;X=1, Y=2, Z=3)
GeoInterface.z(c) == 3
```
1 change: 1 addition & 0 deletions src/GeoInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ include("types.jl")
include("interface.jl")
include("fallbacks.jl")
include("utils.jl")
include("base.jl")

end # module
26 changes: 26 additions & 0 deletions src/base.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Implementation of GeoInterface for Base Types

GeoInterface.isgeometry(::Type{<:AbstractVector{<:Real}}) = true
GeoInterface.geomtrait(::AbstractVector{<:Real}) = PointTrait()
GeoInterface.ncoord(::PointTrait, geom::AbstractVector{<:Real}) = Base.length(geom)
GeoInterface.getcoord(::PointTrait, geom::AbstractVector{<:Real}, i) = getindex(geom, i)

GeoInterface.isgeometry(::Type{<:NTuple{N,<:Real}}) where {N} = true
GeoInterface.geomtrait(::NTuple{N,<:Real}) where {N} = PointTrait()
GeoInterface.ncoord(::PointTrait, geom::NTuple{N,<:Real}) where {N} = N
GeoInterface.getcoord(::PointTrait, geom::NTuple{N,<:Real}, i) where {N} = getindex(geom, i)

for i in 2:4
sig = NamedTuple{default_coord_names[1:i],NTuple{i,T}} where {T<:Real}
GeoInterface.isgeometry(::Type{<:sig}) = true
GeoInterface.geomtrait(::sig) = PointTrait()
GeoInterface.ncoord(::PointTrait, geom::sig) = i
GeoInterface.getcoord(::PointTrait, geom::sig, i) = getindex(geom, i)
end

# Custom coordinate order/names NamedTuple
GeoInterface.isgeometry(::Type{<:NamedTuple{Keys,NTuple{N,T}}}) where {Keys,N,T<:Real} = all(in(default_coord_names), Keys)
GeoInterface.geomtrait(::NamedTuple{Keys,NTuple{N,T}}) where {Keys,N,T<:Real} = PointTrait()
GeoInterface.ncoord(::PointTrait, geom::NamedTuple{Keys,NTuple{N,T}}) where {Keys,N,T<:Real} = Base.length(geom)
GeoInterface.getcoord(::PointTrait, geom::NamedTuple{Keys,NTuple{N,T}}, i) where {Keys,N,T<:Real} = getindex(geom, i)
GeoInterface.coordnames(::PointTrait, geom::NamedTuple{Keys,NTuple{N,T}}) where {Keys,N,T<:Real} = Keys
4 changes: 2 additions & 2 deletions src/utils.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Test whether the required interface for your `geom` has been implemented correctly."""
function testgeometry(geom)
try
@assert isgeometry(geom)
@assert isgeometry(geom) "Geom doesn't implement `isgeometry`."
type = geomtrait(geom)

if type == PointTrait()
Expand All @@ -18,7 +18,7 @@ function testgeometry(geom)
issub = geomtrait(g2) isa subtype
!issub && error("Implemented hierarchy for this geometry type is incorrect. Subgeometry should be a $subtype")
end
@assert testgeometry(g2) # recursive testing of subgeometries
@assert testgeometry(g2) "Subgeometry implementation is not valid."
end
end
catch e
Expand Down
39 changes: 39 additions & 0 deletions test/test_primitives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,42 @@ end
@test GeoInterface.astext(geom) isa String
@test GeoInterface.asbinary(geom) isa Vector{UInt8}
end

@testset "Base Implementations" begin

@testset "Vector" begin
geom = [1, 2]
@test testgeometry(geom)
@test GeoInterface.x(geom) == 1
@test GeoInterface.ncoord(geom) == 2
@test collect(GeoInterface.getcoord(geom)) == geom
end

@testset "Tuple" begin
geom = (1, 2)
@test testgeometry(geom)
@test GeoInterface.x(geom) == 1
@test GeoInterface.ncoord(geom) == 2
@test collect(GeoInterface.getcoord(geom)) == [1, 2]
end

@testset "NamedTuple" begin
geom = (; X=1, Y=2)
@test testgeometry(geom)
@test GeoInterface.x(geom) == 1
@test collect(GeoInterface.getcoord(geom)) == [1, 2]

geom = (; X=1, Y=2, Z=3)
@test testgeometry(geom)
geom = (; X=1, Y=2, Z=3, M=4)
@test testgeometry(geom)
geom = (; Z=3, X=1, Y=2, M=4)
@test testgeometry(geom)

@test GeoInterface.x(geom) == 1
@test GeoInterface.m(geom) == 4
@test GeoInterface.ncoord(geom) == 4
@test collect(GeoInterface.getcoord(geom)) == [3, 1, 2, 4]

end
end

2 comments on commit 70413dc

@evetion
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/60418

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.0.0 -m "<description of version>" 70413dcea1b2517d2a091a076a5845c0f02c0c3d
git push origin v1.0.0

Please sign in to comment.