Досягаемость в геоинформационных задачах представляет собой вычисление области, в пределах которой объект или набор объектов считается доступным при заданных ограничениях расстояния. В контексте 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);
В задачах анализа инфраструктуры часто требуется определить все объекты, находящиеся в радиусе обслуживания.
Процесс включает три этапа:
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" });
}
Такой подход моделирует поэтапное расширение доступности, например, влияние инфраструктуры во времени или рост зоны обслуживания.