via conda

June 25, 2026 ยท View on GitHub

Important

xarray-spatial uses AI assistance more aggressively than other open-source projects. Before opening a PR, read the AI-Assisted Contribution Policy and run your changes through the project's approved AI review workflow (see the slash-command suite in .claude/commands/). PRs that ignore the workflow are likely to be rejected.

Feature freeze in effect. The project is working toward its first major release (1.0.0). Until 1.0.0 ships, only bug fixes, test coverage, performance work, and documentation PRs will be considered. New feature proposals will be triaged but not implemented until after the release.

Contributors Wanted!. xarray-spatial is currently looking for contributors to help run pre-defined AI-assisted workflows as we approach v1.0.0. If you are interested, please add an issue and flag @brendancol and we can chat.

Latest Release
pypi version conda-forge version
Downloads
PyPI downloads per month conda-forge downloads
License MIT People GitHub contributors
Build Status Coverage

title

:round_pushpin: Fast, Accurate Python library for Raster Operations

:zap: Extensible with Numba

:fast_forward: Scalable with Dask

:desktop_computer: GPU-accelerated with CuPy and Numba CUDA

:confetti_ball: Free of GDAL / GEOS Dependencies

:earth_africa: General-Purpose Spatial Processing, Geared Towards GIS Professionals


Xarray-Spatial is a Python library for raster analysis built on xarray. It has 150+ functions for surface analysis, hydrology (D8, D-infinity, MFD), fire behavior, flood modeling, multispectral indices, proximity, classification, pathfinding, and interpolation. Functions dispatch automatically across four backends (NumPy, Dask, CuPy, Dask+CuPy). A built-in GeoTIFF/COG reader and writer handles raster I/O without GDAL.

Installation

# via pip
pip install xarray-spatial

# with plotting helpers (matplotlib)
pip install xarray-spatial[plot]

# with vector rasterization (shapely): rasterize, polygonize
pip install xarray-spatial[vector]

# via conda
conda install -c conda-forge xarray-spatial

Downloading our starter examples and data

Once you have xarray-spatial installed in your environment, you can use one of the following in your terminal (with the environment active) to download our examples and/or sample data into your local directory.

xrspatial examples : Download the examples notebooks and the data used.

xrspatial copy-examples : Download the examples notebooks but not the data. Note: you won't be able to run many of the examples.

xrspatial fetch-data : Download just the data and not the notebooks.

In all the above, the command will download and store the files into your current directory inside a folder named 'xrspatial-examples'.

xarray-spatial grew out of the Datashader project, which provides fast rasterization of vector data (points, lines, polygons, meshes, and rasters) for use with xarray-spatial.

xarray-spatial does not depend on GDAL or GEOS. Raster I/O, reprojection, compression codecs, and coordinate handling are all pure Python and Numba -- no C/C++ bindings anywhere in the stack.

API reference docs and 33+ user guide notebooks cover every module.

Raster-huh?

Rasters are regularly gridded datasets like GeoTIFFs, JPGs, and PNGs.

In the GIS world, rasters are used for representing continuous phenomena (e.g. elevation, rainfall, distance), either directly as numerical values, or as RGB images created for humans to view. Rasters typically have two spatial dimensions, but may have any number of other dimensions (time, type of measurement, etc.)

Supported Spatial Functions with Supported Inputs

Each cell shows the feature tier for that function on that backend (see issue #2415). A blank cell means no implementation on that backend; a path that was previously documented as a CPU fallback is reported here as advanced (it works as a documented execution mode, but is not native-parity tested).

โœ… stable ยท ๐Ÿ”ผ advanced ยท ๐Ÿงช experimental ยท ๐Ÿ”ง internal ยท ๐Ÿšซ unsupported

GeoTIFF / COG I/O ยท Classification ยท Diffusion ยท Focal ยท Morphological ยท Fire ยท Multispectral ยท Multivariate ยท MCDA ยท Pathfinding ยท Proximity ยท Reproject / Merge ยท Raster / Vector Conversion ยท Surface ยท Hydrology ยท Flood ยท Interpolation ยท Dasymetric ยท Zonal ยท Templates ยท Utilities


GeoTIFF / COG I/O

Native GeoTIFF and Cloud Optimized GeoTIFF reader/writer. No GDAL required.

VRT is supported as a conservative advanced feature for simple GeoTIFF mosaics, not as a full GDAL VRT replacement. See the VRT support matrix for the supported subset and what is out of scope.

NameDescriptionNumPyDaskCuPy GPUDask+CuPy GPUCloud
open_geotiffRead GeoTIFF / COG / VRTโœ…โœ…๐Ÿงช๐Ÿงช๐Ÿ”ผ
to_geotiffWrite DataArray as GeoTIFF / COG / VRTโœ…โœ…๐Ÿงช๐Ÿงช๐Ÿ”ผ

open_geotiff and to_geotiff select the backend from their parameters (gpu=, chunks=, .vrt path); GPU read/write is reached with gpu=True, not a separate function:

from xrspatial.geotiff import open_geotiff, to_geotiff

open_geotiff('dem.tif')                              # NumPy
open_geotiff('dem.tif', chunks=512)                  # Dask
open_geotiff('dem.tif', gpu=True)                    # CuPy (nvCOMP + GDS)
open_geotiff('dem.tif', gpu=True, chunks=512)        # Dask + CuPy
open_geotiff('https://example.com/cog.tif')          # HTTP COG
open_geotiff('s3://bucket/dem.tif')                  # Cloud (S3/GCS/Azure)
open_geotiff('mosaic.vrt')                           # VRT mosaic (auto-detected)

to_geotiff(cupy_array, 'out.tif')                    # auto-detects GPU
to_geotiff(data, 'out.tif', gpu=True)                # force GPU compress
to_geotiff(data, 'out.tif', compression='zstd')      # ZSTD for smaller files
to_geotiff(data, 'cog.tif', cog=True)                # COG with auto overviews
to_geotiff(data, 'cog.tif', cog=True,                # COG with explicit levels
           overview_levels=[2, 4, 8],
           overview_resampling='nearest')
to_geotiff(data, 'mosaic.vrt')                       # write a tiled VRT mosaic

open_geotiff('dem.tif', dtype='float32')             # half memory
open_geotiff('dem.tif', dtype='float32', chunks=512) # Dask + half memory
to_geotiff(data, 'out.tif', compression_level=1)     # fast scratch write
to_geotiff(data, 'out.tif', compression_level=22)    # max compression
to_geotiff(dask_da, 'out.tif')                       # stream Dask to single TIFF
to_geotiff(dask_da, 'mosaic.vrt')                    # stream Dask to VRT

# Accessor methods
da.xrs.to_geotiff('out.tif', compression='lzw')     # write from DataArray
ds.xrs.open_geotiff('large_dem.tif')                 # read windowed to Dataset extent

# xarray backend engine
import xarray as xr
xr.open_dataset('dem.tif', engine='xrspatial')   # open as a Dataset
xr.open_mfdataset('*.tif', engine='xrspatial',   # share one var name
                  backend_kwargs={'default_name': 'band_data'})

Compression codecs: Deflate, LZW (Numba JIT), ZSTD, PackBits, JPEG (Pillow, internal-only: requires allow_internal_only_jpeg=True and is not readable by GDAL), JPEG 2000 (glymur, experimental: requires allow_experimental_codecs=True), uncompressed

GPU codecs: Deflate and ZSTD via nvCOMP batch API; JPEG 2000 via nvJPEG2000; LZW via Numba CUDA kernels

Features:

  • Tiled, stripped, BigTIFF, multi-band (RGB/RGBA), sub-byte (1/2/4/12-bit)
  • Predictors: horizontal differencing (pred=2), floating-point (pred=3)
  • GeoKeys: EPSG, WKT/PROJ (via pyproj), citations, units, ellipsoid, vertical CRS
  • Metadata: nodata masking, palette colormaps, DPI/resolution, GDALMetadata XML, arbitrary tag preservation
  • Cloud storage: S3 (s3://), GCS (gs://), Azure (az://) via fsspec
  • GPUDirect Storage: SSDโ†’GPU direct DMA via KvikIO (optional)
  • Thread-safe mmap reads, atomic writes, HTTP connection reuse (urllib3)
  • Overview generation (CPU and GPU): mean, nearest, min, max, median, mode, cubic
  • Planar config, big-endian byte swap, PixelIsArea/PixelIsPoint

Consistency: 100% pixel-exact match vs rioxarray on all tested files (Landsat 8, Copernicus DEM, USGS 1-arc-second, USGS 1-meter).


Reproject / Merge / Resample

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
ResampleChanges raster resolution (cell size) without reprojection. Nearest, bilinear, cubic, average, mode, min, max, median methodsStandard (interpolation / block aggregation)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
ReprojectReprojects a raster to a new CRS with Numba JIT / CUDA coordinate transforms and resampling. Supports vertical datums (EGM96, EGM2008) and horizontal datum shifts (NAD27, OSGB36, etc.)Standard (inverse mapping)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
MergeMerges multiple rasters into a single mosaic with configurable overlap strategy. Same-CRS tiles skip reprojection and are placed by direct coordinate alignmentStandard (mosaic)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coordinate transforms. pyproj is used only for CRS metadata parsing (~1ms, once per call) and output grid boundary estimation (~500 control points, once per call). Any CRS pair without a built-in kernel falls back to pyproj automatically.

ProjectionEPSG examplesCPU NumbaCUDA GPU
Web Mercator3857โœ…๏ธโœ…๏ธ
UTM / Transverse Mercator326xx, 327xx, State Planeโœ…๏ธโœ…๏ธ
Ellipsoidal Mercator3395โœ…๏ธโœ…๏ธ
Lambert Conformal Conic2154, 2229, State Planeโœ…๏ธโœ…๏ธ
Albers Equal Area5070โœ…๏ธโœ…๏ธ
Cylindrical Equal Area6933โœ…๏ธโœ…๏ธ
SinusoidalMODIS gridsโœ…๏ธโœ…๏ธ
Lambert Azimuthal Equal Area3035, 6931, 6932โœ…๏ธโœ…๏ธ
Polar Stereographic3031, 3413, 3996โœ…๏ธโœ…๏ธ
Oblique Stereographiccustom WGS84โœ…๏ธpyproj fallback
Oblique Mercator (Hotine)3375 (RSO)implemented, disabledpyproj fallback

Vertical datum support: geoid_height, ellipsoidal_to_orthometric, orthometric_to_ellipsoidal convert between ellipsoidal (GPS) and orthometric (map/MSL) heights using EGM96 (vendored, 2.6MB) or EGM2008 (77MB, downloaded on first use). Reproject can apply vertical shifts during reprojection via the vertical_crs parameter.

Datum shift support: Reprojection from non-WGS84 datums (NAD27, OSGB36, DHDN, MGI, ED50, BD72, CH1903, D73, AGD66, Tokyo) applies grid-based shifts from PROJ CDN (sub-metre accuracy) with 7-parameter Helmert fallback (1-5m accuracy). 14 grids are registered covering North America, UK, Germany, Austria, Spain, Netherlands, Belgium, Switzerland, Portugal, and Australia.

ITRF frame support: itrf_transform converts between ITRF2000, ITRF2008, ITRF2014, and ITRF2020 using 14-parameter time-dependent Helmert transforms from PROJ data files. Shifts are mm-level.


Utilities

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
PreviewDownsamples a raster to target pixel dimensions for visualizationCustomโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
RescaleMin-max normalization to a target range (default [0, 1])Standardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
StandardizeZ-score normalization (subtract mean, divide by std)Standardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
rechunk_no_shuffleRechunk dask arrays using whole-chunk multiples (no shuffle)Custom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
fused_overlapFuse sequential map_overlap calls into a single passCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
multi_overlapRun multi-output kernel in a single overlap passCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
validateCheck a raster against the xarray-spatial input contract (.xrs.validate())Customโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Templates

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
from_templateEmpty study-area grid for a named region (CONUS, NYC, ...) or country code; preserve='area'/'shape' picks an EPSG projection by propertyCustomโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Surface

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
AspectComputes downslope direction of each cell in degreesHorn 1981โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
NorthnessNorth-south component of aspect: cos(aspect) for linear modelsStage 1976โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
EastnessEast-west component of aspect: sin(aspect) for linear modelsStage 1976โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
CurvatureMeasures rate of slope change (concavity/convexity) at each cellZevenbergen & Thorne 1987โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
HillshadeSimulates terrain illumination from a given sun angle and azimuthGDAL gdaldemโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
RoughnessComputes local relief as max minus min elevation in a 3ร—3 windowGDAL gdaldemโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Sky-View FactorMeasures the fraction of visible sky hemisphere at each cellZakek et al. 2011โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
SlopeComputes terrain gradient steepness at each cell in degreesHorn 1981โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Terrain GenerationGenerates synthetic terrain from fBm or ridged fractal noise with optional domain warping, Worley blending, and hydraulic erosionCustom (fBm)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
TPIComputes Topographic Position Index (center minus mean of neighbors)Weiss 2001โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
TRIComputes Terrain Ruggedness Index (local elevation variation)Riley et al. 1999โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
LandformsClassifies terrain into 10 landform types using the Weiss (2001) TPI schemeWeiss 2001โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
ViewshedDetermines visible cells from a given observer point on terrainGRASS GIS r.viewshed๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Cumulative ViewshedCounts how many observers can see each cellCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Visibility FrequencyFraction of observers with line-of-sight to each cellCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Line of SightElevation profile and visibility along a point-to-point transectCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Min Observable HeightFinds the minimum observer height needed to see each cellCustom๐Ÿงช
Perlin NoiseGenerates smooth continuous random noise for procedural texturesPerlin 1985โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Worley NoiseGenerates cellular (Voronoi) noise returning distance to the nearest feature pointWorley 1996โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Hydraulic ErosionSimulates particle-based water erosion to carve valleys and deposit sedimentCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Bump MappingAdds randomized bump features to simulate natural terrain variationCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Hydrology

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Flow Direction (D8)Computes D8 flow direction from each cell toward the steepest downhill neighborO'Callaghan & Mark 1984โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Direction (Dinf)Computes D-infinity flow direction as a continuous angle toward the steepest downslope facetTarboton 1997โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Direction (MFD)Partitions flow to all downslope neighbors with an adaptive exponent (Qin et al. 2007)Qin et al. 2007โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Accumulation (D8)Counts upstream cells draining through each cell in a D8 flow direction gridJenson & Domingue 1988โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Accumulation (Dinf)Accumulates upstream area by splitting flow proportionally between two neighbors (Tarboton 1997)Tarboton 1997โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Accumulation (MFD)Accumulates upstream area through all MFD flow paths weighted by directional fractionsQin et al. 2007โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Length (D8)Computes D8 flow path length from each cell to outlet (downstream) or from divide (upstream)Standard (D8 tracing)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Length (Dinf)Proportion-weighted flow path length using D-inf angle decomposition (downstream or upstream)Tarboton 1997๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Length (MFD)Proportion-weighted flow path length using MFD fractions (downstream or upstream)Qin et al. 2007๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Fill (D8)Fills depressions in a DEM using Planchon-Darboux iterative floodingPlanchon & Darboux 2002โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Sink (D8)Identifies and labels depression cells in a D8 flow direction gridStandard (D8 tracing)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Watershed (D8)Labels each cell with the pour point it drains to via D8 flow directionStandard (D8 tracing)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Watershed (Dinf)Labels each cell with the pour point it drains to via D-infinity flow directionTarboton 1997โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Watershed (MFD)Labels each cell with the pour point it drains to via MFD fractionsQin et al. 2007โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
BasinsDelineates drainage basins by labeling each cell with its outlet IDStandard (D8 tracing)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Stream Order (D8)Assigns Strahler or Shreve stream order to cells in a drainage networkStrahler 1957, Shreve 1966โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Stream Order (Dinf)Strahler/Shreve stream ordering on D-infinity flow direction gridsTarboton 1997โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Stream Order (MFD)Strahler/Shreve stream ordering on MFD fraction gridsFreeman 1991โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Stream Link (D8)Assigns unique IDs to each stream segment between junctionsStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Stream Link (Dinf)Stream link segmentation on D-infinity flow direction gridsTarboton 1997โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Stream Link (MFD)Stream link segmentation on MFD fraction gridsFreeman 1991โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Snap Pour PointSnaps pour points to the highest-accumulation cell within a search radiusCustomโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Path (D8)Traces downstream flow paths from start points through a D8 direction gridStandard (D8 tracing)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Path (Dinf)Traces downstream flow paths using D-infinity dominant neighborTarboton 1997๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flow Path (MFD)Traces downstream flow paths through MFD fraction-weighted neighborsQin et al. 2007๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
HAND (D8)Computes Height Above Nearest Drainage by tracing D8 flow to the nearest stream cellNobre et al. 2011โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
HAND (Dinf)Computes Height Above Nearest Drainage using D-infinity flow directionNobre et al. 2011โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
HAND (MFD)Computes Height Above Nearest Drainage using MFD fractionsNobre et al. 2011โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
TWITopographic Wetness Index: ln(specific catchment area / tan(slope))Beven & Kirkby 1979โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Flood

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Flood DepthComputes water depth above terrain from a HAND raster and water levelStandard (HAND-based)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
InundationProduces a binary flood/no-flood mask from a HAND raster and water levelStandard (HAND-based)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Curve Number RunoffEstimates runoff depth from rainfall using the SCS/NRCS curve number methodSCS/NRCSโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Travel TimeEstimates overland flow travel time via simplified Manning's equationManning 1891โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Vegetation RoughnessDerives Manning's roughness coefficients from NLCD land cover or NDVISCS/NRCSโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Vegetation Curve NumberDerives SCS curve numbers from land cover and hydrologic soil groupSCS/NRCSโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flood Depth (Vegetation)Manning-based steady-state flow depth incorporating vegetation roughnessManning 1891โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Multispectral

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Atmospherically Resistant Vegetation Index (ARVI)Vegetation index resistant to atmospheric effects using blue band correctionKaufman & Tanre 1992โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Burn Area Index (BAI)Spectral distance to charcoal reflectance point for burn scar detectionChuvieco et al. 2002โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Enhanced Built-Up and Bareness Index (EBBI)Highlights built-up areas and barren land from thermal and SWIR bandsAs-syakur et al. 2012โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Enhanced Vegetation Index (EVI)Enhanced vegetation index reducing soil and atmospheric noiseHuete et al. 2002โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Green Chlorophyll Index (GCI)Estimates leaf chlorophyll content from green and NIR reflectanceGitelson et al. 2003โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Modified Soil Adjusted Vegetation Index (MSAVI2)Self-adjusting soil line vegetation index, no L parameter neededQi et al. 1994โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Normalized Burn Ratio (NBR)Measures burn severity using NIR and SWIR band differenceUSGS Landsatโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Normalized Burn Ratio 2 (NBR2)Refines burn severity mapping using two SWIR bandsUSGS Landsatโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Normalized Difference Built-up Index (NDBI)Picks out built-up and urban areas from SWIR and NIR bandsZha et al. 2003โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Normalized Difference Moisture Index (NDMI)Detects vegetation moisture stress from NIR and SWIR reflectanceUSGS Landsatโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Normalized Difference Snow Index (NDSI)Separates snow and ice from clouds using green and SWIR bandsHall et al. 1995โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Normalized Difference Water Index (NDWI)Maps open water bodies using green and NIR band differenceMcFeeters 1996โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Modified Normalized Difference Water Index (MNDWI)Detects water in urban areas using green and SWIR bandsXu 2006โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Normalized Difference Vegetation Index (NDVI)Quantifies vegetation density from red and NIR band differenceRouse et al. 1973โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Optimized Soil Adjusted Vegetation Index (OSAVI)SAVI with fixed L=0.16, tuned for sparse vegetationRondeaux et al. 1996โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Soil Adjusted Vegetation Index (SAVI)Vegetation index with soil brightness correction factorHuete 1988โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Structure Insensitive Pigment Index (SIPI)Estimates carotenoid-to-chlorophyll ratio for plant stress detectionPenuelas et al. 1995โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
True ColorComposites red, green, and blue bands into a natural color imageStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

For a broader catalog of spectral indices and sensor-specific band combinations, see awesome-spectral-indices and its companion xarray library spyndex.


Classification

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
BinaryBinarizes values by membership in a target set (1 if match, 0 otherwise)Standardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Box PlotClassifies values into bins based on box plot quartile boundariesPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Equal IntervalDivides the value range into equal-width binsPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Head/Tail BreaksClassifies heavy-tailed distributions using recursive mean splittingPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Maximum BreaksFinds natural groupings by maximizing differences between sorted valuesPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Natural BreaksOptimizes class boundaries to minimize within-class variance (Jenks)Jenks 1967, PySALโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
PercentilesAssigns classes based on user-defined percentile breakpointsPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
QuantileDistributes values into classes with equal observation countsPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
ReclassifyRemaps pixel values to new classes using a user-defined lookupPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Std MeanClassifies values by standard deviation intervals from the meanPySAL mapclassifyโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Focal

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
ApplyApplies a custom function over a sliding neighborhood windowStandard๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
HotspotsIdentifies statistically significant spatial clusters using Getis-Ord Gi*Getis & Ord 1992โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Emerging HotspotsClassifies time-series hot/cold spot trends using Gi* and Mann-KendallGetis & Ord 1992, Mann 1945๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
MeanComputes the mean value within a sliding neighborhood windowStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Focal StatisticsComputes summary statistics over a sliding neighborhood windowStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
BilateralFeature-preserving smoothing via bilateral filteringTomasi & Manduchi 1998๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
GLCM TextureComputes Haralick GLCM texture features over a sliding windowHaralick et al. 1973๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Sobel XHorizontal gradient via Sobel operator (detects vertical edges)Sobel & Feldman 1968๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Sobel YVertical gradient via Sobel operator (detects horizontal edges)Sobel & Feldman 1968๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
LaplacianOmnidirectional second-derivative edge detectorStandard๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Prewitt XHorizontal gradient via Prewitt operator (detects vertical edges)Prewitt 1970๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Prewitt YVertical gradient via Prewitt operator (detects horizontal edges)Prewitt 1970๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Proximity

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
AllocationAssigns each cell to the identity of the nearest source featureStandard (Dijkstra)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Balanced AllocationPartitions a cost surface into territories of roughly equal cost-weighted areaCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Cost DistanceComputes minimum accumulated cost to the nearest source through a friction surfaceStandard (Dijkstra)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Least-Cost CorridorIdentifies zones of low cumulative cost between two source locationsStandard (Dijkstra)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
DirectionComputes the direction from each cell to the nearest source featureStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
ProximityComputes the distance from each cell to the nearest source featureStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Surface DistanceComputes distance along the 3D terrain surface to the nearest sourceStandard (Dijkstra)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Surface AllocationAssigns each cell to the nearest source by terrain surface distanceStandard (Dijkstra)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Surface DirectionComputes compass direction to the nearest source by terrain surface distanceStandard (Dijkstra)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Zonal

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
ApplyApplies a custom function to each zone in a classified rasterStandard๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Clip PolygonClips a raster to an arbitrary polygon with maskingStandard๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
CropExtracts the bounding rectangle of a specific zoneStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
RegionsIdentifies connected regions of non-zero cellsStandard (CCL)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
TrimRemoves nodata border rows and columns from a rasterStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Zonal StatisticsComputes summary statistics for a value raster within each zoneStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Zonal Cross TabulateCross-tabulates agreement between two categorical rastersStandard๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Interpolation

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
IDWInverse Distance Weighting from scattered points (arrays or a GeoDataFrame) to a raster gridStandard (IDW)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
KrigingOrdinary Kriging with automatic variogram fitting (spherical, exponential, gaussian); accepts arrays or a GeoDataFrameStandard (ordinary kriging)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
SplineThin Plate Spline interpolation with optional smoothing; accepts arrays or a GeoDataFrameStandard (TPS)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Morphological

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
ErodeMorphological erosion (local minimum over structuring element)Standard (morphology)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
DilateMorphological dilation (local maximum over structuring element)Standard (morphology)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
OpeningErosion then dilation (removes small bright features)Standard (morphology)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
ClosingDilation then erosion (fills small dark gaps)Standard (morphology)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
GradientDilation minus erosion (edge detection)Standard (morphology)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
White Top-hatOriginal minus opening (isolate bright features)Standard (morphology)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Black Top-hatClosing minus original (isolate dark features)Standard (morphology)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
SieveRemove small connected clumps from classified rastersGDAL sieve๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Fire

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
dNBRDifferenced Normalized Burn Ratio (pre minus post NBR)USGSโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
RdNBRRelative dNBR normalized by pre-fire vegetation densityUSGSโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Burn Severity ClassUSGS 7-class burn severity from dNBR thresholdsUSGSโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Fireline IntensityByram's fireline intensity from fuel load and spread rate (kW/m)Byram 1959โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Flame LengthFlame length derived from fireline intensity (m)Byram 1959โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Rate of SpreadSimplified Rothermel spread rate with Anderson 13 fuel models (m/min)Rothermel 1972, Anderson 1982โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
KBDIKeetch-Byram Drought Index single time-step update (0-800 mm)Keetch & Byram 1968โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Raster / Vector Conversion

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
PolygonizeConverts contiguous regions of equal value into vector polygonsStandard (CCL)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
ContoursExtracts elevation contour lines (isolines) from a raster surfaceStandard (marching squares)๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
RasterizeRasterizes vector geometries (polygons, lines, points) from a GeoDataFrameStandard (scanline, Bresenham)๐Ÿ”ผ๐Ÿ”ผ

Kernel Density Estimation

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
KDEPoint-to-raster kernel density estimation (Gaussian, Epanechnikov, quartic); accepts arrays or a GeoDataFrameSilverman 1986๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Line DensityLine-segment-to-raster density estimationStandard๐Ÿ”ผ

Multivariate

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Mahalanobis DistanceMeasures statistical distance from a multi-band reference distribution, accounting for band correlationsMahalanobis 1936โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Multi-Criteria Decision Analysis (MCDA)

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
StandardizeConverts criterion rasters to 0-1 suitability scale (linear, sigmoidal, gaussian, triangular, piecewise, categorical)Standardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
AHP WeightsDerives criterion weights from pairwise comparisons using the Saaty eigenvector method with consistency ratioSaaty 1980โœ…๐Ÿšซ๐Ÿšซ๐Ÿšซ
Rank WeightsDerives weights from a rank ordering (ROC, rank sum, reciprocal)Standardโœ…๐Ÿšซ๐Ÿšซ๐Ÿšซ
WLCWeighted Linear Combination (fully compensatory weighted sum)Malczewski 2006โœ…๐Ÿ”ผ๐Ÿงช๐Ÿงช
WPMWeighted Product Model (multiplicative, penalizes low scores)Standardโœ…๐Ÿ”ผ๐Ÿงช๐Ÿงช
OWAOrdered Weighted Averaging with tunable risk attitudeYager 1988โœ…๐Ÿ”ผ๐Ÿงช๐Ÿงช
Fuzzy OverlayCombines criteria using fuzzy set operators (AND, OR, sum, product, gamma)Eastman 1999โœ…๐Ÿ”ผ๐Ÿงช๐Ÿงช
Boolean OverlayCombines binary criterion masks using AND/OR logicStandardโœ…๐Ÿ”ผ๐Ÿงช๐Ÿงช
ConstrainMasks exclusion zones from a suitability surfaceStandardโœ…๐Ÿ”ผ๐Ÿงช๐Ÿงช
SensitivityAssesses weight stability via one-at-a-time or Monte Carlo perturbationStandardโœ…๐Ÿ”ผ๐Ÿงช๐Ÿงช

Pathfinding

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
A* PathfindingFinds the least-cost path between two cells on a cost surfaceHart et al. 1968โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
Multi-Stop SearchRoutes through N waypoints in sequence, with optional TSP reorderingCustom๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Diffusion

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
DiffuseRuns explicit forward-Euler diffusion on a 2D scalar fieldStandard (heat equation)โœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Dasymetric

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
DisaggregateRedistributes zonal totals to pixels using an ancillary weight surfaceMennis 2003๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ
PycnophylacticTobler's pycnophylactic interpolation preserving zone totals via Laplacian smoothingTobler 1979โœ…๐Ÿšซ๐Ÿ”ผ๐Ÿšซ
Validate DisaggregationChecks that disaggregated pixel sums match the original zone totalsStandardโœ…๐Ÿ”ผ๐Ÿ”ผ๐Ÿ”ผ

Usage

Quick Start

Importing xrspatial registers an .xrs accessor on DataArrays and Datasets, giving you tab-completable access to every spatial operation:

import xrspatial as xrs
from xrspatial.geotiff import open_geotiff, to_geotiff

# Read a GeoTIFF (no GDAL required)
elevation = open_geotiff('dem.tif')

# Surface analysis
slope = elevation.xrs.slope()
hillshaded = elevation.xrs.hillshade(azimuth=315, angle_altitude=45)
aspect = elevation.xrs.aspect()

# Reproject and write as a Cloud Optimized GeoTIFF
dem_wgs84 = elevation.xrs.reproject(target_crs='EPSG:4326')
to_geotiff(dem_wgs84, 'output.tif', cog=True)

# Classification
classes = elevation.xrs.equal_interval(k=5)
breaks = elevation.xrs.natural_breaks(k=10)

# Proximity
distance = elevation.xrs.proximity(target_values=[1])

# Multispectral
vegetation = nir.xrs.ndvi(red)
enhanced_vi = nir.xrs.evi(red, blue)
Dataset Support

The .xrs accessor works on Datasets too. Single-input functions apply the operation to each data variable. Multi-input functions (multispectral indices) accept string kwargs that map band aliases to variable names:

ds = xr.Dataset({'band_4': red, 'band_5': nir})

# Single-input: slope computed for each variable
slope_ds = ds.xrs.slope()

# Multi-input: map variable names to band parameters
ndvi_result = ds.xrs.ndvi(nir='band_5', red='band_4')
Function Import Style

All operations are also available as standalone functions:

import xrspatial as xrs

hillshaded = xrs.hillshade(elevation)
slope_result = xrs.slope(elevation)
vegetation = xrs.ndvi(nir, red)

Check out the user guide here.


title title

Dependencies

Core: numpy, numba, scipy, xarray, zstandard

Optional:

  • matplotlib โ€” the .xrs.plot accessor helpers (pip install xarray-spatial[plot])
  • shapely โ€” the vector-to-raster paths, rasterize and polygonize (pip install xarray-spatial[vector])
  • pyproj โ€” WKT/PROJ CRS resolution
  • cupy โ€” GPU acceleration
  • dask โ€” out-of-core processing
  • libnvcomp โ€” GPU batch decompression (deflate, ZSTD)
  • kvikio โ€” GPUDirect Storage (SSD โ†’ GPU)
  • fsspec + s3fs/gcsfs/adlfs โ€” cloud storage

libnvcomp and kvikio are not pulled in by the gpu extra. They are runtime dependencies of the GeoTIFF GPU read path and must be installed separately (typically via conda from the rapidsai/nvidia channels), since libnvcomp ships as a system library and kvikio requires a matching CUDA toolkit.

title

Notes on GDAL

xarray-spatial does not depend on GDAL. The built-in GeoTIFF/COG reader and writer (xrspatial.geotiff) handles raster I/O natively using only numpy, numba, and the standard library. This means:

  • Zero GDAL installation hassle. pip install xarray-spatial gets you everything needed to read and write GeoTIFFs, COGs, and VRT files.
  • Pure Python, fully extensible. All codec, header parsing, and metadata code is readable Python/Numba, not wrapped C/C++.
  • GPU-accelerated reads. With optional nvCOMP and nvJPEG2000, compressed tiles decompress directly on the GPU via CUDA -- something GDAL cannot do.

The native reader is pixel-exact against rasterio/GDAL across Landsat 8, Copernicus DEM, USGS 1-arc-second, and USGS 1-meter DEMs.

Citation

Cite this code:

xarray-contrib/xarray-spatial, https://github.com/xarray-contrib/xarray-spatial, ยฉ2020-2026.