#gis #geography #geospatial

bin+lib geographiclib-rs

A port of geographiclib in Rust

9 releases

0.2.7 Feb 17, 2026
0.2.5 May 9, 2025
0.2.4 Feb 6, 2024
0.2.3 Mar 2, 2023
0.2.0 Apr 29, 2020

#202 in Geospatial

Download history 128887/week @ 2025-11-13 137505/week @ 2025-11-20 104624/week @ 2025-11-27 128032/week @ 2025-12-04 130869/week @ 2025-12-11 106685/week @ 2025-12-18 70310/week @ 2025-12-25 99874/week @ 2026-01-01 159228/week @ 2026-01-08 143817/week @ 2026-01-15 170525/week @ 2026-01-22 181218/week @ 2026-01-29 183074/week @ 2026-02-05 216654/week @ 2026-02-12 229607/week @ 2026-02-19 239910/week @ 2026-02-26

908,018 downloads per month
Used in 590 crates (4 directly)

MIT license

175KB
3.5K SLoC

geographiclib-rs

A subset of geographiclib implemented in Rust.

Documentation

Currently this implements the direct and the inverse geodesic calculations.

If instead you are looking for Rust bindings to Karney's C++ implementation, see https://crates.io/geographiclib.

Examples

// Determine the point 10000 km NE of JFK - the "direct" geodesic calculation.
use geographiclib_rs::{Geodesic, DirectGeodesic};

let g = Geodesic::wgs84();
let jfk_lat = 40.64;
let jfk_lon = -73.78;
let northeast_azimuth = 45.0;

let (lat, lon, az) = g.direct(jfk_lat, jfk_lon, northeast_azimuth, 10e6);

use approx::assert_relative_eq;
assert_relative_eq!(lat, 32.621100463725796);
assert_relative_eq!(lon, 49.05248709295982);
assert_relative_eq!(az,  140.4059858768007);
// Determine the distance between two points - the "inverse" geodesic calculation.
use geographiclib_rs::{Geodesic, InverseGeodesic};

let g = Geodesic::wgs84();
let p1 = (34.095925, -118.2884237);
let p2 = (59.4323439, 24.7341649);
let s12: f64 = g.inverse(p1.0, p1.1, p2.0, p2.1);

use approx::assert_relative_eq;
assert_relative_eq!(s12, 9094718.72751138);
// Determine the perimeter and area of a polygon.
use geographiclib_rs::{Geodesic, PolygonArea, Winding};

let g = Geodesic::wgs84();
let mut pa = PolygonArea::new(&g, Winding::CounterClockwise);
pa.add_point(0.0, 0.0);
pa.add_point(0.0, 1.0);
pa.add_point(1.0, 1.0);
pa.add_point(1.0, 0.0);

let (perimeter_m, area_m_squared, num_points) = pa.compute(false);

use approx::assert_relative_eq;
assert_relative_eq!(perimeter_m, 443770.91724830196);
assert_relative_eq!(area_m_squared, 12308778361.469452);
assert_eq!(num_points, 4);
// Determine the distance between rovers Pathfinder and Curiosity on Mars
use geographiclib_rs::{Geodesic, InverseGeodesic};

let mars = Geodesic::new(3396190.0, 1.0 / 169.8944472);
let pathfinder = (19.26, 326.75);
let curiosity = (-4.765700445, 137.39820983);
let distance_m: f64 = mars.inverse(curiosity.0, curiosity.1, pathfinder.0, pathfinder.1);

assert_eq!(distance_m.round(), 9639113.0);

Features

  1. accurate: Enabled by default. Use the accurate crate to provide high accuracy polygon areas and perimeters in PolygonArea. Can be disabled for better performance or when PolygonArea is not being used.

Benchmarking

To compare the direct and inverse geodesic calculation against the geographiclib c bindings, run:

cargo bench

Which produces output like:

direct (c wrapper)/default
                        time:   [23.420 µs 23.495 µs 23.578 µs]
direct (rust impl)/default
                        time:   [23.894 µs 23.952 µs 24.017 µs]
inverse (c wrapper)/default
                        time:   [42.505 µs 42.561 µs 42.627 µs]
inverse (rust impl)/default
                        time:   [51.093 µs 51.174 µs 51.273 µs]

Showing that, at least in this benchmark, the Rust implementation is 2% slower for Direct geodesic calculations and 20% slower for Inverse calculations.

Dependencies

~1MB
~17K SLoC