%matplotlib inline
import json
import numpy as np
import rioxarray
import stackstac
from matplotlib import pyplot as plt
item = json.load(open("test-tl-stac.geojson", "rt"))
xx = stackstac.stack(
[item], dtype="float32", bounds_latlon=(-180, -90, 180, +90), xy_coords="topleft"
)
yy = stackstac.stack(
[item], dtype="float32", bounds_latlon=(-180, -90, 180, +90), xy_coords="center"
)
We expect image data to be identical between the two modes
assert (xx.data == yy.data).all().compute()
fig, axs = plt.subplots(2, 1, figsize=(8, 7))
for idx in range(2):
xx.isel(band=idx).isel(time=0).plot.imshow(ax=axs[idx])
Data spans whole globe in EPSG:4326
projection with 1 degree pixels.
_, _, NY, NX = xx.shape
expect_x_left = np.linspace(-180, 180, NX + 1)[:-1] # -180 -> +179
expect_x_center = expect_x_left + 0.5 # -179.5 -> 179.5
expect_y_left = np.linspace(90, -90, NY + 1)[:-1] # +90 -> -89
expect_y_center = expect_y_left - 0.5 # 89.5 -> -89.5
Top-left coordinates are done correctly
np.testing.assert_allclose(xx.x, expect_x_left)
np.testing.assert_allclose(xx.y, expect_y_left)
Y coordinate is incorrectly computed when xy_coord="center"
. As a result rioxarray
reports incorrect transform and bounds.
(yy.rio.transform(), yy.attrs["transform"], yy.rio.bounds(), yy.attrs["spec"].bounds)
(Affine(1.0, 0.0, -180.0, 0.0, -1.0, 91.0), Affine(1.0, 0.0, -180.0, 0.0, -1.0, 90.0), (-180.0, -89.0, 180.0, 91.0), (-180.0, -90.0, 180.0, 90.0))
np.testing.assert_allclose(yy.x, expect_x_center)
np.testing.assert_allclose(yy.y, expect_y_center)
--------------------------------------------------------------------------- AssertionError Traceback (most recent call last) /tmp/ipykernel_3823/1215019092.py in <module> ----> 1 np.testing.assert_allclose(yy.y, expect_y_center) [... skipping hidden 1 frame] ~/.envs/ODC/lib/python3.9/site-packages/numpy/testing/_private/utils.py in assert_array_compare(comparison, x, y, err_msg, verbose, header, precision, equal_nan, equal_inf) 842 verbose=verbose, header=header, 843 names=('x', 'y'), precision=precision) --> 844 raise AssertionError(msg) 845 except ValueError: 846 import traceback AssertionError: Not equal to tolerance rtol=1e-07, atol=0 Mismatched elements: 180 / 180 (100%) Max absolute difference: 1. Max relative difference: 2. x: array([ 90.5, 89.5, 88.5, 87.5, 86.5, 85.5, 84.5, 83.5, 82.5, 81.5, 80.5, 79.5, 78.5, 77.5, 76.5, 75.5, 74.5, 73.5, 72.5, 71.5, 70.5, 69.5, 68.5, 67.5, 66.5, 65.5, 64.5,... y: array([ 89.5, 88.5, 87.5, 86.5, 85.5, 84.5, 83.5, 82.5, 81.5, 80.5, 79.5, 78.5, 77.5, 76.5, 75.5, 74.5, 73.5, 72.5, 71.5, 70.5, 69.5, 68.5, 67.5, 66.5, 65.5, 64.5, 63.5,...