Is it possible to use some gdal API to call gdal_translate
from Python code? I do not mean simply executing the gdal_translate.exe from the file system, but rather call it somehow in code so I do not need to know the exact directory the gdal_translate executable is in?
-
5Yes, as of gdal-2.1. This answer should be accepted as correct.– PeteCommented May 19, 2017 at 21:53
6 Answers
Since GDAL 2.1 (more info here), GDAL and OGR utilities can be used as library functions. For instance:
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
If you are going to use projWin
parameter make sure input raster has SRID set:
gdal_edit.py -a_srs EPSG:4326 input.tif
-
3All the options that
gdal.Translate()
takes are listed here: gdal.org/python/osgeo.gdal-module.html#TranslateOptions Commented Oct 6, 2018 at 17:34 -
2I've tried to use this and don't get any errors but the output file isn't created. Any ideas why?– smartseCommented Nov 6, 2020 at 16:24
-
also getting no output file and no errors. Output paths and projWin params are correct.– RobCommented Jan 19, 2021 at 17:26
-
updated link with
gdal.Translate()
options here: gdal.org/api/python/utilities.html#osgeo.gdal.Translate– EvhzCommented Aug 16 at 18:46
The below still works but is outdated. For recent versions of GDAL, see this answer.
See the GDAL API Tutorial.
#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
If you want more output control, such as resizing, subsetting, etc... use a VRT as input, this is how gdal_translate does it internally.
-
-
1@butcher - no. Because the question did not mention reprojection. Of course you can reproject rasters with the gdal python API. If you want to know how, ask a new question.– user2856Commented Jul 2, 2014 at 7:00
-
I have done it already here: gis.stackexchange.com/questions/103874/… but thius was marked as a duplicate :-(– RiccardoCommented Jul 2, 2014 at 7:30
-
2@butcher - that was closed as a duplicate of this question. Your question also asks about gdal_translate. Are you aware that gdal_translate does not reproject? If you want to reproject, use gdalwarp or the gdal python API method - gdal.ReprojectImage– user2856Commented Jul 2, 2014 at 9:11
Yes you can call the GDAL Utilities from within Python. There are very minor differences in the approach depending on whether the utility is an exe in its own right or also a piece of python code. Either way though you need to use the subprocess module:
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)
You will notice that I add escaped quotation marks around my paths. This is because, on Windows, I have had trouble with paths, especially ones with spaces or where one of the '\' characters makes another accidental escaped character. So, I just preserve the proper path in aspec as it were.
If you are using one of the python utilities, just do the same thing except your exe at the start of the subprocess command string is now "C:\python32\python.exe" (or whichever version you have) and your second element is the python utility you want to use.
Obviously you can also iterate over your file system rather than using hard-coded constants, but this is just an example.
EDIT - Generalizing for QGIS plugins
QGIS creates/modifies a number of environment variables at start up. So, you can build generalised path variables to the GDAL libraries/utilities using these (see Settings->Options->System) instead of the hard-coded paths in the example above.
-
So I can't do this? import gdal_translate and then call the .main() ?– Katie E.Commented Nov 29, 2012 at 17:06
-
No - that won't work. gdal_translate is not a Python package, so python won't know anything about it. You will get an error saying "ImportError No Module named gdal_translate". Use the subprocess module to call it instead. Commented Nov 29, 2012 at 17:37
-
ok one similiar questions with using gdal_retile.py.. I tried to do the following: import gdal_retile gdal_retile.main("-v -r bilinear -levels 4 -ps 2048 2048 -co \"tiled=YES\" -targetDir cablepyramid --optfile files.txt") but I get the error: Unrecognised command option: - Any idea why?– Katie E.Commented Nov 29, 2012 at 20:01
-
Offhand I can't see the issue except my guess is that it might not like the '--optfile' switch. The latter is not documented. Commented Nov 30, 2012 at 9:25
-
@MappaGnosis Is there an alternative of gdal_translate within Python gdal library? Commented Sep 23, 2013 at 12:43
I do this with various gdal commands using os.system which you can use to call functions just as from command line:
os.system("gdal_translate -of GTiff " + sourcefile + " " + destinationfile)
It's also described in lecture 7 here: http://www.gis.usu.edu/~chrisg/python/2009/
-
GDAL commands are available as python functions in GDAL 2.1 through RFC 59.1. Also
subprocess.call
is safer thanos.system
. Commented Oct 27, 2016 at 12:36 -
2Someone needs to write up a good example of those Python functions; I wrestled with
gdal.Warp()
for a couple of hours to properly get aPG:
datasource ascutlineDSName
to drive thecutlineSQL
. (I know, right? A couple of hours actually working something out? The horror!</kidding>). Got it working eventually, and it seems to be significantly faster thanos.system()
orsubprocess.call()
. It's doing ~2 million cutlines, so I won't know if it's actually faster until some time tonight... but it's working exactly right.– GT.Commented Feb 22, 2017 at 6:46
Here is a quick code for anyone wanting to save bands from a composite multi-band TIF to individual files using 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
This could be useful for further processing (e.g. using Rasterio, like here).
Here is a version if you face issues with implementations suggested by @MappaGnosis It will print errors if any to help you fix arguments.
import subprocess
common_args=['gdal_translate', '-sds', '-co', 'compress=LZW']
def export_hd5_to_Geotiff(input_hdf_file):
target_dir=input_hdf_file.replace('.hdf','')
target_file=ntpath.basename(input_hdf_file).replace('.hdf','.tif')
target_with_path=os.path.join(target_dir,target_file)
def youCanQuoteMe(item):
return "\"" + item + "\""
current_args=[]
current_args.extend(common_args)
current_args.append(input_hdf_file)
current_args.append(target_with_path)
print(current_args)
if not os.path.exists(target_dir):
os.makedirs(target_dir)
proc = subprocess.Popen(current_args, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout,stderr=proc.communicate()
print(stdout)
print(stderr)
hdf_files=[item for item in os.listdir(src_path) if item.endswith('.hdf')]
for hdf_file in hdf_files:
export_hd5_to_Geotiff(os.path.join(src_path,hdf_file))
break