Геолокация и карты в Rust: обзор инструментов и примеры кода
Rust — язык системного программирования, который всё чаще используется для создания высоконагруженных сервисов, работающих с пространственными данными. Благодаря производительности, безопасности памяти и активному сообществу, экосистема Rust предлагает несколько зрелых библиотек для работы с геолокацией, картами и форматами геоданных. В этой статье мы рассмотрим ключевые инструменты: geo, georust (включая gpx и geojson), а также интеграцию с картографическими библиотеками через WebAssembly.
1. Основная библиотека: geo
Библиотека geo — это ядро экосистемы геопространственных вычислений в Rust. Она предоставляет типы данных (точки, линии, полигоны), алгоритмы (расчет расстояний, площади, пересечений) и поддержку популярных координатных систем (WGS84, UTM).
Установка
# Cargo.toml
[dependencies]
geo = "0.27"
Пример: расчет расстояния между двумя точками
use geo::{point, Distance};
fn main() {
let moscow = point!(x: 37.6173, y: 55.7558);
let london = point!(x: -0.1276, y: 51.5074);
// Расстояние по сфере (алгоритм Хаверсина)
let distance = moscow.distance_haversine(&london);
println!("Расстояние от Москвы до Лондона: {:.2} км", distance / 1000.0);
}
Библиотека поддерживает:
- Типы геометрий:
Point,LineString,Polygon,MultiPointи др. - Алгоритмы: буферизация, упрощение линий (Ramer-Douglas-Peucker), расчет центроида.
- Работу с CRS через крейт
proj.
2. Работа с форматами: GeoJSON и GPX
Для чтения и записи геоданных используются отдельные крейты из экосистемы georust.
GeoJSON
Крейт geojson позволяет сериализовать/десериализовать GeoJSON — стандартный формат обмена геоданными.
use geojson::{Feature, GeoJson, Geometry, Value};
use serde_json;
fn main() {
let geojson_str = r#"{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [37.6173, 55.7558]
},
"properties": {
"name": "Moscow"
}
}"#;
let geojson: GeoJson = geojson_str.parse().unwrap();
if let GeoJson::Feature(feature) = geojson {
println!("Геометрия: {:?}", feature.geometry);
}
}
GPX (GPS Exchange Format)
Крейт gpx предназначен для работы с треками и путевыми точками, записанными GPS-устройствами.
use gpx::read;
use std::fs::File;
fn main() {
let file = File::open("track.gpx").unwrap();
let gpx = read(file).unwrap();
for track in gpx.tracks {
println!("Название трека: {:?}", track.name);
for segment in track.segments {
for point in segment.points {
println!("Точка: ({:.4}, {:.4})", point.point().x(), point.point().y());
}
}
}
}
3. Визуализация карт: Leaflet.js через WASM
Для отображения карт на веб-странице можно использовать Leaflet.js в связке с Rust через WebAssembly. Популярный подход — генерация HTML/JavaScript на стороне Rust с помощью крейта wasm-bindgen и встраивание карты через leaflet.js.
Пример: создание карты с маркером
// cargo.toml
[dependencies]
wasm-bindgen = "0.2"
// main.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn init_map() {
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
// Создаем div для карты
let map_div = document.create_element("div").unwrap();
map_div.set_attribute("id", "map").unwrap();
map_div.set_attribute("style", "height: 400px;").unwrap();
document.body().unwrap().append_child(&map_div).unwrap();
// Встраиваем скрипт Leaflet
let script = document.create_element("script").unwrap();
script.set_inner_html(r#"
var map = L.map('map').setView([55.7558, 37.6173], 10);
L.tileLayer