Дублирующиеся координаты в наборах геометрии возникают на разных этапах обработки пространственных данных: при конвертации форматов, при объединении слоёв, при импорте из GPS-треков, при агрегации пользовательских событий или при многократном выполнении геоопераций. В контексте Turf.js такие дубликаты влияют на корректность вычислений длины, площади, направлений и топологических операций.
Дубликаты можно условно разделить на два типа:
1. Последовательные дубликаты Когда одинаковые координаты идут подряд внутри LineString или Polygon:
[10, 10] → [10, 10] → [11, 11]
2. Глобальные дубликаты Когда одинаковые точки встречаются в разных частях геометрии:
[10, 10] ... [50, 50] ... [10, 10]
Разница между этими случаями критична: первый тип устраняется локальной очисткой координат, второй требует полноценной дедупликации набора.
Turf.js оперирует GeoJSON-объектами и предоставляет минимальный набор инструментов для итерации и трансформации координат.
Ключевые функции:
Фундаментальная особенность Turf.js: библиотека не хранит состояние данных, а работает исключительно через трансформацию GeoJSON.
Наиболее частая проблема — повторяющиеся соседние точки в LineString и Polygon. Turf.js решает её встроенной функцией:
import { cleanCoords } from "@turf/turf";
const line = {
type: "Feature",
geometry: {
type: "LineString",
coordinates: [
[30, 10],
[30, 10],
[31, 11],
[31, 11],
[32, 12]
]
}
};
const cleaned = cleanCoords(line);
cleanCoords проходит по массиву координат и удаляет
только те точки, которые:
Важно: функция не удаляет глобальные дубликаты, а работает только локально.
Для линий удаляются повторяющиеся соседние координаты, при этом структура сохраняется.
Для полигонов дополнительно учитывается замыкание контура. Если последняя точка совпадает с первой, лишнее повторение устраняется, но замкнутость сохраняется.
Вложенные геометрии обрабатываются рекурсивно, каждая компонента очищается отдельно.
Когда требуется удалить все повторяющиеся точки в пределах FeatureCollection, используется другой подход.
import { coordEach } from "@turf/turf";
const seen = new Set();
const result = [];
coordEach(featureCollection, (coord) => {
const key = coord.join(",");
if (!seen.has(key)) {
seen.add(key);
result.push(coord);
}
});
Каждая координата сериализуется в строку, которая используется как уникальный идентификатор. Это простой, но эффективный способ устранения глобальных повторов.
Удаление координат в “плоском” виде разрушает геометрию, поэтому результат необходимо собирать обратно:
import { point, featureCollection } from "@turf/turf";
const features = result.map(c => point(c));
const fc = featureCollection(features);
Однако такой подход применим только для точечных наборов. Для LineString и Polygon требуется восстановление последовательностей, иначе геометрия теряет смысл.
Иногда недостаточно сравнения координат — важно учитывать идентичность объектов.
Turf.js предоставляет:
import { booleanEqual } from "@turf/turf";
if (booleanEqual(featureA, featureB)) {
// геометрии идентичны
}
Этот метод проверяет полное геометрическое совпадение, включая порядок координат и тип геометрии.
При работе с FeatureCollection часто встречается ситуация, когда:
Один из устойчивых методов — нормализация координат перед сравнением:
const normalize = (coord) => `${coord[0].toFixed(6)}:${coord[1].toFixed(6)}`;
Далее используется Set:
const set = new Set();
coordEach(fc, (coord) => {
set.add(normalize(coord));
});
Такой подход устраняет ошибки, связанные с плавающей точкой.
Удаление дубликатов в полигонах требует аккуратности:
После очистки необходимо проверять валидность структуры:
Практическая схема обработки часто состоит из двух этапов:
const step1 = cleanCoords(feature);
coordEach(step1, (coord) => {
// удаление глобальных дублей
});
Такой двухуровневый подход позволяет минимизировать потери данных и сохранить геометрию.
При работе с десятками тысяч точек ключевым фактором становится производительность.
Map позволяет хранить дополнительные метаданные:
const map = new Map();
coordEach(fc, (coord) => {
const key = coord[0] + ":" + coord[1];
if (!map.has(key)) {
map.set(key, true);
}
});
Избегание JSON.stringify ускоряет обработку, особенно
при потоковой обработке координат.
1. Потеря структуры LineString Удаление координат без восстановления последовательности приводит к разрывам линии.
2. Нарушение замыкания Polygon Удаление первой или последней точки может разомкнуть контур.
3. Игнорирование точности float Координаты
[10.0000001, 20] и [10, 20] могут считаться
разными без нормализации.
4. Избыточная дедупликация Удаление всех повторов без учета топологии приводит к деградации геометрии.
cleanCoordscleanCoords
coordEach + Set
booleanEqual
При масштабировании важно учитывать:
Подход с последовательной фильтрацией координат позволяет обрабатывать геоданные без значительных затрат памяти даже при миллионах точек.