Geolocalização e mapas em Rust: visão geral das bibliotecas e exemplos práticos
Rust é uma linguagem de programação de sistemas que está ganhando popularidade em áreas que exigem alto desempenho e segurança. Trabalhar com dados geoespaciais não é exceção. Se você está desenvolvendo um serviço de rastreamento de transporte, um sistema de informação geográfica ou simplesmente deseja adicionar um mapa interativo ao seu site, o ecossistema Rust oferece várias soluções maduras. Neste artigo, analisaremos as principais bibliotecas para geolocalização e exibição de mapas, além de fornecer exemplos práticos de código.
1. Biblioteca geo — base para cálculos geométricos
A biblioteca geo (crates geo-types e geo) fornece tipos de dados básicos: pontos, linhas, polígonos, bem como algoritmos para trabalhar com eles. Ela é a base para muitos outros crates geo.
// 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);
// Distância haversine (em metros) let dist = haversine_distance(&moscow, &spb); println!("Distância Moscou — SPb: {:.0} km", dist / 1000.0);
// Criando um polígono 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!("Área do polígono: {:?}", polygon.unsigned_area());}Recursos:
- Tipos: Point, Line, LineString, Polygon, MultiPoint, GeometryCollection
- Algoritmos: distância Haversine, Vincenty, área, centroide, buffer, interseções
- Serialização via serde (compatível com GeoJSON)
2. geoutils — trabalho com GPS e formatos de dados
O crate geoutils é especializado em análise e validação de dados GPS. Ele pode ler strings NMEA (protocolo padrão de receptores GPS) e converter coordenadas.
// cargo add geoutilsuse geoutils::{Location, Distance};
fn main() { // Criando um ponto a partir de latitude/longitude let point_a = Location::new(55.7558, 37.6173).unwrap(); let point_b = Location::new(59.9343, 30.3351).unwrap();
// Distância haversine let dist = point_a.distance_to(&point_b).unwrap(); println!("Distância: {} km", dist.as_kilometers());
// Analisando string NMEA (exemplo) 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!("Análise NMEA: {:?}", loc); }}Características:
- Análise de NMEA-0183 (GPGGA, GPRMC)
- Suporte a formatos: DMS (graus/minutos/segundos), graus decimais
- Conversão entre sistemas de coordenadas (WGS84, UTM)
3. mapbox-gl-native-rs — renderização de mapas em Rust
Para exibir mapas em aplicativos desktop ou embarcados, você pode usar o wrapper Rust para Mapbox GL Native. A biblioteca permite renderizar tiles vetoriais, sobrepor marcadores e polígonos e gerenciar estilos.
// Exemplo simplificado — requer configuração do ambiente// 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"));
// Adicionando um marcador map.add_marker(37.6173, 55.7558, "Moscou");
// Renderizando em um buffer (por exemplo, PNG) let img = map.render_to_image(); img.save("map.png").unwrap();}Nota: Para funcionar, é necessário ter instalado