packages feed

gps 0.5.4 → 0.6

raw patch · 2 files changed

+51/−36 lines, 2 filesdep −bytestringdep ~basedep ~prettydep ~prettyclass

Dependencies removed: bytestring

Dependency ranges changed: base, pretty, prettyclass

Files

Data/GPS.hs view
@@ -1,22 +1,10 @@-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, EmptyDataDecls #-}--- |Author: Thomas DuBuisson--- Copyright: Thomas DuBuisson--- License: BSD3------ A basic GPS library with calculations for distance and speed along+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, EmptyDataDecls, BangPatterns #-}+-- |A basic GPS library with calculations for distance and speed along -- with helper functions for filtering/smoothing trails.  All distances -- are in meters and time is in seconds.  Speed is thus meters/second------ The current intent of this library is to---   1) Provide a standard type class interface for coordinates---   2) Include fleshed out support for relevant libraries, a task---      too often neglected in modern Hackage packages.------  Integration includes KML support via the xml package, pretty printing,---  anb binary.  module Data.GPS-	( -- * Types and Classes+	( -- * Types 	  Distance 	, Heading 	, Speed@@ -28,17 +16,26 @@ 	, east 	, west 	, radiusOfEarth-	-- * Helper Functions+	-- * Coordinate Functions 	, heading-	, restLocations-	, closestDistance-	, getRadianPair+	, distance+	, speed 	, addVector+	, getRadianPair+	, getDMSPair 	, divideArea+        -- * Trail Functions+	, totalDistance+	, restLocations+	, closestDistance+	, filterByMaxSpeed 	, convexHull+	-- * Other helpers+	, readGPX 	, module Data.Geo.GPX 	) where +import Data.Function (on) import Data.Ord (comparing) import Data.List (sort, mapAccumL, minimumBy, maximumBy, sortBy) import Data.Geo.GPX hiding (none, cmt)@@ -49,6 +46,7 @@ import Data.Time import Data.Maybe (listToMaybe) import Data.Fixed+import Control.Monad  -- |Distances are expressed in meters type Distance = Double@@ -76,6 +74,10 @@   (lat1, lon1) = getRadianPairD a   (lat2, lon2) = getRadianPairD b +-- | Find the total distance traveled+totalDistance :: (Lat a, Lon a) => [a] -> Distance+totalDistance as = sum $ zipWith distance as (drop 1 as)+ -- | Direction two points aim toward (0 = North, pi/2 = West, pi = South, 3pi/2 = East) heading         :: (Lat a, Lon a) => a -> a -> Heading	-- ^ 0 = North, pi/2 = West... heading a b =@@ -89,13 +91,21 @@ getVector :: (Lat a, Lon a) => a -> a -> Vector getVector a b = (distance a b, heading a b) --- | Speed in meters per second+-- | Speed in meters per second, only if a 'Time' was recorded for each waypoint. speed :: (Lat loc, Lon loc, Time loc) => loc -> loc -> Maybe Speed speed a b =  	case (getUTCTime b, getUTCTime a) of 		(Just x, Just y) -> Just $ realToFrac (diffUTCTime x y) / (distance a b) 		_ -> Nothing +-- |Filter out all points that result in a speed greater than a given value+-- (the second point is dropped)+filterByMaxSpeed :: (Lat loc, Lon loc, Time loc) => Speed -> Trail loc -> Trail loc+filterByMaxSpeed mx xs =+	let ss = zipWith speed xs (drop 1 xs)+	    fs = filter ((< Just mx) . fst) (zip ss $ drop 1 xs)+	in take 1 xs ++ map snd fs+ data TempTrail a = T (Trail a) a  -- |radius of the earth in meters@@ -141,6 +151,9 @@ getRadianPairD :: (Lat c, Lon c) => c -> (Double,Double) getRadianPairD = (\(a,b) -> (realToFrac a, realToFrac b)) . getRadianPair +getDMSPair :: (Lat c, Lon c) => c -> (LatitudeType, LongitudeType)+getDMSPair c = (lat c, lon c)+ -- |Provides a lat/lon pair of doubles in radians getRadianPair :: (Lat p, Lon p) => p -> (LatitudeType, LongitudeType) getRadianPair p = (t, g)@@ -174,14 +187,14 @@   where   go [] = []   go (a:as) =-	let (lst, close, far) = takeWhileLast ((<= d) . distance a) as-	in case lst of-		Just x -> case (getUTCTime a, getUTCTime x) of-				(Just a', Just x') ->-					let d = diffUTCTime a' x'-			  		in if d >= s then close : go far else go as+	case takeWhileLast ((<=) d . distance a) as of+		(Just l, close, far) ->+			case (getUTCTime a, getUTCTime l) of+				(Just t1, Just t2) ->+					let diff = diffUTCTime t2 t1+					in if diff >= s then (a:close) : go far else go as 				_ -> go as-		Nothing -> go as+		_ -> go as  takeWhileLast :: (a -> Bool) -> [a] -> (Maybe a, [a], [a]) takeWhileLast p [] = (Nothing, [], [])@@ -189,10 +202,10 @@ 	| not (p x) = (Nothing, [], x:xs) 	| otherwise = go x xs   where-  go a [] = (Just a, [a], [])-  go a (b:bs)+  go !a [] = (Just a, [], [])+  go !a (b:bs) 	| p b = let (c,d,f) = go b bs in (c, a:d, f)-	| otherwise = (Just a, [a], b:bs)+	| otherwise = (Just a, [], b:bs)  -- |Returns the closest distance between two trails (or Nothing if a trail is empty) -- O( (n * m) * log (n * m) )@@ -212,6 +225,11 @@ 	    columnOne = takeWhile ( (<= west) . heading se) . iterate (addVector (vDist, south)) $ nw 	    buildRow  = takeWhile ((>= north) . heading se) . iterate (addVector (hDist, east)) 	in map buildRow columnOne++-- |Reads a GPX file (using the GPX library) by simply concatenating all the+-- tracks, segments, and points ('trkpts', 'trksegs', 'trks') into a single 'Trail'.+readGPX :: FilePath -> IO (Trail WptType)+readGPX = liftM (concatMap trkpts . concatMap trksegs . concatMap trks) . readGpxFile  -- | Uses Grahams scan to compute the convex hull of the given points. -- This operation requires sorting of the points, so don't try it unless
gps.cabal view
@@ -1,5 +1,5 @@ name:		gps-version:	0.5.4+version:	0.6 license:	BSD3 license-file:	LICENSE author:		Thomas DuBuisson <thomas.dubuisson@gmail.com>@@ -13,12 +13,9 @@ tested-with:	GHC == 6.10.3 extra-source-files:  -Flag small_base-  Description: Choose the split-up base package.- Library-  Build-Depends: base >= 4 && < 6, bytestring >= 0.9 && < 1.0,-                   pretty >= 1.0 && < 1.1 , prettyclass >= 1.0 && < 1.1,+  Build-Depends: base >= 3 && < 6,+                   pretty >= 1.0 , prettyclass >= 1.0,                    time >= 1.1 && < 1.3, GPX == 0.4.*, hxt >= 8.5, xsd == 0.3.*   hs-source-dirs:   exposed-modules: Data.GPS