Commit a24d363
Add progressive globe with H3 aggregation and sample drill-down (#50)
* Add H3 spatial indexing, two-tier facet loading, and benchmark optimizations (#5)
Add H3 spatial indexing, two-tier facet loading, and benchmark optimizations
## Changes
- isamples_explorer.qmd: Two-tier facet loading (2KB summary for instant counts)
- parquet_cesium_isamples_wide.qmd: Zoom-adaptive H3 clustering with LOD
- zenodo_isamples_analysis.qmd: Data-driven H3 regional analysis
- narrow_vs_wide_performance.qmd: Added geospatial and facet benchmarks
## Fixes Applied (Codex review)
- Fixed MODE(n) → MODE(source) for cluster coloring
- Added camera listener cleanup to prevent leaks
- Added NaN guard for cluster label parsing
- Added user-facing warning for facet summary failures
Closes #1, #2, #3, #4
* Add progressive globe demo with H3 aggregated loading
Loads 580KB H3 res4 summary for instant globe render (<1s),
then switches to res6/res8 on zoom with viewport filtering.
Click triggers sample detail query from full 280MB parquet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix progressive globe: render stats bar from OJS cells
DOM elements created in raw HTML aren't available when OJS cells
execute. Move legend, stats bar, and phase indicator into OJS cells
and add null guards on all getElementById calls.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Click cluster dot to fly-to and drill down to next H3 resolution
Clicking an H3 cluster now flies the camera to that location at
an altitude that triggers the next resolution level (res4→res6→res8).
The zoom watcher then automatically loads finer detail.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Redesign progressive globe: side panel + global data + info-only clicks
- Side-by-side layout: globe left, live info panel right (always visible)
- Load full H3 files globally (no viewport filtering) — no gaps when panning
- Click shows cluster info + nearby samples in side panel (no camera fly-to)
- Zoom watcher switches resolution automatically: res4 → res6 → res8
- Stats, legend, cluster card, and sample list all in side panel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix infinite loop: replace OJS reactivity with imperative DOM updates
The side panel was causing a reactive cycle:
globeStatus change → sidePanel re-render → layout re-render →
viewer re-create → phase1 re-run → globeStatus change → loop
Fix: all side panel content is static HTML. Stats, cluster card,
and sample list are updated via getElementById/innerHTML only.
No OJS mutable variables, no reactive cascade.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add sub-res8 individual sample drill-down to progressive globe
- New 4th zoom tier: below 120km altitude, switches from H3 clusters
to individual sample points loaded from lite parquet (60MB vs 280MB)
- Two-stage sample card: instant metadata from lite file, lazy-loaded
description from full wide parquet on click
- Viewport caching with 30% padding for smooth panning
- Stale-request guards for async camera/query flows
- Hysteresis thresholds (120km enter / 180km exit) to prevent flicker
- Separate PointPrimitiveCollection for samples vs clusters
- Cluster click queries now use lite parquet instead of wide (5x faster)
Data files on R2:
- isamples_202601_samples_map_lite.parquet (60MB, 6M rows, 9 columns)
- Still uses H3 summary files for res4/6/8 cluster view
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix bugs from Codex review: deadlock, schema mismatch, timing
- loadRes: wrap in try/catch/finally so `loading` flag always resets
on query failure (was permanent deadlock — finding #2)
- Schema fix: cluster-click query used `n as source` but the lite
parquet has column named `source` (finding #4)
- Remove unnecessary ORDER BY on H3 loads (finding #8)
- Use .pop() instead of [0] for performance timing entries (finding #11)
- Add rel="noopener noreferrer" to target="_blank" link (finding #7)
Deferred: XSS escaping (trusted data), antimeridian handling,
detail click caching, startup error fallback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add progressive globe to sidebar navigation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix cluster-click query: remove description column missing from lite parquet
The samples_map_lite.parquet doesn't have a description column.
Use place_name for nearby sample cards instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add URL state encoding for shareable deep links
- Hash-based URL state: lat, lng, alt, heading, pitch, mode, pid
- v=1 schema versioning for future compatibility
- parseNum with Number.isFinite (avoids lat=0 bug from Codex review)
- replaceState for continuous camera movement, pushState for mode
transitions and sample/cluster selection
- Browser back/forward via hashchange listener with flight animation
- Suppress flag prevents hash write loops during navigation restore
- Deep-link startup: fly to position and restore sample card from pid
- Share View button copies current URL to clipboard with toast
- pid takes precedence over h3 (canonicalized on write)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix startup crash: move _initialHash before globalRect block that reads it
v._initialHash was set after the once() closure that references it,
causing undefined.lat TypeError on page load.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent 4cd3164 commit a24d363
File tree
6 files changed
+1794
-238
lines changed- tutorials
6 files changed
+1794
-238
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| 57 | + | |
| 58 | + | |
57 | 59 | | |
58 | 60 | | |
59 | 61 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
31 | 34 | | |
32 | 35 | | |
33 | 36 | | |
| |||
79 | 82 | | |
80 | 83 | | |
81 | 84 | | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
82 | 89 | | |
83 | 90 | | |
84 | 91 | | |
85 | 92 | | |
86 | | - | |
| 93 | + | |
87 | 94 | | |
88 | | - | |
89 | | - | |
| 95 | + | |
| 96 | + | |
90 | 97 | | |
91 | 98 | | |
92 | 99 | | |
| |||
104 | 111 | | |
105 | 112 | | |
106 | 113 | | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
107 | 177 | | |
108 | 178 | | |
109 | 179 | | |
| |||
131 | 201 | | |
132 | 202 | | |
133 | 203 | | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
134 | 207 | | |
135 | 208 | | |
136 | 209 | | |
| |||
264 | 337 | | |
265 | 338 | | |
266 | 339 | | |
267 | | - | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
268 | 384 | | |
269 | 385 | | |
270 | 386 | | |
| |||
288 | 404 | | |
289 | 405 | | |
290 | 406 | | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
291 | 428 | | |
292 | 429 | | |
293 | 430 | | |
294 | 431 | | |
295 | 432 | | |
296 | 433 | | |
297 | | - | |
298 | | - | |
299 | | - | |
300 | | - | |
301 | | - | |
302 | | - | |
303 | | - | |
304 | | - | |
305 | | - | |
306 | | - | |
307 | | - | |
308 | | - | |
309 | | - | |
310 | | - | |
311 | | - | |
312 | | - | |
313 | | - | |
314 | | - | |
315 | | - | |
316 | | - | |
317 | | - | |
318 | | - | |
319 | | - | |
320 | | - | |
321 | | - | |
322 | | - | |
323 | | - | |
324 | | - | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
325 | 437 | | |
326 | 438 | | |
327 | 439 | | |
| |||
0 commit comments