Разделение коллекций на части

Работа с геоданными в формате GeoJSON часто требует разбиения больших наборов объектов на более управляемые сегменты. Это необходимо для оптимизации вычислений, параллельной обработки, визуализации и ограничения объёма данных в одном запросе. В Turf.js такие операции реализуются через несколько различных подходов: разбиение по количеству объектов, пространственное разбиение по сетке и кластеризация.


Разбиение коллекции по фиксированному размеру (chunking)

Одним из наиболее прямолинейных способов разделения коллекции является функция разбиения на чанки фиксированного размера.

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);

Поведение функции

  • вход: FeatureCollection
  • параметр размера: максимальное количество объектов в одной группе
  • выход: массив FeatureCollection
  • порядок объектов сохраняется

Особенности применения

  • подходит для батчевой обработки API-запросов
  • используется при ограничениях на размер payload
  • не учитывает пространственное расположение объектов

Пространственное разбиение через сетки

Когда важна география распределения объектов, используется разбиение по пространственной сетке. 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"
});

Основные параметры

  • bounding box: область покрытия
  • cellSide: размер ячейки
  • units: единицы измерения (kilometers, miles, degrees)

Распределение точек по сетке

После создания сетки требуется сопоставить объекты с ячейками.

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"
});

Особенности

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

Кластеризация как метод разбиения коллекции

Кластеризация разделяет коллекцию на группы на основе расстояний между объектами.


DBSCAN кластеризация

clusterDbscan

Алгоритм DBSCAN группирует точки на основе плотности.

import clusterDbscan from "@turf/clusters-dbscan";

const clustered = clusterDbscan(points, 50, {
  units: "kilometers"
});

Принцип работы

  • maxDistance задаёт радиус соседства
  • точки, находящиеся в плотных областях, образуют кластеры
  • шумовые точки получают null или отдельную метку

Результат

Каждая точка получает свойство:

{
  "cluster": 0
}

K-means кластеризация

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)
);

Комбинированные подходы разбиения

В практических задачах часто комбинируются несколько методов:

Пример: сетка + кластеризация

  1. создаётся grid через squareGrid
  2. точки распределяются по ячейкам
  3. внутри каждой ячейки выполняется clusterDbscan

Такой подход позволяет:

  • масштабировать обработку
  • учитывать локальную плотность
  • уменьшать вычислительную сложность

Разбиение с сохранением индексов принадлежности

При любом способе разбиения часто требуется сохранить связь между исходным объектом и его частью.

Добавление идентификаторов

const enriched = points.features.map((f, i) => ({
  ...f,
  properties: {
    ...f.properties,
    id: i
  }
}));

Использование в сетке

collect(grid, points, "id", "point_ids");

Это позволяет восстанавливать исходные данные после агрегации.


Иерархическое разбиение коллекций

Для больших наборов данных применяется многоуровневое деление:

  1. глобальная сетка (например, 500 км)
  2. локальная сетка (10–50 км)
  3. кластеризация внутри ячеек
  4. финальная агрегация свойств

Такой подход снижает сложность обработки с O(n²) до приближённо линейной в каждом сегменте.


Особенности производительности

Разные методы разбиения имеют различную вычислительную стоимость:

  • chunk — минимальная сложность O(n)
  • squareGrid / hexGrid — зависят от площади и разрешения
  • clusterDbscan — может достигать O(n²) без оптимизаций
  • clusterKmeans — итеративная оптимизация, зависит от числа кластеров

Выбор метода определяется балансом между точностью пространственного анализа и скоростью обработки данных.


Практическая структура обработки коллекций

Типовой pipeline разбиения включает:

  • нормализацию GeoJSON структуры
  • выбор стратегии разбиения
  • пространственное распределение
  • агрегацию атрибутов
  • формирование новых FeatureCollection

Такой подход позволяет адаптировать обработку под задачи аналитики, визуализации и геопространственного моделирования.