Author: Thomas DuBuisson Copyright: Thomas DuBuisson License: BSD3
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.
- class Coordinate a where
- toDMS :: a -> DMSCoordinate
- fromDMS :: DMSCoordinate -> a
- distance :: a -> a -> Distance
- heading :: a -> a -> Heading
- getVector :: a -> a -> Vector
- class Coordinate coord => Location loc coord time | loc -> coord, loc -> time where
- data DMSCoordinate = DMSCoord {}
- data DMS a = DMS {}
- data Latitude
- data Longitude
- type Distance = Double
- type Heading = Double
- type Speed = Double
- type Vector = (Distance, Heading)
- type Trail a = [a]
- north :: Integer
- south :: Double
- east :: Double
- west :: Double
- radiusOfEarth :: Double
- smoothTrails :: Location a b c => Speed -> Trail a -> [Trail a]
- longestSmoothTrail :: Location a b c => Speed -> Trail a -> Trail a
- restLocations :: Location a b c => Distance -> NominalDiffTime -> Trail a -> [Trail a]
- closestDistance :: Coordinate a => Trail a -> Trail a -> Maybe Distance
- normalizeDMS :: DMSCoordinate -> DMSCoordinate
- dmsToDegreePair :: DMSCoordinate -> (Double, Double)
- dmsToRadianPair :: DMSCoordinate -> (Double, Double)
- degreePairToDMS :: (Double, Double) -> DMSCoordinate
- addVector :: Vector -> DMSCoordinate -> DMSCoordinate
Types and Classes
class Coordinate a whereSource
A coordinate is a place on earths surface. While twoDMS and fromDMS are the only required functions, coordinate systems may provide more accurate calculations of heading, distance, and vectors without the intermediate translation.
toDMS :: a -> DMSCoordinateSource
fromDMS :: DMSCoordinate -> aSource
distance :: a -> a -> DistanceSource
Coordinate DMSCoordinate | |
Coordinate c => Coordinate (c, UTCTime) |
class Coordinate coord => Location loc coord time | loc -> coord, loc -> time whereSource
A location is a coordinate at a specific time
getCoordinate :: loc -> coordSource
Coordinate c => Location (c, UTCTime) c UTCTime |
data DMSCoordinate Source
DMSCoordinate is the typical degree minute second for latitude/longitude used by most civilian GPS devices.
DMS is the degrees, minutes, seconds used for both latitude and longitude
Angles are expressed in radians from North. 0 == North pi/2 == West pi == South (32)pi == East == - (pi 2)
Constants
radius of the earth in meters
Helper Functions
smoothTrails :: Location a b c => Speed -> Trail a -> [Trail a]Source
smoothTrails speed trail
should separate points that would mandate a speed
in excess of the given rate into separate Trails. No point are deleted;
if there is only one correct
trail expected then the largest resulting
trail will likely be the one your looking for.
longestSmoothTrail :: Location a b c => Speed -> Trail a -> Trail aSource
Uses smoothTrails
but returns only the longest resulting trail
restLocations :: Location a b c => Distance -> NominalDiffTime -> Trail a -> [Trail a]Source
Creates a list of trails all of which are within the given distance of each other spanning atleast the given amount of time.
For example restLocations 50 600
would return lists of all points that are within 50 meters of each other and
span at least 10 minutes (600 seconds).
Note this gives points within fifty meters of the earliest point - wandering in a rest area with a 50 meter radius could result in several rest points ([a,b..]) or even none if the distance between individual points exceeds 50m.
closestDistance :: Coordinate a => Trail a -> Trail a -> Maybe DistanceSource
Returns the closest distance between two trails (or Nothing if a trail is empty) O( (n * m) * log (n * m) )
normalizeDMS :: DMSCoordinate -> DMSCoordinateSource
Typically useful for printing, normalizes degrees, minutes, seconds into just degrees and decimal minutes:
DMSCoord (DMS 45 36.938455 0) (DMS ...)
dmsToDegreePair :: DMSCoordinate -> (Double, Double)Source
Provides a lat/lon pair of doubles in degrees
dmsToRadianPair :: DMSCoordinate -> (Double, Double)Source
Provides a lat/lon pair of doubles in radians
degreePairToDMS :: (Double, Double) -> DMSCoordinateSource
addVector :: Vector -> DMSCoordinate -> DMSCoordinateSource
Given a vector and coordinate, computes a new DMS coordinate. Within some epsilon it should hold that if
dest = addVector (dist,heading) start
then
heading == dmsHeading start dest
dist == distance start dest