В Mapbox GL JS геометрия полигонов описывается через стандарт
GeoJSON. Основная структура — объект типа Polygon,
состоящий из массива координатных колец.
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[lng, lat],
[lng, lat],
[lng, lat],
[lng, lat]
]
]
}
}
Первое кольцо определяет внешний контур. Последующие кольца (если
присутствуют) задают отверстия внутри полигона. Важно учитывать, что
координаты задаются в порядке [долгота, широта], а не
наоборот.
Многополигональная геометрия (MultiPolygon) используется
для объектов, состоящих из нескольких несвязанных областей.
В Mapbox GL JS полигон визуализируется через слой типа
fill.
map.addSource('region', {
type: 'geojson',
data: polygonGeoJSON
});
map.addLayer({
id: 'region-fill',
type: 'fill',
source: 'region',
paint: {
'fill-color': '#3b82f6',
'fill-opacity': 0.4
}
});
Для обводки используется отдельный слой line:
map.addLayer({
id: 'region-outline',
type: 'line',
source: 'region',
paint: {
'line-color': '#1e3a8a',
'line-width': 2
}
});
Геометрия хранится в формате WGS84, но визуализация происходит в проекции Web Mercator, что важно учитывать при вычислении площади.
Площадь полигона на карте не может корректно вычисляться через обычные планиметрические формулы в экранных координатах, поскольку:
Поэтому применяются геодезические алгоритмы, учитывающие кривизну Земли.
Библиотека Turf.js предоставляет функцию area, которая
вычисляет площадь геометрий GeoJSON на сфере.
import { area } from '@turf/turf';
const polygon = {
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [
[
[30.1, 59.9],
[30.2, 59.9],
[30.2, 60.0],
[30.1, 60.0],
[30.1, 59.9]
]
]
}
};
const result = area(polygon);
Результат возвращается в квадратных метрах.
Алгоритм вычисления площади в Turf.js основан на сферической триангуляции:
Ключевой момент — использование радиана вместо градусной системы внутри вычислений.
Для корректного расчёта важно соблюдать:
Незамкнутые полигоны приводят к некорректной интерпретации геометрии или автоматическому замыканию в сторонних библиотеках.
Полигон может содержать внутренние вырезы:
const polygonWithHole = {
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [
[
[0, 0],
[10, 0],
[10, 10],
[0, 10],
[0, 0]
],
[
[3, 3],
[7, 3],
[7, 7],
[3, 7],
[3, 3]
]
]
}
};
При вычислении площади внутренние кольца автоматически вычитаются из общей площади внешнего контура.
Типичный сценарий работы включает:
map.on('click', () => {
const data = map.getSource('region')._data;
const polygonArea = area(data);
});
В реальных приложениях доступ к _data нежелателен;
предпочтительно хранить GeoJSON отдельно и синхронизировать его с
источником карты.
При использовании mapbox-gl-draw геометрия может
изменяться пользователем в реальном времени. В этом случае площадь
пересчитывается при каждом событии изменения:
map.on('draw.update', updateArea);
map.on('draw.create', updateArea);
map.on('draw.delete', updateArea);
function updateArea(e) {
const features = draw.getAll();
const total = area(features);
}
Подобный подход используется в геоинформационных редакторах и кадастровых системах.
Частые источники некорректных значений:
1. Перепутанный порядок координат Использование
[lat, lng] вместо [lng, lat] приводит к
искажённой геометрии.
2. Незамкнутый контур Отсутствие повторения первой точки в конце массива координат.
3. Смешение проекций Передача экранных координат вместо географических.
4. Самопересекающиеся полигоны Геометрия с пересечениями может давать нестабильный результат площади.
При обработке множества объектов вычисление площади становится затратной операцией.
Оптимизационные подходы:
FeatureCollectionСтруктура MultiPolygon объединяет несколько независимых
областей:
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[0, 0],
[5, 0],
[5, 5],
[0, 5],
[0, 0]
]
],
[
[
[10, 10],
[15, 10],
[15, 15],
[10, 15],
[10, 10]
]
]
]
}
}
Площадь такого объекта вычисляется как сумма площадей всех полигонов внутри структуры.
В Mapbox GL JS визуальное восприятие площади зависит от zoom-уровня:
Это приводит к ошибочному восприятию размеров без численного расчёта.
Turf.js возвращает площадь в квадратных метрах, однако в интерфейсах часто применяются преобразования:
const meters = area(polygon);
const km = meters / 1_000_000;
const hectares = meters / 10_000;
Расчёт площади в Mapbox GL JS применяется в:
Геометрия становится базовым слоем для дальнейших пространственных вычислений, включая пересечения, буферы и кластеризацию.