Упрощение линий

Геометрические данные в формате GeoJSON часто содержат избыточную детализацию: большое количество точек, несущественные изгибы, шум GPS-трека или результат конвертации из высокоточных источников. Упрощение линий применяется для уменьшения числа координат при сохранении общей формы объекта. Это критично для визуализации, хранения, ускорения пространственных операций и передачи данных по сети.

В Turf.js основным инструментом упрощения является функция turf.simplify, реализующая алгоритм Дугласа–Пекера и его модификации.


Геометрическая основа упрощения

Линия в GeoJSON представляется как LineString — последовательность координат:

{
  "type": "LineString",
  "coordinates": [
    [30.5, 50.5],
    [30.51, 50.51],
    [30.52, 50.52]
  ]
}

Задача упрощения — удалить часть точек, сохранив форму, определяемую отклонением от исходной линии.

Ключевой принцип:

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

Алгоритм Дугласа–Пекера

Алгоритм работает рекурсивно:

  1. Берётся линия между первой и последней точкой
  2. Вычисляется расстояние от всех промежуточных точек до этой линии
  3. Находится точка с максимальным отклонением
  4. Если отклонение больше допуска — линия разбивается на две части
  5. Процесс повторяется для каждой части

Формально упрощение контролируется параметром допуска:

d

где

  • d — расстояние точки до упрощаемого сегмента
  • ε — заданный порог упрощения

Основная функция Turf.js

turf.simplify(geojson, options)

Параметры:

  • geojson — объект GeoJSON (LineString, Polygon, Feature)
  • options.tolerance — допустимое отклонение
  • options.highQuality — использование более точного, но медленного алгоритма
  • options.mutate — изменение исходного объекта

Базовый пример упрощения линии

import { lineString, simplify } from "@turf/turf";

const line = lineString([
  [30.50, 50.50],
  [30.51, 50.51],
  [30.52, 50.52],
  [30.60, 50.60],
  [30.80, 50.70]
]);

const simplified = simplify(line, {
  tolerance: 0.01,
  highQuality: false,
  mutate: false
});

При малом tolerance изменения будут минимальными, при увеличении — количество точек резко сокращается.


Параметр tolerance

tolerance задаёт максимальное допустимое отклонение точки от исходной линии.

Особенности:

  • измеряется в градусах для географических координат (EPSG:4326)
  • влияет на агрессивность упрощения
  • нелинейно влияет на количество удалённых точек

Типичная ошибка — использование слишком большого значения, приводящего к искажению формы объектов.

Пример влияния:

  • 0.001 — лёгкое сглаживание
  • 0.01 — заметное упрощение
  • 0.1 — радикальная потеря деталей

Режим highQuality

Алгоритм Дугласа–Пекера имеет оптимизации, ускоряющие вычисления, но иногда дающие менее точный результат.

simplify(line, {
  tolerance: 0.01,
  highQuality: true
});

Различия:

  • false — быстрее, используется упрощённая проверка расстояний
  • true — точные вычисления, выше нагрузка

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


Упрощение Polygon

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

import { polygon, simplify } from "@turf/turf";

const poly = polygon([[
  [30, 50],
  [31, 50],
  [31, 51],
  [30, 51],
  [30, 50]
]]);

const result = simplify(poly, {
  tolerance: 0.02,
  highQuality: true
});

Особенности:

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

Геодезическое расстояние и проекция

При работе в Turf.js координаты рассматриваются как сферические (WGS84). Это означает, что расстояния не являются евклидовыми в строгом смысле.

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

  • локальные данные (город) — погрешность минимальна
  • глобальные линии (континенты) — возможны искажения

Влияние упрощения на топологию

Упрощение может затрагивать геометрические свойства:

  • изменение длины линии
  • сглаживание резких углов
  • потеря мелких ответвлений
  • изменение площади полигонов

При этом Turf.js старается сохранять:

  • порядок точек
  • направление линии
  • валидность GeoJSON

Практическое применение в обработке GPS-треков

GPS-треки часто содержат шум:

  • дрожание координат
  • случайные отклонения
  • повторяющиеся точки

Пример исходного трека:

const track = lineString([
  [30.1000, 50.1000],
  [30.1001, 50.1002],
  [30.1002, 50.1001],
  [30.2000, 50.2000]
]);

После упрощения:

const clean = simplify(track, {
  tolerance: 0.005
});

Результат:

  • удаляются микроколебания
  • сохраняется общий маршрут
  • уменьшается объём данных

Масштабируемость и производительность

Сложность алгоритма Дугласа–Пекера: