Add an offline terrain shadow overlay to the Overlays panel
Shades the visible map by whether each point is currently blocked from the sun by surrounding terrain (shademap.app-style), computed fully offline via the same Terrarium DEM tiles the Terrain shading layer already renders, plus this session's sun-position math and Radar's checkbox+expandable UI shape. dem.js pulls elevation-at-a-point out on its own since TODO.adoc's slope readout and solar calculator will need the same lookup.
This commit is contained in:
1 parent
a8d58abaca
commit
c9561a5489
7 files changed
+357
-3
No files matched your search
+12
-2
@@ -3,6 +3,7 @@ import { OVERLAYS_ICON, WIKI_ICON, WILDERNESS_ICON, MAP_MARKER_ICON } from "/js/
|
||||
import { notifySidePanelOpen, onlyOneSidePanelOpen } from "/js/panels.js";
|
||||
import { svgToImageData, badgeImageId, escapeHtml } from "/js/gpx.js";
|
||||
import { RadarControl } from "/js/radar.js";
|
||||
import { ShadowControl } from "/js/shadow.js";
|
||||
|
||||
const ICON_IMAGE_SIZE = 48; // rasterized once at this size, rendered much smaller by icon-size below
|
||||
const ICON_SIZE = 0.3; // 48 * 0.3 = ~14px, sized to sit inside the marker badge below
|
||||
@@ -35,7 +36,9 @@ const ELEVATION_COLOR_RAMP = [
|
||||
// is skipped in favor of a local terrain.pmtiles if one's been generated
|
||||
// (see docs/development.adoc), same optional-local-file story as
|
||||
// offline.pmtiles itself.
|
||||
const ONLINE_TERRAIN_TILES = ["https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"];
|
||||
// Exported: dem.js's elevation lookups (shadow.js's raymarch) hit the same
|
||||
// online tile source, rather than duplicating the URL template.
|
||||
export const ONLINE_TERRAIN_TILES = ["https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"];
|
||||
|
||||
// A plain on/off Overlays item — there's nothing to choose, just whether
|
||||
// the shading shows, unlike Radar's expandable scrub/forecast.
|
||||
@@ -121,6 +124,7 @@ export class OverlaysControl {
|
||||
this._map = map;
|
||||
this._hillshade = new HillshadeControl(map);
|
||||
this._radar = new RadarControl(map);
|
||||
this._shadow = new ShadowControl(map);
|
||||
this._wikiEnabled = false; // the checkbox's own state
|
||||
this._wikiMoveHandler = null; // the moveend listener driving its live refetch, while enabled
|
||||
this._wikiRequestSeq = 0; // ignores an in-flight refetch a newer one has already superseded
|
||||
@@ -152,11 +156,13 @@ export class OverlaysControl {
|
||||
<li class="overlays-panel__item"></li>
|
||||
<li class="overlays-panel__item"></li>
|
||||
<li class="overlays-panel__item overlays-panel__item--expandable"></li>
|
||||
<li class="overlays-panel__item overlays-panel__item--expandable"></li>
|
||||
`;
|
||||
const [hillshadeItem, wikiItem, radarItem] = list.children;
|
||||
const [hillshadeItem, wikiItem, radarItem, shadowItem] = list.children;
|
||||
this._hillshade.mount(hillshadeItem);
|
||||
this._mountWiki(wikiItem);
|
||||
this._radar.mount(radarItem);
|
||||
this._shadow.mount(shadowItem);
|
||||
|
||||
onlyOneSidePanelOpen(this._panel, () => this._icon.classList.remove("active"));
|
||||
|
||||
@@ -174,6 +180,10 @@ export class OverlaysControl {
|
||||
this._hillshade.setOfflineAvailable(available);
|
||||
}
|
||||
|
||||
setShadowOfflineAvailable(available) {
|
||||
this._shadow.setOfflineAvailable(available);
|
||||
}
|
||||
|
||||
_mountWiki(li) {
|
||||
li.innerHTML = `
|
||||
<label>
|
||||
|
||||
Reference in new issue
Block a user