Bagaimana cara memanggil gdal_translate dari kode Python?

40

Apakah mungkin menggunakan API gdal untuk menelepon gdal_translatedari kode Python? Maksud saya bukan hanya mengeksekusi gdal_translate.exe dari sistem file, tetapi memanggilnya entah bagaimana dalam kode sehingga saya tidak perlu tahu direktori persisnya di mana gdal_translate dapat dieksekusi?

Katie E.
sumber
4
Ya, mulai gdal-2.1. Jawaban ini harus diterima sebagai benar.
Pete

Jawaban:

27

Sejak GDAL 2.1 (info lebih lanjut di sini ), utilitas GDAL dan OGR dapat digunakan sebagai fungsi perpustakaan. Contohnya:

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
Antonio Falciano
sumber
2
Semua opsi yang gdal.Translate()ada tercantum di sini: gdal.org/python/osgeo.gdal-module.html#TerjemahkanOpsi
Marcelo Villa
23

Lihat Tutorial API GDAL .

#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

Jika Anda ingin lebih banyak kontrol output, seperti mengubah ukuran, mengatur ulang, dll ... menggunakan VRT sebagai input, ini adalah bagaimana gdal_translate melakukannya secara internal.

pengguna2856
sumber
sayangnya ini tidak termasuk proyeksi ulang, kan?
Riccardo
1
@ belanda - tidak. Karena pertanyaannya tidak menyebutkan proyeksi ulang. Tentu saja Anda dapat memproyeksikan ulang raster dengan API python gdal. Jika Anda ingin tahu caranya, ajukan pertanyaan baru.
user2856
Saya sudah melakukannya di sini: gis.stackexchange.com/questions/103874/... tapi ini ditandai sebagai duplikat :-(
Riccardo
2
@butcher - yang ditutup sebagai duplikat dari pertanyaan ini. Pertanyaan Anda juga bertanya tentang gdal_translate. Apakah Anda sadar bahwa gdal_translate tidak memproyeksi ulang? Jika Anda ingin memproyeksi ulang, gunakan gdalwarp atau metode API python gdal - gdal.ReprojectImage
user2856
10

Ya, Anda dapat memanggil Utilitas GDAL dari dalam Python. Ada perbedaan yang sangat kecil dalam pendekatan tergantung pada apakah utilitas itu adalah exe dalam dirinya sendiri atau juga sepotong kode python. Bagaimanapun Anda harus menggunakan modul subproses :

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)

Anda akan melihat bahwa saya menambahkan tanda kutip lolos di jalur saya. Ini karena, pada Windows, saya mengalami masalah dengan jalur, terutama yang memiliki spasi atau di mana salah satu karakter '\' membuat karakter yang lolos secara tidak sengaja. Jadi, saya hanya mempertahankan jalan yang benar di aspec.

Jika Anda menggunakan salah satu utilitas python, lakukan saja hal yang sama kecuali exe Anda di awal string perintah subproses sekarang "C: \ python32 \ python.exe" (atau versi apa pun yang Anda miliki) dan elemen kedua adalah utilitas python yang ingin Anda gunakan.

Jelas Anda juga dapat beralih dari sistem file Anda daripada menggunakan konstanta hard-coded, tetapi ini hanyalah sebuah contoh.

EDIT - Generalisasi untuk plugin
QGIS QGIS membuat / memodifikasi sejumlah variabel lingkungan saat start up. Jadi, Anda dapat membangun variabel jalur umum ke pustaka / utilitas GDAL menggunakan ini (lihat Pengaturan-> Opsi-> Sistem) alih-alih jalur kode-keras pada contoh di atas.

MappaGnosis
sumber
Jadi saya tidak bisa melakukan ini? impor gdal_translate lalu panggil .main ()?
Katie E.
Tidak - itu tidak akan berhasil. gdal_translate bukan paket Python, jadi python tidak akan tahu apa-apa tentang itu. Anda akan mendapatkan pesan kesalahan "ImportError No Module bernama gdal_translate". Gunakan modul subproses untuk memanggilnya sebagai gantinya.
MappaGnosis
ok satu pertanyaan serupa dengan menggunakan gdal_retile.py .. Saya mencoba melakukan hal berikut: import gdal_retile gdal_retile.main ("- v -r bilinear -levels 4 -ps 2048 2048 -co \" tiled = YES \ "-targetDir cablepyramid - -optfile files.txt ") tetapi saya mendapatkan kesalahan: Opsi perintah tidak dikenal: - Ada ide mengapa?
Katie E.
Begitu saja saya tidak bisa melihat masalah kecuali dugaan saya mungkin tidak suka tombol '--optfile'. Yang terakhir tidak didokumentasikan.
MappaGnosis
@MappaGnosis Apakah ada alternatif gdal_translate dalam pustaka Python gdal?
multigoodverse
7

Saya melakukan ini dengan berbagai perintah gdal menggunakan sistem os.s yang dapat Anda gunakan untuk memanggil fungsi seperti dari baris perintah:

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

Ini juga dijelaskan dalam kuliah 7 di sini: http://www.gis.usu.edu/~chrisg/python/2009/

Maks
sumber
Perintah GDAL tersedia sebagai fungsi python di GDAL 2.1 hingga RFC 59.1 . Juga subprocess.calllebih aman daripada os.system.
Dmitri Chubarov
1
Seseorang perlu menulis contoh yang bagus dari fungsi-fungsi Python; Saya bergumul dengan gdal.Warp()selama beberapa jam untuk mendapatkan PG:sumber data cutlineDSNameuntuk mengemudi cutlineSQL. (Saya tahu, kan? Beberapa jam benar-benar menyelesaikan sesuatu ? Kengeriannya! </kidding>). Akhirnya berhasil, dan tampaknya secara signifikan lebih cepat daripada os.system()atau subprocess.call(). Itu bekerja ~ 2 juta cutlines, jadi saya tidak akan tahu apakah itu sebenarnya lebih cepat sampai beberapa waktu malam ini ... tapi itu bekerja dengan tepat.
GT.
3

Berikut adalah kode cepat untuk siapa pun yang ingin menyimpan band dari TIF multi-band komposit ke file individual menggunakan GDAL Translate in 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

Ini bisa berguna untuk pemrosesan lebih lanjut (mis. Menggunakan Rasterio, seperti di sini ).

15Langkah
sumber