Skip to content

GeoZarr

GeoZarr is built from three Zarr conventions. topozarr writes all three as group attributes, and each one answers a single question about the store. Together, they give a web map like zarr-layer what it needs to place the data and pick a resolution without reading any coordinate arrays.

multiscales which groups are levels and how each one derives proj which coordinate reference system EPSG:4326 spatial how array indices map to coordinates [1, 2] (x, y)

In the store, the root group describes the whole pyramid. Each level group repeats proj:code, proj:wkt2, and zarr_conventions. The figure shows only the key attributes. The root also carries proj:wkt2, spatial:transform, spatial:shape, and spatial:registration.

pyramid.zarr/ group 0/ level group air array 1/ level group air array 2/ level group air array zarr_conventions multiscales proj:code spatial:dimensions spatial:bbox proj:code repeated per level proj:code proj:code dimension_names: [time, lat, lon] dimension_names: [time, lat, lon] dimension_names: [time, lat, lon] multiscales proj spatial

multiscales

Spec: zarr-conventions/multiscales v0.1

The multiscales convention lists the levels in layout. Each entry after "0" names the level it was derived_from (the previous one), the resampling_method, and a transform whose scale is the ratio between adjacent levels along each spatial dimension (2 by default, or 4 for factors=[1, 4, 16]). Each entry also carries its own spatial:transform and spatial:shape, which give the absolute pixel size.

asset: "0" shape: [8, 8] transform: [a,0,c,0,e,f] asset: "1" shape: [4, 4] transform: [2a,0,c,0,2e,f] asset: "2" shape: [2, 2] transform: [4a,0,c,0,4e,f] derived_from: "0" scale: [2, 2] derived_from: "1" scale: [2, 2] (c, f) origin stays put multiscales: layout entry · relative spatial: per level · absolute

scale and translation cover every dimension of the array, in the dataset's dimension order. For [time, lat, lon], they are [1, 2, 2] and [0, 0, 0]. translation is always zero because every level shares the same corner origin in spatial:transform, as the spatial convention recommends.

proj

Spec: zarr-conventions/proj v0.1

The proj convention sets the CRS with proj:code and proj:wkt2. It applies only to a group's direct child arrays. Level arrays are grandchildren of the root, so topozarr also tags each level group.

proj only at the root pyramid.zarr/ 0/ air proj:code no proj no CRS grandchild of the tagged group proj on each level (topozarr) pyramid.zarr/ 0/ air proj:code proj:code inherits EPSG:4326 parent group has proj

spatial

Spec: zarr-conventions/spatial v0.1

The spatial convention maps array indices to coordinates. spatial:transform is a six-number affine transform. Because each level gets only one transform, this works only for 1-D, uniformly spaced coordinates.

0 1 2 3 4 5 0 1 2 3 col → row ↓ (c, f) a e [a, b, c, d, e, f] x = a·col + b·row + c y = d·col + e·row + f a, e pixel size; e < 0 is north-up b, d rotation, usually 0 c, f top-left corner of the grid pixel center = index + 0.5 col 3, row 2 → (3.5a + c, 2.5e + f)

spatial:dimensions names the Y and X dimensions, in that order. Other dimensions, like time, are left alone.

dimension_names spatial:dimensions 0 time 1 lat 2 lon not spatial "lat" Y "lon" X ordered [Y, X]

topozarr always writes spatial:registration: "pixel", which means cell edges, not cell centers, line up with spatial:bbox.