Skip to content

Commit 3348a73

Browse files
dcherianscottyhqpre-commit-ci[bot]
authored
Add rasterix (#5)
Co-authored-by: Scott Henderson <3924836+scottyhq@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 1ecef16 commit 3348a73

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

docs/earth/raster.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,139 @@
1+
---
2+
jupytext:
3+
text_representation:
4+
format_name: myst
5+
kernelspec:
6+
display_name: Python 3
7+
name: python
8+
---
9+
110
# rasterix: RasterIndex
11+
12+
````{grid}
13+
```{grid-item}
14+
:columns: 3
15+
```{image} https://rasterix.readthedocs.io/en/latest/_static/rasterix.png
16+
---
17+
alt: Alt text
18+
width: 200px
19+
align: center
20+
---
21+
```
22+
```{grid-item}
23+
:columns: 9
24+
```{seealso}
25+
Learn more at the [Rasterix](https://rasterix.readthedocs.io/en/latest/) documentation page.
26+
```
27+
````
28+
29+
## Highlights
30+
31+
Rasterix provides a RasterIndex that allows indexing using a functional transformation defined by an _affine transform_.
32+
33+
It uses {py:class}`~xarray.indexes.CoordinateTransformIndex` as a building block. In doing so,
34+
35+
1. RasterIndex eliminates an entire class of bugs where Xarray allows you to add (for example) two datasets with different affine transforms (and/or projections) and return nonsensical outputs.
36+
1. The associated coordinate variables are lazy, and use very little memory. Thus very large coordinate frames can be represented.
37+
38+
Rasterix uses a function {py:func}`rasterix.assign_index`.
39+
40+
## Example
41+
42+
Here is a GeoTIFF file opened with rioxarray. GeoTIFF files _do not contain explicit coordinate arrays_, instead they commonly store the coefficients of an affine transform that software libraries use to calculate the coordinates.
43+
44+
On reading, we set `"parse_coordinates": False` to tell rioxarray to not generate coordinate variables.
45+
46+
```{code-cell}
47+
import rasterix
48+
import xarray as xr
49+
50+
xr.set_options(display_expand_indexes=True, display_expand_attrs=False, display_expand_data=False)
51+
52+
source = "https://noaadata.apps.nsidc.org/NOAA/G02135/south/daily/geotiff/2024/01_Jan/S_20240101_concentration_v3.0.tif"
53+
54+
da = xr.open_dataarray(source, engine="rasterio", backend_kwargs={"parse_coordinates": False})
55+
da
56+
```
57+
58+
Notice how there are two dimensions `x` and `y`, but no coordinates associated with them.,
59+
60+
The affine transform information is stored in the attributes of `spatial_ref` under the name `"GeoTransform"`
61+
62+
```{code-cell}
63+
da.spatial_ref.attrs
64+
```
65+
66+
### Assignment
67+
68+
Rasterix provides a helpful `assign_index` function to automate the process of creating an index
69+
70+
```{code-cell}
71+
da = rasterix.assign_index(da)
72+
da
73+
```
74+
75+
We now have coordinate values, lazily generated on demand!
76+
77+
### Indexing
78+
79+
Slicing this dataset preserves the RasterIndex, though with a new transform
80+
81+
```{code-cell}
82+
sliced = da.isel(x=slice(100, 200), y=slice(200, 300))
83+
sliced
84+
```
85+
86+
Compare the underlying transforms:
87+
88+
```{code-cell}
89+
sliced.xindexes["x"].transform(), da.xindexes["x"].transform()
90+
```
91+
92+
### Combining
93+
94+
The affine transform is also used for alignment, and combining!
95+
96+
Here is a simple example. We slice the input dataset in to two
97+
98+
```{code-cell}
99+
left = da.isel(x=slice(150))
100+
right = da.isel(x=slice(150, None))
101+
```
102+
103+
Let's look at the bounding boxes for the sliced datasets
104+
105+
```{code-cell}
106+
---
107+
tags: [hide-input]
108+
---
109+
import matplotlib.pyplot as plt
110+
111+
def plot_bbox(bbox):
112+
x0, y0, x1, y1 = bbox
113+
plt.plot([x0, x0, x1, x1, x0], [y0, y1, y1, y0, y0])
114+
115+
plot_bbox(left.xindexes["x"].bbox)
116+
plot_bbox(right.xindexes["x"].bbox)
117+
```
118+
119+
Concatenating these two along x preserves the RasterIndex!
120+
121+
```{code-cell}
122+
combined = xr.concat([left, right], dim="x")
123+
combined
124+
```
125+
126+
```{code-cell}
127+
---
128+
tags: [hide-input]
129+
---
130+
plot_bbox(combined.xindexes["x"].bbox)
131+
```
132+
133+
The coordinates on the combined dataset is equal to the original dataset
134+
135+
```{code-cell}
136+
combined.xindexes["x"].equals(da.xindexes["x"])
137+
```
138+
139+
This functionality extends to [multi-dimsensional tiling](https://rasterix.readthedocs.io/en/latest/raster_index/combining.html#combine-nested) using {py:func}`xarray.combine_nested` too!

0 commit comments

Comments
 (0)