Геопривязка (Georeferencing) растров представляет собой процесс сопоставления пикселей изображения с реальными координатами на поверхности Земли. В результате обычное изображение превращается в пространственный слой, который может отображаться совместно с векторными объектами, спутниковыми снимками, картографическими подложками и другими геоданными.
В OpenLayers геопривязанные растры используются для решения различных задач:
Без геопривязки изображение остается обычным графическим файлом, положение которого относительно карты неизвестно.
Для отображения растра на карте необходимо определить:
Чаще всего геопривязанный растр содержит:
jpg, png,
tif);Наиболее распространенные способы хранения геопривязки:
| Формат | Описание |
|---|---|
| GeoTIFF | Геопривязка встроена в TIFF-файл |
| World File | Отдельный файл (.jgw, .pgw,
.tfw) |
| WMS | Растр генерируется сервером |
| WMTS | Тайловый геопривязанный растр |
| XYZ Tiles | Набор тайлов с фиксированными координатами |
Самый простой способ размещения геопривязанного изображения в
OpenLayers — использование источника ImageStatic.
Ключевым параметром является imageExtent, определяющий
пространственные границы изображения.
import Map from 'ol/Map';
import View from 'ol/View';
import ImageLayer from 'ol/layer/Image';
import Static from 'ol/source/ImageStatic';
const imageLayer = new ImageLayer({
source: new Static({
url: 'images/map.png',
imageExtent: [
418000,
6152000,
432000,
6164000
]
})
});
const map = new Map({
target: 'map',
layers: [imageLayer],
view: new View({
center: [425000, 6158000],
zoom: 10
})
});
Массив imageExtent задается в следующем порядке:
[minX, minY, maxX, maxY]
Где:
minX — западная граница;minY — южная граница;maxX — восточная граница;maxY — северная граница.OpenLayers автоматически растягивает изображение внутри указанного прямоугольника.
При работе с геопривязанными изображениями необходимо явно задавать проекцию.
Пример для Web Mercator:
import { get as getProjection } from 'ol/proj';
const imageLayer = new ImageLayer({
source: new Static({
url: 'map.png',
projection: getProjection('EPSG:3857'),
imageExtent: [
-1000000,
5000000,
-900000,
5100000
]
})
});
Пример для географических координат:
projection: 'EPSG:4326'
Если проекция растра не совпадает с проекцией карты, изображение окажется смещенным или вовсе не отобразится.
Одной из наиболее распространенных задач является наложение исторических карт на современные данные.
Допустим, известны координаты углов старой карты:
Левый нижний угол:
55.7000, 37.5000
Правый верхний угол:
55.9000, 37.8000
Создание слоя:
const historicLayer = new ImageLayer({
source: new Static({
url: 'historic-map.jpg',
projection: 'EPSG:4326',
imageExtent: [
37.5,
55.7,
37.8,
55.9
]
})
});
После добавления слоя историческая карта будет совмещена с современной подложкой.
Для сравнения нескольких наборов данных часто применяется регулировка прозрачности.
const rasterLayer = new ImageLayer({
opacity: 0.6,
source: new Static({
url: 'historic-map.jpg',
projection: 'EPSG:4326',
imageExtent: [
37.5,
55.7,
37.8,
55.9
]
})
});
Значения прозрачности:
| Значение | Результат |
|---|---|
| 0 | Полностью прозрачный |
| 0.5 | Полупрозрачный |
| 1 | Полностью непрозрачный |
На одной карте может присутствовать несколько геопривязанных изображений.
const raster1 = new ImageLayer({
source: new Static({
url: 'image1.png',
imageExtent: [
1000,
1000,
3000,
3000
]
})
});
const raster2 = new ImageLayer({
source: new Static({
url: 'image2.png',
imageExtent: [
2500,
2000,
4500,
4000
]
})
});
Добавление слоев:
const map = new Map({
target: 'map',
layers: [
raster1,
raster2
]
});
Порядок в массиве определяет порядок отрисовки.
Для управления взаимным перекрытием применяется свойство
zIndex.
raster1.setZIndex(1);
raster2.setZIndex(10);
Чем выше значение, тем выше слой располагается в стеке отображения.
Наиболее частый сценарий — отображение растров поверх базовой карты.
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
const osmLayer = new TileLayer({
source: new OSM()
});
const rasterLayer = new ImageLayer({
opacity: 0.7,
source: new Static({
url: 'overlay.png',
imageExtent: [
4120000,
7480000,
4140000,
7500000
],
projection: 'EPSG:3857'
})
});
Создание карты:
const map = new Map({
target: 'map',
layers: [
osmLayer,
rasterLayer
]
});
Такой подход широко используется для наложения тематических данных на базовую картографическую подложку.
Формат GeoTIFF содержит встроенную информацию о пространственном положении изображения.
OpenLayers предоставляет специализированный источник
GeoTIFF.
import GeoTIFF from 'ol/source/GeoTIFF';
const layer = new TileLayer({
source: new GeoTIFF({
sources: [
{
url: 'dem.tif'
}
]
})
});
Преимущества GeoTIFF:
Многие изображения используют дополнительный файл геопривязки.
Примеры:
map.jpg
map.jgw
или
image.png
image.pgw
World File содержит:
размер пикселя по X
вращение
вращение
размер пикселя по Y
координата X
координата Y
Типичный пример:
1.000000
0.000000
0.000000
-1.000000
500000.000000
6200000.000000
OpenLayers напрямую не читает World File. Обычно координаты
извлекаются сервером или внешним инструментом и затем передаются в
imageExtent.
Если известны размеры изображения и координаты углов, можно вычислить границы самостоятельно.
Например:
Ширина: 5000 px
Высота: 3000 px
Левый нижний угол:
100000, 200000
Правый верхний угол:
105000, 203000
Extent будет:
[
100000,
200000,
105000,
203000
]
После этого изображение можно отобразить через
ImageStatic.
Подход подходит только для изображений, которые:
Невозможно корректно обработать:
Для подобных случаев используются серверные ГИС-инструменты:
Очень крупные изображения могут существенно замедлять работу браузера.
Пример проблемного файла:
20000 × 20000 px
Такой растр может занимать сотни мегабайт памяти после декодирования.
Рекомендуемые методы оптимизации:
Вместо одного изображения:
large-image.jpg
используется набор тайлов:
0/0/0.png
0/0/1.png
1/0/0.png
...
Для этого применяются:
Создаются версии изображения различного разрешения:
Zoom 0 → 256×256
Zoom 1 → 512×512
Zoom 2 → 1024×1024
...
Загружается только необходимый уровень детализации.
Для фотографий подходит:
JPEG
Для схем и карт:
PNG
WEBP
Слой можно включать и выключать программно.
rasterLayer.setVisible(false);
Включение:
rasterLayer.setVisible(true);
Проверка состояния:
const visible = rasterLayer.getVisible();
Подобный механизм используется в менеджерах слоев и тематических картах.
Любой слой имеет пространственный охват.
Получение extent:
const extent =
rasterLayer
.getSource()
.getImageExtent();
Результат:
[
minX,
minY,
maxX,
maxY
]
Эти данные могут использоваться для автоматического масштабирования карты.
map.getView().fit(extent);
Карта автоматически покажет весь геопривязанный растр в видимой области.
Последовательность действий обычно выглядит следующим образом:
ImageStatic или
GeoTIFF.Грамотно выполненная геопривязка позволяет интегрировать растровые изображения в единую геоинформационную среду, обеспечивая корректное пространственное совмещение с любыми слоями OpenLayers.