Geolocation and Maps in Rust: Libraries for Working with Coordinates

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Geolocation and Maps in Rust: Overview of Libraries and Practical Examples

Rust is a systems programming language gaining popularity in areas requiring high performance and security. Working with geodata is no exception. Whether you are developing a vehicle tracking service, a geographic information system, or simply want to add an interactive map to a website, the Rust ecosystem offers several mature solutions. In this article, we will review key libraries for geolocation and map rendering, and provide practical code examples.



1. The geo Library — The Foundation of Geometric Computations

The geo library (crates geo-types and geo) provides basic data types: points, lines, polygons, as well as algorithms for working with them. It is the foundation for many other geo-crates.

// cargo add geo-types geouse geo_types::{Point, LineString, Polygon};use geo::algorithm::haversine_distance;

fn main() { let moscow = Point::new(37.6173, 55.7558); let spb = Point::new(30.3351, 60.0);

// Haversine distance (in meters) let dist = haversine_distance(&moscow, &spb); println!("Distance Moscow — St. Petersburg: {:.0} km", dist / 1000.0);

// Creating a polygon let coords = vec![ (37.0, 55.0), (38.0, 55.0), (38.0, 56.0), (37.0, 56.0), (37.0, 55.0), ]; let polygon = Polygon::new( LineString::from(coords), vec![], ); println!("Polygon area: {:?}", polygon.unsigned_area());}

Features:

  • Types: Point, Line, LineString, Polygon, MultiPoint, GeometryCollection
  • Algorithms: Haversine distance, Vincenty distance, area, centroid, buffering, intersections
  • Serialization via serde (GeoJSON compatibility)


2. geoutils — Working with GPS and Data Formats

The geoutils crate specializes in parsing and validating GPS data. It can read NMEA strings (the standard GPS receiver protocol) and convert coordinates.

// cargo add geoutilsuse geoutils::{Location, Distance};

fn main() { // Creating a point from latitude/longitude let point_a = Location::new(55.7558, 37.6173).unwrap(); let point_b = Location::new(59.9343, 30.3351).unwrap();

// Haversine distance let dist = point_a.distance_to(&point_b).unwrap(); println!("Distance: {} km", dist.as_kilometers());

// Parsing an NMEA string (example) let nmea = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47"; if let Ok(loc) = Location::from_nmea(nmea) { println!("NMEA parsing: {:?}", loc); }}

Features:

  • Parsing NMEA-0183 (GPGGA, GPRMC)
  • Support for formats: DMS (degrees/minutes/seconds), decimal degrees
  • Conversion between coordinate systems (WGS84, UTM)


3. mapbox-gl-native-rs — Map Rendering in Rust

For displaying maps in desktop or embedded applications, you can use the Rust wrapper over Mapbox GL Native. The library allows rendering vector tiles, overlaying markers and polygons, and managing styles.

// Simplified example — environment setup required// cargo add mapbox-gl-native-rsuse mapbox_gl_native_rs::{Map, MapOptions, Style};

fn main() { let opts = MapOptions::new() .size(800, 600) .center(37.6173, 55.7558) .zoom(10.0);

let mut map = Map::new(opts); map.load_style(Style::from_url("https://demotiles.mapbox.com/style.json"));

// Adding a marker map.add_marker(37.6173, 55.7558, "Moscow");

// Rendering to a buffer (e.g., to PNG) let img = map.render_to_image(); img.save("map.png").unwrap();}

Note: Requires installation

Recommendations