Repository: JuliaEarth/CoordRefSystems.jl (julia)

Issue:
Review `inbounds` semantics
Some of our current `inbounds` implementations seem to be tied to EPSG code bounds.

For example, the `Mercator` CRS has the following implementation:

https://github.com/JuliaEarth/CoordRefSystems.jl/blob/10b3f944ece7d5c4669eed6dc163ae8d9761afcd/src/crs/projected/mercator.jl#L54-L57

I believe we should use the mathematical definition instead, and allow all values of lat/lon that are in the domain of the formulas.

@eliascarv could you please double check this design decision. Do you agree it would be better to use the mathematical definition always, and encode this EPSG bounds in a separate function? Perhaps `epsgbounds`?

Pull request description:
Fix #266

Patch:
diff --git a/src/crs/projected/mercator.jl b/src/crs/projected/mercator.jl
index fbc6eec7..956f94b9 100644
--- a/src/crs/projected/mercator.jl
+++ b/src/crs/projected/mercator.jl
@@ -53,7 +53,7 @@ isconformal(::Type{<:Mercator}) = true
 
 function inbounds(::Type{<:Mercator}, λ, ϕ)
   T = typeof(λ)
-  -T(π) ≤ λ ≤ T(π) && deg2rad(-T(80)) ≤ ϕ ≤ deg2rad(T(84))
+  -T(π) ≤ λ ≤ T(π) && -T(π) / 2 < ϕ < T(π) / 2
 end
 
 function formulas(::Type{<:Mercator{Datum}}, ::Type{T}) where {Datum,T}
diff --git a/src/crs/projected/webmercator.jl b/src/crs/projected/webmercator.jl
index 7406389e..9dc41569 100644
--- a/src/crs/projected/webmercator.jl
+++ b/src/crs/projected/webmercator.jl
@@ -54,8 +54,7 @@ iscompromise(::Type{<:WebMercator}) = true
 
 function inbounds(::Type{<:WebMercator}, λ, ϕ)
   T = typeof(λ)
-  θ = deg2rad(T(85.06))
-  -T(π) ≤ λ ≤ T(π) && -θ ≤ ϕ ≤ θ
+  -T(π) ≤ λ ≤ T(π) && -T(π) / 2 < ϕ < T(π) / 2
 end
 
 function formulas(::Type{<:WebMercator}, ::Type{T}) where {T}


Test patch:
diff --git a/test/crs/domains.jl b/test/crs/domains.jl
index d3f03c1d..21d396d3 100644
--- a/test/crs/domains.jl
+++ b/test/crs/domains.jl
@@ -1,4 +1,5 @@
 @testset "Projection domain" begin
+  c0 = LatLon(T(90), T(0))
   c1 = LatLon(T(30), T(60))
   c2 = LatLon(T(85), T(60))
   c3 = LatLon{ITRF{2008}}(T(30), T(60))
@@ -7,16 +8,20 @@
   c6 = convert(Lambert, c2)
   c7 = Cartesian(T(1), T(2))
   c8 = Cartesian{WGS84Latest}(T(1), T(2))
-  @test indomain(Mercator, c1)
-  @test !indomain(Mercator, c2)
-  @test indomain(Mercator{WGS84Latest}, c1)
-  @test !indomain(Mercator{WGS84Latest}, c2)
-  @test indomain(Mercator{WGS84{1762}}, c3)
-  @test !indomain(Mercator{WGS84{1762}}, c4)
-  @test indomain(Mercator, c5)
-  @test !indomain(Mercator, c6)
-  @test indomain(Mercator{WGS84Latest}, c7)
-  @test indomain(Mercator{WGS84Latest}, c8)
+  for C in [Mercator, WebMercator]
+    @test !indomain(C, c0)
+    @test indomain(C, c1)
+    @test indomain(C, c2)
+    @test !indomain(C{WGS84Latest}, c0)
+    @test indomain(C{WGS84Latest}, c1)
+    @test indomain(C{WGS84Latest}, c2)
+    @test indomain(C{WGS84{1762}}, c3)
+    @test indomain(C{WGS84{1762}}, c4)
+    @test indomain(C, c5)
+    @test indomain(C, c6)
+    @test indomain(C{WGS84Latest}, c7)
+    @test indomain(C{WGS84Latest}, c8)
+  end
 
   for C in projected
     # forward