Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

SWOT Pixel Cloud Viewer

Carsten Bjerre Ludwigsen · Danish Coastal Authorities · cabjl@kyst.dk

Built with the help of Claude Sonnet 5 by Anthropic.

Data/attribution: SWOT data are NASA/JPL-Caltech, CNES, CSA, UKSA. Basemap tiles are © OpenStreetMap contributors. The DVR90 vertical datum grid is from SDFE (Denmark).

A single HTML page that builds a water-level time series at a lat/lon from SWOT L2_HR_PIXC — the raw pixel cloud (~5–25 m spacing), not the coarser river/lake products. Built for coastal points with complex shorelines that reach/node-averaged products don't resolve well.

Open index.html in a browser, or host it anywhere static. Nothing to build.

How it works

  1. Pick a point, a search radius, and a date range.
  2. The page queries NASA's CMR API for SWOT_L2_HR_PIXC_D granules intersecting your point (no login needed for this step).
  3. Each granule is downloaded and parsed entirely in-browser via h5wasm — no server, no Python.
  4. Pixels within your search radius, in the reliable water classes (water_near_land, open_water, dark_water, and the low-coherence variants), feed the height for that pass.
  5. One point per overpass is plotted and added to the results table.
  6. Clicking a row (or using Prev/Next) opens that pass's full pixel cloud on its own map.

Setup

Each person needs their own free NASA Earthdata token — nothing is shared between users. The page has a "First time here?" panel with the same steps:

  1. Create an account at https://urs.earthdata.nasa.govProfile → Generate Token.
  2. Paste it into the NASA Earthdata bearer token field. Approve the PO.DAAC application under your profile's Applications tab if downloads 401/403 despite a valid token.
  3. If direct downloads get CORS-blocked, use a proxy: paste a shared institutional URL into Proxy base URL, or deploy your own (cloudflare-worker.js on a free Cloudflare Workers account, or proxy.js locally with node proxy.js).

Sharing a proxy across a team

Both cloudflare-worker.js and proxy.js hold no credentials by default — each browser sends its own token, and the proxy just forwards it and fixes CORS. It only restricts where it will relay to (NASA/Earthdata/PROJ hosts), not who can use it. Optional EDL_TOKEN (shared fallback token) and ACCESS_KEY (shared password) secrets exist for institutions that want the older shared-credential model, but most deployments should leave both unset.

Reading the output

  • Height raw — median (not mean) pixel height above WGS84, uncorrected.
  • Height corrected (EGM2008) — median of height − geoid − solid_earth_tide − load_tide_fes − pole_tide, i.e. relative to the geoid with tide effects removed.
  • Height corrected (DVR90) — same tide corrections, but referenced to Denmark's national vertical datum instead of EGM2008, via SDFE's official ETRS89-to-DVR90 grid (fetched from PROJ's public CDN). Toggle between the two on the chart and the pixel-cloud map. Note: SWOT's height is on WGS84 while the DVR90 grid is defined for ETRS89 (a small, slowly-growing divergence between the two frames), and DVR90 itself was realized around 1990, so a slow secular drift from current sea level is possible.
  • Crossover calibration (height_cor_xover) is not applied separately — per NASA/JPL documentation it's already folded into PIXC's height variable (unlike the LR_SSH ocean product), so adding it again would double-count it.
  • Pixels / Mean dist — how many pixels fed the median, and their average distance from your point (a genuine mean, unlike the height values).

The pixel-cloud map

  • Every classified pixel across the whole tile is collected, but only what's in your current viewport gets drawn — pan/zoom re-filters live.
  • The classification checkboxes are a display filter only; the search/stats always use the fixed reliable-water class set regardless.
  • Color scale defaults to a fixed -1 to 1 m window for comparability across passes; "Auto range" snaps to the actual data range on demand.
  • Prev/Next pass buttons switch passes while keeping your current pan/zoom/color range — clicking a fresh table row re-fits the view instead.

Exports

  • Time series CSV / chart PNG — below the chart.
  • Export view (.dat) — whatever's currently drawn on the map, fixed-width columns. In QGIS: Add Delimited Text Layer, delimiter type "Regular expression" with pattern \s+, discard 1 header line, X=lon, Y=lat, CRS EPSG:4326. Includes both EGM2008 and DVR90 heights as separate columns.
  • Export view (.dat all tiles) — same, but one .dat per pass across every result, bundled as a .zip. A download link appears next to the button once ready (not auto-triggered, since long processing can cause the browser to silently block an automatic download).
  • Export view (.png) / (.png all tiles) — map snapshot(s) with a timestamp, granule ID, reference datum, and colorbar burned in. All-tiles version also zips.

Known caveats

  • Browser support: Files Folder and PNG export need Chrome or Edge.
  • File size: PIXC granules are tens to hundreds of MB each; a long time series means many downloads, and whole-tile pixel collection means memory/CPU scale with how much of the tile is water.
  • Not the same as Hydrocron, which only covers river reaches/lakes, not open coast.
  • If PIXC's variable paths ever change: the VARS object and getAttr()/attrTriple() helpers near the top of the <script type="module"> block are the place to adjust. A commented-out DEBUG_DUMP inside processGranule() can inspect a real granule's structure in the console.

About

A no-install browser tool for querying and analyzing NASA SWOT pixel cloud satellite data, with Danish DVR90 datum support.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors