[gdal-dev] ReadAsArray misbehaving...

Even Rouault even.rouault at mines-paris.org
Fri Sep 3 13:52:26 EDT 2010


Riann,

hum, I think you've hit a classical problem with the use of the GDAL python 
bindings. The root of your problem is likely the following line:

 reader = RasterReaderWriter(gdal.Open(iFilename).GetRasterBand(1))

Currently the GDAL python bindings do a poor job with life cycle management of 
native underlying objects. When chaining the calls, some objects can go out-
of-scope and are then destroyed. Specifically, the band object doesn't keep the 
dataset object alive, so the RasterReaderWriter() constructor will get a band 
object with a ghost dataset. This can typically result in application crashes, 
or as you've observed various corruptions.

All in all, I'd advise you rewriting the above as :

ds = gdal.Open(iFilename)
band = ds.GetRasterBand(1)
reader =  RasterReaderWriter(band)
....
.....
ds = None # we can drop the reference on the dataset when we don't need to use 
the reader.

An alternative if you don't want to keep the reference on the dataset in the 
calling code, is to pass both the dataset and the band to RasterReaderWrite() 
so that it can stores them in member variables of the class.

Best regards,

Even

Le vendredi 03 septembre 2010 12:39:09, Riaan van den Dool a écrit :
> I have recently started a new open-source project that will use gdal
> extensively, named scikits.eartho.
> 
> The vision is to implement some advanced algorithms and ideas that we
> develop and work with at the South African Satellite Applications Centre
> (SAC) for use in Python (SciPy).
> 
> I am experiencing some trouble with RasterBand.ReadAsArray.
> 
> My python code:
> 
> import osgeo.gdal as gdal
> 
> class RasterReaderWriter:
>     def __init__(self,  raster):
>         self.raster = raster
>         self.tileWidth =1024
>         self.tileHeight = 1024
>         self.tileNum = 0
> 
>     def setTileSize(self,  width,  height):
>         self.tileWidth =width
>         self.tileHeight = height
> 
>     def resetIterator(self):
>         self.tileNum = 0
> 
>     def readNextTile(self):
>         tileRaster,  offsetX,  offsetY,  width,  height  =
> self.readTile(self.tileNum)
>         self.tileNum = self.tileNum + 1
>         return tileRaster,  offsetX,  offsetY,  width,  height
> 
>     def readTile(self,  tileNum):
>         tilesInWidth = self.raster.XSize / self.tileWidth + 1
>         offsetX = tileNum % tilesInWidth * self.tileWidth
>         offsetY = tileNum / tilesInWidth * self.tileHeight
>         width = min(self.tileWidth,  self.raster.XSize - offsetX)
>         height = min(self.tileHeight,  self.raster.YSize - offsetY)
>         print offsetX,  offsetY,  width,  height
>         tileRaster = self.raster.ReadAsArray(offsetX,  offsetY, width,
> height)
>         return tileRaster,  offsetX,  offsetY,  width,  height
> 
> 
> 
> 
> reader = RasterReaderWriter(gdal.Open(iFilename).GetRasterBand(1))
> print reader.raster.XSize
> print reader.raster.YSize
> tile, offsetX, offsetY, width, height = reader.readNextTile()
> 
> Before the call to readNextTile() the raster XSize and YSize is correct.
> After the call the raster seems to have been corrupted as the XSize and
> YSize have invalid values.
> 
> Any help would be appreciated!
> 
> Riaan


More information about the gdal-dev mailing list