windkit.fill_elevation_nodata#

windkit.fill_elevation_nodata(da: DataArray, max_fill_fraction: float | None = 0.05) → DataArray[source]#

Fill NaN or Inf cells in an elevation raster.

Boundary-connected no-data cells are filled with the nearest valid neighbour. Interior no-data cells are filled by local piecewise-linear interpolation, with nearest-neighbour fallback outside the interpolation hull. A warning is issued for each category of fill applied.

Parameters:
  • da (xarray.DataArray) – 2-D raster DataArray with west_east and south_north dimensions. May contain NaN or Inf values. Dask-backed data is computed into memory.

  • max_fill_fraction (float or None) – Refuse to fill when no-data cells exceed this fraction of the raster. Pass None to fill regardless of size.

Returns:

Copy of da with all no-data cells replaced. Attributes, coordinates, and dtype are preserved. A clean raster is returned unchanged.

Return type:

xarray.DataArray

Raises:

ValueError – If the raster is not a 2-D (south_north, west_east) array, has no valid cell, or if no-data cells exceed max_fill_fraction.

Notes

No-data cells are classified as boundary-connected or interior using 8-connectivity, so a hole that touches the raster edge only diagonally is treated as boundary-connected. Boundary-connected cells are extended flat from the nearest valid cell rather than interpolated.

Interior no-data cells are interpolated from a local neighbourhood of valid cells around each hole rather than the full raster, to keep the triangulation cheap. On a regular grid this makes the result neighbourhood-dependent: for holes several cells apart, it can differ from a full-raster triangulation by an amount comparable to the interpolation error itself.

Examples

>>> import numpy as np
>>> import xarray as xr
>>> da = xr.DataArray(
...     [[np.nan, 1.0], [2.0, 3.0]],
...     dims=["south_north", "west_east"],
... )
>>> fill_elevation_nodata(da, max_fill_fraction=None).values
array([[2., 1.],
       [2., 3.]])