jord-2.0.0.0: Geographical Position Calculations

Copyright(c) 2020 Cedric Liegeois
LicenseBSD3
MaintainerCedric Liegeois <ofmooseandmen@yahoo.fr>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

Data.Geo.Jord.Local

Contents

Description

Type and functions for working with delta vectors in different local reference frames: all frames are location dependent.

In order to use this module you should start with the following imports:

import qualified Data.Geo.Jord.Geodetic as Geodetic
import qualified Data.Geo.Jord.Local as Local

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

Notes:

  • The term Earth is used to be consistent with the paper. However any celestial body reference frame can be used.
  • Though the API accept spherical models, doing so defeats the purpose of this module which is to find exact solutions. Prefer using ellipsoidal models.
Synopsis

Local Reference frame

class Frame a where Source #

class for local reference frames: a reference frame which is location dependant.

Supported frames:

Methods

rEF Source #

Arguments

:: a 
-> [V3]

rotation matrix to transform vectors decomposed in frame a to vectors decomposed Earth-Fixed frame.

Instances
Frame (FrameN a) Source #

R_EN: frame N to Earth

Instance details

Defined in Data.Geo.Jord.Local

Methods

rEF :: FrameN a -> [V3] Source #

Frame (FrameL m) Source #

R_EL: frame L to Earth

Instance details

Defined in Data.Geo.Jord.Local

Methods

rEF :: FrameL m -> [V3] Source #

Frame (FrameB a) Source #

R_EB: frame B to Earth

Instance details

Defined in Data.Geo.Jord.Local

Methods

rEF :: FrameB a -> [V3] Source #

Body frame

data FrameB a Source #

Body frame (typically of a vehicle).

  • Position: The origin is in the vehicle’s reference point.
  • Orientation: The x-axis points forward, the y-axis to the right (starboard) and the z-axis in the vehicle’s down direction.
  • Comments: The frame is fixed to the vehicle.
Instances
Model a => Eq (FrameB a) Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

(==) :: FrameB a -> FrameB a -> Bool #

(/=) :: FrameB a -> FrameB a -> Bool #

Model a => Show (FrameB a) Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

showsPrec :: Int -> FrameB a -> ShowS #

show :: FrameB a -> String #

showList :: [FrameB a] -> ShowS #

Frame (FrameB a) Source #

R_EB: frame B to Earth

Instance details

Defined in Data.Geo.Jord.Local

Methods

rEF :: FrameB a -> [V3] Source #

yaw :: FrameB a -> Angle Source #

body yaw angle (vertical axis).

pitch :: FrameB a -> Angle Source #

body pitch angle (transverse axis).

roll :: FrameB a -> Angle Source #

body roll angle (longitudinal axis).

bOrigin :: FrameB a -> Position a Source #

frame origin.

frameB :: Model a => Angle -> Angle -> Angle -> Position a -> FrameB a Source #

FrameB from given yaw, pitch, roll, position (origin).

Local level/wander azimuth frame

data FrameL a Source #

Local level, Wander azimuth frame.

  • Position: The origin is directly beneath or above the vehicle (B), at Earth’s surface (surface of ellipsoid model).
  • Orientation: The z-axis is pointing down. Initially, the x-axis points towards north, and the y-axis points towards east, but as the vehicle moves they are not rotating about the z-axis (their angular velocity relative to the Earth has zero component along the z-axis). (Note: Any initial horizontal direction of the x- and y-axes is valid for L, but if the initial position is outside the poles, north and east are usually chosen for convenience.)
  • Comments: The L-frame is equal to the N-frame except for the rotation about the z-axis, which is always zero for this frame (relative to Earth). Hence, at a given time, the only difference between the frames is an angle between the x-axis of L and the north direction; this angle is called the wander azimuth angle. The L-frame is well suited for general calculations, as it is non-singular.
Instances
Model a => Eq (FrameL a) Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

(==) :: FrameL a -> FrameL a -> Bool #

(/=) :: FrameL a -> FrameL a -> Bool #

Model a => Show (FrameL a) Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

showsPrec :: Int -> FrameL a -> ShowS #

show :: FrameL a -> String #

showList :: [FrameL a] -> ShowS #

Frame (FrameL m) Source #

R_EL: frame L to Earth

Instance details

Defined in Data.Geo.Jord.Local

Methods

rEF :: FrameL m -> [V3] Source #

wanderAzimuth :: FrameL a -> Angle Source #

wander azimuth: angle between x-axis of the frame L and the north direction.

lOrigin :: FrameL a -> Position a Source #

frame origin.

frameL :: Model a => Angle -> Position a -> FrameL a Source #

FrameL from given wander azimuth, position (origin).

North-East-Down frame

data FrameN a Source #

North-East-Down (local level) frame.

  • Position: The origin is directly beneath or above the vehicle (B), at Earth’s surface (surface of ellipsoid model).
  • Orientation: The x-axis points towards north, the y-axis points towards east (both are horizontal), and the z-axis is pointing down.
  • Comments: When moving relative to the Earth, the frame rotates about its z-axis to allow the x-axis to always point towards north. When getting close to the poles this rotation rate will increase, being infinite at the poles. The poles are thus singularities and the direction of the x- and y-axes are not defined here. Hence, this coordinate frame is not suitable for general calculations.
Instances
Model a => Eq (FrameN a) Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

(==) :: FrameN a -> FrameN a -> Bool #

(/=) :: FrameN a -> FrameN a -> Bool #

Model a => Show (FrameN a) Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

showsPrec :: Int -> FrameN a -> ShowS #

show :: FrameN a -> String #

showList :: [FrameN a] -> ShowS #

Frame (FrameN a) Source #

R_EN: frame N to Earth

Instance details

Defined in Data.Geo.Jord.Local

Methods

rEF :: FrameN a -> [V3] Source #

nOrigin :: FrameN a -> Position a Source #

frame origin.

frameN :: Model a => Position a -> FrameN a Source #

FrameN from given position (origin).

Deltas

data Delta Source #

delta between position in one of the reference frames.

Constructors

Delta 

Fields

Instances
Eq Delta Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

(==) :: Delta -> Delta -> Bool #

(/=) :: Delta -> Delta -> Bool #

Show Delta Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

showsPrec :: Int -> Delta -> ShowS #

show :: Delta -> String #

showList :: [Delta] -> ShowS #

deltaMetres :: Double -> Double -> Double -> Delta Source #

Delta from given x, y and z length in metres.

Delta in the north, east, down frame

data Ned Source #

North, east and down delta (thus in frame FrameN).

Constructors

Ned 

Fields

Instances
Eq Ned Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

(==) :: Ned -> Ned -> Bool #

(/=) :: Ned -> Ned -> Bool #

Show Ned Source # 
Instance details

Defined in Data.Geo.Jord.Local

Methods

showsPrec :: Int -> Ned -> ShowS #

show :: Ned -> String #

showList :: [Ned] -> ShowS #

nedMetres :: Double -> Double -> Double -> Ned Source #

Ned from given north, east and down in metres.

bearing :: Ned -> Angle Source #

bearing v computes the bearing in compass angle of the NED vector v from north.

Compass angles are clockwise angles from true north: 0 = north, 90 = east, 180 = south, 270 = west.

elevation :: Ned -> Angle Source #

elevation v computes the elevation of the NED vector v from horizontal (ie tangent to ellipsoid surface).

slantRange :: Ned -> Length Source #

slantRange v computes the distance from origin in the local system of the NED vector v.

Calculations

deltaBetween :: (Frame a, Model b) => Position b -> Position b -> (Position b -> a) -> Delta Source #

deltaBetween p1 p2 f computes the exact Delta between the two positions p1 and p2 in local frame f. For example:

>>> let p1 = Geodetic.latLongHeightPos 1 2 (Length.metres (-3)) WGS84
>>> let p2 = Geodetic.latLongHeightPos 4 5 (Length.metres (-6)) WGS84
>>> let w = Angle.decimalDegrees 5 -- wander azimuth
>>> Local.deltaBetween p1 p2 (Local.frameL w)
Delta {dx = 359.490578214km, dy = 302.818522536km, dz = 17.404271362km}

nedBetween :: Model a => Position a -> Position a -> Ned Source #

nedBetween p1 p2 computes the exact Ned vector between the two positions p1 and p2, in north, east, and down. For example:

>>> let p1 = Geodetic.latLongHeightPos 1 2 (Length.metres (-3)) WGS84
>>> let p2 = Geodetic.latLongHeightPos 4 5 (Length.metres (-6)) WGS84
>>> Local.nedBetween p1 p2
Ned {north = 331.730234781km, east = 332.997874989km, down = 17.404271362km}

Resulting Ned delta is relative to p1: Due to the curvature of Earth and different directions to the North Pole, the north, east, and down directions will change (relative to Earth) for different places.

Position p1 must be outside the poles for the north and east directions to be defined.

This is equivalent to:

Local.deltaBetween p1 p2 Local.frameN

destination :: (Frame a, Model b) => Position b -> (Position b -> a) -> Delta -> Position b Source #

destination p0 f d computes the destination position from position p0 and delta d in local frame f. For example:

>>> let p0 = Geodetic.latLongHeightPos 49.66618 3.45063 Length.zero WGS84
>>> let y = Angle.decimalDegrees 10 -- yaw
>>> let r = Angle.decimalDegrees 20 -- roll
>>> let p = Angle.decimalDegrees 30 -- pitch
>>> let d = Local.deltaMetres 3000 2000 100
>>> Local.destination p0 (Local.frameB y r p) d
49°41'30.485"N,3°28'52.561"E 6.007735m (WGS84)

destinationN :: Model a => Position a -> Ned -> Position a Source #

destinationN p0 d computes the destination position from position p0 and north, east, down d. For example:

>>> let p0 = Geodetic.latLongHeightPos 49.66618 3.45063 Length.zero WGS84
>>> Local.destinationN p0 (Local.nedMetres 100 200 300)
49°40'1.484"N,3°27'12.242"E -299.996086m (WGS84)
This is equivalent to:
Local.destination p0 Local.frameN