Skip to content

Commit 5b845bb

Browse files
committed
Fix 'lenunit' option to handle coordinates with units
1 parent 9e8ff6b commit 5b845bb

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

src/georef.jl

+20-12
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ georef(table, geoms::AbstractVector{<:Geometry}) = georef(table, GeometrySet(geo
3636
Georeference `table` using coordinates `coords` of points.
3737
3838
Optionally, specify the coordinate reference system `crs`, which is
39-
set by default based on heuristics, and the `lenunit` (default to meters)
39+
set by default based on heuristics, and the `lenunit` (default to meters for unitless values)
4040
that will be used in CRS types that allow this flexibility. Any `CRS` or `EPSG`/`ESRI`
4141
code from [CoordRefSystems.jl](https://github.com/JuliaEarth/CoordRefSystems.jl)
4242
is supported.
@@ -50,7 +50,7 @@ julia> georef((a=[1, 2, 3], b=[4, 5, 6], [(0, 0), (1, 1), (2, 2)], crs=EPSG{4326
5050
julia> georef((a=[1, 2, 3], b=[4, 5, 6], [(0, 0), (1, 1), (2, 2)], lenunit=u"cm")
5151
```
5252
"""
53-
function georef(table, coords::AbstractVector; crs=nothing, lenunit=u"m")
53+
function georef(table, coords::AbstractVector; crs=nothing, lenunit=nothing)
5454
clen = length(first(coords))
5555
ccrs = isnothing(crs) ? Cartesian{NoDatum,clen} : validcrs(crs)
5656
point = pointbuilder(ccrs, lenunit)
@@ -64,7 +64,7 @@ end
6464
Georeference `table` using coordinates of points stored in column `names`.
6565
6666
Optionally, specify the coordinate reference system `crs`, which is
67-
set by default based on heuristics, and the `lenunit` (default to meter)
67+
set by default based on heuristics, and the `lenunit` (default to meters for unitless values)
6868
that will be used in CRS types that allow this flexibility. Any `CRS` or `EPSG`/`ESRI`
6969
code from [CoordRefSystems.jl](https://github.com/JuliaEarth/CoordRefSystems.jl)
7070
is supported.
@@ -78,7 +78,7 @@ georef((a=rand(10), x=rand(10), y=rand(10)), ("x", "y"), crs=EPSG{4326})
7878
georef((a=rand(10), x=rand(10), y=rand(10)), ("x", "y"), lenunit=u"cm")
7979
```
8080
"""
81-
function georef(table, names::AbstractVector{Symbol}; crs=nothing, lenunit=u"m")
81+
function georef(table, names::AbstractVector{Symbol}; crs=nothing, lenunit=nothing)
8282
cols = Tables.columns(table)
8383
tnames = Tables.columnnames(cols)
8484
if names tnames
@@ -158,19 +158,27 @@ end
158158

159159
# point builder for given crs and lenunit
160160
function pointbuilder(crs, u)
161-
if crs <: Cartesian
162-
(xyz...) -> Point(crs((xyz .* u)...))
163-
elseif crs <: Polar
164-
(ρ, ϕ) -> Point(crs* u, ϕ * u"rad"))
165-
elseif crs <: Cylindrical
166-
(ρ, ϕ, z) -> Point(crs* u, ϕ * u"rad", z * u))
167-
elseif crs <: Spherical
168-
(r, θ, ϕ) -> Point(crs(r * u, θ * u"rad", ϕ * u"rad"))
161+
if !isnothing(u)
162+
if crs <: Cartesian
163+
(xyz...) -> Point(crs(withunit.(xyz, u)...))
164+
elseif crs <: Polar
165+
(ρ, ϕ) -> Point(crs(withunit(ρ, u), withunit(ϕ, u"rad")))
166+
elseif crs <: Cylindrical
167+
(ρ, ϕ, z) -> Point(crs(withunit(ρ, u), withunit(ϕ, u"rad"), withunit(z, u)))
168+
elseif crs <: Spherical
169+
(r, θ, ϕ) -> Point(crs(withunit(r, u), withunit(θ, u"rad"), withunit(ϕ, u"rad")))
170+
else
171+
(coords...) -> Point(crs(coords...))
172+
end
169173
else
170174
(coords...) -> Point(crs(coords...))
171175
end
172176
end
173177

178+
# add unit or convert to chosen unit
179+
withunit(x::Number, u) = x * u
180+
withunit(x::Quantity, u) = uconvert(u, x)
181+
174182
# variants of given names with uppercase, etc.
175183
variants(names) = [names; uppercase.(names); uppercasefirst.(names)]
176184

test/georef.jl

+15
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,19 @@
143143
gtb = georef(table, ("x", "y", "z"), crs=Spherical, lenunit=u"km")
144144
@test crs(gtb.geometry) <: Spherical
145145
@test unit(Meshes.lentype(gtb.geometry)) == u"km"
146+
# retain the original units if `lenunit=nothing`
147+
table = (a=rand(10), x=rand(10) * u"cm", y=rand(10) * u"cm")
148+
gtb = georef(table, ("x", "y"))
149+
@test crs(gtb.geometry) <: Cartesian
150+
@test unit(Meshes.lentype(gtb.geometry)) == u"cm"
151+
# convert the units if `lenunit` is passed
152+
table = (a=rand(10), x=rand(10) * u"km", y=rand(10) * u"km")
153+
gtb = georef(table, ("x", "y"), lenunit=u"m")
154+
@test crs(gtb.geometry) <: Cartesian
155+
@test unit(Meshes.lentype(gtb.geometry)) == u"m"
156+
# `lenunit` option only affects Basic CRS
157+
table = (a=rand(10), lat=rand(10), lon=rand(10))
158+
gtb = georef(table, ("lat", "lon"), crs=LatLon, lenunit=u"km")
159+
@test crs(gtb.geometry) <: LatLon
160+
@test unit(Meshes.lentype(gtb.geometry)) == u"m"
146161
end

0 commit comments

Comments
 (0)