Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to overwrite raster opened with rioxarray.open_rasterio ? #485

Closed
openSourcerer9000 opened this issue Mar 8, 2022 · 3 comments
Closed
Labels
question Further information is requested

Comments

@openSourcerer9000
Copy link

using rioxarray.open_rasterio and subsequently rio.to_raster to edit a raster file raises a permission denied error. I can't figure out any way make changes to a TIF and then overwrite it again. Calling .close() on the dataarray seems to have no effect either.

tif = rioxarray.open_rasterio(tifpath)
tif.close()
tif.rio.to_raster(tifpath)

CPLE_AppDefinedError: Deleting ....tif failed: Permission denied

Expected behavior:
overwrite the file, and tif.close() statement to be unnecessary.

As I understand it, xarray reads serialized data lazily, which is why open_rasterio would leave the file open? If that's not accurate, then open_rasterio should either close the file itself, or be implemented as a context manager. Otherwise, it makes sense that rio.to_raster() should be closing the file before overwriting it.

As of now, the only way I've been able to edit a raster is to save as a different file, close the python kernel, and manually copy the new file over, which defeats the purpose of using python in the first place.

I'm on windows FYI
rioxarray 0.9.0
xarray 0.20.0

@openSourcerer9000 openSourcerer9000 added the bug Something isn't working label Mar 8, 2022
@snowman2
Copy link
Member

snowman2 commented Mar 8, 2022

Short answer: I don't recommend overwriting the same file you opened. Instead, write to a new file.
Potentially useful: https://rasterio.readthedocs.io/en/latest/api/rasterio.shutil.html
Related: #477; pydata/xarray#2887

rioxarray lazily loads the data from the file you are reading from. Even if you close the file before writing to disk, it has to re-open the file in order to load the data. At the same time this is happening, it has opened up a path to the file to write to. One potential workaround is to load in the data from memory before closing the file and then writing to disk (See: Dataset.load). However, that may or may not be the end of the hurdles to overcome.

Here is an example of something to try:

with rioxarray.open_rasterio(tifpath) as tif:
    data = tif.load()
data.rio.to_raster(tifpath)

@snowman2 snowman2 added question Further information is requested and removed bug Something isn't working labels Mar 9, 2022
@openSourcerer9000
Copy link
Author

That explanation makes sense. The code snippet doesn't work however, it still never closes the file once it exits the context manager. If you later print tif it will read out your DataArray again.

I believe the purpose of computer files in general is to access data without having to hold it all in memory. The problem is that there seems to be no possible way to ever close a raster opened with rioxarray.open_rasterio, without killing the Python kernel.

It should be possible, whether under the hood or user-implemented, to at least read the file, make changes, write to a separate temporary file, then close the original file and later overwrite it with the temporary file. It seems the ability to actually close the file gets lost in the abstraction to open_rasterio.

@snowman2
Copy link
Member

snowman2 commented Mar 10, 2022

This is the code that should make the file closable:

rioxarray/rioxarray/_io.py

Lines 948 to 950 in 2888deb

# Make the file closeable
result.set_close(manager.close)
result.rio._manager = manager

See: DataArray.set_close & Dataset.set_close.

If you later print tif it will read out your DataArray again.

When calling load it pulls all of the data into the xarray.DataArray instead of lazily loading. Being able to access data inside of the DataArray object isn't necessarily an indicator that the file isn't closed.

You should still be able to access the data in tif after it closes:

with rioxarray.open_rasterio(tifpath) as tif:
   tif.load()
tif.rio.to_raster(tifpath)

Though, there is a possibility something isn't being closed. I recommend looking here and potentially digging into the xarray code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants