В Turf.js точка представляется как GeoJSON-объект типа
Point, обёрнутый в структуру Feature. Базовая
единица работы с наборами точек — коллекция
FeatureCollection, которая позволяет хранить произвольное
количество геообъектов.
const point = turf.point([30.5, 50.5]);
const collection = turf.featureCollection([
turf.point([30.5, 50.5]),
turf.point([30.6, 50.6]),
turf.point([30.7, 50.7])
]);
Ключевая особенность: Turf.js не оперирует «массивами координат» напрямую в геооперациях, а всегда требует строгую GeoJSON-структуру.
Объединение точек в коллекции обычно означает приведение множества
Point-объектов к одной геометрии типа
MultiPoint. Это позволяет рассматривать набор точек как
единый объект, сохраняя при этом их индивидуальные координаты.
const multiPoint = turf.multiPoint([
[30.5, 50.5],
[30.6, 50.6],
[30.7, 50.7]
]);
MultiPoint — это наиболее прямолинейная форма
объединения без потери данных и без изменения пространственных
отношений.
Когда точки уже находятся в FeatureCollection, часто
требуется преобразовать их в единый объект. Для этого используется
ручное извлечение координат.
const points = turf.featureCollection([
turf.point([10, 10]),
turf.point([20, 20]),
turf.point([30, 30])
]);
const coords = points.features.map(f => f.geometry.coordinates);
const merged = turf.multiPoint(coords);
Такой подход сохраняет контроль над структурой и позволяет предварительно фильтровать или трансформировать данные.
Функция turf.combine применяется для объединения разных
типов геометрий в один объект, чаще всего при работе со смешанными
коллекциями. Несмотря на то, что она чаще используется для линий и
полигонов, точки также могут быть включены в общий процесс
нормализации.
const collection = turf.featureCollection([
turf.point([10, 10]),
turf.point([20, 20]),
turf.point([30, 30])
]);
const combined = turf.combine(collection);
Результат возвращает структуру, где геометрии сгруппированы по типам
(например, MultiPoint), что упрощает последующую обработку
в аналитических задачах.
При объединении точек часто возникает проблема повторяющихся координат. Turf.js не удаляет дубликаты автоматически, поэтому требуется предварительная фильтрация.
function removeDuplicates(features) {
const seen = new Set();
return features.filter(f => {
const key = f.geometry.coordinates.join(',');
if (seen.has(key)) return false;
seen.add(key);
return true;
});
}
const cleaned = turf.featureCollection(
removeDuplicates(points.features)
);
const result = turf.multiPoint(
cleaned.features.map(f => f.geometry.coordinates)
);
Такой подход важен при работе с GPS-данными и телеметрией, где дублирование встречается регулярно.
Объединение точек часто выполняется не только по координатам, но и по атрибутам. Например, можно сгруппировать точки по категории или идентификатору.
function groupByProperty(collection, prop) {
return collection.features.reduce((acc, feature) => {
const key = feature.properties[prop];
if (!acc[key]) acc[key] = [];
acc[key].push(feature);
return acc;
}, {});
}
const grouped = groupByProperty(points, 'type');
Далее каждая группа может быть преобразована в
MultiPoint, создавая набор объединённых геометрий по
логическим сегментам данных.
const multiPointsByGroup = Object.keys(grouped).map(key =>
turf.multiPoint(grouped[key].map(f => f.geometry.coordinates))
);
При больших наборах данных простое объединение теряет смысл без
пространственной логики. В таких случаях применяется кластеризация,
например DBSCAN через turf.clustersDbscan.
const clustered = turf.clustersDbscan(points, 1, {
units: 'kilometers'
});
Каждой точке добавляется свойство cluster, после чего
можно собрать объединённые группы:
function buildClusters(collection) {
const clusters = {};
collection.features.forEach(f => {
const id = f.properties.cluster;
if (id === undefined) return;
if (!clusters[id]) clusters[id] = [];
clusters[id].push(f.geometry.coordinates);
});
return Object.values(clusters).map(coords =>
turf.multiPoint(coords)
);
}
const resultClusters = buildClusters(clustered);
Такой подход позволяет объединять точки не произвольно, а на основе плотности распределения.
Перед любыми операциями объединения требуется привести данные к единому формату:
[lng, lat]function normalize(feature) {
if (!feature.geometry || feature.geometry.type !== 'Point') {
return null;
}
const [lng, lat] = feature.geometry.coordinates;
if (typeof lng !== 'number' || typeof lat !== 'number') {
return null;
}
return feature;
}
const normalized = turf.featureCollection(
points.features.map(normalize).filter(Boolean)
);
Объединённые точки часто используются как вход для дальнейших геоопераций:
turf.center)turf.convex)const center = turf.center(multiPoint);
const convexHull = turf.convex(
turf.featureCollection(multiPoint.geometry.coordinates.map(c =>
turf.point(c)
))
);
Хотя convex чаще применяется к
FeatureCollection, объединённые структуры упрощают
подготовку данных.
Типовой рабочий конвейер:
FeatureCollectionMultiPointconst cleaned = removeDuplicates(points.features);
const grouped = groupByProperty(
turf.featureCollection(cleaned),
'category'
);
const result = Object.values(grouped).map(group =>
turf.multiPoint(group.map(f => f.geometry.coordinates))
);
Такая структура позволяет хранить несколько логических объединений точек в одном наборе данных без потери семантики и пространственных связей.