Skip to content

Icechunk and Zarr page: a store's grid and chunks under other projections - #60

Merged
mdsumner merged 2 commits into
mainfrom
claude/project-thread-mxjw59
Oct 27, 2026
Merged

mdsumner merged 2 commits into
mainfrom
claude/project-thread-mxjw59

Conversation

@mdsumner

Copy link
Copy Markdown
Member

Requested by Michael · project thread

What

New page store.html (nav: after Rectilinear chunks). Point it at an Icechunk repository or a Zarr store and it shows where a variable's cells and chunks sit on the earth:

  • reads Icechunk with icechunk-js 0.6.0 (EarthyScience) and Zarr with zarrita 0.7.5, the same pair gridlook uses; both are pinned devDependencies and loaded from jsDelivr +esm in the page
  • finds the CRS from a CF grid_mapping (14 appendix F mappings, plus rotated pole), the EPSG code in crs_wkt, GeoZarr attributes, or 1D lat/lon coordinates (WGS 84 assumed, and the page says so)
  • finds the cells from a GeoTransform, spatial:transform or 1D coordinates (km units are scaled to m)
  • draws a mesh over index space, moving from the globe to a gridlook projection (plus LAEA and the store's own CRS)
  • colours by data (the whole slice when it is small, otherwise a spread of chunks or the chunk you click), by cell area on the earth, or by the angular distortion of the store's CRS
  • shows a readout for the clicked cell: chunk key, x/y, lon/lat, area, h/k, omega, value
  • uses gridlook's URL hash form (#<store>::varname=..::projection=..) and has an "Open in gridlook" link

Checks

test/check-storecrs.mjs (added to npm test):

  • every CF mapping goes through proj4js and is compared with pyproj CRS.from_cf, all within 1 mm. The exception is ellipsoidal aeqd: proj4js 2.12.1 is about 1 m off and inverts it into the wrong hemisphere. 2.22 fixes this. The test reports it rather than failing.
  • cell areas are compared with pyproj Geod, using densified parallel edges
  • six fixture stores (LCC, polar stereographic in km, a global grid inside a group, rotated pole, a plain Zarr store with GeoTransform, and a GLAD-shaped metadata-only store) are served over HTTP and read through js/store-read.js. The first-cell lon/lat is checked against PROJ.

The browser check used Playwright + swiftshader with the CDN routed to local bundles: all fixtures open and draw.

Not yet

  • curvilinear (2D lat/lon) grids are only noted (Regular in what? could fit a CRS to them later)
  • the public icechunk-public-data bucket sends no CORS header, so the browser cannot open it from another site
  • the +esm jsDelivr builds of icechunk-js and zarrita have not been loaded from the real CDN yet

Generated by Claude Code

…ions

store.html opens an Icechunk repository (icechunk-js) or a Zarr store
(zarrita), finds the variable's CRS (CF grid_mapping, EPSG in crs_wkt,
GeoZarr attributes, or lat/lon coordinates) and where its cells are
(GeoTransform, spatial:transform or 1D coordinates), and draws cells and
chunks on the globe, unfolding into a gridlook projection or the store's
own CRS. Colour by data (chunks read on demand), true cell area or the
angular distortion of the store's CRS. The URL hash is gridlook's.

src/core/storecrs.js: CF grid mappings to PROJ strings, coordinate axes,
cell areas, gridlook hash. Checked in test/check-storecrs.mjs against
pyproj's CRS.from_cf and Geod, and small Icechunk/Zarr stores written by
xarray, zarr-python and icechunk (test/make-store-fixtures.py).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5mFPo1pMPQm38dMJ6T5Nu
@mdsumner mdsumner self-assigned this Oct 26, 2026
- rectilinear (uneven 1D) axes with midpoint cell edges
- curvilinear 2D lat/lon grids (e.g. tripolar ocean): bilinear on unit
  vectors, spherical quad areas, cell shape from the Jacobian
- Local folder picker opens a Zarr store from disk (nothing uploaded)
- presets from the public CMIP6 bucket used by gridlook
- auto-read limit lowered to 32MB
- gaussian.zarr and curvilinear.zarr fixtures and tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5mFPo1pMPQm38dMJ6T5Nu
@mdsumner
mdsumner merged commit b645d16 into main Oct 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants