OverviewFilesCommitsIssuesDocsReleasesPeers

terrain-lookdev commits / 6295708

explore: verify coarse and detail agree in colour, and fix a thin-region crash
Checked rather than eyeballed. The same ground rendered as 8 detail tiles and as the 4x2 coarse block covering them, box-downsampled to compare: mean |RGB diff| 9.62 / 255 (3.8%) R detail 103.4 coarse 110.4 +7.0 G detail 115.9 coarse 124.9 +9.0 B detail 76.0 coarse 84.4 +8.4 Within 4%, and the residual is a SYSTEMATIC brightening across all three channels rather than a colour shift -- so the hypsometric ramp is being applied identically and the difference is shading. Left alone deliberately: the coarse layer is shaded at 7.68 km/px, so its surface really is smoother and more uniformly lit. Matching exactly would mean darkening the backdrop to fake shadows that are not there, which is the same mistake as inventing seafloor detail. The check also exposed a latent crash: /api/coarse.png died on any region thinner than 2 px, because np.gradient needs edge_order+1 elements per axis, and the failure surfaced as an opaque message from inside hillshade. The app never hits it (ensureCoarse always asks for a padded box) but a deep zoom would. It now grows the request and crops after shading, the same trick the tile apron uses. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6295708fa95a22ff5f3475e0fa4a0be8e54dcf61
by plankatron <noreply@anthropic.com> · 2026-08-31T20:37:12.000Z

Changed files (1) +11 -1

server.py +11 -1
……@@ -658,6 +658,14 @@ def api_coarse():
658658 ci2 = int(request.args["ci2"]); cj2 = int(request.args["cj2"])
659659 if (ci2 - ci1) * (cj2 - cj1) > 90000:
660660 raise ValueError("coarse region too large")
661 # np.gradient needs >= 2 elements per axis, so a 1-px-thin request dies
662 # inside hillshade with a confusing message. The app always asks for a
663 # large box, but a deep zoom could produce a thin one. Grow it here and
664 # crop after shading, the same trick the tile apron uses.
665 pad_i = max(0, 2 - (ci2 - ci1))
666 pad_j = max(0, 2 - (cj2 - cj1))
667 ci2 += pad_i
668 cj2 += pad_j
661669 q = (f"{app.config['TD_URL']}/coarse?i1={ci1}&j1={cj1}&i2={ci2}&j2={cj2}")
662670 with urllib.request.urlopen(q, timeout=1800) as r:
663671 h = int(r.headers["X-Height"]); w = int(r.headers["X-Width"])
……@@ -672,9 +680,11 @@ def api_coarse():
672680 else:
673681 rgb = colourise_array(elev, 7680.0, view, vmin, vmax,
674682 float(request.args.get("exag", 1.0)))
683 if pad_i or pad_j:
684 rgb = rgb[:rgb.shape[0] - pad_i or None, :rgb.shape[1] - pad_j or None]
675685 resp = Response(to_png(rgb), mimetype="image/png")
676686 resp.headers["Cache-Control"] = "public, max-age=3600"
677 resp.headers["X-Height"] = str(h); resp.headers["X-Width"] = str(w)
687 resp.headers["X-Height"] = str(rgb.shape[0]); resp.headers["X-Width"] = str(rgb.shape[1])
678688 resp.headers["X-Elev"] = f"{elev.min():.0f},{elev.max():.0f}"
679689 return resp
680690 except Exception as e: