xarray-spatial 0.9.5


pip install xarray-spatial

  Latest version

Released: Mar 31, 2026

Project Links

Meta
Author: Xarray-Spatial Developers
Requires Python: >=3.12

Classifiers

Development Status
  • 4 - Beta

Intended Audience
  • Developers
  • Science/Research

License
  • OSI Approved :: MIT License

Operating System
  • OS Independent

Programming Language
  • Python :: 3
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 100+ 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

# 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

โœ… = native backend    ๐Ÿ”„ = accepted (CPU fallback)

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


GeoTIFF / COG I/O

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

Name Description NumPy Dask CuPy GPU Dask+CuPy GPU Cloud
open_geotiff Read GeoTIFF / COG / VRT โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
to_geotiff Write DataArray as GeoTIFF / COG โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
write_vrt Generate VRT mosaic from GeoTIFFs โœ…๏ธ

open_geotiff and to_geotiff auto-dispatch to the correct backend:

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, 'ortho.tif', compression='jpeg')    # JPEG for orthophotos
write_vrt('mosaic.vrt', ['tile1.tif', 'tile2.tif'])  # generate VRT

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

Compression codecs: Deflate, LZW (Numba JIT), ZSTD, PackBits, JPEG (Pillow), JPEG 2000 (glymur), 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: mean, nearest, min, max, median, mode, cubic
  • Planar config, big-endian byte swap, PixelIsArea/PixelIsPoint

Read performance (real-world files, A6000 GPU):

File Format xrspatial CPU rioxarray GPU (nvCOMP)
render_demo 187x253 uncompressed 0.2ms 2.4ms 0.7ms
Landsat B4 1310x1093 uncompressed 1.0ms 6.0ms 1.7ms
Copernicus 3600x3600 deflate+fp3 241ms 195ms 872ms
USGS 1as 3612x3612 LZW+fp3 275ms 215ms 747ms
USGS 1m 10012x10012 LZW 1.25s 1.80s 990ms

Read performance (synthetic tiled, GPU shines at scale):

Size Codec xrspatial CPU rioxarray GPU (nvCOMP)
4096x4096 deflate 265ms 211ms 158ms
4096x4096 zstd 73ms 159ms 58ms
8192x8192 deflate 1.06s 859ms 565ms
8192x8192 zstd 288ms 668ms 171ms

Write performance (synthetic tiled):

Size Codec xrspatial CPU rioxarray GPU (nvCOMP)
2048x2048 deflate 424ms 110ms 135ms
2048x2048 zstd 49ms 83ms 81ms
4096x4096 deflate 1.68s 447ms 302ms
8192x8192 deflate 6.84s 2.03s 1.11s
8192x8192 zstd 847ms 822ms 1.03s
Consistency: 100% pixel-exact match vs rioxarray on all tested files (Landsat 8, Copernicus DEM, USGS 1-arc-second, USGS 1-meter).

Reproject / Merge

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Reproject Reprojects 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) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Merge Merges multiple rasters into a single mosaic with configurable overlap strategy Standard (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.

Projection EPSG examples CPU Numba CUDA GPU
Web Mercator 3857 โœ…๏ธ โœ…๏ธ
UTM / Transverse Mercator 326xx, 327xx, State Plane โœ…๏ธ โœ…๏ธ
Ellipsoidal Mercator 3395 โœ…๏ธ โœ…๏ธ
Lambert Conformal Conic 2154, 2229, State Plane โœ…๏ธ โœ…๏ธ
Albers Equal Area 5070 โœ…๏ธ โœ…๏ธ
Cylindrical Equal Area 6933 โœ…๏ธ โœ…๏ธ
Sinusoidal MODIS grids โœ…๏ธ โœ…๏ธ
Lambert Azimuthal Equal Area 3035, 6931, 6932 โœ…๏ธ โœ…๏ธ
Polar Stereographic 3031, 3413, 3996 โœ…๏ธ โœ…๏ธ
Oblique Stereographic custom WGS84 โœ…๏ธ pyproj fallback
Oblique Mercator (Hotine) 3375 (RSO) implemented, disabled pyproj 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.

Reproject performance (reproject-only, 1024x1024, bilinear, vs rioxarray):

Transform xrspatial rioxarray
WGS84 -> Web Mercator 23ms 14ms
WGS84 -> UTM 33N 24ms 18ms
WGS84 -> Albers CONUS 41ms 33ms
WGS84 -> LAEA Europe 57ms 17ms
WGS84 -> Polar Stere S 44ms 38ms
WGS84 -> LCC France 44ms 25ms
WGS84 -> Ellipsoidal Merc 27ms 14ms
WGS84 -> CEA EASE-Grid 24ms 15ms

Full pipeline (read 3600x3600 Copernicus DEM + reproject to EPSG:3857 + write GeoTIFF):

Backend Time
NumPy 784ms
CuPy GPU 348ms
Dask+CuPy GPU 343ms
rioxarray (GDAL) 749ms

Merge performance (4 overlapping same-CRS tiles, vs rioxarray):

Tile size xrspatial rioxarray Speedup
512x512 16ms 29ms 1.8x
1024x1024 52ms 76ms 1.5x
2048x2048 361ms 280ms 0.8x

Same-CRS tiles skip reprojection entirely and are placed by direct coordinate alignment.


Utilities

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Preview Downsamples a raster to target pixel dimensions for visualization Custom โœ…๏ธ โœ…๏ธ โœ…๏ธ ๐Ÿ”„
Rescale Min-max normalization to a target range (default [0, 1]) Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Standardize Z-score normalization (subtract mean, divide by std) Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
rechunk_no_shuffle Rechunk dask arrays using whole-chunk multiples (no shuffle) Custom ๐Ÿ”„ โœ…๏ธ ๐Ÿ”„ โœ…๏ธ
fused_overlap Fuse sequential map_overlap calls into a single pass Custom ๐Ÿ”„ โœ…๏ธ ๐Ÿ”„ โœ…๏ธ
multi_overlap Run multi-output kernel in a single overlap pass Custom ๐Ÿ”„ โœ…๏ธ ๐Ÿ”„ โœ…๏ธ

Surface

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Aspect Computes downslope direction of each cell in degrees Horn 1981 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Northness North-south component of aspect: cos(aspect) for linear models Stage 1976 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Eastness East-west component of aspect: sin(aspect) for linear models Stage 1976 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Curvature Measures rate of slope change (concavity/convexity) at each cell Zevenbergen & Thorne 1987 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Hillshade Simulates terrain illumination from a given sun angle and azimuth GDAL gdaldem โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Roughness Computes local relief as max minus min elevation in a 3ร—3 window GDAL gdaldem โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Sky-View Factor Measures the fraction of visible sky hemisphere at each cell Zakek et al. 2011 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Slope Computes terrain gradient steepness at each cell in degrees Horn 1981 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Terrain Generation Generates synthetic terrain from fBm or ridged fractal noise with optional domain warping, Worley blending, and hydraulic erosion Custom (fBm) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
TPI Computes Topographic Position Index (center minus mean of neighbors) Weiss 2001 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
TRI Computes Terrain Ruggedness Index (local elevation variation) Riley et al. 1999 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Landforms Classifies terrain into 10 landform types using the Weiss (2001) TPI scheme Weiss 2001 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Viewshed Determines visible cells from a given observer point on terrain GRASS GIS r.viewshed โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Min Observable Height Finds the minimum observer height needed to see each cell (experimental) Custom โœ…๏ธ
Perlin Noise Generates smooth continuous random noise for procedural textures Perlin 1985 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Worley Noise Generates cellular (Voronoi) noise returning distance to the nearest feature point Worley 1996 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Hydraulic Erosion Simulates particle-based water erosion to carve valleys and deposit sediment Custom โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Bump Mapping Adds randomized bump features to simulate natural terrain variation Custom โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Hydrology

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Flow Direction (D8) Computes D8 flow direction from each cell toward the steepest downhill neighbor O'Callaghan & Mark 1984 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Flow Direction (Dinf) Computes D-infinity flow direction as a continuous angle toward the steepest downslope facet Tarboton 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 grid Jenson & 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 fractions Qin 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 โœ…๏ธ โœ…๏ธ โœ…๏ธ ๐Ÿ”„
Watershed Labels each cell with the pour point it drains to via D8 flow direction Standard (D8 tracing) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Basins Delineates drainage basins by labeling each cell with its outlet ID Standard (D8 tracing) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Stream Order Assigns Strahler or Shreve stream order to cells in a drainage network Strahler 1957, Shreve 1966 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Stream Order (Dinf) Strahler/Shreve stream ordering on D-infinity flow direction grids Tarboton 1997 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Stream Order (MFD) Strahler/Shreve stream ordering on MFD fraction grids Freeman 1991 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Stream Link Assigns unique IDs to each stream segment between junctions Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Stream Link (Dinf) Stream link segmentation on D-infinity flow direction grids Tarboton 1997 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Stream Link (MFD) Stream link segmentation on MFD fraction grids Freeman 1991 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Snap Pour Point Snaps pour points to the highest-accumulation cell within a search radius Custom โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Flow Path Traces downstream flow paths from start points through a D8 direction grid Standard (D8 tracing) โœ…๏ธ โœ…๏ธ ๐Ÿ”„ ๐Ÿ”„
HAND Computes Height Above Nearest Drainage by tracing D8 flow to the nearest stream cell Nobre et al. 2011 โœ…๏ธ โœ…๏ธ ๐Ÿ”„ ๐Ÿ”„
TWI Topographic Wetness Index: ln(specific catchment area / tan(slope)) Beven & Kirkby 1979 โœ…๏ธ โœ…๏ธ โœ…๏ธ ๐Ÿ”„

Flood

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Flood Depth Computes water depth above terrain from a HAND raster and water level Standard (HAND-based) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Inundation Produces a binary flood/no-flood mask from a HAND raster and water level Standard (HAND-based) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Curve Number Runoff Estimates runoff depth from rainfall using the SCS/NRCS curve number method SCS/NRCS โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Travel Time Estimates overland flow travel time via simplified Manning's equation Manning 1891 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Vegetation Roughness Derives Manning's roughness coefficients from NLCD land cover or NDVI SCS/NRCS โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Vegetation Curve Number Derives SCS curve numbers from land cover and hydrologic soil group SCS/NRCS โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Flood Depth (Vegetation) Manning-based steady-state flow depth incorporating vegetation roughness Manning 1891 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Multispectral

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Atmospherically Resistant Vegetation Index (ARVI) Vegetation index resistant to atmospheric effects using blue band correction Kaufman & Tanre 1992 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Burn Area Index (BAI) Spectral distance to charcoal reflectance point for burn scar detection Chuvieco et al. 2002 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Enhanced Built-Up and Bareness Index (EBBI) Highlights built-up areas and barren land from thermal and SWIR bands As-syakur et al. 2012 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Enhanced Vegetation Index (EVI) Enhanced vegetation index reducing soil and atmospheric noise Huete et al. 2002 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Green Chlorophyll Index (GCI) Estimates leaf chlorophyll content from green and NIR reflectance Gitelson et al. 2003 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Modified Soil Adjusted Vegetation Index (MSAVI2) Self-adjusting soil line vegetation index, no L parameter needed Qi et al. 1994 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Normalized Burn Ratio (NBR) Measures burn severity using NIR and SWIR band difference USGS Landsat โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Normalized Burn Ratio 2 (NBR2) Refines burn severity mapping using two SWIR bands USGS Landsat โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Normalized Difference Built-up Index (NDBI) Picks out built-up and urban areas from SWIR and NIR bands Zha et al. 2003 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Normalized Difference Moisture Index (NDMI) Detects vegetation moisture stress from NIR and SWIR reflectance USGS Landsat โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Normalized Difference Snow Index (NDSI) Separates snow and ice from clouds using green and SWIR bands Hall et al. 1995 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Normalized Difference Water Index (NDWI) Maps open water bodies using green and NIR band difference McFeeters 1996 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Modified Normalized Difference Water Index (MNDWI) Detects water in urban areas using green and SWIR bands Xu 2006 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Normalized Difference Vegetation Index (NDVI) Quantifies vegetation density from red and NIR band difference Rouse et al. 1973 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Optimized Soil Adjusted Vegetation Index (OSAVI) SAVI with fixed L=0.16, tuned for sparse vegetation Rondeaux et al. 1996 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Soil Adjusted Vegetation Index (SAVI) Vegetation index with soil brightness correction factor Huete 1988 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Structure Insensitive Pigment Index (SIPI) Estimates carotenoid-to-chlorophyll ratio for plant stress detection Penuelas et al. 1995 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
True Color Composites red, green, and blue bands into a natural color image Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Classification

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Box Plot Classifies values into bins based on box plot quartile boundaries PySAL mapclassify โœ…๏ธ โœ… โœ… ๐Ÿ”„
Equal Interval Divides the value range into equal-width bins PySAL mapclassify โœ…๏ธ โœ… โœ… โœ…
Head/Tail Breaks Classifies heavy-tailed distributions using recursive mean splitting PySAL mapclassify โœ…๏ธ โœ… ๐Ÿ”„ ๐Ÿ”„
Maximum Breaks Finds natural groupings by maximizing differences between sorted values PySAL mapclassify โœ…๏ธ โœ… ๐Ÿ”„ ๐Ÿ”„
Natural Breaks Optimizes class boundaries to minimize within-class variance (Jenks) Jenks 1967, PySAL โœ…๏ธ โœ… ๐Ÿ”„ ๐Ÿ”„
Percentiles Assigns classes based on user-defined percentile breakpoints PySAL mapclassify โœ…๏ธ โœ… โœ… ๐Ÿ”„
Quantile Distributes values into classes with equal observation counts PySAL mapclassify โœ…๏ธ โœ… โœ… ๐Ÿ”„
Reclassify Remaps pixel values to new classes using a user-defined lookup PySAL mapclassify โœ…๏ธ โœ… โœ… โœ…
Std Mean Classifies values by standard deviation intervals from the mean PySAL mapclassify โœ…๏ธ โœ… โœ… โœ…

Focal

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Apply Applies a custom function over a sliding neighborhood window Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Hotspots Identifies statistically significant spatial clusters using Getis-Ord Gi* Getis & Ord 1992 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Emerging Hotspots Classifies time-series hot/cold spot trends using Gi* and Mann-Kendall Getis & Ord 1992, Mann 1945 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Mean Computes the mean value within a sliding neighborhood window Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Focal Statistics Computes summary statistics over a sliding neighborhood window Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Bilateral Feature-preserving smoothing via bilateral filtering Tomasi & Manduchi 1998 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
GLCM Texture Computes Haralick GLCM texture features over a sliding window Haralick et al. 1973 โœ…๏ธ โœ…๏ธ ๐Ÿ”„ ๐Ÿ”„
Sobel X Horizontal gradient via Sobel operator (detects vertical edges) Sobel & Feldman 1968 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Sobel Y Vertical gradient via Sobel operator (detects horizontal edges) Sobel & Feldman 1968 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Laplacian Omnidirectional second-derivative edge detector Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Prewitt X Horizontal gradient via Prewitt operator (detects vertical edges) Prewitt 1970 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Prewitt Y Vertical gradient via Prewitt operator (detects horizontal edges) Prewitt 1970 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Proximity

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Allocation Assigns each cell to the identity of the nearest source feature Standard (Dijkstra) โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Balanced Allocation Partitions a cost surface into territories of roughly equal cost-weighted area Custom โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Cost Distance Computes minimum accumulated cost to the nearest source through a friction surface Standard (Dijkstra) โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Least-Cost Corridor Identifies zones of low cumulative cost between two source locations Standard (Dijkstra) โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Direction Computes the direction from each cell to the nearest source feature Standard โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Proximity Computes the distance from each cell to the nearest source feature Standard โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Surface Distance Computes distance along the 3D terrain surface to the nearest source Standard (Dijkstra) โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Surface Allocation Assigns each cell to the nearest source by terrain surface distance Standard (Dijkstra) โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ
Surface Direction Computes compass direction to the nearest source by terrain surface distance Standard (Dijkstra) โœ…๏ธ โœ… โœ…๏ธ โœ…๏ธ

Zonal

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Apply Applies a custom function to each zone in a classified raster Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Crop Extracts the bounding rectangle of a specific zone Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Regions Identifies connected regions of non-zero cells Standard (CCL) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Trim Removes nodata border rows and columns from a raster Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Zonal Statistics Computes summary statistics for a value raster within each zone Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ ๐Ÿ”„
Zonal Cross Tabulate Cross-tabulates agreement between two categorical rasters Standard โœ…๏ธ โœ…๏ธ ๐Ÿ”„ ๐Ÿ”„

Interpolation

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
IDW Inverse Distance Weighting from scattered points to a raster grid Standard (IDW) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Kriging Ordinary Kriging with automatic variogram fitting (spherical, exponential, gaussian) Standard (ordinary kriging) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Spline Thin Plate Spline interpolation with optional smoothing Standard (TPS) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Morphological

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Erode Morphological erosion (local minimum over structuring element) Standard (morphology) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Dilate Morphological dilation (local maximum over structuring element) Standard (morphology) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Opening Erosion then dilation (removes small bright features) Standard (morphology) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Closing Dilation then erosion (fills small dark gaps) Standard (morphology) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Gradient Dilation minus erosion (edge detection) Standard (morphology) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
White Top-hat Original minus opening (isolate bright features) Standard (morphology) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Black Top-hat Closing minus original (isolate dark features) Standard (morphology) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Fire

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
dNBR Differenced Normalized Burn Ratio (pre minus post NBR) USGS โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
RdNBR Relative dNBR normalized by pre-fire vegetation density USGS โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Burn Severity Class USGS 7-class burn severity from dNBR thresholds USGS โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Fireline Intensity Byram's fireline intensity from fuel load and spread rate (kW/m) Byram 1959 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Flame Length Flame length derived from fireline intensity (m) Byram 1959 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Rate of Spread Simplified Rothermel spread rate with Anderson 13 fuel models (m/min) Rothermel 1972, Anderson 1982 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
KBDI Keetch-Byram Drought Index single time-step update (0-800 mm) Keetch & Byram 1968 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Raster / Vector Conversion

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Polygonize Converts contiguous regions of equal value into vector polygons Standard (CCL) โœ…๏ธ โœ…๏ธ โœ…๏ธ ๐Ÿ”„
Contours Extracts elevation contour lines (isolines) from a raster surface Standard (marching squares) โœ…๏ธ โœ…๏ธ ๐Ÿ”„ ๐Ÿ”„
Rasterize Rasterizes vector geometries (polygons, lines, points) from a GeoDataFrame Standard (scanline, Bresenham) โœ…๏ธ โœ…๏ธ

Multivariate

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Mahalanobis Distance Measures statistical distance from a multi-band reference distribution, accounting for band correlations Mahalanobis 1936 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Multi-Criteria Decision Analysis (MCDA)

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Standardize Converts criterion rasters to 0-1 suitability scale (linear, sigmoidal, gaussian, triangular, piecewise, categorical) Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
AHP Weights Derives criterion weights from pairwise comparisons using the Saaty eigenvector method with consistency ratio Saaty 1980 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Rank Weights Derives weights from a rank ordering (ROC, rank sum, reciprocal) Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
WLC Weighted Linear Combination (fully compensatory weighted sum) Malczewski 2006 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
WPM Weighted Product Model (multiplicative, penalizes low scores) Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
OWA Ordered Weighted Averaging with tunable risk attitude Yager 1988 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Fuzzy Overlay Combines criteria using fuzzy set operators (AND, OR, sum, product, gamma) Eastman 1999 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Boolean Overlay Combines binary criterion masks using AND/OR logic Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Constrain Masks exclusion zones from a suitability surface Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Sensitivity Assesses weight stability via one-at-a-time or Monte Carlo perturbation Standard โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Pathfinding

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
A* Pathfinding Finds the least-cost path between two cells on a cost surface Hart et al. 1968 โœ…๏ธ โœ… ๐Ÿ”„ ๐Ÿ”„
Multi-Stop Search Routes through N waypoints in sequence, with optional TSP reordering Custom โœ…๏ธ โœ… ๐Ÿ”„ ๐Ÿ”„

Diffusion

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Diffuse Runs explicit forward-Euler diffusion on a 2D scalar field Standard (heat equation) โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ

Dasymetric

Name Description Source NumPy xr.DataArray Dask xr.DataArray CuPy GPU xr.DataArray Dask GPU xr.DataArray
Disaggregate Redistributes zonal totals to pixels using an ancillary weight surface Mennis 2003 โœ…๏ธ โœ…๏ธ โœ…๏ธ โœ…๏ธ
Pycnophylactic Tobler's pycnophylactic interpolation preserving zone totals via Laplacian smoothing Tobler 1979 โœ…๏ธ

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, matplotlib, zstandard

Optional:

  • 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

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. For uncompressed files it reads 5-7x faster than rioxarray; for compressed COGs it is comparable or faster with GPU acceleration.

Citation

Cite this code:

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

Wheel compatibility matrix

Platform Python 3
any

Files in release

Extras:
Dependencies:
numba
scipy
xarray
numpy
matplotlib
zstandard