xrspatial.templates.from_template#

xrspatial.templates.from_template(name: str, resolution: float | Tuple[float, float] | None = None, *, height: int | None = None, width: int | None = None, preserve: str | None = None, backend: str = 'numpy', fill: float = nan, chunks: int | str | Tuple | None = None) DataArray[source]#

Create an empty DataArray for a common study area.

The returned raster is NaN-filled and obeys the xarray-spatial array contract: a 2-D ['y', 'x'] grid with pixel-center 1-D coordinates (north-up, descending y) and res/crs attributes. It covers the study area’s rectangular bounding box and is meant as a starting canvas.

The requested resolution is honored exactly. The study-area box is rarely a whole number of cells wide, so the far edges (right, top) are nudged out by up to half a cell to land on an exact multiple of the cell size, anchoring the lower-left corner. attrs['res'] therefore matches the resolution you pass.

Parameters:
  • name (str) – A curated region name (case-insensitive): a national/metro area such as 'conus' or 'nyc', a continental or subcontinental region such as 'europe', 'southeast_asia', 'east_africa', or 'south_america' (call list_templates() for the full set), or 'world'; a global-projection name, e.g. 'web_mercator' (EPSG:3857), 'wgs84' / 'latlon' (EPSG:4326, the same grid as 'world'), 'equal_earth' (EPSG:8857), or 'pacific' / 'pdc' (EPSG:3832, a Pacific-centered PDC Mercator); a world-city name (case-insensitive), e.g. 'london', 'tokyo', 'sao_paulo'; or an ISO-3166 / GADM alpha-3 country code, e.g. 'USA', 'FRA', 'JPN'. Curated regions and cities come back in a projected CRS (cities in their UTM zone); country codes come back in EPSG:4326. Where two cities share a name the larger keeps the bare name and the others take a _<iso2> suffix (e.g. 'hyderabad' vs 'hyderabad_pk').

  • resolution (float or tuple of float, optional) – Cell size in the template’s CRS units (metres for projected regions, degrees for country codes). A scalar gives square cells; a (res_x, res_y) tuple sets each axis. Defaults to a per-template value so a bare from_template('conus') works. Ignored on the height / width path unless given (see below).

  • height (int, optional) – Grid shape in cells. Supply both (or neither). When given, the result is exactly height x width cells anchored at the region’s lower-left corner, and the extent floats off that anchor rather than snapping to the study-area box: with resolution the extent is shape x resolution; without it the resolution is derived so the exact shape spans the region bbox. Use this to ask for a tiling-friendly shape directly.

  • width (int, optional) – Grid shape in cells. Supply both (or neither). When given, the result is exactly height x width cells anchored at the region’s lower-left corner, and the extent floats off that anchor rather than snapping to the study-area box: with resolution the extent is shape x resolution; without it the resolution is derived so the exact shape spans the region bbox. Use this to ask for a tiling-friendly shape directly.

  • preserve ({'area', 'shape'}, optional) – Reproject the template into an EPSG-coded projection chosen for the property it preserves, instead of the template’s default CRS. 'area' gives an equal-area projection (a curated national/continental code such as EPSG:5070, or EPSG:8857 Equal Earth where none is curated). 'shape' gives a conformal projection: the centroid’s UTM zone (UPS at the poles). When set, resolution is in metres and attrs['crs'] is the chosen EPSG int. Requires pyproj.

  • backend (str, default='numpy') – Array backend: 'numpy', 'dask+numpy' (alias 'dask'), 'cupy', or 'dask+cupy'. The eager backends ('numpy', 'cupy') materialize the whole grid, so they are subject to a 500-million-cell cap; the dask backends build a lazy chunk graph and are not.

  • fill (float, default=numpy.nan) – Value the grid is filled with. The dtype is always float32.

  • chunks (int, str, or tuple, optional) – Dask chunk specification. Supplying it returns a lazy, chunked grid: an eager backend is promoted to its dask variant ('numpy' to 'dask+numpy', 'cupy' to 'dask+cupy'), and the cell cap no longer applies. When omitted (or 'auto'), the dask backends tile the grid into even, square-ish blocks (~2048 cells per side) tuned for the neighborhood ops – slope, hillshade, focal – that run on the result through map_overlap. To make that tiling exact, a multi-block grid has its extent padded out from the lower-left anchor so each axis is a whole number of blocks: every chunk is full-size with no ragged remainder, the requested resolution is unchanged, and the padded grid still covers the study area (it only grows). The padding is dask-only – eager grids and explicit height / width keep the exact bbox-derived shape – and a grid small enough to not be worth splitting stays a single chunk, unpadded. Pass an explicit value to override the tiling. The data stays lazy, but a very fine resolution still builds one task per chunk, so an extreme shape with small explicit chunks can make a task graph large enough to bog down the client; a grid that would split into more than 1,000,000 chunks raises ValueError. The default tiling grows its block for such grids so it never trips that cap on its own.

Returns:

template – Empty 2-D raster with dims=('y', 'x') and pixel-center coordinates. attrs carries res and crs plus the CF Conventions grid-mapping keys grid_mapping_name (the projection token, e.g. 'albers_conical_equal_area') and crs_wkt (full WKT, which carries the human-readable CRS name). The x / y coordinates follow CF axis conventions: units 'm' with standard_name 'projection_x_coordinate' / 'projection_y_coordinate' for projected templates, or 'degrees_east' / 'degrees_north' with standard_name 'longitude' / 'latitude' for EPSG:4326. The grid-mapping keys require pyproj; without it they are omitted (the default, dependency-free path), and grid_mapping_name is also omitted for projections CF does not define (e.g. Equal Earth), leaving crs_wkt alone. These keys sit directly on attrs (the library’s flat CRS convention), not on a separate CF grid-mapping variable, so a strict CF reader will not auto-detect them as a grid mapping.

Return type:

xarray.DataArray

Examples

>>> from xrspatial import from_template
>>> agg = from_template("conus")            # Albers, default 5 km cells
>>> agg.attrs["crs"]
5070
>>> agg = from_template("conus", resolution=1000)   # 1 km cells
>>> agg = from_template("FRA")              # France bbox in EPSG:4326
>>> agg.attrs["crs"]
4326
>>> from_template("web_mercator").attrs["crs"]   # global EPSG:3857
3857
>>> from_template("latlon").attrs["crs"]         # alias for wgs84
4326
>>> from_template("equal_earth").attrs["crs"]    # global equal-area
8857
>>> from_template("london").attrs["crs"]    # greater London, UTM 30N
32630
>>> from_template("FRA", preserve="shape").attrs["crs"]   # UTM 30N
32630
>>> from_template("FRA", preserve="area").attrs["crs"]    # Equal Earth
8857
>>> # passing chunks returns a lazy dask grid, exempt from the cell cap
>>> agg = from_template("new_england", resolution=10, chunks=512)
>>> type(agg.data).__name__
'Array'
>>> # ask for an exact tiling-friendly shape; the extent floats
>>> from_template("conus", resolution=1000, height=4096, width=6144).shape
(4096, 6144)

Recipes#

Pick a grid, drop your own data onto it with DataArray.xrs.coregister, then run any tool. coregister reprojects a raster or rasterizes a GeoDataFrame onto the template’s exact grid, so layers line up cell-for-cell.

>>> grid = from_template("conus", resolution=1000)
>>> elevation = grid.xrs.coregister(my_dem)        # raster -> grid
>>> roads = grid.xrs.coregister(my_roads_gdf)      # vectors -> grid
>>> slope = elevation.xrs.slope()

For an out-of-core workflow, ask for a dask backend; the default tiling keeps the downstream graph parallel and overlap-friendly:

>>> grid = from_template("conus", resolution=250, backend="dask")
>>> slope = grid.xrs.coregister(my_dem).xrs.slope()  # stays lazy