Работа с геоданными в формате GeoJSON часто требует разбиения больших наборов объектов на более управляемые сегменты. Это необходимо для оптимизации вычислений, параллельной обработки, визуализации и ограничения объёма данных в одном запросе. В Turf.js такие операции реализуются через несколько различных подходов: разбиение по количеству объектов, пространственное разбиение по сетке и кластеризация.
Одним из наиболее прямолинейных способов разделения коллекции является функция разбиения на чанки фиксированного размера.
chunkФункция разбивает FeatureCollection на массив
подколлекций, каждая из которых содержит не более заданного количества
элементов.
import chunk from "@turf/chunk";
import { featureCollection, point } from "@turf/helpers";
const points = featureCollection([
point([0, 0]),
point([1, 1]),
point([2, 2]),
point([3, 3]),
point([4, 4])
]);
const result = chunk(points, 2);
FeatureCollectionFeatureCollectionКогда важна география распределения объектов, используется разбиение по пространственной сетке. Turf.js предоставляет инструменты генерации регулярных сеток и последующего распределения объектов по ячейкам.
squareGridСоздаёт регулярную квадратную сетку в пределах bounding box.
import squareGrid from "@turf/square-grid";
import bbox from "@turf/bbox";
const bounds = [-180, -90, 180, 90];
const grid = squareGrid(bounds, 50, {
units: "kilometers"
});
После создания сетки требуется сопоставить объекты с ячейками.
pointsWithinPolygonПозволяет выбрать точки, находящиеся внутри каждой ячейки.
import pointsWithinPolygon from "@turf/points-within-polygon";
const pointsInCell = pointsWithinPolygon(points, cell);
collectИспользуется для агрегации свойств объектов внутри полигона.
import collect from "@turf/collect";
const collected = collect(grid, points, "elevation", "values");
Результат добавляет массив значений в свойства каждой ячейки.
hexGridГексагональная сетка часто используется для более равномерного распределения расстояний между центрами ячеек.
import hexGrid from "@turf/hex-grid";
const hexes = hexGrid([-180, -85, 180, 85], 10, {
units: "kilometers"
});
Кластеризация разделяет коллекцию на группы на основе расстояний между объектами.
clusterDbscanАлгоритм DBSCAN группирует точки на основе плотности.
import clusterDbscan from "@turf/clusters-dbscan";
const clustered = clusterDbscan(points, 50, {
units: "kilometers"
});
maxDistance задаёт радиус соседстваnull или отдельную меткуКаждая точка получает свойство:
{
"cluster": 0
}
clusterKmeansРазделяет коллекцию на заранее заданное количество кластеров.
import clusterKmeans from "@turf/clusters-kmeans";
const clustered = clusterKmeans(points, {
numberOfClusters: 3
});
Иногда коллекции делятся не только геометрически, но и на основе пересечения с другими слоями.
booleanIntersectsИспользуется для фильтрации объектов по пересечению.
import booleanIntersects from "@turf/boolean-intersects";
const filtered = features.features.filter(f =>
booleanIntersects(f, polygon)
);
В практических задачах часто комбинируются несколько методов:
squareGridclusterDbscanТакой подход позволяет:
При любом способе разбиения часто требуется сохранить связь между исходным объектом и его частью.
const enriched = points.features.map((f, i) => ({
...f,
properties: {
...f.properties,
id: i
}
}));
collect(grid, points, "id", "point_ids");
Это позволяет восстанавливать исходные данные после агрегации.
Для больших наборов данных применяется многоуровневое деление:
Такой подход снижает сложность обработки с O(n²) до приближённо линейной в каждом сегменте.
Разные методы разбиения имеют различную вычислительную стоимость:
chunk — минимальная сложность O(n)squareGrid / hexGrid — зависят от площади и
разрешенияclusterDbscan — может достигать O(n²) без
оптимизацийclusterKmeans — итеративная оптимизация, зависит от
числа кластеровВыбор метода определяется балансом между точностью пространственного анализа и скоростью обработки данных.
Типовой pipeline разбиения включает:
Такой подход позволяет адаптировать обработку под задачи аналитики, визуализации и геопространственного моделирования.