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

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

Основная идея заключается в формализации «доступности» через геометрию: если объект находится внутри определённой области вокруг источника, он считается достижимым.


Геометрическая модель досягаемости

В Turf.js досягаемость обычно моделируется через радиусное расстояние от точки-источника. Такой подход опирается на предположение евклидовой плоскости (или её приближение на малых расстояниях).

Ключевая функция — построение круга вокруг точки:

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

const center = turf.point([71.4304, 51.1281]); // координаты точки
const radius = 5; // километры

const reachableArea = turf.circle(center, radius, {
  steps: 64,
  units: "kilometers"
});

Функция turf.circle формирует полигон, аппроксимирующий окружность. Этот полигон и есть базовая зона досягаемости.

Смысл параметров:

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

Досягаемость через буферные зоны

Альтернативный способ — использование буфера вокруг точки или линии. Буферная зона расширяет геометрию на заданное расстояние.

const point = turf.point([71.4304, 51.1281]);

const buffer = turf.buffer(point, 3, {
  units: "kilometers"
});

Буфер отличается от окружности тем, что может применяться не только к точкам, но и к линиям и полигонам.

Для линейных объектов это особенно важно: досягаемость трассы или маршрута формируется как коридор вокруг линии.

const line = turf.lineString([
  [71.0, 51.0],
  [71.5, 51.2]
]);

const corridor = turf.buffer(line, 2, {
  units: "kilometers"
});

Проверка принадлежности объектов зоне досягаемости

После построения зоны необходимо определить, какие объекты попадают внутрь неё. Для этого используется проверка попадания точки в полигон.

const target = turf.point([71.45, 51.13]);

const isReachable = turf.booleanPointInPolygon(target, reachableArea);

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

При работе с множеством объектов применяется фильтрация:

const points = turf.featureCollection([
  turf.point([71.44, 51.12]),
  turf.point([71.50, 51.20]),
  turf.point([72.00, 51.50])
]);

const reachablePoints = turf.pointsWithinPolygon(points, reachableArea);

Моделирование досягаемости для набора объектов

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

Процесс включает три этапа:

  1. Построение зоны досягаемости
  2. Формирование набора объектов
  3. Пространственная фильтрация
const center = turf.point([71.4304, 51.1281]);

const serviceArea = turf.circle(center, 10, {
  steps: 128,
  units: "kilometers"
});

const hospitals = turf.featureCollection([
  turf.point([71.40, 51.10]),
  turf.point([71.60, 51.20]),
  turf.point([72.10, 51.30])
]);

const availableHospitals = turf.pointsWithinPolygon(hospitals, serviceArea);

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


Расстояние как основа досягаемости

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

const a = turf.point([71.4304, 51.1281]);
const b = turf.point([71.50, 51.20]);

const distance = turf.distance(a, b, { units: "kilometers" });

Далее применяется пороговое условие:

const threshold = 5;

const reachable = distance <= threshold;

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


Комбинированная модель досягаемости

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

const center = turf.point([71.4304, 51.1281]);

const rawCandidates = turf.featureCollection([
  turf.point([71.42, 51.11]),
  turf.point([71.70, 51.40]),
  turf.point([72.00, 51.80])
]);

const area = turf.buffer(center, 8, { units: "kilometers" });

const filtered = turf.pointsWithinPolygon(rawCandidates, area);

При необходимости добавляется дополнительная проверка расстояния для уточнения границ.


Досягаемость через сеточную аппроксимацию

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

const bbox = turf.bbox(area);
const cellSide = 1; // километры

const grid = turf.pointGrid(bbox, cellSide, {
  units: "kilometers"
});

const reachableGrid = turf.pointsWithinPolygon(grid, area);

Такой подход позволяет:

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

Учет геометрических ограничений

Стандартные функции Turf.js работают в евклидовой модели, что накладывает ограничения на точность:

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

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


Сравнение подходов моделирования

Окружность (turf.circle)

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

Буфер (turf.buffer)

  • универсальность (точки, линии, полигоны)
  • подходит для зон влияния объектов

Расстояние (turf.distance)

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

Сеточная модель

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

Пространственные пересечения как расширение модели

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

const areaA = turf.circle(turf.point([71.4, 51.1]), 5, { units: "kilometers" });
const areaB = turf.circle(turf.point([71.5, 51.15]), 5, { units: "kilometers" });

const overlap = turf.intersect(areaA, areaB);

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


Итеративное расширение зоны досягаемости

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

let area = turf.circle(center, 2, { units: "kilometers" });

for (let i = 0; i < 3; i++) {
  area = turf.buffer(area, 2, { units: "kilometers" });
}

Такой подход моделирует поэтапное расширение доступности, например, влияние инфраструктуры во времени или рост зоны обслуживания.