coordinate 0.0.3 → 0.0.4
raw patch · 17 files changed
+530/−530 lines, 17 files
Files
- coordinate.cabal +9/−9
- src/Data/GPS/Coordinate.hs +0/−9
- src/Data/GPS/Coordinate/Coordinate.hs +0/−74
- src/Data/GPS/Coordinate/DegreesLatitude.hs +0/−57
- src/Data/GPS/Coordinate/DegreesLongitude.hs +0/−56
- src/Data/GPS/Coordinate/Latitude.hs +0/−109
- src/Data/GPS/Coordinate/Longitude.hs +0/−106
- src/Data/GPS/Coordinate/Minutes.hs +0/−50
- src/Data/GPS/Coordinate/Seconds.hs +0/−60
- src/Data/Geo/Coordinate.hs +9/−0
- src/Data/Geo/Coordinate/Coordinate.hs +74/−0
- src/Data/Geo/Coordinate/DegreesLatitude.hs +57/−0
- src/Data/Geo/Coordinate/DegreesLongitude.hs +56/−0
- src/Data/Geo/Coordinate/Latitude.hs +109/−0
- src/Data/Geo/Coordinate/Longitude.hs +106/−0
- src/Data/Geo/Coordinate/Minutes.hs +50/−0
- src/Data/Geo/Coordinate/Seconds.hs +60/−0
coordinate.cabal view
@@ -1,5 +1,5 @@ name: coordinate-version: 0.0.3+version: 0.0.4 license: BSD3 license-File: etc/LICENCE author: Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>@@ -38,14 +38,14 @@ src exposed-modules:- Data.GPS.Coordinate- Data.GPS.Coordinate.Coordinate- Data.GPS.Coordinate.DegreesLatitude- Data.GPS.Coordinate.DegreesLongitude- Data.GPS.Coordinate.Latitude- Data.GPS.Coordinate.Longitude- Data.GPS.Coordinate.Minutes- Data.GPS.Coordinate.Seconds+ Data.Geo.Coordinate+ Data.Geo.Coordinate.Coordinate+ Data.Geo.Coordinate.DegreesLatitude+ Data.Geo.Coordinate.DegreesLongitude+ Data.Geo.Coordinate.Latitude+ Data.Geo.Coordinate.Longitude+ Data.Geo.Coordinate.Minutes+ Data.Geo.Coordinate.Seconds test-suite doctests type:
− src/Data/GPS/Coordinate.hs
@@ -1,9 +0,0 @@-module Data.GPS.Coordinate(module C) where--import Data.GPS.Coordinate.Coordinate as C-import Data.GPS.Coordinate.DegreesLatitude as C-import Data.GPS.Coordinate.DegreesLongitude as C-import Data.GPS.Coordinate.Latitude as C-import Data.GPS.Coordinate.Longitude as C-import Data.GPS.Coordinate.Minutes as C-import Data.GPS.Coordinate.Seconds as C
− src/Data/GPS/Coordinate/Coordinate.hs
@@ -1,74 +0,0 @@-module Data.GPS.Coordinate.Coordinate(- Coordinate-, HasCoordinate(..)-, coordinateLatLon-, coordinateLonLat-, coordinateDMSLatLon-, coordinateLatDMSLon-, coordinateDMSLatDMSLon-) where--import Prelude(Eq, Show, Ord, id, (.))-import Control.Lens(Iso', Lens', iso, lens, mapping, swapped, withIso)-import Data.GPS.Coordinate.Latitude-import Data.GPS.Coordinate.Longitude-import Data.GPS.Coordinate.DegreesLatitude-import Data.GPS.Coordinate.DegreesLongitude-import Data.GPS.Coordinate.Minutes-import Data.GPS.Coordinate.Seconds--data Coordinate =- Coordinate- Latitude- Longitude- deriving (Eq, Ord, Show)--coordinateLatLon ::- Iso' (Latitude, Longitude) Coordinate-coordinateLatLon =- iso (\(lat, lon) -> Coordinate lat lon) (\(Coordinate lat lon) -> (lat, lon))--coordinateLonLat ::- Iso' (Longitude, Latitude) Coordinate-coordinateLonLat =- swapped . coordinateLatLon--coordinateDMSLatLon ::- Iso' ((DegreesLatitude, Minutes, Seconds), Longitude) Coordinate-coordinateDMSLatLon =- swapped . mapping dmsLatitude . coordinateLonLat--coordinateLatDMSLon ::- Iso' (Latitude, (DegreesLongitude, Minutes, Seconds)) Coordinate-coordinateLatDMSLon =- mapping dmsLongitude . coordinateLatLon--coordinateDMSLatDMSLon ::- Iso' ((DegreesLatitude, Minutes, Seconds), (DegreesLongitude, Minutes, Seconds)) Coordinate-coordinateDMSLatDMSLon =- iso (\((td, tm, ts), (nd, nm, ns)) -> Coordinate (withIso dmsLatitude (\k _ -> k (td, tm, ts))) (withIso dmsLongitude (\k _ -> k (nd, nm, ns))))- (\(Coordinate lat lon) -> (withIso dmsLatitude (\_ k -> k lat), withIso dmsLongitude (\_ k -> k lon)))--class HasCoordinate t where- coordinate ::- Lens' t Coordinate--instance HasCoordinate Coordinate where- coordinate =- id--instance HasLatitude Coordinate where- latitude =- lens (\(Coordinate lat _) -> lat) (\(Coordinate _ lon) lat -> Coordinate lat lon)--instance HasLongitude Coordinate where- longitude =- lens (\(Coordinate _ lon) -> lon) (\(Coordinate lat _) lon -> Coordinate lat lon)--instance HasDegreesLatitude Coordinate where- degreesLatitude =- latitude . degreesLatitude--instance HasDegreesLongitude Coordinate where- degreesLongitude =- longitude . degreesLongitude
− src/Data/GPS/Coordinate/DegreesLatitude.hs
@@ -1,57 +0,0 @@-module Data.GPS.Coordinate.DegreesLatitude(- DegreesLatitude-, HasDegreesLatitude(..)-, nDegreesLatitude-) where--import Prelude(Int, Bool(..), Eq, Show, Ord(..), id, (&&))-import Data.Maybe(Maybe(..))-import Control.Lens(Prism', Lens', prism')---- $setup--- >>> import Control.Lens((#), (^?))--- >>> import Data.Foldable(all)--- >>> import Prelude(Eq(..))--newtype DegreesLatitude =- DegreesLatitude Int- deriving (Eq, Ord, Show)---- | A prism on degrees latitude to an integer between -90 and 90 exclusive.------ >>> 7 ^? nDegreesLatitude--- Just (DegreesLatitude 7)------ >>> 0 ^? nDegreesLatitude--- Just (DegreesLatitude 0)------ >>> 89 ^? nDegreesLatitude--- Just (DegreesLatitude 89)------ >>> 90 ^? nDegreesLatitude--- Nothing------ >>> (-89) ^? nDegreesLatitude--- Just (DegreesLatitude (-89))------ >>> (-90) ^? nDegreesLatitude--- Nothing------ prop> all (\m -> nDegreesLatitude # m == n) (n ^? nDegreesLatitude)-nDegreesLatitude ::- Prism' Int DegreesLatitude-nDegreesLatitude =- prism'- (\(DegreesLatitude i) -> i)- (\i -> case i > -90 && i < 90 of- True -> Just (DegreesLatitude i)- False -> Nothing)--class HasDegreesLatitude t where- degreesLatitude ::- Lens' t DegreesLatitude--instance HasDegreesLatitude DegreesLatitude where- degreesLatitude =- id-
− src/Data/GPS/Coordinate/DegreesLongitude.hs
@@ -1,56 +0,0 @@-module Data.GPS.Coordinate.DegreesLongitude(- DegreesLongitude-, HasDegreesLongitude(..)-, nDegreesLongitude-) where--import Prelude(Int, Bool(..), Eq, Show, Ord(..), id, (&&))-import Data.Maybe(Maybe(..))-import Control.Lens(Prism', Lens', prism')---- $setup--- >>> import Control.Lens((#), (^?))--- >>> import Data.Foldable(all)--- >>> import Prelude(Eq(..))--newtype DegreesLongitude =- DegreesLongitude Int- deriving (Eq, Ord, Show)---- | A prism on degrees longitude to an integer between -180 and 180 exclusive.------ >>> 7 ^? nDegreesLongitude--- Just (DegreesLongitude 7)------ >>> 0 ^? nDegreesLongitude--- Just (DegreesLongitude 0)------ >>> 179 ^? nDegreesLongitude--- Just (DegreesLongitude 179)------ >>> 180 ^? nDegreesLongitude--- Nothing------ >>> (-179) ^? nDegreesLongitude--- Just (DegreesLongitude (-179))------ >>> (-180) ^? nDegreesLongitude--- Nothing------ prop> all (\m -> nDegreesLongitude # m == n) (n ^? nDegreesLongitude)-nDegreesLongitude ::- Prism' Int DegreesLongitude-nDegreesLongitude =- prism'- (\(DegreesLongitude i) -> i)- (\i -> case i > -180 && i < 180 of- True -> Just (DegreesLongitude i)- False -> Nothing)--class HasDegreesLongitude t where- degreesLongitude ::- Lens' t DegreesLongitude--instance HasDegreesLongitude DegreesLongitude where- degreesLongitude =- id
− src/Data/GPS/Coordinate/Latitude.hs
@@ -1,109 +0,0 @@-module Data.GPS.Coordinate.Latitude(- Latitude-, HasLatitude(..)-, dmsLatitude-, fracLatitude-) where--import Prelude(Double, Eq, Show, Ord(..), Num(..), Bool(..), Monad(..), id, (&&), properFraction, fromIntegral)-import Control.Lens(Iso', Prism', Lens', iso, prism', lens, (#), (^?))-import Data.GPS.Coordinate.DegreesLatitude-import Data.GPS.Coordinate.Minutes-import Data.GPS.Coordinate.Seconds---- $setup--- >>> import Control.Lens((^?))--data Latitude =- Latitude- DegreesLatitude- Minutes- Seconds- deriving (Eq, Ord, Show)---- | An isomorphism on the triple of degrees latitude, minutes, seconds to a latitude.------ >>> do deg <- 7 ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude--- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 7.0000))------ >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude--- Just (Latitude (DegreesLatitude 89) (Minutes 59) (Seconds 59.0000))------ >>> do deg <- (-7) ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude--- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 7.0000))------ >>> do deg <- (-89) ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude--- Just (Latitude (DegreesLatitude (-89)) (Minutes 59) (Seconds 59.0000))------ >>> do deg <- 90 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude--- Nothing------ >>> do deg <- 89 ^? nDegreesLatitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude--- Nothing------ >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLatitude--- Nothing-dmsLatitude ::- Iso' (DegreesLatitude, Minutes, Seconds) Latitude-dmsLatitude =- iso (\(d, m, s) -> Latitude d m s) (\(Latitude d m s) -> (d, m, s))---- | A prism on latitude to a double between -90 and 90 inclusive.------ >>> 7 ^? fracLatitude--- Just (Latitude (DegreesLatitude 7) (Minutes 0) (Seconds 0.0000))------ >>> (-7) ^? fracLatitude--- Just (Latitude (DegreesLatitude (-7)) (Minutes 0) (Seconds 0.0000))------ >>> 7.12 ^? fracLatitude--- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 12.0000))------ >>> (-7.12) ^? fracLatitude--- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 12.0000))------ >>> 90 ^? fracLatitude--- Nothing------ >>> (-90) ^? fracLatitude--- Nothing------ >>> 15.63791 ^? fracLatitude--- Just (Latitude (DegreesLatitude 15) (Minutes 38) (Seconds 16.4760))------ >>> 89.1 ^? fracLatitude--- Just (Latitude (DegreesLatitude 89) (Minutes 5) (Seconds 60.0000))------ >>> 89.2 ^? fracLatitude--- Just (Latitude (DegreesLatitude 89) (Minutes 12) (Seconds 0.0000))-fracLatitude ::- Prism' Double Latitude-fracLatitude =- prism' (\(Latitude d m s) ->- fromIntegral (nDegreesLatitude # d) + nSeconds # s + fromIntegral (nMinutes # m * 60))- (\x -> let (d, z) = properFraction x- (m, s) = properFraction ((z :: Double) * 60)- in do d' <- d ^? nDegreesLatitude- m' <- abs m ^? nMinutes- s' <- (abs s * 60) ^? nSeconds- return (Latitude d' m' s'))--class HasLatitude t where- latitude ::- Lens' t Latitude--instance HasLatitude Latitude where- latitude =- id--instance HasDegreesLatitude Latitude where- degreesLatitude =- lens (\(Latitude d _ _) -> d) (\(Latitude _ m s) d -> Latitude d m s)--instance HasMinutes Latitude where- minutes =- lens (\(Latitude _ m _) -> m) (\(Latitude d _ s) m -> Latitude d m s)--instance HasSeconds Latitude where- seconds =- lens (\(Latitude _ _ s) -> s) (\(Latitude d m _) s -> Latitude d m s)
− src/Data/GPS/Coordinate/Longitude.hs
@@ -1,106 +0,0 @@-module Data.GPS.Coordinate.Longitude(- Longitude-, HasLongitude(..)-, dmsLongitude-, fracLongitude-) where--import Prelude(Double, Eq, Show, Ord(..), Num(..), Bool(..), Monad(..), id, (&&), properFraction, fromIntegral)-import Control.Lens(Iso', Prism', Lens', iso, prism', lens, (#), (^?))-import Data.GPS.Coordinate.DegreesLongitude-import Data.GPS.Coordinate.Minutes-import Data.GPS.Coordinate.Seconds--data Longitude =- Longitude- DegreesLongitude- Minutes- Seconds- deriving (Eq, Ord, Show)---- | An isomorphism on the triple of degrees longitude, minutes, seconds to a longitude.------ >>> do deg <- 7 ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude--- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 7.0000))------ >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude--- Just (Longitude (DegreesLongitude 179) (Minutes 59) (Seconds 59.0000))------ >>> do deg <- (-7) ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude--- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 7.0000))------ >>> do deg <- (-179) ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude--- Just (Longitude (DegreesLongitude (-179)) (Minutes 59) (Seconds 59.0000))------ >>> do deg <- 180 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude--- Nothing------ >>> do deg <- 179 ^? nDegreesLongitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude--- Nothing------ >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLongitude--- Nothing-dmsLongitude ::- Iso' (DegreesLongitude, Minutes, Seconds) Longitude-dmsLongitude =- iso (\(d, m, s) -> Longitude d m s) (\(Longitude d m s) -> (d, m, s))---- | A prism on longitude to a double between -180 and 180 inclusive.------ >>> 7 ^? fracLongitude--- Just (Longitude (DegreesLongitude 7) (Minutes 0) (Seconds 0.0000))------ >>> (-7) ^? fracLongitude--- Just (Longitude (DegreesLongitude (-7)) (Minutes 0) (Seconds 0.0000))------ >>> 7.12 ^? fracLongitude--- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 12.0000))------ >>> (-7.12) ^? fracLongitude--- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 12.0000))------ >>> 180 ^? fracLongitude--- Nothing------ >>> (-180) ^? fracLongitude--- Nothing------ >>> 15.63791 ^? fracLongitude--- Just (Longitude (DegreesLongitude 15) (Minutes 38) (Seconds 16.4760))------ >>> 179.1 ^? fracLongitude--- Just (Longitude (DegreesLongitude 179) (Minutes 5) (Seconds 60.0000))------ >>> 179.2 ^? fracLongitude--- Just (Longitude (DegreesLongitude 179) (Minutes 11) (Seconds 60.0000))-fracLongitude ::- Prism' Double Longitude-fracLongitude =- prism' (\(Longitude d m s) ->- fromIntegral (nDegreesLongitude # d) + nSeconds # s + fromIntegral (nMinutes # m * 60))- (\x -> let (d, z) = properFraction x- (m, s) = properFraction ((z :: Double) * 60)- in do d' <- d ^? nDegreesLongitude- m' <- abs m ^? nMinutes- s' <- (abs s * 60) ^? nSeconds- return (Longitude d' m' s'))--class HasLongitude t where- longitude ::- Lens' t Longitude--instance HasLongitude Longitude where- longitude =- id--instance HasDegreesLongitude Longitude where- degreesLongitude =- lens (\(Longitude d _ _) -> d) (\(Longitude _ m s) d -> Longitude d m s)--instance HasMinutes Longitude where- minutes =- lens (\(Longitude _ m _) -> m) (\(Longitude d _ s) m -> Longitude d m s)--instance HasSeconds Longitude where- seconds =- lens (\(Longitude _ _ s) -> s) (\(Longitude d m _) s -> Longitude d m s)
− src/Data/GPS/Coordinate/Minutes.hs
@@ -1,50 +0,0 @@-module Data.GPS.Coordinate.Minutes(- Minutes-, HasMinutes(..)-, nMinutes-) where--import Prelude(Functor, Int, Bool(..), Eq, Show, Ord(..), (&&), id)-import Data.Maybe(Maybe(..))-import Control.Lens(Prism', Lens', prism')---- $setup--- >>> import Control.Lens((#), (^?))--- >>> import Data.Foldable(all)--- >>> import Prelude(Eq(..))--newtype Minutes =- Minutes Int- deriving (Eq, Ord, Show)---- | A prism on minutes to an integer between 0 and 59 inclusive.------ >>> 7 ^? nMinutes--- Just (Minutes 7)------ >>> 0 ^? nMinutes--- Just (Minutes 0)------ >>> 59 ^? nMinutes--- Just (Minutes 59)------ >>> 60 ^? nMinutes--- Nothing------ prop> all (\m -> nMinutes # m == n) (n ^? nMinutes)-nMinutes ::- Prism' Int Minutes-nMinutes =- prism'- (\(Minutes i) -> i)- (\i -> case i >= 0 && i < 60 of- True -> Just (Minutes i)- False -> Nothing)--class HasMinutes t where- minutes ::- Lens' t Minutes--instance HasMinutes Minutes where- minutes =- id
− src/Data/GPS/Coordinate/Seconds.hs
@@ -1,60 +0,0 @@-module Data.GPS.Coordinate.Seconds(- Seconds-, HasSeconds(..)-, nSeconds-) where--import Prelude(Double, Bool(..), Eq, Show(..), Ord(..), id, (&&), (++), showParen, showString)-import Data.Maybe(Maybe(..))-import Control.Lens(Prism', Lens', prism')-import Text.Printf(printf)---- $setup--- >>> import Control.Lens((#), (^?))--- >>> import Data.Foldable(all)--- >>> import Prelude(Eq(..))--newtype Seconds =- Seconds Double- deriving (Eq, Ord)---- | A show instance that prints to 4 decimal places.--- This is to take floating-point rounding errors into account.-instance Show Seconds where- showsPrec n (Seconds d) =- showParen (n > 10) (showString ("Seconds " ++ printf "%0.4f" d))---- | A prism on seconds to a double between 0 inclusive and 60 exclusive.------ >>> 7 ^? nSeconds--- Just (Seconds 7.0000)------ >>> 0 ^? nSeconds--- Just (Seconds 0.0000)------ >>> 59 ^? nSeconds--- Just (Seconds 59.0000)------ >>> 59.99 ^? nSeconds--- Just (Seconds 59.9900)------ >>> 60 ^? nSeconds--- Nothing------ prop> all (\m -> nSeconds # m == n) (n ^? nSeconds)-nSeconds ::- Prism' Double Seconds-nSeconds =- prism'- (\(Seconds d) -> d)- (\d -> case d >= 0 && d < 60 of- True -> Just (Seconds d)- False -> Nothing)--class HasSeconds t where- seconds ::- Lens' t Seconds--instance HasSeconds Seconds where- seconds =- id
+ src/Data/Geo/Coordinate.hs view
@@ -0,0 +1,9 @@+module Data.Geo.Coordinate(module C) where++import Data.Geo.Coordinate.Coordinate as C+import Data.Geo.Coordinate.DegreesLatitude as C+import Data.Geo.Coordinate.DegreesLongitude as C+import Data.Geo.Coordinate.Latitude as C+import Data.Geo.Coordinate.Longitude as C+import Data.Geo.Coordinate.Minutes as C+import Data.Geo.Coordinate.Seconds as C
+ src/Data/Geo/Coordinate/Coordinate.hs view
@@ -0,0 +1,74 @@+module Data.Geo.Coordinate.Coordinate(+ Coordinate+, HasCoordinate(..)+, coordinateLatLon+, coordinateLonLat+, coordinateDMSLatLon+, coordinateLatDMSLon+, coordinateDMSLatDMSLon+) where++import Prelude(Eq, Show, Ord, id, (.))+import Control.Lens(Iso', Lens', iso, lens, mapping, swapped, withIso)+import Data.Geo.Coordinate.Latitude+import Data.Geo.Coordinate.Longitude+import Data.Geo.Coordinate.DegreesLatitude+import Data.Geo.Coordinate.DegreesLongitude+import Data.Geo.Coordinate.Minutes+import Data.Geo.Coordinate.Seconds++data Coordinate =+ Coordinate+ Latitude+ Longitude+ deriving (Eq, Ord, Show)++coordinateLatLon ::+ Iso' (Latitude, Longitude) Coordinate+coordinateLatLon =+ iso (\(lat, lon) -> Coordinate lat lon) (\(Coordinate lat lon) -> (lat, lon))++coordinateLonLat ::+ Iso' (Longitude, Latitude) Coordinate+coordinateLonLat =+ swapped . coordinateLatLon++coordinateDMSLatLon ::+ Iso' ((DegreesLatitude, Minutes, Seconds), Longitude) Coordinate+coordinateDMSLatLon =+ swapped . mapping dmsLatitude . coordinateLonLat++coordinateLatDMSLon ::+ Iso' (Latitude, (DegreesLongitude, Minutes, Seconds)) Coordinate+coordinateLatDMSLon =+ mapping dmsLongitude . coordinateLatLon++coordinateDMSLatDMSLon ::+ Iso' ((DegreesLatitude, Minutes, Seconds), (DegreesLongitude, Minutes, Seconds)) Coordinate+coordinateDMSLatDMSLon =+ iso (\((td, tm, ts), (nd, nm, ns)) -> Coordinate (withIso dmsLatitude (\k _ -> k (td, tm, ts))) (withIso dmsLongitude (\k _ -> k (nd, nm, ns))))+ (\(Coordinate lat lon) -> (withIso dmsLatitude (\_ k -> k lat), withIso dmsLongitude (\_ k -> k lon)))++class HasCoordinate t where+ coordinate ::+ Lens' t Coordinate++instance HasCoordinate Coordinate where+ coordinate =+ id++instance HasLatitude Coordinate where+ latitude =+ lens (\(Coordinate lat _) -> lat) (\(Coordinate _ lon) lat -> Coordinate lat lon)++instance HasLongitude Coordinate where+ longitude =+ lens (\(Coordinate _ lon) -> lon) (\(Coordinate lat _) lon -> Coordinate lat lon)++instance HasDegreesLatitude Coordinate where+ degreesLatitude =+ latitude . degreesLatitude++instance HasDegreesLongitude Coordinate where+ degreesLongitude =+ longitude . degreesLongitude
+ src/Data/Geo/Coordinate/DegreesLatitude.hs view
@@ -0,0 +1,57 @@+module Data.Geo.Coordinate.DegreesLatitude(+ DegreesLatitude+, HasDegreesLatitude(..)+, nDegreesLatitude+) where++import Prelude(Int, Bool(..), Eq, Show, Ord(..), id, (&&))+import Data.Maybe(Maybe(..))+import Control.Lens(Prism', Lens', prism')++-- $setup+-- >>> import Control.Lens((#), (^?))+-- >>> import Data.Foldable(all)+-- >>> import Prelude(Eq(..))++newtype DegreesLatitude =+ DegreesLatitude Int+ deriving (Eq, Ord, Show)++-- | A prism on degrees latitude to an integer between -90 and 90 exclusive.+--+-- >>> 7 ^? nDegreesLatitude+-- Just (DegreesLatitude 7)+--+-- >>> 0 ^? nDegreesLatitude+-- Just (DegreesLatitude 0)+--+-- >>> 89 ^? nDegreesLatitude+-- Just (DegreesLatitude 89)+--+-- >>> 90 ^? nDegreesLatitude+-- Nothing+--+-- >>> (-89) ^? nDegreesLatitude+-- Just (DegreesLatitude (-89))+--+-- >>> (-90) ^? nDegreesLatitude+-- Nothing+--+-- prop> all (\m -> nDegreesLatitude # m == n) (n ^? nDegreesLatitude)+nDegreesLatitude ::+ Prism' Int DegreesLatitude+nDegreesLatitude =+ prism'+ (\(DegreesLatitude i) -> i)+ (\i -> case i > -90 && i < 90 of+ True -> Just (DegreesLatitude i)+ False -> Nothing)++class HasDegreesLatitude t where+ degreesLatitude ::+ Lens' t DegreesLatitude++instance HasDegreesLatitude DegreesLatitude where+ degreesLatitude =+ id+
+ src/Data/Geo/Coordinate/DegreesLongitude.hs view
@@ -0,0 +1,56 @@+module Data.Geo.Coordinate.DegreesLongitude(+ DegreesLongitude+, HasDegreesLongitude(..)+, nDegreesLongitude+) where++import Prelude(Int, Bool(..), Eq, Show, Ord(..), id, (&&))+import Data.Maybe(Maybe(..))+import Control.Lens(Prism', Lens', prism')++-- $setup+-- >>> import Control.Lens((#), (^?))+-- >>> import Data.Foldable(all)+-- >>> import Prelude(Eq(..))++newtype DegreesLongitude =+ DegreesLongitude Int+ deriving (Eq, Ord, Show)++-- | A prism on degrees longitude to an integer between -180 and 180 exclusive.+--+-- >>> 7 ^? nDegreesLongitude+-- Just (DegreesLongitude 7)+--+-- >>> 0 ^? nDegreesLongitude+-- Just (DegreesLongitude 0)+--+-- >>> 179 ^? nDegreesLongitude+-- Just (DegreesLongitude 179)+--+-- >>> 180 ^? nDegreesLongitude+-- Nothing+--+-- >>> (-179) ^? nDegreesLongitude+-- Just (DegreesLongitude (-179))+--+-- >>> (-180) ^? nDegreesLongitude+-- Nothing+--+-- prop> all (\m -> nDegreesLongitude # m == n) (n ^? nDegreesLongitude)+nDegreesLongitude ::+ Prism' Int DegreesLongitude+nDegreesLongitude =+ prism'+ (\(DegreesLongitude i) -> i)+ (\i -> case i > -180 && i < 180 of+ True -> Just (DegreesLongitude i)+ False -> Nothing)++class HasDegreesLongitude t where+ degreesLongitude ::+ Lens' t DegreesLongitude++instance HasDegreesLongitude DegreesLongitude where+ degreesLongitude =+ id
+ src/Data/Geo/Coordinate/Latitude.hs view
@@ -0,0 +1,109 @@+module Data.Geo.Coordinate.Latitude(+ Latitude+, HasLatitude(..)+, dmsLatitude+, fracLatitude+) where++import Prelude(Double, Eq, Show, Ord(..), Num(..), Bool(..), Monad(..), id, (&&), properFraction, fromIntegral)+import Control.Lens(Iso', Prism', Lens', iso, prism', lens, (#), (^?))+import Data.Geo.Coordinate.DegreesLatitude+import Data.Geo.Coordinate.Minutes+import Data.Geo.Coordinate.Seconds++-- $setup+-- >>> import Control.Lens((^?))++data Latitude =+ Latitude+ DegreesLatitude+ Minutes+ Seconds+ deriving (Eq, Ord, Show)++-- | An isomorphism on the triple of degrees latitude, minutes, seconds to a latitude.+--+-- >>> do deg <- 7 ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 7.0000))+--+-- >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- Just (Latitude (DegreesLatitude 89) (Minutes 59) (Seconds 59.0000))+--+-- >>> do deg <- (-7) ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 7.0000))+--+-- >>> do deg <- (-89) ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- Just (Latitude (DegreesLatitude (-89)) (Minutes 59) (Seconds 59.0000))+--+-- >>> do deg <- 90 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- Nothing+--+-- >>> do deg <- 89 ^? nDegreesLatitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- Nothing+--+-- >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- Nothing+dmsLatitude ::+ Iso' (DegreesLatitude, Minutes, Seconds) Latitude+dmsLatitude =+ iso (\(d, m, s) -> Latitude d m s) (\(Latitude d m s) -> (d, m, s))++-- | A prism on latitude to a double between -90 and 90 inclusive.+--+-- >>> 7 ^? fracLatitude+-- Just (Latitude (DegreesLatitude 7) (Minutes 0) (Seconds 0.0000))+--+-- >>> (-7) ^? fracLatitude+-- Just (Latitude (DegreesLatitude (-7)) (Minutes 0) (Seconds 0.0000))+--+-- >>> 7.12 ^? fracLatitude+-- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 12.0000))+--+-- >>> (-7.12) ^? fracLatitude+-- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 12.0000))+--+-- >>> 90 ^? fracLatitude+-- Nothing+--+-- >>> (-90) ^? fracLatitude+-- Nothing+--+-- >>> 15.63791 ^? fracLatitude+-- Just (Latitude (DegreesLatitude 15) (Minutes 38) (Seconds 16.4760))+--+-- >>> 89.1 ^? fracLatitude+-- Just (Latitude (DegreesLatitude 89) (Minutes 5) (Seconds 60.0000))+--+-- >>> 89.2 ^? fracLatitude+-- Just (Latitude (DegreesLatitude 89) (Minutes 12) (Seconds 0.0000))+fracLatitude ::+ Prism' Double Latitude+fracLatitude =+ prism' (\(Latitude d m s) ->+ fromIntegral (nDegreesLatitude # d) + nSeconds # s + fromIntegral (nMinutes # m * 60))+ (\x -> let (d, z) = properFraction x+ (m, s) = properFraction ((z :: Double) * 60)+ in do d' <- d ^? nDegreesLatitude+ m' <- abs m ^? nMinutes+ s' <- (abs s * 60) ^? nSeconds+ return (Latitude d' m' s'))++class HasLatitude t where+ latitude ::+ Lens' t Latitude++instance HasLatitude Latitude where+ latitude =+ id++instance HasDegreesLatitude Latitude where+ degreesLatitude =+ lens (\(Latitude d _ _) -> d) (\(Latitude _ m s) d -> Latitude d m s)++instance HasMinutes Latitude where+ minutes =+ lens (\(Latitude _ m _) -> m) (\(Latitude d _ s) m -> Latitude d m s)++instance HasSeconds Latitude where+ seconds =+ lens (\(Latitude _ _ s) -> s) (\(Latitude d m _) s -> Latitude d m s)
+ src/Data/Geo/Coordinate/Longitude.hs view
@@ -0,0 +1,106 @@+module Data.Geo.Coordinate.Longitude(+ Longitude+, HasLongitude(..)+, dmsLongitude+, fracLongitude+) where++import Prelude(Double, Eq, Show, Ord(..), Num(..), Bool(..), Monad(..), id, (&&), properFraction, fromIntegral)+import Control.Lens(Iso', Prism', Lens', iso, prism', lens, (#), (^?))+import Data.Geo.Coordinate.DegreesLongitude+import Data.Geo.Coordinate.Minutes+import Data.Geo.Coordinate.Seconds++data Longitude =+ Longitude+ DegreesLongitude+ Minutes+ Seconds+ deriving (Eq, Ord, Show)++-- | An isomorphism on the triple of degrees longitude, minutes, seconds to a longitude.+--+-- >>> do deg <- 7 ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 7.0000))+--+-- >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- Just (Longitude (DegreesLongitude 179) (Minutes 59) (Seconds 59.0000))+--+-- >>> do deg <- (-7) ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 7.0000))+--+-- >>> do deg <- (-179) ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- Just (Longitude (DegreesLongitude (-179)) (Minutes 59) (Seconds 59.0000))+--+-- >>> do deg <- 180 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- Nothing+--+-- >>> do deg <- 179 ^? nDegreesLongitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- Nothing+--+-- >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- Nothing+dmsLongitude ::+ Iso' (DegreesLongitude, Minutes, Seconds) Longitude+dmsLongitude =+ iso (\(d, m, s) -> Longitude d m s) (\(Longitude d m s) -> (d, m, s))++-- | A prism on longitude to a double between -180 and 180 inclusive.+--+-- >>> 7 ^? fracLongitude+-- Just (Longitude (DegreesLongitude 7) (Minutes 0) (Seconds 0.0000))+--+-- >>> (-7) ^? fracLongitude+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 0) (Seconds 0.0000))+--+-- >>> 7.12 ^? fracLongitude+-- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 12.0000))+--+-- >>> (-7.12) ^? fracLongitude+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 12.0000))+--+-- >>> 180 ^? fracLongitude+-- Nothing+--+-- >>> (-180) ^? fracLongitude+-- Nothing+--+-- >>> 15.63791 ^? fracLongitude+-- Just (Longitude (DegreesLongitude 15) (Minutes 38) (Seconds 16.4760))+--+-- >>> 179.1 ^? fracLongitude+-- Just (Longitude (DegreesLongitude 179) (Minutes 5) (Seconds 60.0000))+--+-- >>> 179.2 ^? fracLongitude+-- Just (Longitude (DegreesLongitude 179) (Minutes 11) (Seconds 60.0000))+fracLongitude ::+ Prism' Double Longitude+fracLongitude =+ prism' (\(Longitude d m s) ->+ fromIntegral (nDegreesLongitude # d) + nSeconds # s + fromIntegral (nMinutes # m * 60))+ (\x -> let (d, z) = properFraction x+ (m, s) = properFraction ((z :: Double) * 60)+ in do d' <- d ^? nDegreesLongitude+ m' <- abs m ^? nMinutes+ s' <- (abs s * 60) ^? nSeconds+ return (Longitude d' m' s'))++class HasLongitude t where+ longitude ::+ Lens' t Longitude++instance HasLongitude Longitude where+ longitude =+ id++instance HasDegreesLongitude Longitude where+ degreesLongitude =+ lens (\(Longitude d _ _) -> d) (\(Longitude _ m s) d -> Longitude d m s)++instance HasMinutes Longitude where+ minutes =+ lens (\(Longitude _ m _) -> m) (\(Longitude d _ s) m -> Longitude d m s)++instance HasSeconds Longitude where+ seconds =+ lens (\(Longitude _ _ s) -> s) (\(Longitude d m _) s -> Longitude d m s)
+ src/Data/Geo/Coordinate/Minutes.hs view
@@ -0,0 +1,50 @@+module Data.Geo.Coordinate.Minutes(+ Minutes+, HasMinutes(..)+, nMinutes+) where++import Prelude(Functor, Int, Bool(..), Eq, Show, Ord(..), (&&), id)+import Data.Maybe(Maybe(..))+import Control.Lens(Prism', Lens', prism')++-- $setup+-- >>> import Control.Lens((#), (^?))+-- >>> import Data.Foldable(all)+-- >>> import Prelude(Eq(..))++newtype Minutes =+ Minutes Int+ deriving (Eq, Ord, Show)++-- | A prism on minutes to an integer between 0 and 59 inclusive.+--+-- >>> 7 ^? nMinutes+-- Just (Minutes 7)+--+-- >>> 0 ^? nMinutes+-- Just (Minutes 0)+--+-- >>> 59 ^? nMinutes+-- Just (Minutes 59)+--+-- >>> 60 ^? nMinutes+-- Nothing+--+-- prop> all (\m -> nMinutes # m == n) (n ^? nMinutes)+nMinutes ::+ Prism' Int Minutes+nMinutes =+ prism'+ (\(Minutes i) -> i)+ (\i -> case i >= 0 && i < 60 of+ True -> Just (Minutes i)+ False -> Nothing)++class HasMinutes t where+ minutes ::+ Lens' t Minutes++instance HasMinutes Minutes where+ minutes =+ id
+ src/Data/Geo/Coordinate/Seconds.hs view
@@ -0,0 +1,60 @@+module Data.Geo.Coordinate.Seconds(+ Seconds+, HasSeconds(..)+, nSeconds+) where++import Prelude(Double, Bool(..), Eq, Show(..), Ord(..), id, (&&), (++), showParen, showString)+import Data.Maybe(Maybe(..))+import Control.Lens(Prism', Lens', prism')+import Text.Printf(printf)++-- $setup+-- >>> import Control.Lens((#), (^?))+-- >>> import Data.Foldable(all)+-- >>> import Prelude(Eq(..))++newtype Seconds =+ Seconds Double+ deriving (Eq, Ord)++-- | A show instance that prints to 4 decimal places.+-- This is to take floating-point rounding errors into account.+instance Show Seconds where+ showsPrec n (Seconds d) =+ showParen (n > 10) (showString ("Seconds " ++ printf "%0.4f" d))++-- | A prism on seconds to a double between 0 inclusive and 60 exclusive.+--+-- >>> 7 ^? nSeconds+-- Just (Seconds 7.0000)+--+-- >>> 0 ^? nSeconds+-- Just (Seconds 0.0000)+--+-- >>> 59 ^? nSeconds+-- Just (Seconds 59.0000)+--+-- >>> 59.99 ^? nSeconds+-- Just (Seconds 59.9900)+--+-- >>> 60 ^? nSeconds+-- Nothing+--+-- prop> all (\m -> nSeconds # m == n) (n ^? nSeconds)+nSeconds ::+ Prism' Double Seconds+nSeconds =+ prism'+ (\(Seconds d) -> d)+ (\d -> case d >= 0 && d < 60 of+ True -> Just (Seconds d)+ False -> Nothing)++class HasSeconds t where+ seconds ::+ Lens' t Seconds++instance HasSeconds Seconds where+ seconds =+ id