Use of Python with GDAL. How to speed up ?
Julien Fiore
julienfiore at gmail.com
Fri Mar 17 05:08:43 EST 2006
Hi,
I wrote a function to compute openness (a digital elevation model
attribute). The function opens the gdal-compatible input raster and
reads the values in a square window around each cell. The results are
stored in a "1 line buffer". At the end of the line, the buffer is
written to the output raster.
It runs very slowly and I suspect the raster access to be the main
bottleneck. Do you have any idea to speed-up the process ?
Thanks for any help.
Julien
Here is the code:
#################################################
## openness.py
##
## Julien Fiore, UNIGE
##
## code inspired by Matthew Perry's "slope.cpp"
# import
import numpy
import gdal
from gdal.gdalconst import * # for GA_ReadOnly in gdal.gdal.Open()
def openness(infile, outfile, R=1):
"""
Calculates the openness of a gdal-supported raster DEM.
Returns nothing.
Parameters:
infile: input file (georeferenced raster)
outfile: output file (GeoTIF)
R: opennness radius (in cells). Window size = (2*R +
1)**2
"""
# open inGrid
try:
inGrid = gdal.gdal.Open(infile, GA_ReadOnly )
except IOError:
print 'could not open inGrid'
inGridBand = inGrid.GetRasterBand(1) # get raster band
# get inGrid parameters
geoTrans = inGrid.GetGeoTransform() # returns list
(xOrigin,xcellsize,...)
cellSizeX = geoTrans[1]
cellSizeY = geoTrans[5]
nXSize = inGrid.RasterXSize
nYSize = inGrid.RasterYSize
nullValue = inGridBand.GetNoDataValue()
# Create openness output file
format = "GTiff"
driver = gdal.gdal.GetDriverByName( format )
outGrid=driver.CreateCopy(outfile,inGrid) # Creates output raster
with
# same properties as
input
outGridBand = outGrid.GetRasterBand(1) # Access Band 1
outGridBand.SetNoDataValue(nullValue)
# moving window
winSize= 2*R + 1
# openness buffer array (1 line)
buff = inGridBand.ReadAsArray(xoff=0, yoff=0, win_xsize=nXSize,
win_ysize=1)
# create distance array for Openness
dist=numpy.zeros((winSize,winSize),float)
for i in range(winSize):
for j in range(winSize):
dist[i][j]=numpy.sqrt((cellSizeX*(i-R))**2 +
(cellSizeY*(j-R))**2)
# openness loop
for i in range(nYSize):
for j in range(nXSize):
containsNull = 0
# excludes the edges
if (i <= (R-1) or j <= (R-1) or i >= (nYSize-R) or j >=
(nXSize-R) ):
buff[0][j] = nullValue
continue # continues with loop next iteration
# read window
win = inGridBand.ReadAsArray(j-R, i-R, winSize, winSize)
# Check if window has null value
for value in numpy.ravel(win):
if value == nullValue :
containsNull = 1
break # breaks out of the smallest enclosing loop
if (containsNull == 1):
# write Null value to buffer
buff[0][j] = nullValue
continue # continues with loop next iteration
else:
# openness calculation with "tan=opp/adj"
# East
E=180.0 # 180 = max angle possible between nadir and
horizon
for k in range(R+1,2*R):
angle= 90.0 -
numpy.arctan((win[k][R]-win[R][R])/dist[k][R])
if angle<E: E=angle
# West
W=180.0
for k in range(0,R-1):
angle= 90.0 -
numpy.arctan((win[k][R]-win[R][R])/dist[k][R])
if angle<W: W=angle
# North
N=180.0
for k in range(0,R-1):
angle= 90.0 -
numpy.arctan((win[R][k]-win[R][R])/dist[R][k])
if angle<N: N=angle
# South
S=180.0
for k in range(R+1,2*R):
angle= 90.0 -
numpy.arctan((win[R][k]-win[R][R])/dist[R][k])
if angle<S: S=angle
# mean openness angle
buff[0][j]= (E+W+N+S)/4
# Writes buffer to file
outGridBand.WriteArray(array=buff,xoff=0, yoff=i)
outGridBand.FlushCache()
# close datasets
del inGrid
del outGrid
return
if __name__ == "__main__":
# meazure time taken
from time import clock
startTime=clock() # START...
# Import Psyco if available
psycoBool=False
try:
import psyco
psyco.full()
psycoBool=True
except ImportError:
pass
startTime=clock()
# openness parameters
infile = 'E:/GIS/CH/VD/lidar/lowcut_filter/gaussian/xsmall5'
outfile = 'E:/GIS/CH/VD/lidar/openness/openness.tif' # geotiff
(.tif)
R=4
# call openness function
openness(infile,outfile,R)
endTime = clock() # ...END
# print information
print '\nOpenness OK, R=' +str(R) + '; Time elapsed: ' +
str(endTime-startTime) + ' seconds'
print 'psyco = ' + repr(psycoBool)
##############################################################
More information about the Python-list
mailing list