Определение касания геометрий

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

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


Топологическая интерпретация касания

Два геометрических объекта считаются касающимися, если выполняются следующие условия:

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

Для линейных объектов касание часто выражается через общую конечную точку. Для полигонов — через совпадение ребра или вершины без наложения внутренних областей.


Основные типы касания

Касание точка–линия

Точка может лежать на линии, не являясь частью её внутренней структуры. В Turf.js это проверяется через:

turf.booleanPointOnLine(point, lineString)

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


Касание линия–линия

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

Для базовой проверки используется:

turf.booleanIntersects(line1, line2)

Однако данный метод фиксирует как касание, так и пересечение, поэтому для выделения именно касания требуется дополнительная фильтрация по типу пересечения.

Более строгая логика включает проверку количества общих точек и отсутствия перекрытия сегментов.


Касание полигон–полигон

Касание полигонов определяется через соприкосновение границ без пересечения внутренних областей:

turf.booleanTouches(polygon1, polygon2)

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


Функция turf.booleanTouches

Основной инструмент Turf.js для определения касания геометрий — предикат:

turf.booleanTouches(feature1, feature2)

Функция поддерживает комбинации геометрий:

  • Point / LineString
  • Point / Polygon
  • LineString / LineString
  • LineString / Polygon
  • Polygon / Polygon

Возвращаемое значение:

  • true — геометрии касаются;
  • false — касания нет или присутствует пересечение внутренних областей.

Логика работы алгоритма касания

Внутренне проверка касания включает несколько этапов:

  1. Нормализация входных GeoJSON объектов.
  2. Выделение границ (boundary) геометрий.
  3. Проверка пересечения границ.
  4. Проверка отсутствия пересечения внутренних областей.
  5. Исключение случаев полного совпадения (identical geometries).

Математически касание можно выразить через множества:

  • A ∩ B ≠ ∅ (существует пересечение)
  • interior(A) ∩ interior(B) = ∅

Примеры касания геометрий

Касание двух полигонов по ребру

const poly1 = turf.polygon([[
  [0, 0], [4, 0], [4, 4], [0, 4], [0, 0]
]]);

const poly2 = turf.polygon([[
  [4, 0], [8, 0], [8, 4], [4, 4], [4, 0]
]]);

turf.booleanTouches(poly1, poly2);

Результат: true, так как полигоны имеют общую границу по линии x = 4.


Касание линии и полигона

const line = turf.lineString([[0, 2], [4, 2]]);
const poly = turf.polygon([[
  [4, 0], [6, 0], [6, 4], [4, 4], [4, 0]
]]);

turf.booleanTouches(line, poly);

Результат: true, если линия касается полигона в точке или вдоль границы, но не входит внутрь области.


Касание точек и линий

const point = turf.point([2, 2]);
const line = turf.lineString([[0, 2], [4, 2]]);

turf.booleanPointOnLine(point, line);

Результат: true, так как точка лежит на линии.


Отличие касания от пересечения

Тип отношения Граница пересечения Пересечение внутренних областей Результат
Касание Да Нет true
Пересечение Да Да true
Разделение Нет Нет false

В Turf.js функция booleanIntersects не различает касание и пересечение, поэтому для строгой топологической классификации требуется комбинированный анализ.


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

Построение дорожных сетей

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

Анализ границ земельных участков

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

Геозонирование

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


Ограничения и точность вычислений

Геометрические операции в Turf.js зависят от вычислений в плоской проекции. Основные ограничения:

  • ошибки округления при работе с координатами;
  • приближённое представление криволинейных границ;
  • влияние плотности вершин в LineString и Polygon;
  • возможные ложные касания при совпадении координат с плавающей точкой.

Для повышения точности применяется:

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

Сложные случаи касания

Касание в одной точке

Минимальный случай — две геометрии имеют единственную общую вершину. Например, полигоны, соприкасающиеся углом.

Касание по сегменту

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

Почти касание

При численных погрешностях координаты могут не совпадать идеально, но находиться в пределах допустимого расстояния. В Turf.js для этого используется предварительная обработка через буферизацию:

turf.buffer(geometry, 0.0001)

Композиция касаний в пространственном анализе

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

  • построения графов смежности;
  • кластеризации геометрических объектов;
  • определения границ регионов влияния;
  • анализа топологических сетей.

Касание часто выступает промежуточным уровнем между полной независимостью объектов и их пересечением.


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

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

const touches = turf.booleanTouches(a, b);
const intersects = turf.booleanIntersects(a, b);

const strictTouch = touches && !turf.booleanOverlap(a, b);

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


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

Каждая геометрия в Turf.js может быть представлена через:

  • interior (внутренность)
  • boundary (граница)

Касание определяется как пересечение границ при отсутствии пересечения внутренних областей:

A ∩ B ≠ ∅
interior(A) ∩ interior(B) = ∅

Это определение лежит в основе большинства пространственных предикатов касания.