Геолокация и карты в JavaScript (Node.js)
Работа с географическими данными и отображением карт — одна из ключевых задач современных веб-приложений. В экосистеме Node.js существует множество библиотек, позволяющих обрабатывать координаты, строить маршруты, выполнять обратное геокодирование и рендерить интерактивные карты. В этой статье мы рассмотрим основные инструменты и приведём практические примеры кода для серверной части (Node.js).
1. Основные библиотеки для работы с геоданными
1.1. Leaflet (клиентская часть) и node-leaflet
Leaflet — самая популярная JavaScript-библиотека для интерактивных карт. Она работает на стороне браузера, но для Node.js существует пакет leaflet (через npm install leaflet), который позволяет рендерить карты на сервере с помощью leaflet-headless или использовать данные в формате GeoJSON.
Пример генерации карты в виде изображения на сервере (с помощью leaflet-static):
const L = require('leaflet');
const { createCanvas } = require('canvas');
const map = L.map(createCanvas(800, 600), {
center: [55.751244, 37.618423], // Москва
zoom: 10
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
// Экспорт в PNG (упрощённо)
const buffer = map.getCanvas().toBuffer();
require('fs').writeFileSync('map.png', buffer);
1.2. OpenStreetMap (OSM) и Overpass API
OpenStreetMap предоставляет бесплатные тайлы и API для поиска объектов. В Node.js для работы с OSM часто используют пакет osmosis или прямые HTTP-запросы к https://nominatim.openstreetmap.org.
Пример обратного геокодирования (получение адреса по координатам):
const fetch = require('node-fetch');
async function reverseGeocode(lat, lon) {
const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}`;
const response = await fetch(url, {
headers: { 'User-Agent': 'PythonLibExample/1.0' }
});
const data = await response.json();
return data.display_name;
}
reverseGeocode(55.751244, 37.618423).then(addr => console.log(addr));
// Результат: "Москва, Россия, Красная площадь"
1.3. Turf.js — геопространственный анализ
Turf.js — мощная библиотека для выполнения геометрических операций: буферизация, объединение полигонов, расчёт расстояний, площади и т.д. Работает как в браузере, так и в Node.js.
Пример вычисления расстояния между двумя точками (в километрах):
const turf = require('@turf/turf');
const point1 = turf.point([37.618423, 55.751244]); // [lon, lat]
const point2 = turf.point([30.315868, 59.939095]); // Санкт-Петербург
const distance = turf.distance(point1, point2, { units: 'kilometers' });
console.log(`Расстояние: ${distance.toFixed(2)} км`); // ≈ 634.5 км
1.4. GeoJSON и shapefile
GeoJSON — формат для хранения географических структур (точки, линии, полигоны). В Node.js для работы с ним достаточно встроенного JSON.parse, а для чтения shape-файлов используют пакет shapefile.
const shapefile = require('shapefile');
shapefile.open('path/to/file.shp')
.then(source => source.read()
.then(function log(result) {
if (result.done) return;
console.log(result.value); // GeoJSON Feature
return source.read().then(log);
}))
.catch(error => console.error(error));
2. Продвинутые инструменты
2.1. Mapbox GL JS (Node.js)
Mapbox предоставляет коммерческую платформу с высокодетализированными картами. Для серверного рендеринга используйте @mapbox/mapbox-gl-native. Требуется ключ API.
2.2. Nominatim (геокодинг)
Помимо обратного геокодирования, Nominatim позволяет искать объекты по названию. Пример:
async function searchPlace(query) {
const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}`;
const res = await fetch(url, { headers: { 'User-Agent': 'PythonLib' } });
const data = await res.json();
return data.map(item => ({ name: item.display_name, lat: item.lat, lon: item.lon }));
}
searchPlace('Эйфелева башня').then(console.log);