Проверка наложения полигонов

Работа с полигонами в геоинформационных системах требует точных операций определения пересечений, вложенности и частичного наложения. В библиотеке Turf.js реализован набор функций, позволяющих выполнять анализ геометрических отношений между объектами на основе стандарта GeoJSON.

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


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

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

  • Полное совпадение областей (идентичные полигоны)
  • Частичное пересечение (overlap)
  • Вложенность одного полигона в другой (containment)
  • Отсутствие пересечения

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


Основные методы Turf.js для анализа наложений

booleanOverlap

Функция booleanOverlap проверяет, имеют ли два полигона общую площадь пересечения, но ни один из них не содержится полностью в другом.

import booleanOverlap from "@turf/boolean-overlap";

const poly1 = {
  type: "Feature",
  geometry: {
    type: "Polygon",
    coordinates: [[
      [0, 0],
      [4, 0],
      [4, 4],
      [0, 4],
      [0, 0]
    ]]
  }
};

const poly2 = {
  type: "Feature",
  geometry: {
    type: "Polygon",
    coordinates: [[
      [2, 2],
      [6, 2],
      [6, 6],
      [2, 6],
      [2, 2]
    ]]
  }
};

booleanOverlap(poly1, poly2); // true

Ключевое свойство: возвращает true только при частичном перекрытии площадей.


booleanIntersects

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

import booleanIntersects from "@turf/boolean-intersects";

booleanIntersects(poly1, poly2);

Она возвращает true в случаях:

  • пересечения границ
  • частичного наложения
  • касания по ребру
  • точечного контакта

Таким образом, booleanIntersects шире по смыслу, чем booleanOverlap.


booleanContains

Для проверки полного включения одного полигона в другой используется booleanContains.

import booleanContains from "@turf/boolean-contains";

booleanContains(poly1, poly2);

Если poly1 полностью содержит poly2, функция возвращает true. Это важно для различения сценариев:

  • включение (containment)
  • частичное наложение (overlap)
  • касание (touch)

booleanWithin

Обратная операция к booleanContains:

import booleanWithin from "@turf/boolean-within";

booleanWithin(poly2, poly1);

Используется для проверки, находится ли один полигон строго внутри другого.


Практическая логика различения типов пересечений

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

Ситуация Метод Результат
Частичное перекрытие booleanOverlap true
Любое пересечение booleanIntersects true
Полное включение A в B booleanContains(A, B) true
Полное включение B в A booleanWithin(B, A) true

Обработка сложных полигонов

Реальные геометрии часто содержат:

  • самопересечения
  • некорректный порядок координат
  • дубликаты точек

Для повышения стабильности проверки используется предварительная нормализация.

Проверка и очистка геометрии

import cleanCoords from "@turf/clean-coords";

const cleaned = cleanCoords(poly1);

Также применяется:

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

Учет дыр (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]
      ]
    ]
  }
};

При проверке наложения важно учитывать, что:

  • внешний контур определяет основную площадь
  • внутренние кольца исключают области из анализа
  • пересечение может происходить как с внешним контуром, так и с «дырой»

Геометрическая интерпретация пересечения

В Turf.js пересечение полигонов вычисляется через:

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

Внутри booleanOverlap используется комбинация топологических правил:

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

Типовые ошибки при проверке наложений

Ошибка 1: использование booleanIntersects вместо booleanOverlap

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

Ошибка 2: отсутствие нормализации координат

Некорректные полигоны могут давать:

  • нестабильные результаты
  • ложные отрицания пересечений

Ошибка 3: игнорирование вложенности

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


Комбинированные проверки наложения

В реальных системах часто применяется каскадная логика:

import booleanIntersects from "@turf/boolean-intersects";
import booleanContains from "@turf/boolean-contains";
import booleanOverlap from "@turf/boolean-overlap";

function analyzeRelation(a, b) {
  if (!booleanIntersects(a, b)) return "no_intersection";

  if (booleanContains(a, b)) return "a_contains_b";
  if (booleanContains(b, a)) return "b_contains_a";

  if (booleanOverlap(a, b)) return "partial_overlap";

  return "touch_or_point_intersection";
}

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


Производительность при массовых проверках

При работе с большим количеством полигонов ключевым фактором становится сложность попарных проверок.

Оптимизационные подходы:

  • предварительное ограничение по bounding box
  • пространственные индексы (R-tree)
  • фильтрация по площади перед точной проверкой

Bounding box-проверка:

import bbox from "@turf/bbox";
import booleanIntersects from "@turf/boolean-intersects";

function fastCheck(a, b) {
  const [minX1, minY1, maxX1, maxY1] = bbox(a);
  const [minX2, minY2, maxX2, maxY2] = bbox(b);

  const overlap =
    minX1 <= maxX2 &&
    maxX1 >= minX2 &&
    minY1 <= maxY2 &&
    maxY1 >= minY2;

  if (!overlap) return false;

  return booleanIntersects(a, b);
}

Практическое применение в GIS-задачах

Проверка наложения полигонов используется в:

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

Во всех случаях ключевым является точное определение типа пересечения, а не только факт его наличия.