44
55"""
66 RectilinearGrid(x, y, z, ...)
7- RectilinearGrid{Datum }(x, y, z, ...)
7+ RectilinearGrid{M,C }(x, y, z, ...)
88
99A rectilinear grid with vertices at sorted coordinates `x`, `y`, `z`, ...,
10- and a given `Datum ` (default to `NoDatum `).
10+ manifold `M` (default to `𝔼`) and CRS type `C ` (default to `Cartesian `).
1111
1212## Examples
1313
@@ -20,49 +20,84 @@ julia> y = [0.0, 0.1, 0.3, 0.7, 0.9, 1.0]
2020julia> RectilinearGrid(x, y)
2121```
2222"""
23- struct RectilinearGrid{Datum,Dim,ℒ<: Len ,V<: AbstractVector{ℒ} } <: Grid{𝔼{Dim},Cartesian{Datum,Dim,ℒ},Dim}
24- xyz:: NTuple{Dim,V}
25- topology:: GridTopology{Dim}
26-
27- function RectilinearGrid {Datum} (
28- xyz:: NTuple{Dim,<:AbstractVector{<:Len}} ,
29- topology:: GridTopology{Dim}
30- ) where {Datum,Dim}
31- coords = float .(xyz)
32- V = eltype (coords)
33- new {Datum,Dim,eltype(V),V} (coords, topology)
34- end
23+ struct RectilinearGrid{M<: Manifold ,C<: CRS ,N,X<: NTuple{N,AbstractVector} } <: Grid{M,C,N}
24+ xyz:: X
25+ topology:: GridTopology{N}
26+ RectilinearGrid {M,C,N,X} (xyz, topology) where {M<: Manifold ,C<: CRS ,N,X<: NTuple{N,AbstractVector} } = new (xyz, topology)
3527end
3628
37- RectilinearGrid {Datum} (xyz:: NTuple{Dim,<:AbstractVector} , topology:: GridTopology{Dim} ) where {Datum,Dim} =
38- RectilinearGrid {Datum} (addunit .(xyz, u " m" ), topology)
29+ function RectilinearGrid {M,C} (xyz:: NTuple{N,AbstractVector} , topology:: GridTopology{N} ) where {M<: Manifold ,C<: CRS ,N}
30+ if M < : 🌐 && ! (C <: LatLon )
31+ throw (ArgumentError (" rectilinear grid on `🌐` requires `LatLon` coordinates" ))
32+ end
33+
34+ T = CoordRefSystems. mactype (C)
35+ nc = CoordRefSystems. ncoords (C)
36+ us = CoordRefSystems. units (C)
37+
38+ if N ≠ nc
39+ throw (ArgumentError ("""
40+ A $N -dimensional rectilinear grid requires a CRS with $N coordinates.
41+ The provided CRS has $nc coordinates.
42+ """ ))
43+ end
44+
45+ xyz′ = ntuple (i -> numconvert .(T, _withunit .(xyz[i], us[i])), nc)
46+ RectilinearGrid {M,C,N,typeof(xyz′)} (xyz′, topology)
47+ end
3948
40- function RectilinearGrid {Datum} (xyz:: Tuple ) where {Datum}
41- coords = promote (collect .(xyz)... )
42- topology = GridTopology (length .(coords) .- 1 )
43- RectilinearGrid {Datum} (coords, topology)
49+ function RectilinearGrid {M,C} (xyz:: NTuple{N,AbstractVector} ) where {M<: Manifold ,C<: CRS ,N}
50+ topology = GridTopology (length .(xyz) .- 1 )
51+ RectilinearGrid {M,C} (xyz, topology)
4452end
4553
46- RectilinearGrid {Datum} (xyz... ) where {Datum} = RectilinearGrid {Datum} (xyz)
54+ RectilinearGrid {M,C} (xyz:: AbstractVector... ) where {M<: Manifold ,C<: CRS } = RectilinearGrid {M,C} (xyz)
55+
56+ function RectilinearGrid (xyz:: NTuple{N,AbstractVector} ) where {N}
57+ try
58+ L = promote_type (ntuple (i -> _lentype (eltype (xyz[i])), N)... )
59+ M = 𝔼{N}
60+ C = Cartesian{NoDatum,N,L}
61+ RectilinearGrid {M,C} (xyz)
62+ catch
63+ throw (ArgumentError (" invalid units for cartesian coordinates" ))
64+ end
65+ end
4766
48- RectilinearGrid (args ... ) = RectilinearGrid {NoDatum} (args ... )
67+ RectilinearGrid (xyz :: AbstractVector ... ) = RectilinearGrid (xyz )
4968
50- vertex (g:: RectilinearGrid{Datum} , ijk:: Dims ) where {Datum} = Point (Cartesian {Datum} (getindex .(g. xyz, ijk)))
69+ function vertex (g:: RectilinearGrid , ijk:: Dims )
70+ ctor = CoordRefSystems. constructor (crs (g))
71+ Point (ctor (getindex .(g. xyz, ijk)... ))
72+ end
5173
5274xyz (g:: RectilinearGrid ) = g. xyz
5375
5476XYZ (g:: RectilinearGrid ) = XYZ (xyz (g))
5577
56- function Base. getindex (g:: RectilinearGrid{Datum} , I:: CartesianIndices ) where {Datum}
57- @boundscheck _checkbounds (g, I)
58- dims = size (I)
59- start = Tuple (first (I))
60- stop = Tuple (last (I)) .+ 1
61- xyz = ntuple (i -> g. xyz[i][start[i]: stop[i]], embeddim (g))
62- RectilinearGrid {Datum} (xyz, GridTopology (dims))
78+ @generated function Base. getindex (g:: RectilinearGrid{M,C,N} , I:: CartesianIndices ) where {M,C,N}
79+ exprs = ntuple (N) do i
80+ :(g. xyz[$ i][start[$ i]: stop[$ i]])
81+ end
82+
83+ quote
84+ @boundscheck _checkbounds (g, I)
85+ dims = size (I)
86+ start = Tuple (first (I))
87+ stop = Tuple (last (I)) .+ 1
88+ xyz = ($ (exprs... ),)
89+ RectilinearGrid {M,C} (xyz, GridTopology (dims))
90+ end
6391end
6492
6593function Base. summary (io:: IO , g:: RectilinearGrid )
6694 join (io, size (g), " ×" )
6795 print (io, " RectilinearGrid" )
6896end
97+
98+ # -----------------
99+ # HELPER FUNCTIONS
100+ # -----------------
101+
102+ _lentype (:: Type{T} ) where {T<: Len } = T
103+ _lentype (:: Type{T} ) where {T<: Number } = Met{T}
0 commit comments