RasterToNumPyArray gives an error

6539
10
12-15-2011 10:30 PM
GraziaZulian
New Contributor II
I'm having problems by using RasterToNumPyArray.

With the smal test data base it works, but if I try with a huge dataset (columns and rows: 67000, 58000, cellsize: 100 m) it gives me this error:

Traceback (most recent call last):
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 309, in RunScript
    debugger.run(codeObject, __main__.__dict__, start_stepping=0)
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\pythonwin\pywin\debugger\__init__.py", line 60, in run
    _GetCurrentDebugger().run(cmd, globals,locals, start_stepping)
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\pythonwin\pywin\debugger\debugger.py", line 624, in run
    exec cmd in globals, locals
  File "D:\ES_Map\recreationnew\RecNumpy2.py", line 31, in <module>
    in1 = arcpy.RasterToNumPyArray(arcpy.env.workspace + "\\eu_coastna") #arcpy.RasterToNumPyArray(input1)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\__init__.py", line 1113, in RasterToNumPyArray
    return _RasterToNumPyArray(*args, **kwargs)
RuntimeError: ERROR 999998: Unexpected Error.


could you help me please.
here is a simple example of my code
Tags (2)
0 Kudos
10 Replies
DavidWilton
Occasional Contributor II

I ran into this issue so I wrote an iterator class to do this. In my case I wanted to return the X,Y,Z values but you could easily modify to return the numpy array.

It can be used simply like this:

for block in RasterBlockIterator(raster, no_data_val=self.no_data_val):
   for point in block:
      x = point[0]
      y = point[1] 
      z = point[2]‍‍‍‍‍

The iterator class. If you want the numpy array just return the arr on line 62. By default it works in blocks of 1000*1000

class RasterBlockIterator:
    """Iterator that extracts tiles of data from a Esri Raster."""

    def __init__(self, raster: arcpy.Raster, tile_size=(1000, 1000), no_data_val=np.nan):
        """
        :param raster: Raster to iterate
        :param tile_size: size of each block/tile to extrac to numpy array
        :param no_data_val: value in the raster which should be treated as no data
        """
        self.tile_size = tile_size
        self.raster = raster
        self.no_data_val = no_data_val
        self.cell_size = raster.meanCellHeight
        self.pos = 0

        # work out the size of all the block to create. They won't be extracted at this point
        t_rows = raster.height
        t_cols = raster.width
        x_min = raster.extent.XMin
        y_min = raster.extent.YMin
        self.tiles = []
        for row in range(0, t_rows, tile_size[1]):
            for col in range(0, t_cols, tile_size[0]):
                colend = min([t_cols, col + tile_size[0]])
                rowend = min([t_rows, row + tile_size[1]])
                xstart = x_min + (col * self.cell_size)
                ystart = y_min + (row * self.cell_size)
                self.tiles.append(namedtuple('tile', 'colstart colend rowstart rowend xstart ystart')(
                    colstart=col,
                    colend=colend,
                    rowstart=row,
                    rowend=rowend,
                    xstart=xstart,
                    ystart=ystart
                ))

    def __iter__(self):
        return self

    def __len__(self):
        return len(self.tiles)

    def __next__(self) -> List[Tuple[float, float, float]]:

        try:
            tile = self.tiles[self.pos]
        except IndexError:
            raise StopIteration

        lower_l = arcpy.Point(tile.xstart, tile.ystart)
        ncols = tile.colend - tile.colstart
        rnrows = tile.rowend - tile.rowstart
        arr = arcpy.RasterToNumPyArray(self.raster, nodata_to_value=np.nan,
                                       lower_left_corner=lower_l,
                                       ncols=ncols, nrows=rnrows)
        # Loop over rows and extract X,Y,Z
        output_data = [
            (j * self.cell_size + tile.xstart, i * self.cell_size + tile.ystart, value)
            for i, row in enumerate(arr)
            for j, value in enumerate(row)
            if not self.no_data_val == value and not np.isnan(value)
        ]

        self.pos += 1
        return output_data‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

```

0 Kudos