Gdal: отсечение растра другим растром

14

Я пишу простую утилиту для обрезки пакетов многоканальных растровых файлов геотифов в одну и ту же (меньшую) область. Используя gdalwarp, я легко могу обрезать файл, используя шейп-файл с одним полигоном:

gdalwarp -cutline clipper.shp -crop_to_cutline input.tif output.tif

Однако фактическая область, в которую я хочу обрезать, всегда будет первоначально определяться другим растровым файлом геотифов, а не шейп-файлом. Было бы хорошо, если бы я мог использовать экстент этого растра в качестве файла отсечения, но я не уверен, как это сделать. Неудивительно, что следующее не работает (оно не вызывает ошибку, оно просто ничего не производит):

gdalwarp -cutline clipper.tif-crop_to_cutline input.tif output.tif

Итак, мой вопрос, есть ли способ снабдить растром gdalwarp -cutline? Альтернативно, есть ли другая функция gdal, которая может обрезать растр, используя другой растр? Если ни то, ни другое невозможно, существует ли очень простой способ создания шейп-файла с одним полигоном, определяемым экстентом растра?

Этот код будет заключен в более обширный скрипт на python, поэтому я могу использовать утилиты gdal для командной строки или любые привязки python для gdal.

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

Джо
источник

Ответы:

11

Я не знаю, возможно ли обрезать растр с помощью другого растра, но вы можете использовать gdaltindex, чтобы построить шейп-файл с размером вашего растра.

http://www.gdal.org/gdaltindex.html

lejedi76
источник
4
gdaltindex отлично работает, чтобы сделать вырезанный шейп-файл из моего начального растра. Чтобы решить проблему, я использую gdaltindex clipper.shp clipper.tif, а затемgdalwarp -cutline clipper.shp -crop_to_cutline input.tif output.tif
Джо
Я использовал этот подход, но обнаружил, что в обрезанной версии он иногда был отключен на один пиксель. Я думаю, что проще вычислить ваши целевые экстенты, как ответ Ксавье ниже, а затем использовать gdalwarp и указать -te_srs для обработки несоответствующих CRS.
Джон
7

Для неправильных полигонов и при условии, что ваш растровый файл geotiff является двоичным, вы можете использовать GDAL_Calc :

GDAL_Calc.py -A Mask.tif -B CutBigImageToClip.tif --outfile=SmallerFile.tif --NoDataValue=0 --Calc="B*(A>0)" 

Этот запрос будет заполнять 0, где Mask.tif <= 0 и BigImage, где Mask> 0. Для этого оба растра должны иметь одинаковый размер ячейки, строки и столбцы. Чтобы извлечь те же экстенты, используйте GDAL_Translate с -projwin ulx uly lrx lryпараметром (прямоугольник находится в проецируемых координатах), но убедитесь, что прямоугольник projwin не распространяется по краям любого растра.

GDAL_Translate -of GTIFF -projwin ulx uly lrx lry BigImageToClip.tif CutBigImageToClip.tif

Подставьте значения для поля projwin, полученного из Mask.

Майкл Стимсон
источник
1
+1 Это полезная информация, но я думаю, что смогу решить свою проблему за несколько шагов, используя ответ @ lejedi.
Джо
4

Решение в Python напрямую, без придания формы:

import gdal
from gdalconst import GA_ReadOnly

data = gdal.Open('img_mask.tif', GA_ReadOnly)
geoTransform = data.GetGeoTransform()
minx = geoTransform[0]
maxy = geoTransform[3]
maxx = minx + geoTransform[1] * data.RasterXSize
miny = maxy + geoTransform[5] * data.RasterYSize
call('gdal_translate -projwin ' + ' '.join([str(x) for x in [minx, maxy, maxx, miny]]) + ' -of GTiff img_orig.tif img_out.tif', shell=True)
XavierCLL
источник
1
NB. Это решение работает, только если они находятся в одной SRS.
Skylion
@Skylion Но вы можете легко объяснить это, включив опцию -te_srs, хотя вам также нужно использовать gdalwarp вместо опции -te.
Джон