新增features多选模式
This commit is contained in:
@@ -12,12 +12,12 @@ import HistoryDataPanel from "./HistoryDataPanel"; // 引入绘图面板组件
|
||||
import VectorSource from "ol/source/Vector";
|
||||
import VectorLayer from "ol/layer/Vector";
|
||||
import { Style, Stroke, Fill, Circle } from "ol/style";
|
||||
import { FeatureLike } from "ol/Feature";
|
||||
import Feature from "ol/Feature";
|
||||
import StyleEditorPanel from "./StyleEditorPanel";
|
||||
import { LayerStyleState } from "./StyleEditorPanel";
|
||||
import StyleLegend from "./StyleLegend"; // 引入图例组件
|
||||
import { handleMapClickSelectFeatures as mapClickSelectFeatures } from "@/utils/mapQueryService";
|
||||
import { useNotification } from "@refinedev/core";
|
||||
|
||||
import { config } from "@/config/config";
|
||||
const backendUrl = config.BACKEND_URL;
|
||||
@@ -35,12 +35,11 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
}) => {
|
||||
const map = useMap();
|
||||
const data = useData();
|
||||
const { open } = useNotification();
|
||||
if (!data) return null;
|
||||
const { currentTime, selectedDate, schemeName } = data;
|
||||
const [activeTools, setActiveTools] = useState<string[]>([]);
|
||||
const [highlightFeature, setHighlightFeature] = useState<FeatureLike | null>(
|
||||
null
|
||||
);
|
||||
const [highlightFeatures, setHighlightFeatures] = useState<Feature[]>([]);
|
||||
const [showPropertyPanel, setShowPropertyPanel] = useState<boolean>(false);
|
||||
const [showDrawPanel, setShowDrawPanel] = useState<boolean>(false);
|
||||
const [showStyleEditor, setShowStyleEditor] = useState<boolean>(false);
|
||||
@@ -56,7 +55,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
layerName: "节点图层",
|
||||
styleConfig: {
|
||||
property: "pressure",
|
||||
classificationMethod: "pretty_breaks",
|
||||
classificationMethod: "custom_breaks",
|
||||
segments: 6,
|
||||
minSize: 4,
|
||||
maxSize: 12,
|
||||
@@ -175,18 +174,74 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
// 清除之前的高亮
|
||||
source.clear();
|
||||
// 添加新的高亮要素
|
||||
if (highlightFeature instanceof Feature) {
|
||||
source.addFeature(highlightFeature);
|
||||
highlightFeatures.forEach((feature) => {
|
||||
if (feature instanceof Feature) {
|
||||
source.addFeature(feature);
|
||||
}
|
||||
}, [highlightFeature]);
|
||||
});
|
||||
}, [highlightFeatures, highlightLayer]);
|
||||
// 地图点击选择要素事件处理函数
|
||||
const handleMapClickSelectFeatures = useCallback(
|
||||
async (event: { coordinate: number[] }) => {
|
||||
if (!map) return;
|
||||
const feature = await mapClickSelectFeatures(event, map); // 调用导入的函数
|
||||
setHighlightFeature(feature);
|
||||
if (!feature || !(feature instanceof Feature)) return;
|
||||
|
||||
if (activeTools.includes("history")) {
|
||||
// 历史查询模式:支持同类型多选
|
||||
const featureId = feature.getProperties().id;
|
||||
const layerId = feature.getId()?.toString().split(".")[0] || "";
|
||||
|
||||
// 简单的类型检查函数
|
||||
const getBaseType = (lid: string) => {
|
||||
if (lid.includes("pipe")) return "pipe";
|
||||
if (lid.includes("junction")) return "junction";
|
||||
if (lid.includes("tank")) return "tank";
|
||||
if (lid.includes("reservoir")) return "reservoir";
|
||||
if (lid.includes("pump")) return "pump";
|
||||
if (lid.includes("valve")) return "valve";
|
||||
return lid;
|
||||
};
|
||||
|
||||
// 检查是否与已选要素类型一致
|
||||
if (highlightFeatures.length > 0) {
|
||||
const firstLayerId =
|
||||
highlightFeatures[0].getId()?.toString().split(".")[0] || "";
|
||||
|
||||
if (getBaseType(layerId) !== getBaseType(firstLayerId)) {
|
||||
// 如果点击的是已选中的要素(为了取消选中),则不报错
|
||||
const isAlreadySelected = highlightFeatures.some(
|
||||
(f) => f.getProperties().id === featureId
|
||||
);
|
||||
if (!isAlreadySelected) {
|
||||
open?.({
|
||||
type: "error",
|
||||
message: "请选择相同类型的要素进行多选查询。",
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setHighlightFeatures((prev) => {
|
||||
const existingIndex = prev.findIndex(
|
||||
(f) => f.getProperties().id === featureId
|
||||
);
|
||||
|
||||
if (existingIndex !== -1) {
|
||||
// 如果已存在,移除
|
||||
return prev.filter((_, i) => i !== existingIndex);
|
||||
} else {
|
||||
// 如果不存在,添加
|
||||
return [...prev, feature];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 其他模式(如 info):单选
|
||||
setHighlightFeatures([feature]);
|
||||
}
|
||||
},
|
||||
[map, setHighlightFeature]
|
||||
[map, activeTools, highlightFeatures, open]
|
||||
);
|
||||
// 添加矢量属性查询事件监听器
|
||||
useEffect(() => {
|
||||
@@ -243,13 +298,14 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
switch (tool) {
|
||||
case "info":
|
||||
setShowPropertyPanel(false);
|
||||
setHighlightFeature(null);
|
||||
setHighlightFeatures([]);
|
||||
break;
|
||||
case "draw":
|
||||
setShowDrawPanel(false);
|
||||
break;
|
||||
case "history":
|
||||
setShowHistoryPanel(false);
|
||||
setHighlightFeatures([]);
|
||||
break;
|
||||
}
|
||||
};
|
||||
@@ -273,7 +329,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
// 关闭所有面板(除了样式编辑器)
|
||||
const closeAllPanelsExceptStyle = () => {
|
||||
setShowPropertyPanel(false);
|
||||
setHighlightFeature(null);
|
||||
setHighlightFeatures([]);
|
||||
setShowDrawPanel(false);
|
||||
setShowHistoryPanel(false);
|
||||
// 样式编辑器保持其当前状态,不自动关闭
|
||||
@@ -283,11 +339,12 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
>({});
|
||||
// 添加 useEffect 来查询计算属性
|
||||
useEffect(() => {
|
||||
if (!highlightFeature || !selectedDate || !showPropertyPanel) {
|
||||
if (highlightFeatures.length === 0 || !selectedDate || !showPropertyPanel) {
|
||||
setComputedProperties({});
|
||||
return;
|
||||
}
|
||||
|
||||
const highlightFeature = highlightFeatures[0];
|
||||
const id = highlightFeature.getProperties().id;
|
||||
if (!id) {
|
||||
setComputedProperties({});
|
||||
@@ -334,11 +391,12 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
};
|
||||
// 仅当 currentTime 有效时查询
|
||||
if (currentTime !== -1 && queryType) queryComputedProperties();
|
||||
}, [highlightFeature, currentTime, selectedDate]);
|
||||
}, [highlightFeatures, currentTime, selectedDate]);
|
||||
|
||||
// 从要素属性中提取属性面板需要的数据
|
||||
const getFeatureProperties = useCallback(() => {
|
||||
if (!highlightFeature) return {};
|
||||
if (highlightFeatures.length === 0) return {};
|
||||
const highlightFeature = highlightFeatures[0];
|
||||
const layer = highlightFeature?.getId()?.toString().split(".")[0];
|
||||
const properties = highlightFeature.getProperties();
|
||||
// 计算属性字段,增加 key 字段
|
||||
@@ -613,7 +671,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
return result;
|
||||
}
|
||||
return {};
|
||||
}, [highlightFeature, computedProperties]);
|
||||
}, [highlightFeatures, computedProperties]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -663,14 +721,18 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
(HistoryPanel ? (
|
||||
<HistoryPanel
|
||||
featureInfos={(() => {
|
||||
if (!highlightFeature || !showHistoryPanel) return [];
|
||||
const properties = highlightFeature.getProperties();
|
||||
if (highlightFeatures.length === 0 || !showHistoryPanel)
|
||||
return [];
|
||||
|
||||
return highlightFeatures
|
||||
.map((feature) => {
|
||||
const properties = feature.getProperties();
|
||||
const id = properties.id;
|
||||
if (!id) return [];
|
||||
if (!id) return null;
|
||||
|
||||
// 从图层名称推断类型
|
||||
const layerId =
|
||||
highlightFeature.getId()?.toString().split(".")[0] || "";
|
||||
feature.getId()?.toString().split(".")[0] || "";
|
||||
let type = "unknown";
|
||||
|
||||
if (layerId.includes("pipe")) {
|
||||
@@ -688,9 +750,11 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
}
|
||||
// 仅处理 type 为 pipe 或 junction 的情况
|
||||
if (type !== "pipe" && type !== "junction") {
|
||||
return [];
|
||||
return null;
|
||||
}
|
||||
return [[id, type]];
|
||||
return [id, type];
|
||||
})
|
||||
.filter(Boolean) as [string, string][];
|
||||
})()}
|
||||
scheme_type="burst_Analysis"
|
||||
scheme_name={schemeName}
|
||||
@@ -699,14 +763,18 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
) : (
|
||||
<HistoryDataPanel
|
||||
featureInfos={(() => {
|
||||
if (!highlightFeature || !showHistoryPanel) return [];
|
||||
const properties = highlightFeature.getProperties();
|
||||
if (highlightFeatures.length === 0 || !showHistoryPanel)
|
||||
return [];
|
||||
|
||||
return highlightFeatures
|
||||
.map((feature) => {
|
||||
const properties = feature.getProperties();
|
||||
const id = properties.id;
|
||||
if (!id) return [];
|
||||
if (!id) return null;
|
||||
|
||||
// 从图层名称推断类型
|
||||
const layerId =
|
||||
highlightFeature.getId()?.toString().split(".")[0] || "";
|
||||
feature.getId()?.toString().split(".")[0] || "";
|
||||
let type = "unknown";
|
||||
|
||||
if (layerId.includes("pipe")) {
|
||||
@@ -724,9 +792,11 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
}
|
||||
// 仅处理 type 为 pipe 或 junction 的情况
|
||||
if (type !== "pipe" && type !== "junction") {
|
||||
return [];
|
||||
return null;
|
||||
}
|
||||
return [[id, type]];
|
||||
return [id, type];
|
||||
})
|
||||
.filter(Boolean) as [string, string][];
|
||||
})()}
|
||||
scheme_type="burst_Analysis"
|
||||
scheme_name={schemeName}
|
||||
|
||||
Reference in New Issue
Block a user