Copyright | (c) 2018 Cedric Liegeois |
---|---|

License | BSD3 |

Maintainer | Cedric Liegeois <ofmooseandmen@yahoo.fr> |

Stability | experimental |

Portability | portable |

Safe Haskell | Safe |

Language | Haskell2010 |

Types and functions for working with Great Circle.

All functions are implemented using the vector-based approached described in Gade, K. (2010). A Non-singular Horizontal Position Representation

This module assumes a spherical earth.

- data GreatCircle
- greatCircle :: (Eq a, Position a, Show a) => a -> a -> GreatCircle
- greatCircleE :: (Eq a, Position a) => a -> a -> Either String GreatCircle
- greatCircleF :: (Eq a, MonadFail m, Position a) => a -> a -> m GreatCircle
- greatCircleBearing :: Position a => a -> Angle -> GreatCircle
- crossTrackDistance :: Position a => a -> GreatCircle -> Length
- crossTrackDistance' :: Position a => a -> GreatCircle -> Length -> Length
- intersections :: Position a => GreatCircle -> GreatCircle -> Maybe (a, a)
- isInside :: (Eq a, Position a) => a -> [a] -> Bool

# 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.

# Smart constructors

greatCircle :: (Eq a, Position a, Show a) => a -> a -> GreatCircle Source #

greatCircleE :: (Eq a, Position a) => a -> a -> Either String GreatCircle Source #

greatCircleF :: (Eq a, MonadFail m, Position a) => a -> a -> m GreatCircle Source #

greatCircleBearing :: Position a => a -> Angle -> GreatCircle Source #

`GreatCircle`

passing by the given `Position`

and heading on given bearing.

# Geodesic calculations

crossTrackDistance :: Position a => a -> GreatCircle -> Length Source #

`crossTrackDistance'`

assuming a radius of `meanEarthRadius`

.

crossTrackDistance' :: Position a => a -> GreatCircle -> Length -> Length Source #

Signed distance from given `Position`

to given `GreatCircle`

.
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 (latLongDecimal 51 0) (latLongDecimal 52 1) let gc2 = greatCircle (latLongDecimal 52 1) (latLongDecimal 51 0) crossTrackDistance p gc1 == (- crossTrackDistance p gc2)

intersections :: Position 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.

isInside :: (Eq a, Position a) => a -> [a] -> Bool Source #

Determines whether the given `Position`

is inside the polygon defined by the given list of `Position`

s.
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 positions does not at least defines a triangle.