Skip to content

Commit 70413dc

Browse files
authored
Merge pull request #57 from JuliaGeo/feat/add-base-implementations
Add implementations for Base types.
2 parents acf609b + e1b3d9b commit 70413dc

File tree

5 files changed

+82
-2
lines changed

5 files changed

+82
-2
lines changed

docs/src/guides/defaults.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,17 @@ npoint(::QuadTrait, geom) = 4
4545
npoint(::PentagonTrait, geom) = 5
4646
npoint(::HexagonTrait, geom) = 6
4747
```
48+
49+
# Implementations
50+
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.
51+
52+
```julia
53+
a = [1, 2, 3]
54+
GeoInterface.x(a) == 1
55+
56+
b = (1, 2, 3)
57+
GeoInterface.y(b) == 2
58+
59+
c = (;X=1, Y=2, Z=3)
60+
GeoInterface.z(c) == 3
61+
```

src/GeoInterface.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ include("types.jl")
4545
include("interface.jl")
4646
include("fallbacks.jl")
4747
include("utils.jl")
48+
include("base.jl")
4849

4950
end # module

src/base.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Implementation of GeoInterface for Base Types
2+
3+
GeoInterface.isgeometry(::Type{<:AbstractVector{<:Real}}) = true
4+
GeoInterface.geomtrait(::AbstractVector{<:Real}) = PointTrait()
5+
GeoInterface.ncoord(::PointTrait, geom::AbstractVector{<:Real}) = Base.length(geom)
6+
GeoInterface.getcoord(::PointTrait, geom::AbstractVector{<:Real}, i) = getindex(geom, i)
7+
8+
GeoInterface.isgeometry(::Type{<:NTuple{N,<:Real}}) where {N} = true
9+
GeoInterface.geomtrait(::NTuple{N,<:Real}) where {N} = PointTrait()
10+
GeoInterface.ncoord(::PointTrait, geom::NTuple{N,<:Real}) where {N} = N
11+
GeoInterface.getcoord(::PointTrait, geom::NTuple{N,<:Real}, i) where {N} = getindex(geom, i)
12+
13+
for i in 2:4
14+
sig = NamedTuple{default_coord_names[1:i],NTuple{i,T}} where {T<:Real}
15+
GeoInterface.isgeometry(::Type{<:sig}) = true
16+
GeoInterface.geomtrait(::sig) = PointTrait()
17+
GeoInterface.ncoord(::PointTrait, geom::sig) = i
18+
GeoInterface.getcoord(::PointTrait, geom::sig, i) = getindex(geom, i)
19+
end
20+
21+
# Custom coordinate order/names NamedTuple
22+
GeoInterface.isgeometry(::Type{<:NamedTuple{Keys,NTuple{N,T}}}) where {Keys,N,T<:Real} = all(in(default_coord_names), Keys)
23+
GeoInterface.geomtrait(::NamedTuple{Keys,NTuple{N,T}}) where {Keys,N,T<:Real} = PointTrait()
24+
GeoInterface.ncoord(::PointTrait, geom::NamedTuple{Keys,NTuple{N,T}}) where {Keys,N,T<:Real} = Base.length(geom)
25+
GeoInterface.getcoord(::PointTrait, geom::NamedTuple{Keys,NTuple{N,T}}, i) where {Keys,N,T<:Real} = getindex(geom, i)
26+
GeoInterface.coordnames(::PointTrait, geom::NamedTuple{Keys,NTuple{N,T}}) where {Keys,N,T<:Real} = Keys

src/utils.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Test whether the required interface for your `geom` has been implemented correctly."""
22
function testgeometry(geom)
33
try
4-
@assert isgeometry(geom)
4+
@assert isgeometry(geom) "Geom doesn't implement `isgeometry`."
55
type = geomtrait(geom)
66

77
if type == PointTrait()
@@ -18,7 +18,7 @@ function testgeometry(geom)
1818
issub = geomtrait(g2) isa subtype
1919
!issub && error("Implemented hierarchy for this geometry type is incorrect. Subgeometry should be a $subtype")
2020
end
21-
@assert testgeometry(g2) # recursive testing of subgeometries
21+
@assert testgeometry(g2) "Subgeometry implementation is not valid."
2222
end
2323
end
2424
catch e

test/test_primitives.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,42 @@ end
290290
@test GeoInterface.astext(geom) isa String
291291
@test GeoInterface.asbinary(geom) isa Vector{UInt8}
292292
end
293+
294+
@testset "Base Implementations" begin
295+
296+
@testset "Vector" begin
297+
geom = [1, 2]
298+
@test testgeometry(geom)
299+
@test GeoInterface.x(geom) == 1
300+
@test GeoInterface.ncoord(geom) == 2
301+
@test collect(GeoInterface.getcoord(geom)) == geom
302+
end
303+
304+
@testset "Tuple" begin
305+
geom = (1, 2)
306+
@test testgeometry(geom)
307+
@test GeoInterface.x(geom) == 1
308+
@test GeoInterface.ncoord(geom) == 2
309+
@test collect(GeoInterface.getcoord(geom)) == [1, 2]
310+
end
311+
312+
@testset "NamedTuple" begin
313+
geom = (; X=1, Y=2)
314+
@test testgeometry(geom)
315+
@test GeoInterface.x(geom) == 1
316+
@test collect(GeoInterface.getcoord(geom)) == [1, 2]
317+
318+
geom = (; X=1, Y=2, Z=3)
319+
@test testgeometry(geom)
320+
geom = (; X=1, Y=2, Z=3, M=4)
321+
@test testgeometry(geom)
322+
geom = (; Z=3, X=1, Y=2, M=4)
323+
@test testgeometry(geom)
324+
325+
@test GeoInterface.x(geom) == 1
326+
@test GeoInterface.m(geom) == 4
327+
@test GeoInterface.ncoord(geom) == 4
328+
@test collect(GeoInterface.getcoord(geom)) == [3, 1, 2, 4]
329+
330+
end
331+
end

0 commit comments

Comments
 (0)