Работа с elevation данными

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

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

  • цифровые модели рельефа (DEM — Digital Elevation Model);
  • цифровые модели поверхности (DSM — Digital Surface Model);
  • растровые карты высот;
  • тайловые сервисы Terrain RGB;
  • GeoTIFF-файлы с высотной информацией;
  • векторные объекты с атрибутами высоты.

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


Основные форматы хранения высот

DEM (Digital Elevation Model)

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

Типичные значения:

Координата Высота
x1, y1 153 м
x2, y2 178 м
x3, y3 201 м

DEM часто применяется для:

  • построения профилей местности;
  • расчёта уклонов;
  • анализа водосборов;
  • создания теневого рельефа.

DSM (Digital Surface Model)

DSM содержит высоты всех объектов на поверхности:

  • зданий;
  • деревьев;
  • мостов;
  • инженерных сооружений.

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


GeoTIFF

Наиболее распространённый формат хранения растровых данных высот.

Каждый пиксель GeoTIFF содержит числовое значение высоты:

145
146
149
151
...

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


Использование GeoTIFF в OpenLayers

Для загрузки высотной модели применяется класс GeoTIFF.

Пример подключения слоя:

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/WebGLTile.js';
import GeoTIFF from 'ol/source/GeoTIFF.js';

const elevationLayer = new TileLayer({
    source: new GeoTIFF({
        sources: [
            {
                url: 'data/dem.tif'
            }
        ]
    })
});

const map = new Map({
    target: 'map',
    layers: [elevationLayer],
    view: new View({
        center: [0, 0],
        zoom: 8
    })
});

В данном случае OpenLayers:

  1. загружает GeoTIFF;
  2. декодирует растровые значения;
  3. формирует тайлы;
  4. отображает результат через WebGL.

Получение значений высоты

Высотные данные часто используются не для отображения, а для анализа.

Метод getData() позволяет получить значение пикселя.

Пример:

map.on('pointermove', (event) => {

    const data = elevationLayer.getData(event.pixel);

    if (data) {
        console.log('Высота:', data[0]);
    }

});

Значение массива соответствует содержимому канала растра.

Для однослойного DEM:

const height = data[0];

Terrain RGB

Многие современные сервисы предоставляют высоты через RGB-кодирование.

Пример кодирования:

R = 134
G = 210
B = 45

Высота вычисляется по специальной формуле.

Например, в сервисе Mapbox Terrain RGB:

height =
    -10000 +
    ((R * 256 * 256 + G * 256 + B) * 0.1);

Таким образом обычное изображение может содержать детальную модель рельефа.


Декодирование Terrain RGB

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

Пример:

map.on('click', (event) => {

    const pixelData = terrainLayer.getData(event.pixel);

    if (!pixelData) {
        return;
    }

    const r = pixelData[0];
    const g = pixelData[1];
    const b = pixelData[2];

    const elevation =
        -10000 +
        ((r * 256 * 256 + g * 256 + b) * 0.1);

    console.log(elevation);

});

Подобный подход широко применяется в веб-ГИС благодаря высокой производительности и компактности хранения.


Визуализация рельефа через цветовую шкалу

Высоты можно отображать различными цветами.

Пример распределения:

Высота Цвет
0–100 м зелёный
100–500 м жёлтый
500–1000 м коричневый
>1000 м белый

В OpenLayers подобная визуализация реализуется через WebGL-выражения.

Пример:

const elevationLayer = new TileLayer({
    source: geoTiffSource,
    style: {
        color: [
            'interpolate',
            ['linear'],
            ['band', 1],

            0,
            [0, 128, 0],

            500,
            [255, 255, 0],

            1000,
            [160, 82, 45],

            3000,
            [255, 255, 255]
        ]
    }
});

В результате формируется гипсометрическая карта.


Создание теневого рельефа (Hillshade)

Hillshade позволяет визуально подчеркнуть формы местности.

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

Требуются:

  • высота;
  • направление солнца;
  • угол подъёма солнца;
  • производные рельефа.

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


Вычисление уклона

Уклон является одной из важнейших характеристик рельефа.

Формула:

Slope=()

где:

  • Δh — изменение высоты;
  • Δd — горизонтальное расстояние.

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

Упрощённый пример:

const dzdx =
    (rightHeight - leftHeight) /
    (2 * pixelSize);

const dzdy =
    (bottomHeight - topHeight) /
    (2 * pixelSize);

const slope =
    Math.atan(
        Math.sqrt(
            dzdx * dzdx +
            dzdy * dzdy
        )
    );

Подобные вычисления применяются при:

  • проектировании дорог;
  • анализе маршрутов;
  • строительстве;
  • гидрологических исследованиях.

Расчёт экспозиции склона

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

Типичные значения:

Угол Направление
север
90° восток
180° юг
270° запад

Расчёт выполняется через производные поверхности:

const aspect =
    Math.atan2(
        dzdy,
        -dzdx
    );

Экспозиция используется в:

  • сельском хозяйстве;
  • лесном хозяйстве;
  • солнечной энергетике;
  • климатических исследованиях.

Построение профиля высот

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

Алгоритм состоит из нескольких этапов:

  1. создание линии;
  2. получение набора точек на линии;
  3. извлечение высот;
  4. построение графика.

Схема выборки:

A ---- B ---- C ---- D ---- E

Для каждой точки:

const coordinate =
    line.getCoordinateAt(fraction);

const elevation =
    getElevation(coordinate);

Полученные значения формируют массив:

[
    120,
    128,
    135,
    152,
    161,
    174
]

На основе массива строится профиль маршрута.


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

Для определения высоты конкретной точки необходимо:

  1. перевести координаты в пиксель;
  2. определить соответствующий тайл;
  3. получить значение растра.

Пример:

function getElevation(coordinate) {

    const pixel =
        map.getPixelFromCoordinate(
            coordinate
        );

    const data =
        elevationLayer.getData(pixel);

    return data ? data[0] : null;
}

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


Работа с высотой во векторных объектах

Высота может храниться в атрибутах объектов.

Пример GeoJSON:

{
  "type": "Feature",
  "properties": {
    "name": "Peak",
    "elevation": 2540
  }
}

Получение значения:

const height =
    feature.get('elevation');

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

  • вершины гор;
  • геодезические пункты;
  • здания;
  • инженерные объекты.

Отображение высоты в подписи объекта

Высотные значения часто выводятся непосредственно на карте.

Пример:

import Style from 'ol/style/Style.js';
import Text from 'ol/style/Text.js';

const style = feature => {

    return new Style({
        text: new Text({
            text:
                feature.get('elevation') + ' м'
        })
    });

};

В результате пользователь видит абсолютную отметку объекта.


Интерактивное определение высоты по щелчку

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

Пример:

map.on('singleclick', event => {

    const data =
        elevationLayer.getData(
            event.pixel
        );

    if (!data) {
        return;
    }

    const elevation = data[0];

    console.log(
        `Высота: ${elevation} м`
    );

});

Подобный механизм используется в:

  • туристических картах;
  • геоинформационных системах;
  • кадастровых сервисах;
  • инженерных приложениях.

Оптимизация работы с большими моделями рельефа

Высотные данные могут занимать десятки гигабайт.

Для повышения производительности применяются следующие подходы:

Тайлирование

Исходный растр разбивается на множество небольших фрагментов.

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

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

Многоуровневые пирамиды

Для каждого масштаба создаётся отдельный набор тайлов.

Структура:

Zoom 0
Zoom 1
Zoom 2
Zoom 3
...
Zoom 15

На малых масштабах используются данные низкого разрешения.


WebGL-рендеринг

При работе с рельефом предпочтительно использовать:

import WebGLTile from 'ol/layer/WebGLTile.js';

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

  • ускорение вычислений на GPU;
  • плавное масштабирование;
  • возможность сложной обработки растров.

Кэширование данных

Повторно загруженные тайлы сохраняются в памяти браузера.

Это позволяет:

  • уменьшить сетевой трафик;
  • ускорить навигацию по карте;
  • снизить нагрузку на сервер.

Типичные области применения elevation-данных

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

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

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