feat(map): manage agent overlays in layer panel
This commit is contained in:
@@ -99,6 +99,7 @@ import {
|
||||
import { getResponsivePadding, getResponsiveWorkbenchPadding } from "./map/camera";
|
||||
import { exportMapViewImage } from "./map/export-view";
|
||||
import { setMapLayersVisibility } from "./map/layer-visibility";
|
||||
import { MAP_STYLE_TOKENS } from "./map/map-colors";
|
||||
import {
|
||||
BASE_LAYER_OPTIONS,
|
||||
INITIAL_LAYER_VISIBILITY,
|
||||
@@ -298,9 +299,6 @@ function MapWorkbenchContent({
|
||||
const artifactActive = artifactWorkspace.activeArtifact !== null;
|
||||
const activeSpatialOverlay = artifactWorkspace.activeArtifact?.spatialOverlay ?? null;
|
||||
const activeArtifactHasSpatialView = Boolean(activeSpatialOverlay?.features.length);
|
||||
const allowDemoSimulation =
|
||||
(!getWorkbenchProject(getAccessToken) || getWorkbenchProject(getAccessToken)?.gs_workspace === "tjwater_next")
|
||||
&& (artifactWorkspace.activeArtifact === null || artifactWorkspace.activeArtifact.origin === "demo");
|
||||
const latestAnalysisAvailable = Boolean(
|
||||
latestAnalysisArtifact?.blocks.some(
|
||||
(block) =>
|
||||
@@ -355,11 +353,6 @@ function MapWorkbenchContent({
|
||||
|
||||
useEffect(() => {
|
||||
setImpactVisible(activeArtifactHasSpatialView);
|
||||
setLayerVisibility((current) =>
|
||||
current.simulation === activeArtifactHasSpatialView
|
||||
? current
|
||||
: { ...current, simulation: activeArtifactHasSpatialView }
|
||||
);
|
||||
}, [activeArtifactHasSpatialView, artifactWorkspace.activeArtifact?.id]);
|
||||
|
||||
function openAgentWorkspaceForViewport() {
|
||||
@@ -458,7 +451,6 @@ function MapWorkbenchContent({
|
||||
onSelectFeature: handleSelectFeature,
|
||||
selectedFeature: detailFeature,
|
||||
simulationOverlay: activeSpatialOverlay,
|
||||
allowDemoSimulation,
|
||||
networkView: projectPresentation.networkView,
|
||||
geoserverWorkspace: getWorkbenchProject(getAccessToken)?.gs_workspace,
|
||||
getAccessToken
|
||||
@@ -690,23 +682,55 @@ function MapWorkbenchContent({
|
||||
[activeToolId, mapReady, toggleToolbarTool]
|
||||
);
|
||||
|
||||
const layerControlItems = useMemo(
|
||||
() => createLayerControlItems(layerVisibility, availableSourceIds, sourceFeatureCounts),
|
||||
[availableSourceIds, layerVisibility, sourceFeatureCounts]
|
||||
const overlayLayers = [
|
||||
{ scope: "investigation", description: "Agent 调查", surface: presentation },
|
||||
{ scope: "chat", description: "Agent 对话", surface: chatPresentation },
|
||||
{ scope: "preview", description: "本地预览", surface: previewPresentation }
|
||||
].flatMap(({ scope, description, surface }) => surface.overlay ? [{
|
||||
id: `presentation:${scope}:${surface.overlay.overlay_id}`,
|
||||
title: surface.overlay.title,
|
||||
description: `${description} · ${surface.overlay.mode === "heatmap" ? "热力分布" : "空间范围"}`,
|
||||
featureCount: surface.overlay.data.features.length,
|
||||
color: MAP_STYLE_TOKENS.state.risk as string,
|
||||
visible: surface.overlay.visible,
|
||||
disabled: surface.history.selectedId !== null,
|
||||
onToggle: (visible: boolean) => {
|
||||
if (surface.overlay?.visible !== visible) surface.toggleOverlay();
|
||||
}
|
||||
}] : []);
|
||||
if (activeArtifactHasSpatialView && artifactWorkspace.activeArtifact) {
|
||||
overlayLayers.push({
|
||||
id: `artifact:${artifactWorkspace.activeArtifact.id}`,
|
||||
title: artifactWorkspace.activeArtifact.title,
|
||||
description: "分析成果 · 空间范围",
|
||||
featureCount: activeSpatialOverlay!.features.length,
|
||||
color: MAP_STYLE_TOKENS.state.agent,
|
||||
visible: impactVisible,
|
||||
disabled: false,
|
||||
onToggle: setImpactVisible
|
||||
});
|
||||
}
|
||||
const layerControlItems = createLayerControlItems(
|
||||
layerVisibility, availableSourceIds, sourceFeatureCounts, overlayLayers
|
||||
);
|
||||
const visibleLegendItems = useMemo(
|
||||
() => createVisibleMapLegendItems(layerControlItems),
|
||||
[layerControlItems]
|
||||
);
|
||||
function handleToggleLayer(layerControlId: string, visible: boolean) {
|
||||
if (layerControlId === "simulation") {
|
||||
setImpactVisible(visible);
|
||||
return;
|
||||
}
|
||||
const overlay = overlayLayers.find((item) => item.id === layerControlId);
|
||||
if (overlay) {
|
||||
if (!overlay.disabled) overlay.onToggle(visible);
|
||||
return;
|
||||
}
|
||||
presentationLayerChangesRef.current.delete(layerControlId);
|
||||
const map = mapRef.current;
|
||||
|
||||
setLayerVisibility((current) => ({ ...current, [layerControlId]: visible }));
|
||||
if (layerControlId === "simulation") {
|
||||
setImpactVisible(visible);
|
||||
}
|
||||
|
||||
if (!map || !mapReady) {
|
||||
return;
|
||||
}
|
||||
@@ -1079,7 +1103,7 @@ function MapWorkbenchContent({
|
||||
measurement.clear();
|
||||
drawing.clear();
|
||||
geocoding.clear();
|
||||
handleToggleLayer("simulation", false);
|
||||
setImpactVisible(false);
|
||||
showMapNotice({ tone: "success", message: "已清空所有高亮和覆盖层。" });
|
||||
}
|
||||
|
||||
@@ -1471,10 +1495,10 @@ function MapWorkbenchContent({
|
||||
</div>
|
||||
{!devPanelOpen ? (
|
||||
<>
|
||||
<div className="pointer-events-auto absolute right-3 top-10 hidden lg:block">
|
||||
<div className="pointer-events-auto absolute right-3 top-10 z-50 hidden lg:block">
|
||||
<MapToolbar items={toolbarItems} />
|
||||
</div>
|
||||
<div className="pointer-events-auto absolute right-16 top-10 hidden lg:block">
|
||||
<div className="pointer-events-auto absolute right-16 top-10 z-50 hidden lg:block">
|
||||
<ToolbarPanel {...toolbarPanelProps} />
|
||||
</div>
|
||||
</>
|
||||
@@ -1570,7 +1594,7 @@ function MapWorkbenchContent({
|
||||
|
||||
{mobileSheet === null && !readingWorkspace?.active && artifactWorkspace.surfaceMode !== "focus" ? (
|
||||
<div
|
||||
className="absolute left-3 right-3 z-30 transition-[bottom] duration-200 ease-out motion-reduce:transition-none lg:hidden"
|
||||
className="absolute left-3 right-3 z-50 transition-[bottom] duration-200 ease-out motion-reduce:transition-none lg:hidden"
|
||||
style={{
|
||||
bottom: mobileOverlayLayout.mapControlBottom,
|
||||
"--mobile-tool-available-height": `calc(100dvh - ${mobileOverlayLayout.mapControlBottom}px - 4.5rem)`
|
||||
|
||||
Reference in New Issue
Block a user