Растровые данные в PostGIS
- О чём эта тема
- Вторая половина мира геоданных — растры в базе данных: загрузка снимков и моделей рельефа утилитой raster2pgsql, тайлы и их индексация, обрезка и объединение, растеризация и векторизация, статистика по каналам и алгебра растров на примере NDVI.
- Аннотация
- Конспект начинается с типа raster: каждый растр содержит один или несколько каналов со значениями пикселей. Подробно разобрана утилита командной строки raster2pgsql — от расположения исполняемого файла до всех ключевых параметров; интерактивный конструктор собирает команду загрузки по выбранным флагам и объясняет каждый из них. Дальше — что происходит внутри базы: представления raster_columns и raster_overviews, нумерация тайлов rid, выпуклая оболочка тайла и знакомая по лекции 3 задача пространственной индексации. Практический блок на данных SRTM и Landsat 8 показывает пересечение растра с вектором, обрезку ST_Clip, объединение ST_Union и обе стороны преобразования растр—вектор с их принципиальными потерями. Аналитическая часть: метаданные и статистика (ST_SummaryStats с группировкой, ST_Histogram, ST_Quantile), извлечение каналов ST_Band, значения в точке ST_Value, уклон ST_Slope, переклассификация ST_Reclass, индекс топографической позиции и алгебра растров с вычислением NDVI через выражение и через функцию обратного вызова. Завершают конспект справочные списки функций: статистика, доступ к каналам и пространственные отношения между растрами.
- Пререквизиты
- Лекция 3 (GiST-индексация), лекция 4 (SRID и системы координат), практика 4 (векторные геометрии PostGIS). Работа с raster2pgsql упоминалась и в контексте вопросов к зачёту № 17 и 25.
- Мотивация
- В главе 3 РГР вы обрезали растр плотности населения по границе региона в QGIS — мышкой. Теперь представьте, что таких регионов восемьдесят пять, снимков — за двадцать лет, и всё это нужно пересчитывать каждый месяц. Ручная работа исключена: растры загружаются в PostGIS, а обрезка, статистика и вычисление индексов становятся SQL-запросами, которые можно автоматизировать. Один запрос — NDVI по всем полям области; второй — средняя высота по каждому району. Это и есть растровый анализ в базе данных.
1. Растр в PostGIS
Растр — это тип пространственных данных, используемый для представления растровых данных, например импортированных из файлов JPEG, TIFF, PNG, цифровых моделей рельефа. Каждый растр содержит один или более каналов, каждый из которых имеет набор значений в пикселях.
postgis_raster — в дополнение к базовому PostGIS
(Extensions → Create → Extension).
2. Загрузка растров с помощью raster2pgsql
raster2pgsql — инструмент командной строки, который поставляется
вместе с PostGIS. Если вы работаете в Windows и используете пакет приложений Stack
Builder, вы найдёте raster2pgsql.exe в папке
C:\Program Files\PostgreSQL\15\bin, где 15 — версия PostgreSQL,
которую вы используете.
2.1. Параметры командной строки
При запуске без аргументов raster2pgsql показывает все доступные параметры. Наиболее используемые из них:
-s SRID— задаёт SRID исходного растра. Если не указан, raster2pgsql пытается определить SRID по метаданным или использует SRID 0;-t размер-тайла— определяет размер тайла (ширина × высота в пикселях). Значение auto автоматически делит растр на равномерные тайлы (32–100 пикселей). Количество строк таблицы не меньше числа файлов;-R— регистрирует растр как внешний, хранящийся вне базы;-F— добавляет столбец с именем исходного файла растра (по умолчанию filename); полезно при разбивке на тайлы;-n имя-столбца— задаёт имя столбца для хранения имени файла (используется с -F);-l множитель— создаёт обзорные таблицы с именем o_множитель_имятаблицы; эти таблицы всегда хранятся в базе;-I— создаёт пространственный индекс GiST на столбце растра;-C— применяет стандартные ограничения на столбец растра;-e— выполняет инструкции отдельно, а не в одной транзакции;-G— выводит поддерживаемые форматы GDAL.
Режимы обработки таблиц (взаимоисключающие):
-c имя-таблицы— создаёт и заполняет новую таблицу (по умолчанию);-d имя-таблицы— удаляет таблицу, создаёт заново, заполняет данными;-a имя-таблицы— добавляет растр в существующую таблицу;-p имя-таблицы— только создаёт таблицу (подготовительный режим).
2.2. Пример загрузки
raster2pgsql -s 3763 -N -32767 -t 128x128 -I -C -M -d C:\Users\Evgenie\Downloads\Landsat8_L1TP_RGBN.TIF rasters.landsat8 | psql -d postgis_raster_db -h localhost -U postgres -p 5432
Разбор опций raster2pgsql:
-s 3763— SRID растра (в примере 3763 — конкретная система координат);-N -32767— значение NoData: все пиксели с этим значением интерпретируются как отсутствующие данные;-t 128x128— разбивает растровый файл на тайлы 128 × 128 пикселей, что оптимизирует работу с большими данными;-I— создаёт пространственный индекс GiST на растровом столбце, ускоряя пространственные запросы;-C— добавляет стандартные ограничения: проверку SRID, размеров тайлов и значений пикселей;-M— добавляет метаданные о минимальных и максимальных значениях пикселей в каждом тайле, что полезно для анализа;-d— удаляет существующую таблицу (если есть), создаёт новую и заполняет её данными;- путь к файлу — растровый файл Landsat 8 для загрузки;
rasters.landsat8— имя таблицы: rasters — схема, landsat8 — таблица;| psql— передаёт сгенерированный SQL-код напрямую в клиент PostgreSQL:-d— имя базы,-h— хост,-U— пользователь,-p— порт (по умолчанию 5432).
При указании параметра -G raster2pgsql перечисляет все поддерживаемые
растровые форматы. Сценарий для загрузки нескольких файлов с разбивкой на тайлы
и обзорными уровнями:
raster2pgsql -d -e -l 2,3 -I -C -M -F -Y -t 256x256 *.tif nyc_dem
Чтобы загрузить все файлы одинакового формата из папки, достаточно поставить символ * и через точку добавить расширение.
2.3. Конструктор команды raster2pgsql
Соберите свою команду загрузки: отмечайте флаги — команда и пояснения обновляются на лету. Попробуйте воспроизвести пример из раздела 2.2, а затем — сценарий с обзорными таблицами.
3. Метаданные растров в базе
PostGIS предоставляет два представления растровых каталогов: raster_columns и raster_overviews. Эти представления — часть системы метаданных PostGIS и используются для каталогизации информации о растровых данных в базе (аналогично geometry_columns для векторов — см. практику 4).
3.1. raster_columns
Каталог всех столбцов типа raster в базе данных. Колонки представления: r_table_catalog (имя текущей базы), r_table_schema (схема), r_table_name (таблица), r_raster_column (растровый столбец), srid (система координат), scale_x и scale_y (масштабы по осям), blocksize_x и blocksize_y (размеры блоков), same_alignment (одинаковое выравнивание), regular_blocking (регулярное блокирование), num_bands (количество каналов), pixel_types (типы пикселей), nodata_values (значения «нет данных»), out_db (хранение вне базы), extent (максимальный охват), spatial_index (наличие пространственного индекса).
3.2. raster_overviews
Каталогизирует информацию о таблицах обзоров (уменьшенных копий растра для быстрого просмотра); информация не дублирует raster_columns. Колонки: o_table_catalog, o_table_schema, o_table_name, o_raster_column — база, схема, таблица и столбец обзора; r_table_catalog, r_table_schema, r_table_name, r_raster_column — растровая таблица, обслуживаемая этим обзором; overview_factor — уровень пирамиды обзора: чем выше число, тем ниже разрешение таблицы.
Общая схема хранения растра в базе: основная таблица со ссылками на таблицу тайлов (rid, raster, filename), таблица систем координат (srid, auth_name, auth_srid, srtext) и обзорные таблицы с overview_factor.
3.3. Плагин raster2postgis в QGIS
Можно обойтись и без консоли: плагин raster2postgis загружает растр на сервер PostgreSQL прямо из QGIS. Работает, только если на сервере установлена утилита raster2pgsql; для первого запуска требуются права суперпользователя, а перед установкой плагина необходимо установить модуль Python unidecode.
4. Тайлы растра и пространственная индексация
Как «увидеть» нарезку на тайлы? Функция ST_ConvexHull вычисляет выпуклую оболочку геометрии — наименьшую выпуклую геометрию, которая окружает все геометрии входного набора. В общем случае выпуклая оболочка является полигоном; для тайла растра это его рамка. Выпуклая оболочка двух и более коллинеарных точек — линия, одной точки — точка.
Зачем это нужно? У каждого тайла есть rid: нумерация начинается с верхнего левого угла и заканчивается в правом нижнем.
Каждый тайл имеет координаты своих углов, например
POLYGON((293325 6321615, 297165 6321615, 297165 6317775, 293325 6317775)).
Возникает знакомый вопрос: как отсортировать данные так, чтобы быстро ответить
на пространственный запрос — например, находится ли точка (294325, 6331615) внутри
указанной области? Основная проблема в том, что проверять нужно обязательно
и координату X, и координату Y — это та самая задача пространственной индексации,
которую решают GiST-индексы и кривая Гильберта из
лекции 3.
Пример запроса для отображения фрагмента снимка в указанных границах:
SELECT ST_AsTIFF(ST_Union(rast), 'LZW') AS tiff FROM lc09_l2sp_008021_20240206_20240209_02_t1_sr_b1 WHERE ST_Intersects( ST_SetSRID( ST_GeomFromText('POLYGON((293325 6321615, 297165 6321615, 297165 6317775, 293325 6317775, 293325 6321615))'), 32621), -- SRID должен совпадать с системой координат растра rast );
5. Растр и вектор вместе
Входные данные примеров: цифровая модель рельефа SRTM и цветосинтезированное изображение Landsat 8 в формате TIFF (чёрные поля — значение «нет данных»), а также векторные шейп-файлы Португалии: железные дороги (линии), церкви (точки) и округа города Порту (полигоны).
5.1. Пересечение растра с вектором
CREATE TABLE schema_name.intersects AS SELECT a.rast, b.municipality FROM public.dem AS a, vectors.porto_parishes AS b WHERE ST_Intersects(a.rast, b.geom) AND b.municipality ILIKE 'porto';
Запрос отбирает тайлы ЦМР, пересекающие границу округа, — но тайлы остаются целыми, с «лишними» краями за границей.
5.2. Обрезка растра по вектору: ST_Clip
CREATE TABLE schema_name.clip AS SELECT ST_Clip(a.rast, b.geom, true), b.municipality FROM public.dem AS a, vectors.porto_parishes AS b WHERE ST_Intersects(a.rast, b.geom) AND b.municipality LIKE 'PORTO';
Третий аргумент true заполняет области вне полигона значением NoData — растр обрезается точно по границе (так же работала «Обрезка растра по маске» в QGIS в главе 3 РГР).
5.3. Объединение фрагментов: ST_Union
CREATE TABLE schema_name.union AS SELECT ST_Union(ST_Clip(a.rast, b.geom, true)) FROM public.dem AS a, vectors.porto_parishes AS b WHERE b.municipality ILIKE 'porto' AND ST_Intersects(b.geom, a.rast);
ST_Union собирает обрезанные тайлы в один непрерывный растр — теперь с ним можно работать как с единым изображением.
5.4. Растеризация и векторизация
Преобразования между моделями данных несимметричны:
- слои с категориальными растрами хорошо преобразуются в векторные слои: одна переменная преобразуется в один столбец, пиксели одинакового значения группируются;
- непрерывные растровые слои (высоты, температуры) не преобразуются осмысленно;
- векторные слои плохо преобразуются в растровые: каждый атрибут должен быть преобразован в отдельный растр, нет поддержки текстовых значений (например, «M34»), глобальные характеристики ареала теряют значение, топологические отношения между объектами теряются, разрешение должно быть высоким, чтобы соответствовать вектору, а обратное преобразование в исходный вектор очень сложно или невозможно.
В векторном слое каждый объект имеет собственный уникальный идентификатор; в растровом слое, преобразованном из векторного, каждый объект также должен сохранять свою уникальность.
Для растеризации PostGIS предоставляет функцию ST_AsRaster. Примеры её применения (в исходных материалах в этих примерах по ошибке повторялся код ST_Clip — здесь приведён корректный вызов по документации PostGIS):
-- пример 1: растеризация полигонов округов по образцу существующего растра CREATE TABLE schema_name.porto_raster AS SELECT ST_AsRaster(b.geom, a.rast, '8BUI', 255, 0) AS rast FROM public.dem AS a, vectors.porto_parishes AS b WHERE b.municipality ILIKE 'porto' LIMIT 1; -- пример 2: ST_AsRaster + ST_Union - один растр из всех полигонов SELECT ST_Union(ST_AsRaster(geom, 100, 100, '8BUI', 255, 0)) FROM vectors.porto_parishes WHERE municipality ILIKE 'porto';
6. Анализ растровых изображений
6.1. Метаданные и статистика
Помимо функций для получения метаданных на уровнях растра и канала, PostGIS предоставляет несколько функций для получения информативной статистики о составе и значениях пикселей в канале, которая помогает решить, как обрезать или переклассифицировать растры: ST_Count, ST_CountAgg, ST_Histogram, ST_Quantile, ST_SummaryStats, ST_SummaryStatsAgg и ST_ValueCount.
-- количество пикселей и метаданные SELECT ST_Count(rast), (ST_MetaData(rast)).* FROM rasters.dem LIMIT 1;
6.2. Извлечение канала: ST_Band
Чтобы извлечь один канал из многоканального растра, используется функция ST_Band:
6.3. Уклон: ST_Slope
ST_Slope — функция PostGIS, которая вычисляет угол наклона для каждого пикселя растрового изображения. Используется для анализа поверхности, например для определения крутизны или уклона ландшафта; угол наклона вычисляется на основе изменения высотных значений цифровой модели рельефа (DEM).
6.4. Классификация: ST_Reclass
ST_Reclass — функция переклассификации растровых данных: она изменяет значения пикселей на основе заданных диапазонов или условий. Например, можно заменить пиксели определённого диапазона на другие значения — скажем, преобразовать все значения меньше нуля в ноль.
6.5. Статистика: ST_SummaryStats
ST_SummaryStats возвращает сводную статистику — количество, сумму, среднее, стандартное отклонение, минимум и максимум — для канала растра. Статистику можно генерировать для каждого тайла или с группировкой:
6.6. Значение пикселя: ST_Value
ST_Value извлекает значение пикселя растра по указанным координатам. Пример: извлечение высот точек из таблицы places по ЦМР.
6.7. Индекс топографической позиции (TPI)
TPI — переменная второго порядка, позволяющая различать местоположения вдоль профиля склонов: от привершинных (пригребневых) элементарных поверхностей до подножий склонов и прикилевых элементов эрозионной сети.
6.8. Алгебра растров: NDVI
Существует два способа использования картографической алгебры в PostGIS: через выражение и через функцию обратного вызова. Классический пример — вычисление вегетационного индекса NDVI по снимку Landsat 8:
-- способ 1: выражение (алгебра двух каналов) CREATE TABLE rasters.ndvi AS SELECT ST_MapAlgebra( rast, 4, -- канал NIR (в файле RGBN каналы: 1=Red, 2=Green, 3=Blue, 4=NIR) rast, 1, -- канал Red '([rast1] - [rast2]) / ([rast1] + [rast2])::float', '32BF' ) AS rast FROM rasters.landsat8;
Способ 2 — функция обратного вызова: создаётся функция
schema_name.ndvi с параметрами value (трёхмерный массив значений double
precision с данными растров), pos (двумерный массив целых чисел с координатами
пикселей) и VARIADIC userargs (параметр переменной длины для произвольного количества
дополнительных текстовых аргументов); затем она передаётся в ST_MapAlgebra.
7. Справочник специальных функций
7.1. Статистика
- ST_Count — количество пикселей в заданном канале растра (по умолчанию канал 1); при exclude_nodata_value = true учитываются только пиксели, не равные значению NoData;
- ST_CountAgg — агрегат: количество пикселей в канале набора растров;
- ST_Histogram — набор записей, обобщающих распределение данных по диапазонам-бинам; количество бинов вычисляется автоматически, если не указано;
- ST_Quantile — квантили растра в контексте выборки или популяции: значение на 25 %, 50 %, 75 % процентили;
- ST_SummaryStats — сводная статистика (количество, сумма, среднее, стандартное отклонение, минимум, максимум) для канала растра;
- ST_SummaryStatsAgg — то же для набора растров (агрегат);
- ST_ValueCount — набор записей «значение — число пикселей с этим значением»; значения округляются до ближайшего целого, пиксели NoData по умолчанию не учитываются.
7.2. Доступ к каналам растра
- ST_BandMetaData — основные метаданные канала;
- ST_BandNoDataValue — значение, представляющее отсутствие данных;
- ST_BandIsNoData — true, если канал заполнен только значениями NoData;
- ST_BandPath — системный путь к каналу, хранящемуся в файловой системе;
- ST_BandFileSize — размер файла канала;
- ST_BandFileTimestamp — временная метка файла канала;
- ST_BandPixelType — тип пикселя канала;
- ST_MinPossibleValue — минимальное значение, которое может храниться в данном типе пикселя;
- ST_HasNoBand — true, если канала с указанным номером нет.
7.3. Пространственные отношения между растрами
- ST_Contains / ST_ContainsProperly — растр A содержит растр B (строго внутри — для Properly);
- ST_Covers / ST_CoveredBy — ни одна точка B не лежит вне A (и наоборот);
- ST_Disjoint — растры не пересекаются;
- ST_Intersects / ST_Overlaps — пересечение (Overlaps — частичное, без полного вложения);
- ST_Touches — есть общая точка, но внутренности не пересекаются;
- ST_SameAlignment / ST_NotSameAlignmentReason — одинаковы ли ориентация, масштаб, привязка и смещение (пиксели ложатся на одну сетку); вторая функция объясняет причину рассогласования;
- ST_Within / ST_DWithin / ST_DFullyWithin — вложенность и нахождение в пределах заданного расстояния.
Контрольные вопросы
-
Тип пространственных данных для растров (JPEG, TIFF, PNG, ЦМР); каждый растр содержит один или более каналов со значениями пикселей. Для работы требуется расширение postgis_raster в дополнение к базовому PostGIS.
-
-s — SRID растра; -N — значение NoData; -t — нарезка на тайлы 128×128; -I — GiST-индекс; -C — стандартные ограничения (SRID, размеры, значения); -M — метаданные мин/макс по тайлам; -d — пересоздать таблицу. Сгенерированный SQL передаётся конвейером в psql с параметрами подключения.
-
-c — создать и заполнить новую таблицу (по умолчанию); -d — удалить существующую, создать заново и заполнить; -a — добавить растры в существующую таблицу; -p — подготовительный режим: только создать структуру таблицы без данных. Режимы взаимоисключающие.
-
raster_columns — все растровые столбцы базы: SRID, масштабы, размеры блоков, число каналов, типы пикселей, NoData, охват, наличие индекса. raster_overviews — таблицы обзоров (уменьшенных копий): какую растровую таблицу обслуживает обзор и overview_factor — уровень пирамиды (чем выше, тем ниже разрешение).
-
ST_Intersects(rast, geom) отбирает тайлы, пересекающие полигон; ST_Clip(rast, geom, true) обрезает каждый тайл по границе, заполняя внешнее NoData; ST_Union собирает обрезанные тайлы в единый растр. Экспорт — ST_AsTIFF.
-
Каждый атрибут требует отдельного растра; текстовые значения не поддерживаются; глобальные характеристики ареала и топологические отношения теряются; для соответствия вектору нужно высокое разрешение; обратное преобразование в исходный вектор крайне сложно или невозможно. Хорошо векторизуются только категориальные растры.
-
Через выражение в ST_MapAlgebra ('([rast1]-[rast2])/([rast1]+[rast2])') и через функцию обратного вызова (PL/pgSQL-функция с параметрами value[][][] и pos[][], передаваемая в ST_MapAlgebra). NDVI = (NIR − Red) / (NIR + Red); в учебном файле RGBN каналы упорядочены как 1=Red, 2=Green, 3=Blue, 4=NIR, поэтому в ST_MapAlgebra подставляются каналы 4 и 1.
-
ST_SummaryStats (и ST_SummaryStatsAgg для набора растров), ST_Value, ST_Slope, ST_Reclass, ST_Histogram; дополнительно ST_Quantile — квантили, ST_ValueCount — частоты значений, ST_Count — число пикселей.
Источники
- PostGIS Documentation. Raster Reference : [сайт]. — URL: https://postgis.net/docs/RT_reference.html (дата обращения: 18.08.2026).
- PostGIS Documentation. Loading and Creating Rasters (raster2pgsql) : [сайт]. — URL: https://postgis.net/docs/using_raster_dataman.html (дата обращения: 18.08.2026).
- Обе, Р. PostGIS в действии / Р. Обе, Л. Су. — М. : ДМК Пресс, 2022. — 754 с.
- Weiss, A. Topographic Position and Landforms Analysis : poster presentation // ESRI User Conference. — San Diego, CA, 2001.