Copyright | (c) 2018 Cedric Liegeois |
---|---|
License | BSD3 |
Maintainer | Cedric Liegeois <ofmooseandmen@yahoo.fr> |
Stability | experimental |
Portability | portable |
Safe Haskell | Safe |
Language | Haskell2010 |
Geodetic calculations assuming a spherical earth model.
All functions are implemented using the vector-based approached described in Gade, K. (2010). A Non-singular Horizontal Position Representation
Synopsis
- data GreatCircle
- greatCircle :: (NTransform a, Show a) => a -> a -> GreatCircle
- greatCircleE :: NTransform a => a -> a -> Either String GreatCircle
- greatCircleF :: (NTransform a, MonadFail m) => a -> a -> m GreatCircle
- greatCircleBearing :: NTransform a => a -> Angle -> GreatCircle
- angularDistance :: NTransform a => a -> a -> Maybe a -> Angle
- antipode :: NTransform a => a -> a
- crossTrackDistance :: NTransform a => a -> GreatCircle -> Length -> Length
- crossTrackDistance84 :: NTransform a => a -> GreatCircle -> Length
- destination :: NTransform a => a -> Angle -> Length -> Length -> a
- destination84 :: NTransform a => a -> Angle -> Length -> a
- finalBearing :: (Eq a, NTransform a) => a -> a -> Maybe Angle
- initialBearing :: (Eq a, NTransform a) => a -> a -> Maybe Angle
- interpolate :: NTransform a => a -> a -> Double -> a
- intersections :: NTransform a => GreatCircle -> GreatCircle -> Maybe (a, a)
- insideSurface :: (Eq a, NTransform a) => a -> [a] -> Bool
- mean :: NTransform a => [a] -> Maybe a
- surfaceDistance :: NTransform a => a -> a -> Length -> Length
- surfaceDistance84 :: NTransform a => a -> a -> Length
The GreatCircle
type
data GreatCircle Source #
A circle on the _surface_ of the Earth which lies in a plane passing through the Earth's centre. Every two distinct and non-antipodal points on the surface of the Earth define a Great Circle.
It is internally represented as its normal vector - i.e. the normal vector to the plane containing the great circle.
See greatCircle
, greatCircleE
, greatCircleF
or greatCircleBearing
constructors.
Instances
Eq GreatCircle Source # | |
Defined in Data.Geo.Jord.Geodetics (==) :: GreatCircle -> GreatCircle -> Bool # (/=) :: GreatCircle -> GreatCircle -> Bool # | |
Show GreatCircle Source # | |
Defined in Data.Geo.Jord.Geodetics showsPrec :: Int -> GreatCircle -> ShowS # show :: GreatCircle -> String # showList :: [GreatCircle] -> ShowS # |
Smart constructors
greatCircle :: (NTransform a, Show a) => a -> a -> GreatCircle Source #
GreatCircle
passing by both given positions. error
s if given positions are
equal or antipodal.
greatCircleE :: NTransform a => a -> a -> Either String GreatCircle Source #
GreatCircle
passing by both given positions. A Left
indicates that given positions are
equal or antipodal.
greatCircleF :: (NTransform a, MonadFail m) => a -> a -> m GreatCircle Source #
GreatCircle
passing by both given positions. fail
s if given positions are
equal or antipodal.
greatCircleBearing :: NTransform a => a -> Angle -> GreatCircle Source #
GreatCircle
passing by the given position and heading on given bearing.
Calculations
angularDistance :: NTransform a => a -> a -> Maybe a -> Angle Source #
angularDistance p1 p2 n
computes the angle between the horizontal positions p1
and p2
.
If n
is Nothing
, the angle is always in [0..180], otherwise it is in [-180, +180],
signed + if p1
is clockwise looking along n
, - in opposite direction.
antipode :: NTransform a => a -> a Source #
antipode p
computes the antipodal horizontal position of p
:
the horizontal position on the surface of the Earth which is diametrically opposite to p
.
crossTrackDistance :: NTransform a => a -> GreatCircle -> Length -> Length Source #
crossTrackDistance p gc
computes the signed distance horizontal position p
to great circle gc
.
Returns a negative Length
if position if left of great circle,
positive Length
if position if right of great circle; the orientation of the
great circle is therefore important:
let gc1 = greatCircle (decimalLatLong 51 0) (decimalLatLong 52 1) let gc2 = greatCircle (decimalLatLong 52 1) (decimalLatLong 51 0) crossTrackDistance p gc1 == (- crossTrackDistance p gc2)
crossTrackDistance84 :: NTransform a => a -> GreatCircle -> Length Source #
crossTrackDistance
using the mean radius of the WGS84 reference ellipsoid.
destination :: NTransform a => a -> Angle -> Length -> Length -> a Source #
destination p b d r
computes the destination position from position p
having
travelled the distance d
on the initial bearing (compass angle) b
(bearing will normally vary
before destination is reached) and using the earth radius r
.
destination84 :: NTransform a => a -> Angle -> Length -> a Source #
destination
using the mean radius of the WGS84 reference ellipsoid.
finalBearing :: (Eq a, NTransform a) => a -> a -> Maybe Angle Source #
finalBearing p1 p2
computes the final bearing arriving at p2
from p1
in compass angle.
Compass angles are clockwise angles from true north: 0 = north, 90 = east, 180 = south, 270 = west.
The final bearing will differ from the initialBearing
by varying degrees according to distance and latitude.
Returns Nothing
if both horizontal positions are equals.
initialBearing :: (Eq a, NTransform a) => a -> a -> Maybe Angle Source #
initialBearing p1 p2
computes the initial bearing from p1
to p2
in compass angle.
Compass angles are clockwise angles from true north: 0 = north, 90 = east, 180 = south, 270 = west.
Returns Nothing
if both horizontal positions are equals.
interpolate :: NTransform a => a -> a -> Double -> a Source #
intersections :: NTransform a => GreatCircle -> GreatCircle -> Maybe (a, a) Source #
Computes the intersections between the two given GreatCircle
s.
Two GreatCircle
s intersect exactly twice unless there are equal (regardless of orientation),
in which case Nothing
is returned.
insideSurface :: (Eq a, NTransform a) => a -> [a] -> Bool Source #
insideSurface p ps
determines whether the p
is inside the polygon defined by the list of positions ps
.
The polygon is closed if needed (i.e. if head ps /= last ps
).
Uses the angle summation test: on a sphere, due to spherical excess, enclosed point angles will sum to less than 360°, and exterior point angles will be small but non-zero.
Always returns False
if ps
does not at least defines a triangle.
mean :: NTransform a => [a] -> Maybe a Source #
mean ps
computes the mean geographic horitzontal position of ps
, if it is defined.
The geographic mean is not defined for antipodals position (since they cancel each other).
Special conditions:
mean [] == Nothing mean [p] == Just p mean [p1, p2, p3] == Just circumcentre mean [p1, .., antipode p1] == Nothing
surfaceDistance :: NTransform a => a -> a -> Length -> Length Source #
surfaceDistance p1 p2
computes the surface distance (length of geodesic) between the positions p1
and p2
.
surfaceDistance84 :: NTransform a => a -> a -> Length Source #
surfaceDistance
using the mean radius of the WGS84 reference ellipsoid.