Как вызвать gdal_translate из кода Python?

40

Можно ли использовать какой-нибудь gdal API для вызова gdal_translateиз кода Python? Я не имею в виду просто выполнить gdal_translate.exe из файловой системы, а скорее как-то вызвать его в коде, чтобы мне не нужно было знать точный каталог, в котором находится исполняемый файл gdal_translate?

Кэти Э.
источник
4
Да, по состоянию на gdal-2.1. Этот ответ должен быть принят как правильный.
Пит

Ответы:

27

Начиная с GDAL 2.1 (подробнее здесь ), утилиты GDAL и OGR можно использовать в качестве библиотечных функций. Например:

from osgeo import gdal

ds = gdal.Open('input.tif')
ds = gdal.Translate('output.tif', ds, projWin = [-75.3, 5.5, -73.5, 3.7])
ds = None
Антонио Фальчано
источник
2
Все возможные варианты gdal.Translate()перечислены здесь: gdal.org/python/osgeo.gdal-module.html#TranslateOptions
Marcelo Villa
23

Смотрите Учебное пособие по GDAL API .

#Import gdal
from osgeo import gdal

#Open existing dataset
src_ds = gdal.Open( src_filename )

#Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )

#Output to new format
dst_ds = driver.CreateCopy( dst_filename, src_ds, 0 )

#Properly close the datasets to flush to disk
dst_ds = None
src_ds = None

Если вы хотите больше контроля над выходом, такого как изменение размера, подмножество и т. Д., Используйте VRT в качестве входных данных, это то, как gdal_translate делает это внутренне.

user2856
источник
к сожалению, это не включает в себя повторное проецирование, не так ли?
Риккардо
1
@butcher - нет. Потому что в вопросе не упоминается репроекция. Конечно, вы можете перепроектировать растры с помощью gdal python API. Если вы хотите узнать как, задайте новый вопрос.
user2856
Я сделал это уже здесь: gis.stackexchange.com/questions/103874/… но это было отмечено как дубликат :-(
Риккардо
2
@butcher - это было закрыто как дубликат этого вопроса. Ваш вопрос также спрашивает о gdal_translate. Вы знаете, что gdal_translate не перепроектирует? Если вы хотите перепроектировать, используйте gdalwarp или метод gdal python API - gdal.ReprojectImage
user2856
10

Да, вы можете позвонить в GDAL Utilities из Python. Есть очень незначительные различия в подходе в зависимости от того, является ли утилита exe-программой или же частью кода Python. В любом случае вам нужно использовать модуль подпроцесса :

import subprocess

# constants
gdalTranslate = r'C:\Program Files\GDAL\gdal_translate.exe'
src = r"C:\somefolder\somefile.tif"
dst = r"C:\someotherfolder\myresul.tif"
cmd = "-ot float32 -outsize 25 25"  # just for example!

# see note below
def youCanQuoteMe(item):
    return "\"" + item + "\""

fullCmd = ' '.join([gdalTranslate, cmd, youCanQuoteMe(src), youCanQuoteMe(dst)])
subprocess.popen(fullCmd)

Вы заметите, что я добавляю экранированные кавычки вокруг моих путей. Это связано с тем, что в Windows у меня были проблемы с путями, особенно с пробелами, или из-за того, что один из символов '\' создает другой случайно экранированный символ. Так что я просто сохраняю правильный путь в aspec как бы.

Если вы используете одну из утилит python, просто сделайте то же самое, за исключением того, что ваш exe в начале командной строки подпроцесса теперь называется "C: \ python32 \ python.exe" (или какой бы версией вы не пользовались), а ваш второй элемент - утилита python, которую вы хотите использовать.

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

РЕДАКТИРОВАТЬ - Обобщение для плагинов QGIS
QGIS QGIS создает / изменяет ряд переменных среды при запуске. Таким образом, вы можете создавать обобщенные переменные пути для библиотек / утилит GDAL, используя их (см. Настройки-> Параметры-> Система) вместо жестко заданных путей в примере выше.

MappaGnosis
источник
Так я не могу этого сделать? импортировать gdal_translate и затем вызывать .main ()?
Кэти Э.
Нет - это не сработает. gdal_translate не является пакетом Python, поэтому python ничего об этом не узнает. Вы получите сообщение об ошибке «ImportError No Module с именем gdal_translate». Вместо этого используйте модуль подпроцесса.
MappaGnosis
Хорошо, один похожий вопрос с использованием gdal_retile.py .. Я попытался сделать следующее: import gdal_retile gdal_retile.main ("- v -r bilinear -levels 4 -ps 2048 2048 -co \" tiled = YES \ "-targetDir cablepyramid - -optfile files.txt "), но я получаю сообщение об ошибке: Нераспознанный параметр команды: - Есть идеи, почему?
Кэти Э.
Вручную я не вижу проблемы, за исключением того, что думаю, что ей может не понравиться ключ «--optfile». Последнее не задокументировано.
MappaGnosis
@MappaGnosis Есть ли альтернатива gdal_translate в библиотеке Python gdal?
мультигудверс
7

Я делаю это с различными командами gdal, используя os.system, которую вы можете использовать для вызова функций так же, как из командной строки:

os.system("gdal_translate -of GTiff " + sourcefile + " " +  destinationfile)

Это также описано в лекции 7 здесь: http://www.gis.usu.edu/~chrisg/python/2009/

Максимум
источник
Команды GDAL доступны как функции python в GDAL 2.1 по RFC 59.1 . И subprocess.callбезопаснее os.system.
Дмитрий Чубаров
1
Кто-то должен написать хороший пример этих функций Python; Я боролся с ним gdal.Warp()в течение нескольких часов, чтобы правильно получить PG:источник данных, cutlineDSNameчтобы управлять cutlineSQL. (Я знаю, верно? Несколько часов на самом деле что-то решает ? Ужас! </ Kidding>). Со временем все заработало, и кажется, что оно значительно быстрее os.system()или subprocess.call(). Это делает ~ 2 миллиона порезов, так что я не буду знать, будет ли это на самом деле быстрее, до некоторого времени сегодня вечером ... но это работает совершенно правильно.
GT.
3

Вот краткий код для тех, кто хочет сохранить полосы из составного многоканального TIF-файла в отдельные файлы с помощью GDAL Translate в Python.

import gdal

in_path = 'C:/GIS/Sample.tif' #input composite raster
out_path = 'C:/GIS/Output/' #output directory for individual bands as files

#Open existing raster ds
src_ds = gdal.Open(in_path)

for i in range(1,src_ds.RasterCount +1): #Save bands as individual files
    out_ds = gdal.Translate(out_path + 'band' + str(i) + '.tiff', src_ds, format='GTiff', bandList=[i])
    out_ds=None

Это может быть полезно для дальнейшей обработки (например, с использованием Растерио, как здесь ).

15Step
источник