Операция определения принадлежности точки области, заданной полигоном, относится к базовым задачам вычислительной геометрии и геоинформационных систем. В контексте Web-GIS и клиентских приложений JavaScript эта задача часто решается с использованием библиотеки Turf.js, предоставляющей набор геопространственных функций, работающих с GeoJSON-структурами.
Полигон в Turf.js представляет собой объект формата GeoJSON с типом
Polygon или MultiPolygon, а точка — объект
типа Point. Проверка выполняется на основе алгоритма
лучевого сканирования (ray casting) или его оптимизированных вариаций,
скрытых внутри реализации библиотеки.
Корректная проверка требует соблюдения строгого формата входных данных.
Точка:
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [lng, lat]
}
}
Полигон:
{
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[lng, lat],
[lng, lat],
[lng, lat],
[lng, lat],
[lng, lat]
]
]
}
}
Первый массив координат определяет внешний контур. Последующие массивы (если присутствуют) задают внутренние вырезы (holes), которые исключаются из области принадлежности.
Для проверки попадания точки в полигон используется функция:
turf.booleanPointInPolygon(point, polygon)
Минимальный пример использования:
import * as turf from "@turf/turf";
const point = turf.point([76.8897, 43.2389]);
const polygon = turf.polygon([[
[76.8800, 43.2400],
[76.9000, 43.2400],
[76.9000, 43.2300],
[76.8800, 43.2300],
[76.8800, 43.2400]
]]);
const result = turf.booleanPointInPolygon(point, polygon);
Результат true означает принадлежность точки области
полигона, false — отсутствие принадлежности.
Внутренний механизм проверки основан на классическом алгоритме ray casting:
Формально логика может быть представлена как булева функция:
P = (N_{intersections} = 1)
где P — принадлежность точки,
N_intersections — количество пересечений луча с границами
полигона.
Для сложных геометрий используется тип MultiPolygon,
представляющий набор независимых полигонов.
const multiPolygon = turf.multiPolygon([
[[
[76.88, 43.24],
[76.90, 43.24],
[76.90, 43.23],
[76.88, 43.23],
[76.88, 43.24]
]],
[[
[76.91, 43.24],
[76.93, 43.24],
[76.93, 43.23],
[76.91, 43.23],
[76.91, 43.24]
]]
]);
const result = turf.booleanPointInPolygon(point, multiPolygon);
Проверка выполняется по каждому полигону набора до первого положительного результата.
Особое значение имеет поведение при попадании точки строго на границу полигона. В Turf.js предусмотрен параметр:
turf.booleanPointInPolygon(point, polygon, { ignoreBoundary: false })
Поведение:
ignoreBoundary: false — точка на границе считается
принадлежащей полигонуignoreBoundary: true — точка на границе считается вне
полигонаЭто различие критично в задачах пространственной аналитики, где граница может трактоваться как отдельная зона или исключаться из расчётов.
Turf.js использует стандарт GeoJSON, где координаты задаются в порядке:
[longitude, latitude]
Ошибка в порядке координат приводит к геометрическим искажениям и некорректным результатам проверки.
Особое внимание требуется при работе с:
Turf.js предполагает входные данные именно в WGS84.
Алгоритм проверки принадлежности точки имеет линейную сложность относительно количества рёбер полигона:
T(n) = O(n)
где n — число вершин внешнего и внутренних контуров.
При больших полигонах или массовых проверках точек возникает необходимость оптимизации:
Turf.js предоставляет вспомогательную функцию предварительной проверки через bounding box:
turf.bboxPolygon
turf.booleanWithin
Перед полной проверкой используется упрощённая проверка попадания в ограничивающий прямоугольник:
const bbox = turf.bbox(polygon);
const isInsideBBox = turf.booleanPointInPolygon(point, turf.bboxPolygon(bbox));
Если точка не попадает в bbox, дальнейшие вычисления исключаются.
Полигон может содержать внутренние области исключения (holes). Структура координат:
[
[outer ring],
[hole 1],
[hole 2]
]
Логика проверки:
Формально:
P = P_{outer} (P_{hole1} P_{hole2} … P_{holen})
Операция принадлежности точки полигону используется в следующих сценариях:
В системах реального времени проверка часто выполняется на потоке координат GPS. В этом случае важна минимизация вычислений:
Каждая точка обрабатывается независимо, что позволяет масштабировать вычисления горизонтально.
Типичные проблемы при использовании функции:
Turf.js частично нормализует входные данные, но корректность геометрии остаётся ответственностью слоя подготовки данных.
Проверка принадлежности точки полигону тесно связана с другими функциями Turf.js:
turf.booleanWithin — проверка вложенности
геометрийturf.intersect — вычисление пересечений полигоновturf.union — объединение областейturf.buffer — расширение геометрий на заданное
расстояниеЭти операции часто комбинируются для построения сложных пространственных правил и аналитических моделей.