module Data.Geo.Jord.Geodetic
(
HorizontalPosition
, Position
, HasCoordinates(..)
, height
, model
, model'
, latLongPos
, latLongPos'
, latLongHeightPos
, latLongHeightPos'
, wgs84Pos
, wgs84Pos'
, s84Pos
, s84Pos'
, nvectorPos
, nvectorPos'
, nvectorHeightPos
, nvectorHeightPos'
, atHeight
, atSurface
, readHorizontalPosition
, horizontalPosition
, readPosition
, position
, nvectorFromLatLong
, nvectorToLatLong
, antipode
, antipode'
, northPole
, southPole
) where
import Prelude hiding (read)
import Text.ParserCombinators.ReadP (ReadP, option, readP_to_S, skipSpaces)
import Data.Geo.Jord.Angle (Angle)
import qualified Data.Geo.Jord.Angle as Angle
import qualified Data.Geo.Jord.LatLong as LL (isValidLatLong, isValidLong, latLongDms, showLatLong)
import Data.Geo.Jord.Length (Length)
import qualified Data.Geo.Jord.Length as Length (length, zero)
import qualified Data.Geo.Jord.Math3d as Math3d (V3, scale, v3x, v3y, v3z, vec3)
import Data.Geo.Jord.Model
import Data.Geo.Jord.Models (S84(..), WGS84(..))
data HCoords =
HCoords Angle Angle !Math3d.V3
data HorizontalPosition a =
HorizontalPosition HCoords a
model :: (Model a) => HorizontalPosition a -> a
model :: HorizontalPosition a -> a
model (HorizontalPosition HCoords
_ a
m) = a
m
data Position a =
Position HCoords Length a
height :: (Model a) => Position a -> Length
height :: Position a -> Length
height (Position HCoords
_ Length
h a
_) = Length
h
model' :: (Model a) => Position a -> a
model' :: Position a -> a
model' (Position HCoords
_ Length
_ a
m) = a
m
class HasCoordinates a where
latitude :: a -> Angle
decimalLatitude :: a -> Double
decimalLatitude = Angle -> Double
Angle.toDecimalDegrees (Angle -> Double) -> (a -> Angle) -> a -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Angle
forall a. HasCoordinates a => a -> Angle
latitude
longitude :: a -> Angle
decimalLongitude :: a -> Double
decimalLongitude = Angle -> Double
Angle.toDecimalDegrees (Angle -> Double) -> (a -> Angle) -> a -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Angle
forall a. HasCoordinates a => a -> Angle
longitude
nvector :: a -> Math3d.V3
instance HasCoordinates (HorizontalPosition a) where
latitude :: HorizontalPosition a -> Angle
latitude (HorizontalPosition (HCoords Angle
lat Angle
_ V3
_) a
_) = Angle
lat
longitude :: HorizontalPosition a -> Angle
longitude (HorizontalPosition (HCoords Angle
_ Angle
lon V3
_) a
_) = Angle
lon
nvector :: HorizontalPosition a -> V3
nvector (HorizontalPosition (HCoords Angle
_ Angle
_ V3
nv) a
_) = V3
nv
instance (Model a) => Show (HorizontalPosition a) where
show :: HorizontalPosition a -> String
show HorizontalPosition a
p = (Angle, Angle) -> String
LL.showLatLong (HorizontalPosition a -> Angle
forall a. HasCoordinates a => a -> Angle
latitude HorizontalPosition a
p, HorizontalPosition a -> Angle
forall a. HasCoordinates a => a -> Angle
longitude HorizontalPosition a
p) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (a -> String
forall a. Show a => a -> String
show (a -> String)
-> (HorizontalPosition a -> a) -> HorizontalPosition a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HorizontalPosition a -> a
forall a. Model a => HorizontalPosition a -> a
model (HorizontalPosition a -> String) -> HorizontalPosition a -> String
forall a b. (a -> b) -> a -> b
$ HorizontalPosition a
p) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
instance (Model a) => Eq (HorizontalPosition a) where
HorizontalPosition a
p1 == :: HorizontalPosition a -> HorizontalPosition a -> Bool
== HorizontalPosition a
p2 = HorizontalPosition a -> Angle
forall a. HasCoordinates a => a -> Angle
latitude HorizontalPosition a
p1 Angle -> Angle -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a -> Angle
forall a. HasCoordinates a => a -> Angle
latitude HorizontalPosition a
p2 Bool -> Bool -> Bool
&& HorizontalPosition a -> Angle
forall a. HasCoordinates a => a -> Angle
longitude HorizontalPosition a
p1 Angle -> Angle -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a -> Angle
forall a. HasCoordinates a => a -> Angle
longitude HorizontalPosition a
p2
instance HasCoordinates (Position a) where
latitude :: Position a -> Angle
latitude (Position (HCoords Angle
lat Angle
_ V3
_) Length
_ a
_) = Angle
lat
longitude :: Position a -> Angle
longitude (Position (HCoords Angle
_ Angle
lon V3
_) Length
_ a
_) = Angle
lon
nvector :: Position a -> V3
nvector (Position (HCoords Angle
_ Angle
_ V3
nv) Length
_ a
_) = V3
nv
instance (Model a) => Show (Position a) where
show :: Position a -> String
show Position a
p =
(Angle, Angle) -> String
LL.showLatLong (Position a -> Angle
forall a. HasCoordinates a => a -> Angle
latitude Position a
p, Position a -> Angle
forall a. HasCoordinates a => a -> Angle
longitude Position a
p) String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Length -> String
forall a. Show a => a -> String
show (Length -> String)
-> (Position a -> Length) -> Position a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Position a -> Length
forall a. Model a => Position a -> Length
height (Position a -> String) -> Position a -> String
forall a b. (a -> b) -> a -> b
$ Position a
p) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (a -> String
forall a. Show a => a -> String
show (a -> String) -> (Position a -> a) -> Position a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Position a -> a
forall a. Model a => Position a -> a
model' (Position a -> String) -> Position a -> String
forall a b. (a -> b) -> a -> b
$ Position a
p) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
instance (Model a) => Eq (Position a) where
Position a
p1 == :: Position a -> Position a -> Bool
== Position a
p2 = Position a -> Angle
forall a. HasCoordinates a => a -> Angle
latitude Position a
p1 Angle -> Angle -> Bool
forall a. Eq a => a -> a -> Bool
== Position a -> Angle
forall a. HasCoordinates a => a -> Angle
latitude Position a
p2 Bool -> Bool -> Bool
&& Position a -> Angle
forall a. HasCoordinates a => a -> Angle
longitude Position a
p1 Angle -> Angle -> Bool
forall a. Eq a => a -> a -> Bool
== Position a -> Angle
forall a. HasCoordinates a => a -> Angle
longitude Position a
p2 Bool -> Bool -> Bool
&& Position a -> Length
forall a. Model a => Position a -> Length
height Position a
p1 Length -> Length -> Bool
forall a. Eq a => a -> a -> Bool
== Position a -> Length
forall a. Model a => Position a -> Length
height Position a
p2
latLongPos :: (Model a) => Double -> Double -> a -> HorizontalPosition a
latLongPos :: Double -> Double -> a -> HorizontalPosition a
latLongPos Double
lat Double
lon = Angle -> Angle -> a -> HorizontalPosition a
forall a. Model a => Angle -> Angle -> a -> HorizontalPosition a
latLongPos' (Double -> Angle
Angle.decimalDegrees Double
lat) (Double -> Angle
Angle.decimalDegrees Double
lon)
latLongPos' :: (Model a) => Angle -> Angle -> a -> HorizontalPosition a
latLongPos' :: Angle -> Angle -> a -> HorizontalPosition a
latLongPos' Angle
lat Angle
lon a
m = HCoords -> a -> HorizontalPosition a
forall a. HCoords -> a -> HorizontalPosition a
HorizontalPosition (Angle -> Angle -> V3 -> HCoords
HCoords Angle
wlat Angle
wlon V3
nv) a
m
where
lon' :: Angle
lon' = Angle -> Angle -> Angle
checkPole Angle
lat Angle
lon
nv :: V3
nv = (Angle, Angle) -> V3
nvectorFromLatLong (Angle
lat, Angle
lon')
(Angle
wlat, Angle
wlon) = Angle -> Angle -> V3 -> a -> (Angle, Angle)
forall a. Model a => Angle -> Angle -> V3 -> a -> (Angle, Angle)
wrap Angle
lat Angle
lon' V3
nv a
m
latLongHeightPos :: (Model a) => Double -> Double -> Length -> a -> Position a
latLongHeightPos :: Double -> Double -> Length -> a -> Position a
latLongHeightPos Double
lat Double
lon = Angle -> Angle -> Length -> a -> Position a
forall a. Model a => Angle -> Angle -> Length -> a -> Position a
latLongHeightPos' (Double -> Angle
Angle.decimalDegrees Double
lat) (Double -> Angle
Angle.decimalDegrees Double
lon)
latLongHeightPos' :: (Model a) => Angle -> Angle -> Length -> a -> Position a
latLongHeightPos' :: Angle -> Angle -> Length -> a -> Position a
latLongHeightPos' Angle
lat Angle
lon Length
h a
m = HorizontalPosition a -> Length -> Position a
forall a. Model a => HorizontalPosition a -> Length -> Position a
atHeight (Angle -> Angle -> a -> HorizontalPosition a
forall a. Model a => Angle -> Angle -> a -> HorizontalPosition a
latLongPos' Angle
lat Angle
lon a
m) Length
h
wgs84Pos :: Double -> Double -> HorizontalPosition WGS84
wgs84Pos :: Double -> Double -> HorizontalPosition WGS84
wgs84Pos Double
lat Double
lon = Double -> Double -> WGS84 -> HorizontalPosition WGS84
forall a. Model a => Double -> Double -> a -> HorizontalPosition a
latLongPos Double
lat Double
lon WGS84
WGS84
wgs84Pos' :: Angle -> Angle -> HorizontalPosition WGS84
wgs84Pos' :: Angle -> Angle -> HorizontalPosition WGS84
wgs84Pos' Angle
lat Angle
lon = Angle -> Angle -> WGS84 -> HorizontalPosition WGS84
forall a. Model a => Angle -> Angle -> a -> HorizontalPosition a
latLongPos' Angle
lat Angle
lon WGS84
WGS84
s84Pos :: Double -> Double -> HorizontalPosition S84
s84Pos :: Double -> Double -> HorizontalPosition S84
s84Pos Double
lat Double
lon = Double -> Double -> S84 -> HorizontalPosition S84
forall a. Model a => Double -> Double -> a -> HorizontalPosition a
latLongPos Double
lat Double
lon S84
S84
s84Pos' :: Angle -> Angle -> HorizontalPosition S84
s84Pos' :: Angle -> Angle -> HorizontalPosition S84
s84Pos' Angle
lat Angle
lon = Angle -> Angle -> S84 -> HorizontalPosition S84
forall a. Model a => Angle -> Angle -> a -> HorizontalPosition a
latLongPos' Angle
lat Angle
lon S84
S84
nvectorPos :: (Model a) => Double -> Double -> Double -> a -> HorizontalPosition a
nvectorPos :: Double -> Double -> Double -> a -> HorizontalPosition a
nvectorPos Double
x Double
y Double
z = V3 -> a -> HorizontalPosition a
forall a. Model a => V3 -> a -> HorizontalPosition a
nvectorPos' (Double -> Double -> Double -> V3
Math3d.vec3 Double
x Double
y Double
z)
nvectorPos' :: (Model a) => Math3d.V3 -> a -> HorizontalPosition a
nvectorPos' :: V3 -> a -> HorizontalPosition a
nvectorPos' V3
v a
m = HCoords -> a -> HorizontalPosition a
forall a. HCoords -> a -> HorizontalPosition a
HorizontalPosition (Angle -> Angle -> V3 -> HCoords
HCoords Angle
lat Angle
wlon V3
nv) a
m
where
(Angle
lat, Angle
lon) = V3 -> (Angle, Angle)
nvectorToLatLong V3
v
lon' :: Angle
lon' = Angle -> Angle -> Angle
checkPole Angle
lat Angle
lon
nv :: V3
nv = (Angle, Angle) -> V3
nvectorFromLatLong (Angle
lat, Angle
lon')
wlon :: Angle
wlon = Angle -> a -> Angle
forall a. Model a => Angle -> a -> Angle
convertLon Angle
lon' a
m
nvectorHeightPos :: (Model a) => Double -> Double -> Double -> Length -> a -> Position a
nvectorHeightPos :: Double -> Double -> Double -> Length -> a -> Position a
nvectorHeightPos Double
x Double
y Double
z = V3 -> Length -> a -> Position a
forall a. Model a => V3 -> Length -> a -> Position a
nvectorHeightPos' (Double -> Double -> Double -> V3
Math3d.vec3 Double
x Double
y Double
z)
nvectorHeightPos' :: (Model a) => Math3d.V3 -> Length -> a -> Position a
nvectorHeightPos' :: V3 -> Length -> a -> Position a
nvectorHeightPos' V3
v Length
h a
m = HorizontalPosition a -> Length -> Position a
forall a. Model a => HorizontalPosition a -> Length -> Position a
atHeight (V3 -> a -> HorizontalPosition a
forall a. Model a => V3 -> a -> HorizontalPosition a
nvectorPos' V3
v a
m) Length
h
atHeight :: (Model a) => HorizontalPosition a -> Length -> Position a
atHeight :: HorizontalPosition a -> Length -> Position a
atHeight (HorizontalPosition HCoords
c a
m) Length
h = HCoords -> Length -> a -> Position a
forall a. HCoords -> Length -> a -> Position a
Position HCoords
c Length
h a
m
atSurface :: (Model a) => Position a -> HorizontalPosition a
atSurface :: Position a -> HorizontalPosition a
atSurface (Position HCoords
c Length
_ a
m) = HCoords -> a -> HorizontalPosition a
forall a. HCoords -> a -> HorizontalPosition a
HorizontalPosition HCoords
c a
m
readHorizontalPosition :: (Model a) => String -> a -> Maybe (HorizontalPosition a)
readHorizontalPosition :: String -> a -> Maybe (HorizontalPosition a)
readHorizontalPosition String
s a
m =
case ((HorizontalPosition a, String) -> HorizontalPosition a)
-> [(HorizontalPosition a, String)] -> [HorizontalPosition a]
forall a b. (a -> b) -> [a] -> [b]
map (HorizontalPosition a, String) -> HorizontalPosition a
forall a b. (a, b) -> a
fst ([(HorizontalPosition a, String)] -> [HorizontalPosition a])
-> [(HorizontalPosition a, String)] -> [HorizontalPosition a]
forall a b. (a -> b) -> a -> b
$ ((HorizontalPosition a, String) -> Bool)
-> [(HorizontalPosition a, String)]
-> [(HorizontalPosition a, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (String -> Bool)
-> ((HorizontalPosition a, String) -> String)
-> (HorizontalPosition a, String)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HorizontalPosition a, String) -> String
forall a b. (a, b) -> b
snd) ([(HorizontalPosition a, String)]
-> [(HorizontalPosition a, String)])
-> [(HorizontalPosition a, String)]
-> [(HorizontalPosition a, String)]
forall a b. (a -> b) -> a -> b
$ ReadP (HorizontalPosition a) -> ReadS (HorizontalPosition a)
forall a. ReadP a -> ReadS a
readP_to_S (a -> ReadP (HorizontalPosition a)
forall a. Model a => a -> ReadP (HorizontalPosition a)
horizontalPosition a
m) String
s of
[] -> Maybe (HorizontalPosition a)
forall a. Maybe a
Nothing
HorizontalPosition a
p:[HorizontalPosition a]
_ -> HorizontalPosition a -> Maybe (HorizontalPosition a)
forall a. a -> Maybe a
Just HorizontalPosition a
p
readPosition :: (Model a) => String -> a -> Maybe (Position a)
readPosition :: String -> a -> Maybe (Position a)
readPosition String
s a
m =
case ((Position a, String) -> Position a)
-> [(Position a, String)] -> [Position a]
forall a b. (a -> b) -> [a] -> [b]
map (Position a, String) -> Position a
forall a b. (a, b) -> a
fst ([(Position a, String)] -> [Position a])
-> [(Position a, String)] -> [Position a]
forall a b. (a -> b) -> a -> b
$ ((Position a, String) -> Bool)
-> [(Position a, String)] -> [(Position a, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (String -> Bool)
-> ((Position a, String) -> String) -> (Position a, String) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Position a, String) -> String
forall a b. (a, b) -> b
snd) ([(Position a, String)] -> [(Position a, String)])
-> [(Position a, String)] -> [(Position a, String)]
forall a b. (a -> b) -> a -> b
$ ReadP (Position a) -> ReadS (Position a)
forall a. ReadP a -> ReadS a
readP_to_S (a -> ReadP (Position a)
forall a. Model a => a -> ReadP (Position a)
position a
m) String
s of
[] -> Maybe (Position a)
forall a. Maybe a
Nothing
Position a
p:[Position a]
_ -> Position a -> Maybe (Position a)
forall a. a -> Maybe a
Just Position a
p
horizontalPosition :: (Model a) => a -> ReadP (HorizontalPosition a)
horizontalPosition :: a -> ReadP (HorizontalPosition a)
horizontalPosition a
m = do
(Angle
lat, Angle
lon) <- a -> ReadP (Angle, Angle)
forall a. Model a => a -> ReadP (Angle, Angle)
LL.latLongDms a
m
HorizontalPosition a -> ReadP (HorizontalPosition a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Angle -> Angle -> a -> HorizontalPosition a
forall a. Model a => Angle -> Angle -> a -> HorizontalPosition a
latLongPos' Angle
lat Angle
lon a
m)
position :: (Model a) => a -> ReadP (Position a)
position :: a -> ReadP (Position a)
position a
m = do
HorizontalPosition a
hp <- a -> ReadP (HorizontalPosition a)
forall a. Model a => a -> ReadP (HorizontalPosition a)
horizontalPosition a
m
ReadP ()
skipSpaces
Length
h <- Length -> ReadP Length -> ReadP Length
forall a. a -> ReadP a -> ReadP a
option Length
Length.zero ReadP Length
Length.length
Position a -> ReadP (Position a)
forall (m :: * -> *) a. Monad m => a -> m a
return (HorizontalPosition a -> Length -> Position a
forall a. Model a => HorizontalPosition a -> Length -> Position a
atHeight HorizontalPosition a
hp Length
h)
nvectorToLatLong :: Math3d.V3 -> (Angle, Angle)
nvectorToLatLong :: V3 -> (Angle, Angle)
nvectorToLatLong V3
v = (Angle
lat, Angle
lon)
where
x :: Double
x = V3 -> Double
Math3d.v3x V3
v
y :: Double
y = V3 -> Double
Math3d.v3y V3
v
z :: Double
z = V3 -> Double
Math3d.v3z V3
v
lat :: Angle
lat = Double -> Double -> Angle
Angle.atan2 Double
z (Double -> Double
forall a. Floating a => a -> a
sqrt (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
y Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
y))
lon :: Angle
lon = Double -> Double -> Angle
Angle.atan2 Double
y Double
x
nvectorFromLatLong :: (Angle, Angle) -> Math3d.V3
nvectorFromLatLong :: (Angle, Angle) -> V3
nvectorFromLatLong (Angle
lat, Angle
lon) = Double -> Double -> Double -> V3
Math3d.vec3 Double
x Double
y Double
z
where
cl :: Double
cl = Angle -> Double
Angle.cos Angle
lat
x :: Double
x = Double
cl Double -> Double -> Double
forall a. Num a => a -> a -> a
* Angle -> Double
Angle.cos Angle
lon
y :: Double
y = Double
cl Double -> Double -> Double
forall a. Num a => a -> a -> a
* Angle -> Double
Angle.sin Angle
lon
z :: Double
z = Angle -> Double
Angle.sin Angle
lat
antipode :: (Model a) => HorizontalPosition a -> HorizontalPosition a
antipode :: HorizontalPosition a -> HorizontalPosition a
antipode HorizontalPosition a
p = V3 -> a -> HorizontalPosition a
forall a. Model a => V3 -> a -> HorizontalPosition a
nvectorPos' (V3 -> V3
anti (V3 -> V3)
-> (HorizontalPosition a -> V3) -> HorizontalPosition a -> V3
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HorizontalPosition a -> V3
forall a. HasCoordinates a => a -> V3
nvector (HorizontalPosition a -> V3) -> HorizontalPosition a -> V3
forall a b. (a -> b) -> a -> b
$ HorizontalPosition a
p) (HorizontalPosition a -> a
forall a. Model a => HorizontalPosition a -> a
model HorizontalPosition a
p)
antipode' :: (Model a) => Position a -> Position a
antipode' :: Position a -> Position a
antipode' Position a
p = V3 -> Length -> a -> Position a
forall a. Model a => V3 -> Length -> a -> Position a
nvectorHeightPos' (V3 -> V3
anti (V3 -> V3) -> (Position a -> V3) -> Position a -> V3
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Position a -> V3
forall a. HasCoordinates a => a -> V3
nvector (Position a -> V3) -> Position a -> V3
forall a b. (a -> b) -> a -> b
$ Position a
p) (Position a -> Length
forall a. Model a => Position a -> Length
height Position a
p) (Position a -> a
forall a. Model a => Position a -> a
model' Position a
p)
anti :: Math3d.V3 -> Math3d.V3
anti :: V3 -> V3
anti V3
v = V3 -> Double -> V3
Math3d.scale V3
v (-Double
1.0)
northPole :: (Model a) => a -> HorizontalPosition a
northPole :: a -> HorizontalPosition a
northPole = Double -> Double -> a -> HorizontalPosition a
forall a. Model a => Double -> Double -> a -> HorizontalPosition a
latLongPos Double
90 Double
0
southPole :: (Model a) => a -> HorizontalPosition a
southPole :: a -> HorizontalPosition a
southPole = Double -> Double -> a -> HorizontalPosition a
forall a. Model a => Double -> Double -> a -> HorizontalPosition a
latLongPos (-Double
90) Double
0
wrap :: (Model a) => Angle -> Angle -> Math3d.V3 -> a -> (Angle, Angle)
wrap :: Angle -> Angle -> V3 -> a -> (Angle, Angle)
wrap Angle
lat Angle
lon V3
nv a
m =
if Angle -> Angle -> a -> Bool
forall a. Model a => Angle -> Angle -> a -> Bool
LL.isValidLatLong Angle
lat Angle
lon a
m
then (Angle
lat, Angle
lon)
else V3 -> a -> (Angle, Angle)
forall a. Model a => V3 -> a -> (Angle, Angle)
llWrapped V3
nv a
m
llWrapped :: (Model a) => Math3d.V3 -> a -> (Angle, Angle)
llWrapped :: V3 -> a -> (Angle, Angle)
llWrapped V3
nv a
m = (Angle
lat, Angle
lon')
where
(Angle
lat, Angle
lon) = V3 -> (Angle, Angle)
nvectorToLatLong V3
nv
lon' :: Angle
lon' = Angle -> a -> Angle
forall a. Model a => Angle -> a -> Angle
convertLon Angle
lon a
m
convertLon :: (Model a) => Angle -> a -> Angle
convertLon :: Angle -> a -> Angle
convertLon Angle
lon a
m =
case (a -> LongitudeRange
forall a. Model a => a -> LongitudeRange
longitudeRange a
m) of
LongitudeRange
L180 -> Angle
lon
LongitudeRange
L360 ->
if Angle -> a -> Bool
forall a. Model a => Angle -> a -> Bool
LL.isValidLong Angle
lon a
m
then Angle
lon
else Angle -> Angle -> Angle
Angle.add Angle
lon (Double -> Angle
Angle.decimalDegrees Double
360)
checkPole :: Angle -> Angle -> Angle
checkPole :: Angle -> Angle -> Angle
checkPole Angle
lat Angle
lon
| Angle
lat Angle -> Angle -> Bool
forall a. Eq a => a -> a -> Bool
== Double -> Angle
Angle.decimalDegrees Double
90 Bool -> Bool -> Bool
|| Angle
lat Angle -> Angle -> Bool
forall a. Eq a => a -> a -> Bool
== Double -> Angle
Angle.decimalDegrees (-Double
90) = Angle
Angle.zero
| Bool
otherwise = Angle
lon