Geodesic
| This documentation was generated with the assistance of AI. Please report any inaccuracies. |
The com.irurueta.navigation.geodesic package is a Java port of
GeographicLib, C.F.F. Karney’s library for exact geodesic calculations on
an ellipsoid of revolution (WGS84 by default). Unlike Frames and GNSS, it is not
based on Groves, 2013 — its algorithms follow
Karney, 2013 and Karney, 2011. See
the bibliography for full citations.
What a geodesic is
A geodesic is the shortest path between two points on a curved surface — the ellipsoid analogue of a straight
line, or of a great-circle arc on a sphere. Geodesic computes two classic problems:
| Problem | Given / find |
|---|---|
Direct |
Given a start point , an initial azimuth , and a distance — find the end point and the azimuth on arrival, . |
Inverse |
Given two points and — find the geodesic distance and the azimuths , at each end. |
Both problems are solved to better than 15 nm of accuracy (see Sec. 9 of
Karney, 2011) using series expansions in the ellipsoid flattening , and
both are exposed as Geodesic.direct(…)/Geodesic.arcDirect(…) and Geodesic.inverse(…), returning a
GeodesicData with:
| Field | Meaning |
|---|---|
|
Distance between the two points (m). |
|
Azimuth (bearing, clockwise from north) at the first/second point. |
|
Arc length between the points, in degrees, on the auxiliary sphere. |
|
Reduced length: how far a geodesic starting parallel to this one, a unit distance away, diverges after traveling . |
|
Geodesic scale: how the separation between nearby geodesics grows/shrinks along the path, seen from each end. |
|
Area between the geodesic and the equator, used by |
var geod = Geodesic.WGS84;
// Direct problem: from Barcelona, heading NE, for 500 km
var direct = geod.direct(41.3851, 2.1734, 45.0, 500_000.0);
var lat2 = direct.getLat2();
var lon2 = direct.getLon2();
var azi2 = direct.getAzi2();
// Inverse problem: distance and bearing between Barcelona and Paris
var inverse = geod.inverse(41.3851, 2.1734, 48.8566, 2.3522);
var distanceMeters = inverse.getS12();
var initialBearing = inverse.getAzi1();
Stepping along a geodesic: GeodesicLine
Computing many points along the same geodesic (e.g., to draw a route) by repeatedly calling direct/inverse
recomputes shared setup on every call. Geodesic.line(lat1, lon1, azi1) (or directLine/inverseLine, which
also fix the total distance/arc) instead returns a GeodesicLine object that captures the starting point and
azimuth once, so subsequent position(distance)/arcPosition(arc) calls are cheap:
var line = geod.line(41.3851, 2.1734, 45.0);
for (var s = 0.0; s <= 500_000.0; s += 50_000.0) {
var point = line.position(s);
System.out.println(point.getLat2() + ", " + point.getLon2());
}
Polygon perimeter and area: PolygonArea
PolygonArea accumulates a sequence of vertices (addPoint) or edges (addEdge, given azimuth + distance) and
computes the polygon’s perimeter and area on the ellipsoid via compute(), following Section 6 of
Karney, 2013. Internally it sums each edge’s S12 contribution using
Accumulator, an extended-precision (~106-bit) running sum based on
Shewchuk, 1997, which keeps the area accurate even for polygons with many
closely-spaced vertices.
var polygon = new PolygonArea(Geodesic.WGS84, false);
polygon.addPoint(41.3851, 2.1734);
polygon.addPoint(41.4036, 2.1744);
polygon.addPoint(41.3947, 2.1900);
PolygonResult result = polygon.compute();
var perimeterMeters = result.getPerimeter();
var areaSquareMeters = result.getArea();
Gnomonic projection
Gnomonic projects points from the ellipsoid onto a plane tangent at a chosen center point, such that every
geodesic through the center maps to a straight line — useful for great-circle-style route planning on a flat
map. It is derived from the geodesic reduced length and scale (Section 8 of
Karney, 2013).
var gnomonic = new Gnomonic(Geodesic.WGS84);
GnomonicData projected = gnomonic.forward(41.3851, 2.1734, 48.8566, 2.3522);
var x = projected.getX();
var y = projected.getY();
GnomonicData backToLatLon = gnomonic.reverse(41.3851, 2.1734, x, y);
Numerical building blocks
Two supporting classes underpin the precision of the algorithms above and are themselves independently cited:
-
GeoMathprovides careful floating-point primitives (hypot,log1p, etc.) that avoid cancellation error, following Goldberg, 1991 and Higham, 2002, with an alternative hypot method noted from Moler & Morrison, 1983 and Dubrulle, 1983. -
Accumulatorimplements the extended-precision running sum from Shewchuk, 1997, used byPolygonAreaso that area computations over many edges don’t accumulate floating-point error.