Линейная геометрия в GeoJSON представляет собой последовательность координат, соединённых отрезками, и при работе с такими структурами часто возникает необходимость разбиения линии на равные или логически обусловленные сегменты. В Turf.js эта задача решается несколькими инструментами, выбор которых зависит от требуемой логики деления: по фиксированной длине, по вершинам или по заданным точкам пересечения.
Перед операциями разбиения линия в Turf.js обычно представляется как
LineString:
import { lineString } from "@turf/helpers";
const line = lineString([
[30.5, 50.5],
[31.0, 50.6],
[31.5, 50.4],
[32.0, 50.7]
]);
Каждая пара координат образует вершину, а между ними формируются сегменты. Именно эти сегменты становятся базовой единицей при дальнейшем разбиении.
В Turf.js отсутствует отдельная функция с названием
lineToSegments, однако эквивалентная операция реализуется
через lineSegment, которая преобразует линию в набор
отдельных отрезков.
import { lineSegment } from "@turf/turf";
const segments = lineSegment(line);
Результатом является FeatureCollection, где каждый
элемент — отдельный отрезок между двумя последовательными вершинами
исходной линии.
Каждый сегмент имеет структуру:
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[x1, y1],
[x2, y2]
]
}
}
Такой подход используется, когда требуется анализировать или модифицировать отдельные участки маршрута, например для расчёта длины, визуализации или привязки атрибутов к сегментам.
Для деления линии на фрагменты фиксированной длины применяется
lineChunk. Эта функция разбивает исходный
LineString на отрезки заданной протяжённости с учётом
геодезической длины.
import { lineChunk } from "@turf/turf";
const chunks = lineChunk(line, 5, { units: "kilometers" });
В данном случае линия будет разделена на сегменты по 5 километров каждый. Последний сегмент может быть короче заданного значения, если остаток длины не кратен шагу.
Особенности поведения:
LineString.Перед разбиением часто требуется определить общую длину линии:
import { length } from "@turf/turf";
const total = length(line, { units: "kilometers" });
Это значение используется для расчёта количества сегментов и динамического выбора шага разбиения.
Пример вычисления количества сегментов:
const step = 2; // км
const count = Math.ceil(total / step);
Когда линия должна быть разделена по внешним геометрическим объектам
(например, точкам пересечения или другой линии), используется
lineSplit.
import { lineSplit, point } from "@turf/turf";
const splitter = point([31.0, 50.6]);
const result = lineSplit(line, splitter);
Также допускается использование линии в качестве разделителя:
const result = lineSplit(line, anotherLine);
Механизм работы:
Важно учитывать, что корректность результата зависит от наличия реального пересечения геометрий.
Для более управляемого сегментирования используется
lineSliceAlong, позволяющая извлекать участок линии между
двумя расстояниями.
genui{“math_block_widget_always_prefetch_v2”:{“content”:“d = ”}}
Хотя формула выше относится к евклидовому расстоянию, Turf.js использует геодезическую модель, но концептуально операция основана на измерении длины вдоль линии.
Пример:
import { lineSliceAlong } from "@turf/turf";
const part = lineSliceAlong(line, 2, 7, { units: "kilometers" });
Результат — подлиния между 2 и 7 километром вдоль исходной геометрии.
Особенности:
В случаях, когда требуется строгий контроль над сегментами, применяется комбинированный подход: вычисление длины и последовательное извлечение частей.
import { lineSliceAlong, length } from "@turf/turf";
const step = 1; // км
const total = length(line, { units: "kilometers" });
let segments = [];
for (let i = 0; i < total; i += step) {
const segment = lineSliceAlong(line, i, i + step, { units: "kilometers" });
segments.push(segment);
}
Такой метод позволяет:
При разбиении линии важен вопрос наследования свойств. В Turf.js свойства исходного объекта не всегда автоматически распределяются между сегментами.
При использовании lineSegment можно вручную переносить
свойства:
const segments = lineSegment(line);
segments.features = segments.features.map((f, index) => {
f.properties = {
...line.properties,
segmentIndex: index
};
return f;
});
Это позволяет сохранять бизнес-логику на уровне отдельных участков маршрута.
При работе с разбиением линий необходимо учитывать несколько факторов:
В реальных задачах часто используется комбинация функций:
lineSegment — для анализа структуры;lineChunk — для грубой сегментации по длине;lineSliceAlong — для точного контроля участков;lineSplit — для геометрического разрезания по
объектам.Такой подход позволяет строить многоуровневую обработку линейных данных: от топологического анализа до прикладной навигации и маршрутизации.