jord- Geographical Position Calculations

Copyright(c) 2018 Cedric Liegeois
MaintainerCedric Liegeois <>
Safe HaskellSafe




Types and functions for working with positions.

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.


The Position type

class Position a where Source #

The Position class defines 2 functions to convert a position to and from a NVector. All functions in this module first convert Position to NVector and any resulting NVector back to a Position. This allows the call site to pass either NVector or LatLong and to get back the same class instance.

Minimal complete definition

fromNVector, toNVector


fromNVector :: NVector -> a Source #

Converts a NVector into Position instance.

toNVector :: a -> NVector Source #

Converts the Position instance into a NVector.

Geodetic calculations

angularDistance :: NVector -> NVector -> Maybe NVector -> Angle Source #

Angle between the two given NVectors. If n is Nothing, the angle is always in [0..180], otherwise it is in [-180, +180], signed + if v1 is clockwise looking along n, - in opposite direction.

antipode :: Position a => a -> a Source #

Returns the antipodal Position of the given Position - i.e. the position on the surface of the Earth which is diametrically opposite to the given position.

destination :: Position a => a -> Angle -> Length -> a Source #

destination' assuming a radius of meanEarthRadius.

destination' :: Position a => a -> Angle -> Length -> Length -> a Source #

Computes the destination Position from the given Position having travelled the given distance on the given initial bearing (bearing will normally vary before destination is reached) and using the given earth radius.

This is known as the direct geodetic problem.

distance :: Position a => a -> a -> Length Source #

distance' assuming a radius of meanEarthRadius.

distance' :: Position a => a -> a -> Length -> Length Source #

Computes the surface distance (length of geodesic) in Meters assuming a spherical Earth between the two given Positions and using the given earth radius.

finalBearing :: Position a => a -> a -> Angle Source #

Computes the final bearing arriving at given destination p2 Position from given Position p1. the final bearing will differ from the initialBearing by varying degrees according to distance and latitude. Returns 180 if both position are equals.

initialBearing :: Position a => a -> a -> Angle Source #

Computes the initial bearing from given p1 Position to given p2 Position, in compass degrees. Returns 0 if both position are equals.

interpolate :: Position a => a -> a -> Double -> a Source #

Computes the Position at given fraction f between the two given Positions p0 and p1.

Special conditions:

    interpolate p0 p1 0.0 => p0
    interpolate p0 p1 1.0 => p1

errors if f || f 1.0

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

Determines whether the given Position is inside the polygon defined by the given list of Positions. 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.

mean :: Position a => [a] -> Maybe a Source #

Computes the geographic mean Position of the given Positions if it is defined.

The geographic mean is not defined for the antipodals positions (since they cancel each other).

Special conditions:

    mean [] == Nothing
    mean [p] == Just p
    mean [p1, p2, p3] == Just circumcentre
    mean [p1, .., antipode p1] == Nothing


meanEarthRadius :: Length Source #

Mean Earth radius: 6,371,008.8 metres.

northPole :: Position a => a Source #

Position of the North Pole.

southPole :: Position a => a Source #

Position of the South Pole.