Overview of geodesics modules

These libraries started life (a long time ago) as simple ‘latitude/longitude’ code fragments covering distances and bearings, intended to help people who had little experience of geodesy, and perhaps limited programming experience.

The intention was to have clear, simple illustrative code samples which could be adapted and re-used in other projects (whether those be coded in JavaScript, Java, C++, Excel VBA, or anything else...). With its untyped C-style syntax, JavaScript reads remarkably close to pseudo-code, exposing the algorithms with a minimum of syntactic distractions.

While still valid for that purpose, they have grown since then into considerable libraries covering both spherical and ellipsoidal earth models, and based on both spherical/ellipsoidal trigonometry and vector-based approaches (complementing these are various mapping-related functions covering UTM coordinates, MGRS grid references, and UK OS grid references).

This is version 2 of the library, which firstly separates the spherical and ellipsoidal elements of the n-vector part of the library, and secondly uses JavaScript ES2015 classes and modules, which makes the code both more immediately readable, and also more accessible to non-JavaScript readers (always bearing in mind JavaScript uses prototype-based classes rather than inheritance-based classes). An ES5 version will remain available on GitHub, for anyone wanting it.

This overview provides a quick reference of how the components relate to each other, and which modules provide which methods. There is a fairly complex set of interdependencies, which may take some consideration to tease out, for anyone wanting to use more than independent sections of the libraries. The spherical routines are generally separate from the ellipsoidal. The core ellipsoidal parts include ellipsoid parameters and datum conversion functions, and support both geodesics on the ellipsoid on the trig side, and NED deltas on the n-vector side. The n-vector parts are relatively new, I’m sure both the spherical and the ellipsoidal dimensions can be developed further.

Click on module name to see full code; click on to see summary of methods.

module functions trig. vector spherical ellipsoidal
dms.js formatting / parsing of degrees, minutes, seconds
class Dms {

    static parseDMS(dmsStr) { }

    static toDMS(deg, format, dp) { }

    static toLat(deg, format, dp) { }

    static toLon(deg, format, dp) { }

    static toBrng(deg, format, dp) { }

    static compassPoint(bearing, precision) {
}

export default Dms;
        
latlon-ellipsoidal.js ellipsoid parameters, datum conversions, cartesian conversion
import Dms from 'dms.js';

class LatLonEllipsoidal {

    constructor(lat, lon, height=0, datum=LatLon.datums.WGS84) { }

    static get ellipsoids() { }

    static get datums() { }

    convertDatum(toDatum) { }

    toCartesian() { }

    toString(format='dms', dp=undefined, heightDp=null) { }

}

class Cartesian {

    constructor(x, y, z) { }

    toLatLon(datum=LatLon.datums.WGS84) { }

    applyTransform(t) { }

    toString(dp=0) { }

}

export { LatLonEllipsoidal as default, Cartesian };
        
latlon-nvector-ellipsoidal.js delta vectors between points
import LatLon, { Cartesian } from 'latlon-ellipsoidal.js';
import Vector3d from 'vector3d.js';

class LatLonNvectorEllipsoidal extends LatLon {

    constructor(lat, lon, height=0, datum=LatLon.datums.WGS84) { }

    deltaTo(point) { }

    destinationPoint(delta) { }

    equals(point) { }

    toNvector() { }

    toCartesian() { } // TODO: replicates LatLonEllipsoidal.toCartesian; fix?

}

class NvectorEllipsoidal extends Vector3d {

    constructor(x, y, z, h=0, datum=LatLon.datums.WGS84) { }

    toLatLon() { }

    toCartesian() { }

    toString(dp) { }

}

class CartesianNvector extends mixin(Vector3d, Cartesian) {

    toNector(datum=LatLon.datums.WGS84) { }
}

class Ned {

    constructor(north, east, down) { }

    get length() { }

    get bearing() { }

    get elevation() { }

    toString() { }

}

export { LatLonNvectorEllipsoidal as default, NvectorEllipsoidal as Nvector, CartesianNvector as Cartesian, Ned };
        
latlon-nvector-spherical.js distances, bearings, and other functions
import Vector3d from 'vector3d.js';
import Dms from 'dms.js';

class LatLonNvectorSpherical {

    constructor(lat, lon) { }

    toNvector() { }

    greatCircle(bearing) { }

    distanceTo(point, radius=6371e3) { }

    bearingTo(point) { }

    midpointTo(point) { }

    destinationPoint(distance, bearing, radius) { }

    static intersection(path1start, path1brngEnd, path2start, path2brngEnd) { }

    crossTrackDistanceTo(pathStart, pathBrngEnd, radius) { }

    nearestPointOnSegment(point1, point2) { }

    enclosedBy(points) { }

    static meanOf(points) { }

    equals(point) { }

    toString(format='dms', dp=0|2|4) { }

}

class NvectorSpherical extends Vector3d {

    constructor(x, y, z, h=0) { }

    toLatLon() { }

    toString(dp) { }

}

export { LatLonNvectorSpherical as default, NvectorSpherical as Nvector };
        
latlon-spherical.js distances, bearings, and other functions
import Dms from 'dms.js';

class LatLonSpherical {

    constructor(lat, lon) { }

    distanceTo(point, radius=6371e3) { }

    bearingTo(point) { }

    finalBearingTo(point) { }

    midpointTo(point) { }

    destinationPoint(distance, bearing, radius) { }

    static intersection(point1, bearing1, point2, bearing2) { }

    crossTrackDistanceTo(pathStart, pathEnd, radius) { }

    maxLatitude(bearing) { }

    static crossingParallels(point1, point2, latitude)

    rhumbDistanceTo(point, radius=6371e3) { }

    rhumbBearingTo(point) { }

    rhumbDestinationPoint(distance, bearing, radius=6371e3) { }

    rhumbMidpointTo(point)

    toString(format='dms', dp=0|2|4) { }
}

// static methods

export default LatLonSpherical;
        
latlon-vincenty.js geodesics on the ellipsoid
import LatLon from 'latlon-ellipsoidal.js';

class LatLonVincenty extends LatLon {

    distanceTo(point) { }

    initialBearingTo(point) { }

    finalBearingTo(point) { }

    destinationPoint(distance, initialBearing) { }

    finalBearingOn(distance, initialBearing) { }

    direct(distance, initialBearing) { }

    inverse(point) { }

}

export default LatLonVincenty;
        
latlon-karney.js geodesics on the ellipsoid
import LatLon from 'latlon-ellipsoidal.js';

class LatLonKarney extends LatLon {

    distanceTo(point) { }

    initialBearingTo(point) { }

}

export default LatLonKarney;
        
mgrs.js MGRS grid references
import Utm, { LatLon } from 'utm.js';

class Mgrs {

    constructor(zone, band, e100k, n100k, easting, northing, datum=LatLon.datums.WGS84) { }

    toUtm() { }

    static parse(mgrsGridRef) { }

    toString(digits) { }
}

class MgrsUtm extends Utm {

    toMgrs() { }

}

export { Mgrs as default, MgrsUtm as Utm };
        
osgridref.js Ordnance Survey grid references
import LatLon from 'latlon-ellipsoidal.js';

class OsGridRef {

    constructor(easting, northing) { }

    toLatLon(datum=LatLon.datums.WGS84) { }

    static parse(gridref) { }

    toString(digits) { }

}

class OsGridRefLatLon extends LatLon {

    toOsGrid() { }

}

export { OsGridRef as default, OsGridRefLatLon as LatLon };
        
utm.js UTM / WGS-84 conversions
import LatLon from 'latlon-ellipsoidal.js';

class Utm {

    constructor(zone, hemisphere, easting, northing, datum=LatLon.datums.WGS84, convergence=null, scale=null) { }

    toLatLon() { }

    parse(utmCoord, datum=LatLon.datums.WGS84) { }

    toString(digits) { }

}

class UtmLatLon extends LatLon {

    toUtm() { }

}

export { Utm as default, UtmLatLon as LatLon };
        
vector3d.js general 3-d vector operations
class Vector3d {

    constructor(x, y, z) { }

    plus(v) { }

    minus(v) { }

    times(x) { }

    dividedBy(x) { }

    dot(v) { }

    cross(v) { }

    negate() { }

    length() { }

    unit() { }

    angleTo(v, vSign) { }

    rotateAround(axis, theta) { }

    toString(precision) { }
}

export default Vector3d;
        

Full JSDoc documentation is also available.