GeographicLib

Pure-Python geodesic distance, bearing, and area calculations on the WGS84 ellipsoid.

Library
PyPI
v2.1
72stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
42/100Fair
Development Activity40
Maintenance16
Community36
Maturity56
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
69/100Good
Architecture78
Code Quality58
Innovation65
Learning Curve75

GeographicLib is a pure-Python implementation of Charles Karney’s geodesic algorithms, solving direct and inverse geodesic problems on an ellipsoidal model of the earth with no runtime dependencies beyond the standard library. It powers accurate distance, azimuth, and area calculations used across GIS tooling, mapping libraries, and scientific computing pipelines that need results matching the reference GeographicLib implementations in C++, Java, and JavaScript.

The library exposes the same API across every GeographicLib language port — Direct, Inverse, ArcDirect, and line-stepping methods — so results are numerically consistent no matter which language a project uses. A companion PolygonArea class computes areas and perimeters of geodesic polygons using compensated summation for numerical stability, making it useful for tasks like measuring survey plots or satellite footprint coverage on the ellipsoid.

What You Get

  • Direct and inverse geodesic solvers (Geodesic.Direct, Geodesic.Inverse, Geodesic.ArcDirect) for distance, azimuth, and reduced-length calculations on any ellipsoid
  • GeodesicLine objects for stepping incrementally along a geodesic path via DirectLine, ArcDirectLine, and InverseLine factory methods
  • PolygonArea class for computing the area and perimeter of geodesic polygons and polylines with compensated (Shewchuk-style) summation for numerical accuracy
  • A capability bitmask system (Geodesic.STANDARD, Geodesic.ALL, Geodesic.LONG_UNROLL, etc.) to control exactly which outputs are computed, trading precision for speed
  • A prebuilt Geodesic.WGS84 singleton plus support for constructing custom ellipsoids from any semi-major axis and flattening

Common Use Cases

  • Computing accurate great-ellipse distances and bearings between GPS coordinates instead of spherical approximations
  • Measuring the true ellipsoidal area of a surveyed plot of land or a geofence polygon from its vertex coordinates
  • Stepping along a geodesic line to plot flight paths, shipping routes, or satellite ground tracks
  • Cross-checking geodesic calculations against other GeographicLib language ports (C++, Java, JavaScript) for consistency

Under The Hood

Architecture The library mirrors the C++ GeographicLib design as a small set of tightly focused modules: geomath.py (a Math class of low-level numeric utilities — sq, cbrt, Shewchuk-style compensated sum, AngRound, sincosd), accumulator.py (an Accumulator class implementing exact/compensated summation for numerically stable area totals), constants.py (ellipsoid constants), geodesiccapability.py (bitmask flags such as LATITUDE, AZIMUTH, DISTANCE, AREA that control which outputs get computed), the core geodesic.py (a large Geodesic class solving Direct/Inverse/ArcDirect via internal series-expansion coefficients A3/C3/C4), geodesicline.py (a GeodesicLine class for incremental stepping, constructed through Geodesic.Line/DirectLine/ArcDirectLine/InverseLine factory methods), and polygonarea.py (a PolygonArea class that accumulates vertices or edges and computes enclosed area via the Accumulator). Control flows from a caller instantiating Geodesic (or using the Geodesic.WGS84 singleton), calling Inverse/Direct, which internally builds a GeodesicLine driven by capability bitflags to selectively compute only the requested outputs. There is no dependency injection; GeodesicLine reaches directly into Geodesic’s internal coefficient state, a tight but expected coupling for a deliberate line-by-line port of a C++ codebase — changing the core series-expansion constants in geodesic.py would ripple into geodesicline.py and polygonarea.py.

Tech Stack Pure Python (roughly 96% of the codebase) with a small CMake footprint used only for release packaging — CMakeLists.txt generates init.py from init.py.in with version substitution and builds the distrib-Python release artifacts, not required for a normal pip install. There are no runtime dependencies beyond the Python standard library (math, sys), a deliberate design choice so the library can be embedded anywhere without a dependency chain. Builds via setuptools (pyproject.toml declares setuptools>=42 as the build backend) with a templated setup.cfg.in filled in by CMake at release time, and is published to PyPI as geographiclib.

Code Quality Two dedicated unittest-based test files provide extensive numeric regression coverage: one comparing direct/inverse geodesic results against precomputed high-precision reference test cases, including antipodal points, coincident points, and NaN handling, and a second focused specifically on signed-zero and sign-consistency edge cases in azimuth and longitude output. There are no type hints or static typing anywhere in the codebase, and no linter/formatter configuration or CI workflow is visible in the shallow clone. Error handling is implicit, relying on standard Python exceptions and math domain errors rather than custom exception types. Method naming follows the source C++ API closely (PascalCase Direct/Inverse/ArcDirect rather than idiomatic Python snake_case), a deliberate choice documented in the project’s own materials to preserve cross-language parity. Comments are extensive, explaining non-obvious numerical techniques such as the exact-summation algorithm in accumulator.py.

API Design The public API deliberately mirrors GeographicLib’s C++, Java, JavaScript, and MATLAB implementations method-for-method, so knowledge of GeographicLib in any one language transfers directly to Python — a genuine cross-language consistency win, at some cost to Pythonic ergonomics (PascalCase methods, plain dicts keyed by capability flags rather than typed return objects). Getting started requires minimal boilerplate: importing Geodesic and calling Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2) returns a dict containing only the requested fields, controlled by public bitmask constants (STANDARD, ALL, LONG_UNROLL) that let advanced callers trade computation cost for output completeness. Documentation is comprehensive for a library this size: a full API reference plus a dedicated runnable-example document covering direct/inverse calculations, polygon area, and geodesic-line stepping. The work is not algorithmically novel in itself — it is a faithful transcription of previously published geodesic algorithms — but the developer experience of a dependency-free, precisely documented, multi-language-consistent geodesy primitive is well executed.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search