Area полигонов

Представление полигона в GeoJSON

В Mapbox GL JS геометрия полигонов описывается через стандарт GeoJSON. Основная структура — объект типа Polygon, состоящий из массива координатных колец.

{
  "type": "Feature",
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [lng, lat],
        [lng, lat],
        [lng, lat],
        [lng, lat]
      ]
    ]
  }
}

Первое кольцо определяет внешний контур. Последующие кольца (если присутствуют) задают отверстия внутри полигона. Важно учитывать, что координаты задаются в порядке [долгота, широта], а не наоборот.

Многополигональная геометрия (MultiPolygon) используется для объектов, состоящих из нескольких несвязанных областей.


Отображение полигонов через fill-layer

В 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, что важно учитывать при вычислении площади.


Геодезическая и проекционная площадь

Площадь полигона на карте не может корректно вычисляться через обычные планиметрические формулы в экранных координатах, поскольку:

  • Web Mercator искажает площади
  • масштаб зависит от широты
  • геометрия задана на сфере (WGS84)

Поэтому применяются геодезические алгоритмы, учитывающие кривизну Земли.


Использование Turf.js для расчёта площади

Библиотека 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 основан на сферической триангуляции:

  • полигон разбивается на треугольники
  • каждый треугольник рассматривается как сферический
  • суммируются ориентированные площади

Ключевой момент — использование радиана вместо градусной системы внутри вычислений.


Особенности координатного порядка и замыкания кольца

Для корректного расчёта важно соблюдать:

  • первое и последнее значение координат должны совпадать (замкнутое кольцо)
  • порядок обхода влияет на знак площади в некоторых алгоритмах
  • внешнее кольцо обычно задаётся против часовой стрелки, внутренние — по часовой

Незамкнутые полигоны приводят к некорректной интерпретации геометрии или автоматическому замыканию в сторонних библиотеках.


Площадь с отверстиями (holes)

Полигон может содержать внутренние вырезы:

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]
      ]
    ]
  }
};

При вычислении площади внутренние кольца автоматически вычитаются из общей площади внешнего контура.


Интеграция Mapbox GL JS и Turf.js

Типичный сценарий работы включает:

  1. Отрисовку полигона на карте
  2. Получение GeoJSON из источника
  3. Передачу данных в Turf
  4. Вывод площади в интерфейс
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
  • вычисление площади на серверной стороне
  • использование Web Worker для изоляции вычислений

Работа с MultiPolygon

Структура 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-уровня:

  • при малом масштабе полигоны выглядят сжатыми
  • при увеличении zoom сохраняется географическая площадь, но увеличивается экранная

Это приводит к ошибочному восприятию размеров без численного расчёта.


Приведение результата к удобным единицам

Turf.js возвращает площадь в квадратных метрах, однако в интерфейсах часто применяются преобразования:

  • м² для малых объектов
  • км² для регионов
  • гектары для сельскохозяйственных участков
const meters = area(polygon);
const km = meters / 1_000_000;
const hectares = meters / 10_000;

Использование в аналитических задачах

Расчёт площади в Mapbox GL JS применяется в:

  • градостроительном анализе
  • мониторинге земельных участков
  • оценке зон покрытия сервисов
  • анализе природных территорий
  • логистических моделях распределения ресурсов

Геометрия становится базовым слоем для дальнейших пространственных вычислений, включая пересечения, буферы и кластеризацию.