feat: extend supply workbench demo and map navigation

This commit is contained in:
2026-09-23 13:19:30 +08:00
parent bebcf2a06c
commit 1752b9ef84
45 changed files with 2137 additions and 449 deletions
@@ -0,0 +1,60 @@
import type { LayerSpecification, SourceSpecification } from "maplibre-gl";
import { z } from "zod";
import { BASE_LAYER_IDS } from "./map-control-config";
import { MAP_STYLE_TOKENS as colors } from "./map-colors";
export const CITY_ROOT = "/city-model";
export const CITY_PREFIX = "fengxian-city-";
export function findCitySceneInsertionLayerId(layers: readonly LayerSpecification[]) {
const basemapLayerIds = new Set<string>(BASE_LAYER_IDS);
return layers.find((layer) => layer.id !== "background" && !basemapLayerIds.has(layer.id))?.id;
}
export const cityManifestSchema = z
.object({
schema_version: z.literal(1),
name: z.string(),
bbox: z.tuple([
z.number().min(-180).max(180),
z.number().min(-90).max(90),
z.number().min(-180).max(180),
z.number().min(-90).max(90)
]),
building_count: z.number().int().nonnegative(),
pipe_count: z.number().int().nonnegative(),
asset_count: z.number().int().nonnegative(),
notice: z.string(),
attribution: z.string()
})
.refine(({ bbox: [w, s, e, n] }) => w < e && s < n, "Invalid scene bounds");
export function citySources(): Record<string, SourceSpecification> {
return {
[CITY_PREFIX + "buildings"]: {
type: "vector",
url: `pmtiles://${window.location.origin}${CITY_ROOT}/buildings.pmtiles`,
minzoom: 12,
maxzoom: 16,
attribution:
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a> · <a href="https://docs.overturemaps.org/attribution/">Overture Maps</a>',
promoteId: "id"
}
};
}
export const CITY_LAYERS: LayerSpecification[] = [
{
id: CITY_PREFIX + "buildings",
source: CITY_PREFIX + "buildings",
"source-layer": "buildings",
type: "fill-extrusion",
minzoom: 12,
paint: {
"fill-extrusion-color": colors.canvas.secondary,
"fill-extrusion-height": ["to-number", ["get", "height_m"], 6],
"fill-extrusion-base": 0,
"fill-extrusion-opacity": 1,
"fill-extrusion-vertical-gradient": true
}
}
];