feat(04-04): map tilt (pitch 35) + runtime building extrusion reusing style-owned colors — device-gate feedback

This commit is contained in:
araharah-executor
2026-10-24 02:53:39 +08:00
parent 430765c778
commit cbe433fef1
+30 -3
View File
@@ -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