I have come across a set of poorly generated rasters which I need to align and regularize. I am open to any quick and dirty way to do this, but prefer QGIS since I have been using it for all my operations thus far.

The rasters contain positive ranges of floating point values, have a NODATA value defined, but also have many cells containing nan values. I would like to convert all nan values to the currently defined NODATA value. To achieve this, I tried many combinations of using the following:

  • gdal raster calculator (using numpy where and isnan functions)
  • raster calculator
  • GRASS r.null tool

However I can't seem to get a workflow going. The gdal raster calc with numpy functions was close, but unfortunately theres no way of referring to the currently defined NODATA value by variable (as far as I know).

I would like to avoid using Python tools like rasterio since rasters should not be delivered in this format anyway (no use scripting this).

Does anyone have a way of achieving this?

| improve this question | | | | |
  • Soliciting "quick and dirty" data massage solutions and refusing to consider Python seems counterintuitive. – Vince May 19 '19 at 14:59
  • I actually know how to do it in python. I just want to see if I can avoid writing a dedicated script to a non-general problem – user32882 May 19 '19 at 15:00
  • r.null usually works fine for me doing such things. What was your workflow using it? – MrXsquared May 19 '19 at 15:03
  • Data cleanup isnt exactly a non-general problem. – Vince May 19 '19 at 15:04
  • r.null successfully converted all nan and NODATA values to -9999 (for example), however the output raster had no defined NODATA value as shown in layer properties> transparency – user32882 May 19 '19 at 15:05

Here's a lazy script I wrote to do this:

import rasterio
import os
import numpy as np

raster = 'Waterways_dist_clipped_30m.tif'

ds = rasterio.open(os.path.join('main_input',raster))
profile = ds.profile

data = ds.read(1)
new_data = np.where(np.isnan(data), profile['nodata'], data).astype(profile['dtype'])

with rasterio.Env():
    with rasterio.open(os.path.join('D:\\TEMP\\rasters', raster), 'w', **profile) as dst:
        dst.write(new_data, 1)


Lord knows I didn't enjoy writing it....

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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