1

I have a numpy array (called out_window) with the following values:

out_window:

[[[499 498 481]
  [494 490 464]
  [483 480 -1]
  [482 -1 -1]]]

This numpy array was obtained by clipping a raster file using a polygon feature and altering only those elements with value different to -1 (-1 is NoData)

I'm trying to update that same raster file with those new values.

import rasterio
import geopandas

raster_in = r'C:\.......\raster_in_file.tif'
raster_out = r'C:\.......\raster_out_file.tif'
copy(raster_in, raster_out)
polyg = gpd.read_file(gdb_vml_polygs, driver='FileGDB', layer=fc_vml_polygs)

out_window, out_transform = mask(raster_in, polyg['geometry'], all_touched=True, crop=True)

out_meta = raster_in.meta.copy()                        

#this is not relevant
width = ...
height = ...
x = ...
y = ...

with rasterio.open(raster_out, "r+", **out_meta) as dest:
    dest.write(out_window, window=Window(x, y, width, height))
dest.close()

The problem is that the instruction dest.write(.....) is overwriting the raster with all 12 values of the out_window array. I do not want to overwrite the raster with the -1 values. Those 3 elements of the raster should be left unaltered.

Is there any way to do this?

4
  • 1
    Can you read the original array specifying a window as well? Commented Jul 22, 2019 at 15:12
  • That's what I ended up doing actually. It works. It just seemed to me a bit too much of a hassle. Commented Jul 22, 2019 at 15:42
  • Well, you just need to write two lines more: one to read the original array and one to replace NoData values with original values (using np.where). Of course, it could be a parameter in the .write() method but its probably not implemented yet. Maybe it could be a good feature to contribute to rasterio if you have the time. Furthermore, feel free to post your answer so people with the same problem in the future have this as a reference. Commented Jul 22, 2019 at 16:08
  • You're right. It actually meant only one more line since I already had a np.where line to change values different to NoData of the array for their average value. Commented Jul 23, 2019 at 11:53

1 Answer 1

1

Issue was overcome by adding a line to read original values using window with same dimensions and same top left cell position than array produced by clipping with polygon.

#Reading tif file
raster = rasterio.open(raster_path)

#copy of raster metadata
out_meta = raster.meta.copy()  

#clipping raster using a polygon
out_window, out_transform = mask(raster, polygon, all_touched=True, crop=True)

#Using 'out_meta' 'out_window' and 'out_transform' we can obtain window dimensions
#and position of top left cell of the window => x, y, width, height

#Reading original values using same size window as array produced by clipping with polygon
window_orig = raster.read(1, window=Window(x, y, width, height))

#Swapping values different to NoData with their average value.
#If NoData then use original values
window_avg = (np.where(out_window!=-1, int(round(avg,0)), window_orig))

#Writing back to raster
with rasterio.open(raster_path, "r+", **out_meta) as dest:
     dest.write(window_avg, window=Window(x, y, width, height))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.