feat(04-04): map tilt (pitch 35) + runtime building extrusion reusing style-owned colors — device-gate feedback
This commit is contained in:
+30
-3
@@ -32,16 +32,43 @@ export function bootMap(container: HTMLElement): MapLibreMap | null {
|
|||||||
style: ramsStyle as StyleSpecification, // inlined at build time (D-14) — NEVER re-set
|
style: ramsStyle as StyleSpecification, // inlined at build time (D-14) — NEVER re-set
|
||||||
center: KL_CENTER,
|
center: KL_CENTER,
|
||||||
zoom: 13,
|
zoom: 13,
|
||||||
|
pitch: 35, // device-gate feedback (2026-10-24): a slight tilt so the 3D city reads as 3D
|
||||||
attributionControl: false, // added below at bottom-left (UI-SPEC §Shell Layout: flush bottom-left chip)
|
attributionControl: false, // added below at bottom-left (UI-SPEC §Shell Layout: flush bottom-left chip)
|
||||||
});
|
});
|
||||||
map.addControl(new AttributionControl({ compact: true }), "bottom-left");
|
map.addControl(new AttributionControl({ compact: true }), "bottom-left");
|
||||||
|
// The Rams derivation ships buildings flat (fill only). Extrude them at
|
||||||
|
// runtime so the pitch reads as depth: the layer REUSES the flat layer's
|
||||||
|
// own style-owned paint values — zero invented colors (DSGN-01 audit-safe).
|
||||||
|
// Height comes from the vector tile's render_height when present.
|
||||||
|
map.on("load", () => {
|
||||||
|
try {
|
||||||
|
const flat = map.getStyle().layers.find((l) => l.id === "building");
|
||||||
|
const src = flat && "source" in flat ? flat.source : undefined;
|
||||||
|
const srcLayer = flat && "source-layer" in flat ? (flat as { "source-layer"?: string })["source-layer"] : undefined;
|
||||||
|
const flatFill = flat && "paint" in flat ? (flat.paint as { "fill-color"?: unknown })["fill-color"] : undefined;
|
||||||
|
if (typeof src === "string" && flatFill !== undefined) {
|
||||||
|
map.addLayer({
|
||||||
|
id: "building-3d",
|
||||||
|
type: "fill-extrusion",
|
||||||
|
source: src,
|
||||||
|
...(srcLayer !== undefined ? { "source-layer": srcLayer } : {}),
|
||||||
|
paint: {
|
||||||
|
"fill-extrusion-color": flatFill as string,
|
||||||
|
"fill-extrusion-height": ["coalesce", ["get", "render_height"], 6],
|
||||||
|
"fill-extrusion-base": 0,
|
||||||
|
"fill-extrusion-opacity": 0.85,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// extrusion is enhancement, never load-bearing — flat map still boots
|
||||||
|
}
|
||||||
|
console.log("RAMS-BASEMAP-READY layers=" + map.getStyle().layers.map((l) => l.id).length);
|
||||||
|
});
|
||||||
map.on("error", (e: { error?: { message?: string } }) => {
|
map.on("error", (e: { error?: { message?: string } }) => {
|
||||||
const inner = e && e.error;
|
const inner = e && e.error;
|
||||||
console.error("RAMS-BASEMAP-ERROR", inner && inner.message ? inner.message : inner);
|
console.error("RAMS-BASEMAP-ERROR", inner && inner.message ? inner.message : inner);
|
||||||
});
|
});
|
||||||
map.on("load", () => {
|
|
||||||
console.log("RAMS-BASEMAP-READY layers=" + map.getStyle().layers.map((l) => l.id).length);
|
|
||||||
});
|
|
||||||
return map;
|
return map;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof GPUInitializationError) return null; // Pitfall 5: shell still renders
|
if (err instanceof GPUInitializationError) return null; // Pitfall 5: shell still renders
|
||||||
|
|||||||
Reference in New Issue
Block a user