Работа с растровыми данными

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

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


Растровые данные в веб-приложениях чаще всего представлены в одном из следующих видов:

ImageData (Canvas API) Пиксельный буфер, где каждый пиксель хранит значения RGBA.

Массивы (TypedArray) Используются для хранения числовых полей: высоты, температуры, интенсивности.

Тайловые схемы (XYZ tiles) Каждый тайл — это отдельное изображение фиксированного размера (обычно 256×256 или 512×512 пикселей).

GeoTIFF (через внешние библиотеки) Формат, сохраняющий геопривязанные растровые данные.

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


Связь Turf.js с растровыми данными

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

Типовой подход:

  1. Растр интерпретируется как функция f(x, y)
  2. Поверх него создаётся сетка точек или полигонов
  3. Значения из растра извлекаются и привязываются к векторным объектам
  4. Turf.js используется для геометрических операций над этой сеткой

Таким образом Turf.js становится инструментом анализа “оцифрованного растра”.


Построение регулярной сетки как основы растрового анализа

Одним из ключевых инструментов Turf.js является создание сеток.

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

import { squareGrid } from "@turf/turf";

const bbox = [30, 50, 40, 60];
const cellSize = 10; // километры

const grid = squareGrid(bbox, cellSize, {
  units: "kilometers"
});

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

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

import { hexGrid } from "@turf/turf";

const grid = hexGrid(bbox, cellSize, {
  units: "kilometers"
});

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


Привязка растровых значений к векторной сетке

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

import { centerOfMass } from "@turf/turf";

function sampleRaster(raster, point) {
  const x = Math.floor(point.geometry.coordinates[0]);
  const y = Math.floor(point.geometry.coordinates[1]);

  return raster[y][x];
}

grid.features.forEach(cell => {
  const center = centerOfMass(cell);
  cell.properties.value = sampleRaster(dem, center);
});

Здесь растр представлен двумерным массивом dem, где индексы соответствуют координатной системе изображения.


Интерполяция растровых данных через векторные методы

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

Метод обратных расстояний (IDW)

Идея заключается в том, что значение в точке зависит от значений ближайших известных точек.

import { distance } from "@turf/turf";

function idwInterpolate(point, samples) {
  let numerator = 0;
  let denominator = 0;

  samples.forEach(s => {
    const d = distance(point, s, { units: "kilometers" });
    const weight = 1 / Math.pow(d + 0.001, 2);

    numerator += s.properties.value * weight;
    denominator += weight;
  });

  return numerator / denominator;
}

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


Преобразование векторных данных в растровую структуру

Одна из ключевых задач — “запекание” векторной геометрии в сетку.

Растеризация точек

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

grid.features.forEach(cell => {
  cell.properties.value = 0;
});

points.features.forEach(pt => {
  grid.features.forEach(cell => {
    const c = centerOfMass(cell);
    const d = distance(pt, c);

    if (d < 5) {
      cell.properties.value += pt.properties.weight;
    }
  });
});

Так формируется плотностное поле, аналог heatmap.


Полигональные маски и обрезка растровых данных

При работе с растрами часто требуется ограничить область анализа геометрией.

import { booleanPointInPolygon } from "@turf/turf";

function maskGridByPolygon(grid, polygon) {
  return {
    ...grid,
    features: grid.features.filter(cell => {
      const c = centerOfMass(cell);
      return booleanPointInPolygon(c, polygon);
    })
  };
}

Так формируется маска, аналогичная растровому clip.


Изолинии и изобанды как связующее звено между растром и вектором

Turf.js содержит инструменты, позволяющие преобразовывать поля значений в изолинии и зоны.

Изолинии

import { isolines } from "@turf/turf";

const lines = isolines(grid, {
  zProperty: "value",
  breaks: [10, 20, 30, 40]
});

Каждая линия соответствует уровню равных значений, что эквивалентно сечению растровой поверхности.

Изобанды

import { isobands } from "@turf/turf";

const bands = isobands(grid, {
  zProperty: "value",
  breaks: [0, 10, 20, 50]
});

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


Работа с высотными моделями (DEM)

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

Типичный сценарий:

  • каждая ячейка содержит высоту
  • вычисляются уклоны, профили, изолинии

Пример оценки локального градиента:

function slope(cell, neighbors) {
  const center = cell.properties.value;

  let dx = neighbors.east.properties.value - neighbors.west.properties.value;
  let dy = neighbors.north.properties.value - neighbors.south.properties.value;

  return Math.sqrt(dx * dx + dy * dy);
}

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


Построение тепловых карт

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

Алгоритм:

  1. Создание сетки
  2. Агрегация значений
  3. Нормализация
  4. Интерполяция цвета (вне Turf.js)
grid.features.forEach(cell => {
  const value = cell.properties.value;

  cell.properties.intensity = value / maxValue;
});

Далее интенсивность используется в визуализации на Canvas или WebGL.


Совмещение тайловых слоёв и векторного анализа

На практике растровые данные часто поступают в виде тайлов, которые загружаются динамически.

Turf.js применяется поверх тайлового слоя для:

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

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

  • тайл загружается как изображение
  • пиксели читаются через Canvas
  • значения передаются в Turf-сетку

Оптимизация обработки растровых аппроксимаций

При увеличении разрешения сетки резко возрастает вычислительная нагрузка.

Основные подходы оптимизации:

1. Пространственная индексация Использование RBush для ускорения поиска соседей.

2. Кэширование центроидов Предварительный расчёт геометрических центров ячеек.

3. Батчевая обработка Группировка операций над сеткой вместо построчного прохода.

4. Уменьшение разрешения сетки Адаптивная генерация grid в зависимости от плотности данных.


Комбинированные модели: вектор + растр

Наиболее мощные сценарии возникают при объединении двух моделей:

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

Пример:

  • растр высот → сетка
  • Turf.js → выделение зон уклона
  • векторизация зон → полигоны опасных территорий

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