GeoJSON представляет собой стандарт обмена географическими данными,
основанный на JSON. В контексте веб-картографии он используется для
описания точек, линий и полигонов вместе с их атрибутами. Библиотека
Leaflet поддерживает GeoJSON напрямую через объект
L.geoJSON, что делает интеграцию пространственных данных
предсказуемой и структурированной.
Типичная структура GeoJSON включает набор объектов типа
Feature внутри FeatureCollection:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [76.95, 43.25]
},
"properties": {
"name": "Объект A",
"category": "example"
}
}
]
}
Координаты в GeoJSON всегда задаются в порядке
[долгота, широта], что критично при переносе данных в
Leaflet, где стандартное представление —
[широта, долгота].
Leaflet предоставляет встроенный слой L.geoJSON, который
преобразует GeoJSON-структуры в визуальные объекты карты.
const map = L.map('map').setView([43.25, 76.95], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'OpenStreetMap'
}).addTo(map);
const geojsonData = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [76.95, 43.25]
},
"properties": {
"name": "Точка 1"
}
}
]
};
L.geoJSON(geojsonData).addTo(map);
При таком подключении каждый объект автоматически интерпретируется и добавляется на карту в виде соответствующего слоя.
На практике данные чаще хранятся отдельно и подгружаются через
HTTP-запросы. Основной подход — использование fetch.
fetch('/data/points.geojson')
.then(response => response.json())
.then(data => {
L.geoJSON(data).addTo(map);
});
При работе с сервером важно учитывать корректную настройку CORS, иначе браузер может блокировать запрос.
Асинхронная загрузка позволяет отделить карту от данных, что особенно важно при работе с динамическими слоями и обновляемой геоинформацией.
Leaflet позволяет управлять тем, как именно GeoJSON объекты будут
визуализированы через опции pointToLayer,
style и onEachFeature.
Для геометрий типа LineString и Polygon
используется функция style:
L.geoJSON(data, {
style: function (feature) {
return {
color: '#2b8cbe',
weight: 3,
opacity: 0.8
};
}
}).addTo(map);
Стиль может зависеть от свойств объекта:
style: function (feature) {
return {
color: feature.properties.category === 'highway' ? 'red' : 'blue',
weight: 2
};
}
По умолчанию точки отображаются как стандартные маркеры, однако
поведение можно переопределить через pointToLayer.
L.geoJSON(data, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, {
radius: 6,
fillColor: '#ff7800',
color: '#000',
weight: 1,
opacity: 1,
fillOpacity: 0.8
});
}
}).addTo(map);
Этот подход позволяет заменить маркеры на кастомные визуальные
элементы, включая circleMarker, marker с
иконками или даже комбинированные слои.
Каждый GeoJSON объект может быть связан с интерактивным поведением
через onEachFeature.
L.geoJSON(data, {
onEachFeature: function (feature, layer) {
if (feature.properties && feature.properties.name) {
layer.bindPopup(feature.properties.name);
}
layer.on('click', function () {
console.log(feature.properties);
});
}
}).addTo(map);
Этот механизм связывает геометрию с бизнес-логикой интерфейса, позволяя строить интерактивные карты с детализацией до каждого объекта.
Leaflet поддерживает фильтрацию элементов до их добавления на карту
через опцию filter.
L.geoJSON(data, {
filter: function (feature) {
return feature.properties.population > 10000;
}
}).addTo(map);
Фильтрация выполняется до рендера, что снижает нагрузку на DOM и улучшает производительность при работе с большими наборами данных.
GeoJSON слой можно обновлять без пересоздания карты. Обычно
используется комбинация удаления и добавления слоя или метод
clearLayers.
const layer = L.geoJSON(data).addTo(map);
// обновление данных
layer.clearLayers();
layer.addData(newData);
Метод addData позволяет добавлять новые объекты поверх
существующих, что полезно для потоковых данных или периодического
обновления.
При обработке больших данных (тысячи или десятки тысяч объектов) возникают проблемы производительности. Основные подходы оптимизации:
Для точечных данных используется библиотека
Leaflet.markercluster.
const markers = L.markerClusterGroup();
L.geoJSON(data, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng);
}
}).eachLayer(function (layer) {
markers.addLayer(layer);
});
map.addLayer(markers);
Кластеризация уменьшает количество DOM-элементов и ускоряет отрисовку.
Сложные полигоны можно предварительно упрощать на сервере или с использованием библиотек типа Turf.js. Это снижает количество координатных точек и ускоряет рендеринг.
Leaflet позволяет модифицировать GeoJSON на этапе загрузки.
coordsToLatLngL.geoJSON(data, {
coordsToLatLng: function (coords) {
return new L.LatLng(coords[1], coords[0]);
}
}).addTo(map);
Эта функция полезна при нестандартных форматах координат или интеграции с внешними системами.
geometryToLayerПозволяет полностью контролировать создание слоёв:
L.geoJSON(data, {
geometryToLayer: function (feature, latlng) {
if (feature.geometry.type === 'Point') {
return L.circle(latlng, { radius: 500 });
}
}
}).addTo(map);
Помимо fetch, часто используется
XMLHttpRequest или библиотеки вроде Axios.
axios.get('/data/map.geojson')
.then(response => {
L.geoJSON(response.data).addTo(map);
});
Такие подходы полезны в проектах с единым HTTP-слоем или централизованной обработкой запросов.
Leaflet позволяет комбинировать данные из разных источников в один слой.
const layer = L.geoJSON().addTo(map);
fetch('/data/a.geojson')
.then(r => r.json())
.then(data => layer.addData(data));
fetch('/data/b.geojson')
.then(r => r.json())
.then(data => layer.addData(data));
Такой подход применяется при агрегации данных из различных сервисов или слоёв аналитики.
Секция properties используется для хранения
бизнес-данных объектов. Leaflet не накладывает ограничений на структуру
этих данных, что позволяет использовать их для визуализации и
логики.
L.geoJSON(data, {
onEachFeature: function (feature, layer) {
const props = feature.properties;
const html = `
<div>
<strong>${props.name}</strong><br>
Категория: ${props.category}
</div>
`;
layer.bindPopup(html);
}
}).addTo(map);
GeoJSON использует систему WGS84 (EPSG:4326). Leaflet также работает в этой системе по умолчанию. Однако при получении данных из других систем координат требуется предварительная трансформация.
Это обычно выполняется на сервере с использованием GDAL или Proj4. В
клиентской части возможна интеграция proj4leaflet,
позволяющая отображать нестандартные проекции.
При работе с внешними GeoJSON источниками важно учитывать обработку ошибок:
fetch('/data/map.geojson')
.then(response => {
if (!response.ok) {
throw new Error('Ошибка загрузки данных');
}
return response.json();
})
.then(data => {
L.geoJSON(data).addTo(map);
})
.catch(error => {
console.error(error);
});
Некорректный JSON или недоступный ресурс могут полностью прервать отрисовку слоя, поэтому обработка ошибок становится частью архитектуры слоя данных.
GeoJSON часто используется совместно с тайловыми слоями, WMS и кастомными оверлеями.
L.tileLayer(urlTemplate).addTo(map);
const geoLayer = L.geoJSON(data, {
style: { color: 'green' }
}).addTo(map);
Такое комбинирование позволяет накладывать векторные данные поверх растровых карт, создавая многослойную визуализацию пространственной информации.