Разрезание линий

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

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

Линия в Turf.js представляет собой последовательность точек, соединённых отрезками:

const line = turf.lineString([
  [30.5, 50.5],
  [31.0, 51.0],
  [32.0, 51.5]
]);

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

Разрезание линии по точке

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

Поиск ближайшей точки на линии

const pt = turf.point([31.2, 51.1]);
const snapped = turf.nearestPointOnLine(line, pt);

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

Разделение через индекс сегмента

После определения позиции на линии можно выполнить разрез:

const sliced = turf.lineSlice(line.geometry.coordinates[0], snapped, line);

В результате получается новая линия от начальной точки до точки разреза. Для получения второй части используется обратное разрезание:

const secondPart = turf.lineSlice(snapped, line.geometry.coordinates[line.geometry.coordinates.length - 1], line);

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

Разрезание по длине линии

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

Сегмент по расстоянию

const segment = turf.lineSliceAlong(line, 2, 5, { units: 'kilometers' });

Функция извлекает часть линии между 2 и 5 километрами от начала. При этом учитывается кривизна земной поверхности, если используется соответствующий режим измерений.

Практическое применение

  • выделение участка дороги между километровыми отметками
  • построение фрагментов маршрута навигации
  • анализ сегментов трека GPS

Разрезание линии точкой пересечения

При работе с пересекающимися объектами используется геометрическое пересечение. Turf.js предоставляет инструменты для нахождения точек пересечения и последующего разбиения линии.

Определение пересечения

const intersect = turf.lineIntersect(line1, line2);

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

Разбиение линии по пересечениям

Алгоритмически процесс выглядит следующим образом:

  1. Получение всех точек пересечения
  2. Сортировка точек вдоль линии
  3. Последовательное применение разрезов
const points = turf.lineIntersect(line1, line2);

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

const withDistances = points.features.map(p => ({
  point: p,
  dist: turf.length(turf.lineSlice(line1.geometry.coordinates[0], p, line1))
}));

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

Полное разбиение линии на сегменты

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

Ручной метод разбиения

const coords = line.geometry.coordinates;

const segments = [];

for (let i = 0; i < coords.length - 1; i++) {
  segments.push(
    turf.lineString([coords[i], coords[i + 1]])
  );
}

Этот метод работает на уровне геометрии без учёта расстояний и кривизны.

Разрезание с учётом полигона

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

Использование пересечения с полигоном

const clipped = turf.lineSplit(line, polygon);

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

Такой подход применяется в:

  • геоаналитике маршрутов
  • расчёте участков дорог в административных зонах
  • выделении сегментов внутри заданных территорий

Алгоритмические особенности lineSplit

Функция разбиения линии по геометрии реализует несколько этапов:

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

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

Обработка MultiLineString

Если исходная геометрия представляет собой набор линий, разрезание применяется к каждой отдельно:

const result = turf.flattenEach(multiLine, function (feature) {
  return turf.lineSplit(feature, polygon);
});

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

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

Turf.js поддерживает расчёты на сфере, что влияет на результаты разрезания при использовании расстояний.

Основные моменты:

  • координаты интерпретируются как WGS84
  • расстояния вычисляются по дуге, а не по плоскости
  • результаты зависят от выбранных единиц измерения
turf.length(line, { units: 'miles' });

Несоответствие единиц измерения часто приводит к логическим ошибкам при разрезании по длине.

Оптимизация разрезания длинных линий

При работе с большими геометриями важно снижать вычислительную нагрузку:

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

Упрощение геометрии уменьшает количество вычисляемых пересечений, но может влиять на точность результата.

Комбинированные сценарии разрезания

На практике часто комбинируются несколько методов:

  • разрезание по полигонам
  • последующее деление по расстоянию
  • дополнительная фильтрация по пересечениям

Типовой сценарий обработки маршрута:

  1. обрезка линии границей региона
  2. деление на километровые сегменты
  3. выделение пересечений с инфраструктурой

Такой подход позволяет получать аналитически удобные фрагменты для последующей обработки в GIS-системах.