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?
Is it possible to use some gdal API to call
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
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.
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.
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/
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