Работа с ячейками сетки

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

Любая регулярная сетка в Turf.js строится на основе ограничивающего прямоугольника и размера ячейки. Ограничивающий прямоугольник задаётся координатами в формате [minX, minY, maxX, maxY], где значения соответствуют долготе и широте в системе WGS84.

Размер ячейки определяет масштаб дискретизации пространства. В Turf.js он задаётся в единицах расстояния (километры, метры, мили) и интерпретируется с учётом геодезической модели Земли.

Геометрическая основа сетки формируется через вычисление границ области и последующее заполнение её повторяющимися геометрическими фигурами.

Ограничивающий прямоугольник и подготовка области

Перед созданием сетки выполняется определение bounding box:

import bbox from "@turf/bbox";

const extent = bbox(geojsonFeatureCollection);

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

import bboxPolygon from "@turf/bbox-polygon";

const areaPolygon = bboxPolygon(extent);

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

Квадратная сетка

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

import squareGrid from "@turf/square-grid";

const grid = squareGrid(extent, 5, {
  units: "kilometers"
});

Каждая ячейка представляет собой Feature с геометрией Polygon и набором свойств:

  • row — индекс строки
  • col — индекс столбца
  • id — уникальный идентификатор ячейки

Структура сетки формируется построчно, начиная с нижней границы bbox.

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

  • пространственная агрегация точек
  • построение heatmap
  • индексирование объектов

Особенности разбиения

Шаг сетки интерпретируется в географических координатах, поэтому реальные размеры ячеек могут слегка варьироваться из-за кривизны поверхности Земли. Это особенно заметно на больших широтах.

Шестиугольная сетка

Шестиугольная сетка создаётся через hexGrid. Геометрия ячейки представляет собой правильный шестиугольник, обеспечивающий более равномерное соседство по сравнению с квадратной структурой.

import hexGrid from "@turf/hex-grid";

const grid = hexGrid(extent, 5, {
  units: "kilometers"
});

Преимущества шестиугольной сетки:

  • равномерное расстояние до соседних центров
  • отсутствие диагональных перекосов
  • более естественная агрегация плотности

Каждая ячейка содержит геометрию Polygon и свойства индексации, аналогичные квадратной сетке.

Треугольная сетка

Треугольная сетка создаётся с помощью triangleGrid. Она формирует равносторонние треугольники, которые могут использоваться в специализированных задачах интерполяции и триангуляции данных.

import triangleGrid from "@turf/triangle-grid";

const grid = triangleGrid(extent, 5, {
  units: "kilometers"
});

Особенности треугольной сетки:

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

Сетка точек

Функция pointGrid создаёт регулярную сетку точек внутри bounding box. В отличие от полигональных сеток, результатом является набор точечных объектов.

import pointGrid from "@turf/point-grid";

const points = pointGrid(extent, 1, {
  units: "kilometers"
});

Применение:

  • генерация контрольных точек
  • выборка пространственных данных
  • дискретизация поверхности

Каждая точка имеет координаты центра соответствующей ячейки.

Связь сетки с геометрическими операциями

Сетки в Turf.js часто используются совместно с операциями пространственного анализа. Основной подход заключается в связывании исходных объектов с ячейками сетки.

Проверка принадлежности точки

Для определения принадлежности точки к ячейке используется booleanPointInPolygon:

import booleanPointInPolygon from "@turf/boolean-point-in-polygon";

const isInside = booleanPointInPolygon(point, cell);

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

Агрегация объектов

Для распределения точек по ячейкам применяется обход всех элементов сетки с последующей фильтрацией:

grid.features.forEach(cell => {
  const pointsInCell = points.features.filter(pt =>
    booleanPointInPolygon(pt, cell)
  );

  cell.properties.count = pointsInCell.length;
});

Такой подход формирует пространственные гистограммы.

Центр ячейки и геометрические свойства

Каждая ячейка сетки может быть приведена к центроиду для упрощённого анализа:

import centroid from "@turf/centroid";

const center = centroid(cell);

Центры ячеек часто используются:

  • при визуализации тепловых карт
  • при кластеризации
  • при построении графов соседства

Индексация и структура данных

Сеточные функции Turf.js возвращают FeatureCollection, где каждая ячейка имеет свойства, позволяющие восстанавливать её положение в сетке.

Типичная структура:

{
  "type": "Feature",
  "geometry": { "type": "Polygon", "coordinates": [...] },
  "properties": {
    "row": 2,
    "col": 5,
    "id": 23
  }
}

Такая структура позволяет:

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

Масштабирование и выбор размера ячейки

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

Малый размер:

  • высокая детализация
  • увеличенное количество ячеек
  • рост вычислительной нагрузки

Большой размер:

  • снижение точности
  • ускорение обработки
  • упрощение визуализации

Выбор масштаба зависит от плотности входных данных и географического охвата.

Работа с пересечениями сетки и объектов

Часто требуется определить пересечение исходных геометрий с сеткой. Для этого применяется комбинация операций пересечения и фильтрации.

Пример логики:

  • каждая ячейка рассматривается как полигон
  • проверяется пересечение с объектом
  • при наличии пересечения ячейка модифицируется
import intersect from "@turf/intersect";

const result = grid.features.map(cell => {
  const overlap = intersect(cell, feature);
  if (overlap) {
    cell.properties.intersects = true;
  }
  return cell;
});

Такой подход используется при построении зон влияния и пространственных масок.

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

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

Преимущества:

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

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

Агрегация статистики по ячейкам

Сетки часто используются для вычисления статистики:

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

Пример накопления значений:

grid.features.forEach(cell => {
  const values = points.features
    .filter(pt => booleanPointInPolygon(pt, cell))
    .map(pt => pt.properties.value);

  cell.properties.sum = values.reduce((a, b) => a + b, 0);
});

Такая структура применяется при построении аналитических слоёв.

Оптимизация обработки сеток

При работе с большими объёмами данных используется ряд оптимизаций:

  • предварительная фильтрация по bounding box
  • кэширование результатов принадлежности
  • разбиение данных на чанки
  • использование пространственных индексов вне Turf.js

На практике основная нагрузка приходится на операции проверки принадлежности точек к полигонам, поэтому уменьшение количества проверок критично для производительности.

Комбинирование типов сеток

Различные типы сеток могут использоваться совместно в одной задаче:

  • квадратная сетка для первичной дискретизации
  • шестиугольная для сглаживания плотности
  • точечная для выборки центров
  • треугольная для интерполяции

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