With the Surface tools, you can quantify and visualize a terrain landform represented by a digital elevation model.

Starting with a raster elevation surface that represented as an Xarray DataArray, these tools help you in identifying some specific patterns that were not readily apparent in the original surface. Return of each function is also an Xarray DataArray.

Hillshade: Creates a shaded relief from a surface raster by considering the illumination source angle and shadows.

Slope: Identifies the slope from each cell of a raster.

Curvature: Calculates the curvature of a raster surface.

Aspect: Derives the aspect from each cell of a raster surface.

Viewshed: Determines visible locations in the input raster surface from a viewpoint with some optional observer features.

Importing Packages

import numpy as np
import datashader as ds
from datashader.transfer_functions import shade
from datashader.transfer_functions import stack
from datashader.transfer_functions import dynspread
from datashader.transfer_functions import set_background
from datashader.colors import Elevation
import pandas as pd

import xrspatial

Generate Terrain Data

The rest of the geo-related functions focus on raster data (or rasterized data, after a previous Datashader step that returns an Xarray object). To demonstrate using these raster-based functions, let’s generate some fake terrain as an elevation raster:

from xrspatial import generate_terrain

W = 800
H = 600

cvs = ds.Canvas(plot_width=W, plot_height=H, x_range=(-20e6, 20e6), y_range=(-20e6, 20e6))
terrain = generate_terrain(canvas=cvs)

shade(terrain, cmap=['black', 'white'], how='linear')

The grayscale value above shows the elevation linearly in intensity (with the large black areas indicating low elevation), but it will look more like a landscape if we map the lowest values to colors representing water, and the highest to colors representing mountaintops:

shade(terrain, cmap=Elevation, how='linear')


Hillshade is a technique used to visualize terrain as shaded relief, illuminating it with a hypothetical light source. The illumination value for each cell is determined by its orientation to the light source, which is based on slope and aspect.

from xrspatial import hillshade

illuminated = hillshade(terrain)

shade(illuminated, cmap=['gray', 'white'], alpha=255, how='linear')

You can combine hillshading with elevation colormapping to convey differences in terrain with elevation:

stack(shade(illuminated, cmap=['gray', 'white'], alpha=255, how='linear'),
      shade(terrain,     cmap=Elevation,         alpha=128, how='linear'))