jord-0.3.0.0: src/Data/Geo/Jord/Earth.hs
-- |
-- Module: Data.Geo.Jord.Earth
-- Copyright: (c) 2018 Cedric Liegeois
-- License: BSD3
-- Maintainer: Cedric Liegeois <ofmooseandmen@yahoo.fr>
-- Stability: experimental
-- Portability: portable
--
-- Ellipsoidal and derived spherical earth models.
--
module Data.Geo.Jord.Earth
( Earth(..)
, Ellipsoid(..)
, eccentricity
, meanRadius
, polarRadius
, spherical
-- * Reference ellipsoids.
, wgs84
, grs80
, wgs72
-- * Spherical models dervived from reference ellipsoids.
, s84
, s80
, s72
, r84
, r80
, r72
) where
import Data.Geo.Jord.Length
-- | Earth model: ellipsoidal or spherical.
data Earth
= Ellipsoidal Ellipsoid
| Spherical Length
deriving (Eq, Show)
-- | Primary ellipsoid parameters.
data Ellipsoid = Ellipsoid
{ equatorialRadius :: Length -- ^ equatorial radius or semi-major axis (a).
, inverseFlattening :: Double -- ^ inverse flattening.
} deriving (Eq, Show)
-- | Computes the eccentricity of the given 'Earth' model.
eccentricity :: Earth -> Double
eccentricity (Ellipsoidal e) = sqrt (1.0 - (b * b) / (a * a))
where
a = semiMajorAxis e
b = semiMinorAxis a (inverseFlattening e)
eccentricity (Spherical _) = 0
-- | Computes the mean radius of the given 'Earth' model.
--
-- This radius can be used for geodetic calculations assuming a spherical earth model.
meanRadius :: Earth -> Length
meanRadius (Ellipsoidal e) = metres ((2.0 * a + b) / 3.0)
where
a = semiMajorAxis e
b = semiMinorAxis a (inverseFlattening e)
meanRadius (Spherical r) = r
-- | Computes the polar radius or semi-minor axis (b) of the given 'Earth' model.
polarRadius :: Earth -> Length
polarRadius (Ellipsoidal e) = metres (semiMinorAxis a f)
where
a = semiMajorAxis e
f = inverseFlattening e
polarRadius (Spherical r) = r
-- | Spherical model derived from given model.
spherical :: Earth -> Earth
spherical e = Spherical (meanRadius e)
-- | World Geodetic System WGS84 ellipsoid.
wgs84 :: Earth
wgs84 = Ellipsoidal (Ellipsoid (metres 6378137.0) (1.0 / 298.257223563))
-- | Geodetic Reference System 1980 ellipsoid.
grs80 :: Earth
grs80 = Ellipsoidal (Ellipsoid (metres 6378137.0) (1.0 / 298.257222101))
-- | World Geodetic System WGS72 ellipsoid.
wgs72 :: Earth
wgs72 = Ellipsoidal (Ellipsoid (metres 6378135.0) (1.0 / 298.26))
-- | Spherical earth model derived from 'wgs84'.
s84 :: Earth
s84 = spherical wgs84
-- | Spherical earth model derived from 'grs80'.
s80 :: Earth
s80 = spherical grs80
-- | Spherical earth model derived from 'wgs72'.
s72 :: Earth
s72 = spherical wgs72
-- | Mean earth radius derived from the 'wgs84' ellipsoid.
r84 :: Length
r84 = meanRadius s84
-- | Mean earth radius derived from the 'grs80' ellipsoid.
r80 :: Length
r80 = meanRadius s80
-- | Mean earth radius derived from the 'wgs72' ellipsoid.
r72 :: Length
r72 = meanRadius s72
-- | semi-major axis (a) in metres.
semiMajorAxis :: Ellipsoid -> Double
semiMajorAxis = toMetres . equatorialRadius
-- | Computes the polar semi-minor axis (b) from @a@ anf @f@.
semiMinorAxis :: Double -> Double -> Double
semiMinorAxis a f = a * (1.0 - f)