I have a raster of the shape (1000,1000) and some areas having no data values. I would like to fill the data gaps by interpolating or tinning (does not matter) over the surrounding areas, however I fail to do that using Python.
I have searched tried some procedures already discussed at stackexchange, but failed to succeed:
Attempt 1: using gdal.FillNodata
import gdal, gdalconst
file = "C:\\Foo\\bar.tif"
raster = gdal.Open(file, gdalconst.GA_Update)
fill = raster.GetRasterBand(1)
f = gdal.FillNodata(targetBand = fill, maskBand = None, maxSearchDist = 50, smoothingIterations = 0)
fill= fi.ReadAsArray()
geotransform = raster.GetGeoTransform()
originX = geotransform[0]
originY = geotransform[3]
pixelWidth = geotransform[1]
pixelHeight = geotransform[5]
cols = raster.RasterXSize
rows = raster.RasterYSize
driver = gdal.GetDriverByName('GTiff')
outRaster = driver.Create("D:\\Foo\\out.tif", cols, rows, 1, gdal.GDT_Float32)
outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
outband = outRaster.GetRasterBand(1)
outband.WriteArray(fir)
outRasterSRS = osr.SpatialReference()
outRasterSRS.ImportFromEPSG(4326)
outRaster.SetProjection(outRasterSRS.ExportToWkt())
outband.FlushCache()
### does not work - it takes ages, even with a smaller example. And if it works, there are no changes compared to the input file
Attempt 2: Using rasterio.fill — However, this returns an AttributeError.
Attempt 3: Using Scipy
import tifffile
from scipy.interpolate import griddata
raster = tifffile.imread("D:\\Foo\\bar.tif")
grid_x, grid_y = np.mgrid[0:1000, 0:1000]
nans = np.argwhere(np.isnan(raster))
coordnotnan = np.argwhere(~np.isnan(raster))
valuenotnan = excr[coordnotnan]
vanona = valuenotnan[:,0,0]
grid_z1 = griddata(coordnotnan,vanona,nans, method=nearest) #for sake of testing
grT = grid_z1.T
rR= list(raster.ravel())
new = []
i = 0
for na in rR:
if np.isnan(na) == True:
new.append(grT[i])
i += 1
else:
new.append(na)
arrayed = np.array(new, dtype=np.float32).reshape((1000,1000))
#...
## Besides being inefficient (loops), it does not seem to take the values of the neighboring pixels
Do you spot the mistakes I've made? Is there another way to get this job done?
Best Answer
rasterio "fill" function is worked for me. using rasterio 1.1.0