Измерение площадей

В интерактивных картографических приложениях на базе MapLibre GL JS измерение площадей опирается на геометрические вычисления над полигонами в географических координатах. Основная задача заключается в корректном определении площади замкнутого контура, заданного набором координат широты и долготы, с учётом проекции и кривизны поверхности Земли.

Геометрическая модель веб-карты обычно работает в проекции Web Mercator, однако сами вычисления площади редко выполняются напрямую в экранных координатах. Причина заключается в искажениях, возникающих при проецировании сферы на плоскость. Поэтому для расчёта площади применяются геодезические алгоритмы.

Геометрическая основа расчёта

Полигон в географическом смысле представляет собой набор координат:

  • внешний контур (outer ring)
  • внутренние отверстия (holes), если они присутствуют

Каждая координата имеет вид:

[долгота, широта]

Для вычисления площади используется один из подходов:

  • сферическая модель Земли
  • эллипсоидальные приближения
  • плоская аппроксимация (для малых объектов)

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

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

В экосистеме MapLibre GL JS стандартным инструментом гео-вычислений является библиотека Turf.js. Она предоставляет функцию area, которая принимает GeoJSON-полигон и возвращает площадь в квадратных метрах.

Структура GeoJSON-полигона:

const polygon = {
  type: "Feature",
  geometry: {
    type: "Polygon",
    coordinates: [
      [
        [37.62, 55.75],
        [37.63, 55.75],
        [37.63, 55.76],
        [37.62, 55.76],
        [37.62, 55.75]
      ]
    ]
  }
};

Расчёт площади:

import * as turf from "@turf/turf";

const area = turf.area(polygon);
console.log(area);

Результат возвращается в квадратных метрах и может быть преобразован в другие единицы измерения.

Интеграция расчёта площади в MapLibre GL JS

В MapLibre GL JS данные обычно поступают в виде GeoJSON-источников. Полигон может быть добавлен как source, а затем отображён через слой fill.

Пример добавления источника:

map.addSource("parcel", {
  type: "geojson",
  data: polygon
});

Отображение полигона:

map.addLayer({
  id: "parcel-fill",
  type: "fill",
  source: "parcel",
  paint: {
    "fill-color": "#3b82f6",
    "fill-opacity": 0.4
  }
});

Расчёт площади выполняется отдельно от рендеринга карты, но может быть синхронизирован с событиями изменения данных.

Обновление площади при редактировании геометрии

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

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

function updateArea(geojson) {
  const calculated = turf.area(geojson);
  return calculated;
}

map.on("draw.update", (e) => {
  const updatedPolygon = e.features[0];
  const area = updateArea(updatedPolygon);
  console.log("Площадь:", area);
});

В реальных приложениях это значение может отображаться в интерфейсе или использоваться для бизнес-логики, например, расчёта стоимости участка.

Работа с отверстиями в полигонах

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

const polygonWithHole = {
  type: "Feature",
  geometry: {
    type: "Polygon",
    coordinates: [
      [
        [0, 0],
        [10, 0],
        [10, 10],
        [0, 10],
        [0, 0]
      ],
      [
        [2, 2],
        [8, 2],
        [8, 8],
        [2, 8],
        [2, 2]
      ]
    ]
  }
};

Внутренний контур автоматически вычитается при расчёте площади через Turf.js, что соответствует геометрическому определению «полигон с вырезом».

Масштаб и точность вычислений

Точность расчёта площади зависит от нескольких факторов:

  • размер объекта на карте
  • выбранная модель Земли
  • плотность координат контура
  • самопересечения полигона

При увеличении масштаба карты визуальная точность возрастает, однако геометрическая модель остаётся независимой от zoom-уровня. Это важно: площадь не должна изменяться при изменении масштаба отображения.

Обработка сложных геометрий

Сложные полигоны могут содержать:

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

Пример MultiPolygon:

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

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

Производительность вычислений

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

  • дебаунс пересчёта при редактировании
  • кэширование результатов для неизменённых геометрий
  • использование Web Worker для вычислений
  • упрощение геометрии (simplification)

Пример дебаунса:

let timeout;

function scheduleAreaUpdate(feature) {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
    const area = turf.area(feature);
    console.log(area);
  }, 200);
}

Единицы измерения и преобразования

Базовая единица результата — квадратный метр. Для отображения в пользовательском интерфейсе часто применяются преобразования:

  • м² → км² (деление на 1 000 000)
  • м² → гектары (деление на 10 000)
function toHectares(areaInSqMeters) {
  return areaInSqMeters / 10000;
}

Такие преобразования выполняются после геодезического расчёта и не влияют на точность исходного значения.

Связь с координатными системами

MapLibre GL JS использует EPSG:3857 для визуализации, однако входные данные чаще представлены в EPSG:4326. Это разделение означает:

  • отображение выполняется в Web Mercator
  • вычисления площади — в географических координатах
  • трансформация происходит на уровне библиотеки рендеринга, а не геометрии

Такое разделение предотвращает накопление ошибок при масштабировании и вращении карты.

Типовые ошибки при измерении площади

На практике встречаются характерные проблемы:

  • незамкнутый контур полигона
  • перепутанный порядок координат (lat/lon вместо lon/lat)
  • самопересечения, приводящие к некорректной геометрии
  • отсутствие нормализации данных перед расчётом

Корректная подготовка GeoJSON является обязательным этапом перед вычислением площади, иначе результат может быть математически нестабилен или искажен.