Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for EPSG:5070 and Albers projections generally #184

Merged
merged 39 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
dd48c37
added export Albers
souma4 Oct 24, 2024
70a727a
includes alberts ea
souma4 Oct 24, 2024
75d8679
adding albers
souma4 Oct 24, 2024
50b92c9
updated get and tests
souma4 Oct 24, 2024
23aa433
Update src/crs/projected/eqareaalbers.jl
souma4 Oct 25, 2024
df36644
Update src/crs/projected/eqareaalbers.jl
souma4 Oct 25, 2024
c8ba857
Update src/crs/projected/eqareaalbers.jl
souma4 Oct 25, 2024
533d8c0
Update src/crs/projected/eqareaalbers.jl
souma4 Oct 25, 2024
969996a
Update src/crs/projected/eqareaalbers.jl
souma4 Oct 25, 2024
dad2dff
Update get.jl to reflect lon\_o changes
souma4 Oct 25, 2024
b1aff8b
Update get.jl test to reflect lon\_o changes
souma4 Oct 25, 2024
7ced673
Change lat\_0 to lat\_o. remove lon\_0
souma4 Oct 25, 2024
8aca199
remove redundant type params
souma4 Oct 25, 2024
59bdc65
add missing type parameters
souma4 Oct 25, 2024
0465362
Apply suggestions from code review
souma4 Oct 25, 2024
79fb671
newline between docstring definition and description
souma4 Oct 25, 2024
ec50d6b
Forgot to update all `\_0` to `\_o`, so fixed
souma4 Oct 25, 2024
d741fa0
Applied suggestions from code review. Restructured eqareaalbers.jl
souma4 Oct 25, 2024
c308279
Applied suggestions from code review: updated to use e\^2 rather than…
souma4 Oct 25, 2024
602f951
fixed docstring from Alber to Albers
souma4 Oct 25, 2024
4a022d8
Updated test/get.jl. Added namespace to shift
souma4 Oct 26, 2024
b06aad4
src/crs/projected/eqareaalbers.jl
souma4 Oct 26, 2024
9607f28
Made adjustments to Albers script and tests
souma4 Oct 27, 2024
31d2648
updated EPSG:5070 and related tests to have proper degree symbols and…
souma4 Oct 28, 2024
da6c794
Fixed \Beta\prime formula so back calculations are correct. All tests…
souma4 Oct 28, 2024
3d26c03
Applied suggestions from code review, fixed inbounds to check rho (wi…
souma4 Oct 28, 2024
42b57de
Changed h functions to _albers to avoid potential namespace conflicts…
souma4 Oct 28, 2024
312f5a0
Merge branch 'JC_add5070_albers' of https://github.com/souma4/CoordRe…
souma4 Oct 28, 2024
ea4d3c6
Remove '_albersλ' and '_albersλ' by fixing the shifted longitude
eliascarv Oct 28, 2024
8e2c9b8
Rename the file
eliascarv Oct 28, 2024
26cf1c7
Add more helpers to avoid code repetition
eliascarv Oct 28, 2024
9bfbbaf
Fix code
eliascarv Oct 28, 2024
b57bade
Fix test
eliascarv Oct 28, 2024
2f866d1
Added WKT strings to strings.jl
souma4 Oct 28, 2024
1b19bf6
Add missing construtor & Update tests
eliascarv Oct 28, 2024
29dec85
Add 'asinclamp' helper function
eliascarv Oct 28, 2024
5edb013
Add missing tests
eliascarv Oct 29, 2024
16c7288
Apply suggestions
eliascarv Oct 29, 2024
3357c82
Update comments
eliascarv Oct 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CoordRefSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export
OrthoNorth,
OrthoSouth,
TransverseMercator,
Albers,
datum,
indomain,

Expand Down
1 change: 1 addition & 0 deletions src/crs/projected.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ include("projected/winkeltripel.jl")
include("projected/robinson.jl")
include("projected/orthographic.jl")
include("projected/transversemercator.jl")
include("projected/eqareaalbers.jl")

# ----------
# FALLBACKS
Expand Down
155 changes: 155 additions & 0 deletions src/crs/projected/eqareaalbers.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
Alber{latₒ, lat₁, lat₂, Datum, Shift}

Albers CRS with latitude origin latₒ standard parallels `lat₁` and `lat₂`, `Datum` and `Shift`.

## Examples

```julia
Albers(1, 1) # add default units
Albers(1m, 1m) # integers are converted converted to floats
Albers(1.0km, 1.0km) # length quantities are converted to meters
Albers(1.0m, 1.0m)
Albers{NAD83}(1.0m, 1.0m)
```

See [EPSG:5070](https://epsg.io/5070).
"""
struct Albers{latₒ,lat₁,lat₂,Datum,Shift,M<:Met} <: Projected{Datum,Shift}
x::M
y::M
end

Albers{latₒ,lat₁,lat₂,Datum,Shift}(x::M, y::M) where {latₒ,lat₁,lat₂,Datum,Shift,M<:Met} =
Albers{latₒ,lat₁,lat₂,Datum,Shift,float(M)}(x, y)
Albers{latₒ,lat₁,lat₂,Datum,Shift}(x::Met, y::Met) where {latₒ,lat₁,lat₂,Datum,Shift} =
Albers{latₒ,lat₁,lat₂,Datum,Shift}(promote(x, y)...)
Albers{latₒ,lat₁,lat₂,Datum,Shift}(x::Len, y::Len) where {latₒ,lat₁,lat₂,Datum,Shift} =
Albers{latₒ,lat₁,lat₂,Datum,Shift}(uconvert(m, x), uconvert(m, y))
Albers{latₒ,lat₁,lat₂,Datum,Shift}(x::Number, y::Number) where {latₒ,lat₁,lat₂,Datum,Shift} =
Albers{latₒ,lat₁,lat₂,Datum,Shift}(addunit(x, m), addunit(y, m))

Albers{latₒ,lat₁,lat₂,Datum}(args...) where {latₒ,lat₁,lat₂,Datum} =
Albers{latₒ,lat₁,lat₂,Datum,Shift()}(args...)

Albers(args...) = Albers{NAD83}(args...)
souma4 marked this conversation as resolved.
Show resolved Hide resolved

Base.convert(
::Type{Albers{latₒ,lat₁,lat₂,Datum,Shift,M}},
coords::Albers{latₒ,lat₁,lat₂,Datum,Shift}
) where {latₒ,lat₁,lat₂,Datum,Shift,M} = Albers{latₒ,lat₁,lat₂,Datum,Shift,M}(coords.x, coords.y)

constructor(::Type{<:Albers{latₒ,lat₁,lat₂,Datum,Shift}}) where {latₒ,lat₁,lat₂,Datum,Shift} =
Albers{latₒ,lat₁,lat₂,Datum,Shift}

lentype(::Type{<:Albers{latₒ,lat₁,lat₂,Datum,Shift,M}}) where {latₒ,lat₁,lat₂,Datum,Shift,M} = M

==(
coords₁::Albers{latₒ,lat₁,lat₂,Datum,Shift},
coords₂::Albers{latₒ,lat₁,lat₂,Datum,Shift}
) where {latₒ,lat₁,lat₂,Datum,Shift} = coords₁.x == coords₂.x && coords₁.y == coords₂.y

# ------------
# CONVERSIONS
# ------------
souma4 marked this conversation as resolved.
Show resolved Hide resolved

# Adapted from PROJ coordinate transformation software
# Initial PROJ 4.3 public domain code was put as Frank Warmerdam as copyright
# holder, but he didn't mean to imply he did the work. Essentially all work was
# done by Gerald Evenden.
# Authors of the original algorithm: Gerald Evenden and Thomas Knudsen
# reference code: https://github.com/OSGeo/PROJ/blob/master/src/projections/aea.cpp

inbounds(::Type{<:Albers}, λ, ϕ) =
-π ≤ λ ≤ π && deg2rad(90) ≤ ϕ ≤ deg2rad(90)

function formulas(::Type{<:Albers{latₒ,lat₁,lat₂,Datum}}, ::Type{T}) where {latₒ,lat₁,lat₂,Datum,T}
# Constants
🌎 = ellipsoid(Datum)
e = T(eccentricity(🌎))
a = numconvert(T, majoraxis(🌎))

# Latitude origin
ϕ₀ = T(ustrip(deg2rad(latₒ)))

# Standard parallels
ϕ₁ = T(ustrip(deg2rad(lat₁)))
ϕ₂ = T(ustrip(deg2rad(lat₂)))

souma4 marked this conversation as resolved.
Show resolved Hide resolved
m₁ = hm(ϕ₁, e)
m₂ = hm(ϕ₂, e)
α₁ = hα(ϕ₁, e)
α₂ = hα(ϕ₂, e)
α₀ = hα(ϕ₀, e)
n = (m₁^2 - m₂^2) / (α₂ - α₁)
C = m₁^2 + n * α₁

Θ = n * λ
ρ = a * sqrt(C - n * hα(ϕ, e)) / n
if ρ < 0
throw(ArgumentError("coordinates outside of the projection domain"))
end
ρ₀ = sqrt(a * (C - n * α₀)) / n
function fx(λ, ϕ)
ρ₀ - ρ * cos(Θ)
end

function fy(λ, ϕ)
ρ * sin(Θ)
end

fx, fy
end

# backward projection formulas

function backward(::Type{<:Albers{latₒ,lat₁,lat₂,Datum}}, x, y) where {latₒ,lat₁,lat₂,Datum}
🌎 = ellipsoid(Datum)
e = oftype(x, eccentricity(🌎))
e² = oftype(x, eccentricity²(🌎))
ϕ₀ = oftype(x, ustrip(deg2rad(latₒ)))
ϕ₁ = oftype(x, ustrip(deg2rad(lat₁)))
ϕ₂ = oftype(x, ustrip(deg2rad(lat₂)))
α₀ = hα(ϕ₀, e)
ρ₀ = sqrt(a * (C - n * α₀)) / n
souma4 marked this conversation as resolved.
Show resolved Hide resolved
α₁ = hα(ϕ₁, e)
α₂ = hα(ϕ₂, e)

m₁ = hm(ϕ₁, e)
m₂ = hm(ϕ₂, e)
n = (m₁^2 - m₂^2) / (α₂ - α₁)
C = m₁^2 + n * α₁

θ = atan2(x, ρ₀ - y)
ρ = sqrt(x^2 + (ρ₀ - y)^2)
α′ = (C - (ρ^2 * n^2) / a^2) / n
β′ = asin(α′ / (1 - (1 - e) / (2 * e) * log((1 - e) / (1 + e))))

λ = θ / n
ϕ =
β′ +
(e^2 / 3 + 31 * e^4 / 180 + 517 * e^6 / 5040) * sin(2 * β′) +
(23 * e^4 / 360 + 251 * e^6 / 3780) * sin(4 * β′) +
(761 * e^6 / 45360) * sin(6 * β′)
souma4 marked this conversation as resolved.
Show resolved Hide resolved

λ, ϕ
end

# -----------------
# HELPER FUNCTIONS
# -----------------

hm(ϕ, e) = cos(ϕ) / sqrt(1 - e^2 * sin(ϕ)^2)

hα(ϕ, e) = (1 - e^2) * (sin(ϕ) / (1 - e^2 * sin(ϕ)^2) - (1 / (2 * e)) * log((1 - e * sin(ϕ)) / (1 + e * sin(ϕ))))
souma4 marked this conversation as resolved.
Show resolved Hide resolved

# ----------
# FALLBACKS
# ----------

Base.convert(::Type{Albers{latₒ,lat₁,lat₂}}, coords::CRS{Datum}) where {latₒ,lat₁,lat₂,Datum} =
convert(Albers{latₒ,lat₁,lat₂,Datum}, coords)
3 changes: 2 additions & 1 deletion src/get.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For the inverse operation, see the [`CoordRefSystems.code`](@ref) function.
"""
function get(code::Type{<:CRSCode})
throw(ArgumentError("""
The provided code $code is not mapped to a CRS type yet.
The provided code $code is not mapped to a CRS type yet.
Please check https://github.com/JuliaEarth/CoordRefSystems.jl/blob/main/src/get.jl
If you know the CRS type of a given code, please submit a pull request.
See https://discourse.julialang.org/t/esri-code-for-british-national-grid-not-known-by-geoio/117641
Expand Down Expand Up @@ -63,6 +63,7 @@ end
@crscode EPSG{4208} LatLon{Aratu}
@crscode EPSG{4269} LatLon{NAD83}
@crscode EPSG{4326} LatLon{WGS84Latest}
@crscode EPSG{5070} shift(Albers{23.0,29.5,45.5,NAD83}, lonₒ=-96.0)
@crscode EPSG{4618} LatLon{SAD69}
@crscode EPSG{4674} LatLon{SIRGAS2000}
@crscode EPSG{4988} Cartesian3D{shift(ITRF{2000}, 2000.4)}
Expand Down
1 change: 1 addition & 0 deletions test/get.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
gettest(EPSG{4208}, LatLon{Aratu})
gettest(EPSG{4269}, LatLon{NAD83})
gettest(EPSG{4326}, LatLon{WGS84Latest})
gettest(EPSG{5070}, shift(Albers{23.0,29.5,45.5,NAD83}, lonₒ=-96.0))
gettest(EPSG{4618}, LatLon{SAD69})
gettest(EPSG{4674}, LatLon{SIRGAS2000})
gettest(EPSG{4988}, Cartesian{CoordRefSystems.shift(ITRF{2000}, 2000.4),3})
Expand Down