{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TemplateHaskell #-} module Data.Geodetic.LL( LL(..) , HasLL(..) , degrees , (<◦>) ) where import Control.Applicative(Applicative((<*>))) import Control.Lens(makeClassy, Iso', iso, (^.)) import Data.Eq(Eq) import Data.Functor((<$>)) import Data.Geodetic.HasDoubles(HasDoubles(doubles)) import Data.Ord(Ord) import Prelude(Fractional((/)), Show, Double, pi, Num((*))) -- $setup -- >>> import Control.Lens data LL = LL { _lat :: Double -- radians , _lon :: Double -- radians } deriving (Eq, Ord, Show) makeClassy ''LL instance HasDoubles LL where doubles f (LL a o) = LL <$> f a <*> f o -- | -- -- >>> ((27.34, 152.15) ^. degrees) -- LL {_lat = 0.47717301749524965, _lon = 2.6555184569093724} -- -- >>> (degrees # LL 0.47717 2.65552) -- (27.33982711025749,152.15008841258037) degrees :: Iso' (Double, Double) LL degrees = iso (\(t, n) -> let r a = a / 180 * pi in LL (r t) (r n)) (\(LL t n) -> let r a = a / pi * 180 in (r t, r n)) -- | -- -- >>> 27.34 <◦> 152.15 -- LL {_lat = 0.47717301749524965, _lon = 2.6555184569093724} -- -- >>> 61.94 <◦> (-152.15) -- LL {_lat = 1.0810569386852877, _lon = -2.6555184569093724} (<◦>) :: Double -> Double -> LL t <◦> n = (t, n) ^. degrees