This throws a ValueError
when trying to build a Dataset from a GOES-CMI STAC item from the Planetary Computer:
import pystac
import planetary_computer
import odc.stac
item = planetary_computer.sign(
pystac.Item.from_file("https://planetarycomputer.microsoft.com/api/stac/v1/collections/goes-cmi/items/OR_ABI-L2-C-M6_G16_s20200012356184")
)
# Drop assets in different projections
# https://github.com/opendatacube/odc-stac/issues/70
bands = {"C01_2km", "C02_2km", "C03_2km"}
item.assets = {k: v for k, v in item.assets.items() if k in bands}
ds = odc.stac.stac_load([item], bands=bands, chunks={})
The error is
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [7], in <cell line: 15>()
12 bands = {"C01_2km", "C02_2km", "C03_2km"}
13 item.assets = {k: v for k, v in item.assets.items() if k in bands}
---> 15 ds = odc.stac.stac_load([item], bands=bands, chunks={})
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/stac/_load.py:460, in load(items, bands, groupby, resampling, dtype, chunks, pool, crs, resolution, align, geobox, bbox, lon, lat, x, y, like, geopolygon, progress, stac_cfg, patch_url, preserve_original_order, **kw)
457 items = list(items)
458 _parsed = list(parse_items(items, cfg=stac_cfg))
--> 460 gbox = output_geobox(
461 _parsed,
462 bands=bands,
463 crs=crs,
464 resolution=resolution,
465 align=align,
466 geobox=geobox,
467 like=like,
468 geopolygon=geopolygon,
469 bbox=bbox,
470 lon=lon,
471 lat=lat,
472 x=x,
473 y=y,
474 )
476 if gbox is None:
477 raise ValueError("Failed to auto-guess CRS/resolution.")
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/stac/_mdtools.py:805, in output_geobox(items, bands, crs, resolution, align, geobox, like, geopolygon, bbox, lon, lat, x, y)
803 x0, y0, x1, y1 = _compute_bbox(items, crs)
804 geopolygon = geom.box(x0, y0, x1, y1, crs)
--> 805 return GeoBox.from_geopolygon(geopolygon, resolution=resolution, align=align)
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/geo/geobox.py:227, in GeoBox.from_geopolygon(geopolygon, resolution, crs, align, shape, tight, anchor, tol)
224 else:
225 geopolygon = geopolygon.to_crs(crs)
--> 227 return GeoBox.from_bbox(
228 geopolygon.boundingbox,
229 crs,
230 shape=shape,
231 resolution=resolution,
232 anchor=anchor,
233 tol=tol,
234 tight=tight,
235 )
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/geo/geobox.py:151, in GeoBox.from_bbox(bbox, crs, tight, shape, resolution, anchor, tol)
149 offy, ny = snap_grid(bbox.bottom, bbox.top, ry, None, tol=tol)
150 else:
--> 151 offx, nx = snap_grid(bbox.left, bbox.right, rx, _snap.x, tol=tol)
152 offy, ny = snap_grid(bbox.bottom, bbox.top, ry, _snap.y, tol=tol)
154 affine = Affine.translation(offx, offy) * Affine.scale(rx, ry)
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/geo/math.py:172, in snap_grid(x0, x1, res, off_pix, tol)
169 return x1, max(nx, 1)
171 off = off_pix * abs(res)
--> 172 _tx, nx = _snap_edge(x0 - off, x1 - off, res, tol)
173 return _tx + off, nx
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/geo/math.py:140, in _snap_edge(x0, x1, res, tol)
138 assert x1 >= x0
139 if res > 0:
--> 140 return _snap_edge_pos(x0, x1, res, tol)
141 _tx, nx = _snap_edge_pos(x0, x1, -res, tol)
142 tx = _tx + nx * (-res)
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/geo/math.py:132, in _snap_edge_pos(x0, x1, res, tol)
130 assert x1 >= x0
131 _x0 = floor(maybe_int(x0 / res, tol))
--> 132 _x1 = ceil(maybe_int(x1 / res, tol))
133 nx = max(1, _x1 - _x0)
134 return _x0 * res, nx
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/geo/math.py:57, in maybe_int(x, tol)
50 def maybe_int(x: float, tol: float) -> Union[int, float]:
51 """
52 Turn almost ints to actual ints.
53
54 pass through other values unmodified.
55 """
---> 57 x_whole, x_part = split_float(x)
59 if abs(x_part) < tol: # almost int
60 return int(x_whole)
File /srv/conda/envs/notebook/lib/python3.8/site-packages/odc/geo/math.py:39, in split_float(x)
28 def split_float(x: float) -> Tuple[float, float]:
29 """
30 Split float number into whole and fractional parts.
31
(...)
37 :return: ``whole, fraction``
38 """
---> 39 x_part = fmod(x, 1.0)
40 x_whole = x - x_part
41 if x_part > 0.5:
ValueError: math domain error
I haven't dug too deeply yet, but x
there at the end, which I think is something like bbox.right
is inf
.
https://planetarycomputer.microsoft.com/api/stac/v1/collections/goes-cmi/items/OR_ABI-L2-C-M6_G16_s20200012356184 is a link to the STAC metadata.