feat(workbench): integrate operational workflows and map state

This commit is contained in:
2026-09-24 04:34:46 +08:00
parent 1752b9ef84
commit 436d5500f1
76 changed files with 5081 additions and 1937 deletions
@@ -1,4 +1,4 @@
import type { Map as MapLibreMap, MapLayerMouseEvent } from "maplibre-gl";
import type { Map as MapLibreMap, MapLayerMouseEvent, PointLike } from "maplibre-gl";
import type { RefObject } from "react";
import { useEffect } from "react";
import type { DetailFeature } from "../types";
@@ -8,6 +8,7 @@ import {
toDetailFeature
} from "../map/feature-adapter";
import { INTERACTIVE_HIT_LAYER_IDS } from "../map/layers";
import { CITY_BUILDING_LAYER_ID } from "../map/city-scene-layers";
import { SOURCE_LAYERS, type WaterNetworkSourceId } from "../map/sources";
export type MapFeatureInteractionState = {
@@ -46,6 +47,16 @@ export function clearMapFeatureInteractionState(
map.removeFeatureState(toFeatureStateTarget(feature), key);
}
type CityOcclusionMap = Pick<
MapLibreMap,
"getLayer" | "getPitch" | "queryRenderedFeatures"
>;
export function isPointOccludedByCityBuilding(map: CityOcclusionMap, point: PointLike) {
if (map.getPitch() <= 0 || !map.getLayer(CITY_BUILDING_LAYER_ID)) return false;
return map.queryRenderedFeatures(point, { layers: [CITY_BUILDING_LAYER_ID] }).length > 0;
}
type UseMapInteractionsOptions = {
availableSourceIds: readonly WaterNetworkSourceId[];
mapRef: RefObject<MapLibreMap | null>;
@@ -74,6 +85,11 @@ export function useMapInteractions({
};
const handleMouseMove = (event: MapLayerMouseEvent) => {
if (isPointOccludedByCityBuilding(map, event.point)) {
clearHoveredFeature();
map.getCanvas().style.cursor = "";
return;
}
const feature = event.features?.[0];
const source = feature && getWaterNetworkSourceId(feature);
const id = feature && getFeatureId(feature);
@@ -100,6 +116,7 @@ export function useMapInteractions({
};
const handleClick = (event: MapLayerMouseEvent) => {
if (isPointOccludedByCityBuilding(map, event.point)) return;
const feature = event.features?.[0];
if (feature) onSelectFeature(toDetailFeature(feature));
};