import React, { useState, useEffect, useCallback, useRef } from "react"; import ToolbarButton from "@components/olmap/common/ToolbarButton"; // 导入Material-UI图标 import BackHandOutlinedIcon from "@mui/icons-material/BackHandOutlined"; import BorderColorOutlinedIcon from "@mui/icons-material/BorderColorOutlined"; import MoreHorizOutlinedIcon from "@mui/icons-material/MoreHorizOutlined"; import TimelineIcon from "@mui/icons-material/Timeline"; import CircleOutlinedIcon from "@mui/icons-material/CircleOutlined"; import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; import GestureIcon from "@mui/icons-material/Gesture"; import UndoIcon from "@mui/icons-material/Undo"; import RedoIcon from "@mui/icons-material/Redo"; import DeleteIcon from "@mui/icons-material/Delete"; import SaveIcon from "@mui/icons-material/Save"; // 导入OpenLayers绘图相关模块 import Draw, { DrawEvent, createBox, GeometryFunction, } from "ol/interaction/Draw"; import VectorSource from "ol/source/Vector"; import VectorLayer from "ol/layer/Vector"; import { Style, Stroke, Fill, Circle } from "ol/style"; import { Geometry } from "ol/geom"; import Feature from "ol/Feature"; import { Type as GeometryType } from "ol/geom/Geometry"; import { useMap } from "../MapComponent"; const DrawPanel: React.FC = () => { const map = useMap(); const [activeTool, setActiveTool] = useState("pan"); const [drawLayer, setDrawLayer] = useState | null>( null ); const [drawnFeatures, setDrawnFeatures] = useState[]>([]); const [historyStack, setHistoryStack] = useState[][]>([]); const [historyIndex, setHistoryIndex] = useState(-1); const drawInteractionRef = useRef(null); // 创建并添加绘图图层 useEffect(() => { if (!map) return; const drawSource = new VectorSource(); const drawVectorLayer = new VectorLayer({ source: drawSource, style: new Style({ stroke: new Stroke({ color: `rgba(255, 152, 0, 0.9)`, width: 2, }), fill: new Fill({ color: `rgba(255, 152, 0, 0.3)`, }), image: new Circle({ radius: 7, stroke: new Stroke({ color: `rgba(255, 152, 0, 0.9)`, width: 2, }), fill: new Fill({ color: `rgba(255, 152, 0, 0.3)`, }), }), }), }); map.addLayer(drawVectorLayer); setDrawLayer(drawVectorLayer); return () => { if (drawInteractionRef.current && map) { map.removeInteraction(drawInteractionRef.current); drawInteractionRef.current = null; } map.removeLayer(drawVectorLayer); }; }, [map, drawInteractionRef]); // 保存到历史记录 const saveToHistory = useCallback( (features: Feature[]) => { setHistoryStack((prevStack) => { const newHistory = prevStack.slice(0, historyIndex + 1); newHistory.push([...features]); setHistoryIndex(newHistory.length - 1); return newHistory; }); }, [historyIndex] ); // 添加绘图交互 const addDrawInteraction = ( type: GeometryType, geometryFunction?: GeometryFunction ) => { if (!drawLayer) return; if (!map) return; // 清除现有的绘图交互 if (drawInteractionRef.current && map) { map.removeInteraction(drawInteractionRef.current); } const source = drawLayer.getSource(); if (!source) return; const drawOptions: { source: VectorSource; type: GeometryType; style: Style; geometryFunction?: GeometryFunction; } = { source: source, type: type, style: new Style({ stroke: new Stroke({ color: `rgba(255, 152, 0, 0.9)`, width: 2, }), fill: new Fill({ color: `rgba(255, 152, 0, 0.3)`, }), image: new Circle({ radius: 7, stroke: new Stroke({ color: `rgba(255, 152, 0, 0.9)`, width: 2, }), fill: new Fill({ color: `rgba(255, 152, 0, 0.3)`, }), }), }), }; // 如果有几何函数,添加它 if (geometryFunction) { drawOptions.geometryFunction = geometryFunction; } const draw = new Draw(drawOptions); // 绘图完成事件 draw.on("drawend", (event: DrawEvent) => { const feature = event.feature; const currentFeatures = [...drawnFeatures, feature]; setDrawnFeatures(currentFeatures); saveToHistory(currentFeatures); }); map.addInteraction(draw); drawInteractionRef.current = draw; }; // 处理工具点击 const handleToolClick = (tool: string) => { // 如果点击的是当前激活的工具,则取消激活 // console.log("当前激活的工具:", activeTool); // console.log("点击的工具:", tool); if (activeTool === tool) { setActiveTool(""); if (drawInteractionRef.current && map) { map.removeInteraction(drawInteractionRef.current); drawInteractionRef.current = null; } return; } if ( tool !== "undo" && tool !== "redo" && tool !== "delete" && tool !== "save" ) { setActiveTool(tool); } // 根据工具类型处理不同的交互 switch (tool) { case "pan": // 平移地图,移除所有绘图交互 if (drawInteractionRef.current && map) { map.removeInteraction(drawInteractionRef.current); drawInteractionRef.current = null; } break; case "select": // 选定要素,移除所有绘图交互 if (drawInteractionRef.current && map) { map.removeInteraction(drawInteractionRef.current); drawInteractionRef.current = null; } break; case "edit": // 编辑要素,移除所有绘图交互 if (drawInteractionRef.current && map) { map.removeInteraction(drawInteractionRef.current); drawInteractionRef.current = null; } break; case "point": addDrawInteraction("Point"); break; case "line": addDrawInteraction("LineString"); break; case "circle": addDrawInteraction("Circle"); break; case "box": // 使用矩形绘制函数 addDrawInteraction("Circle", createBox()); break; case "polygon": addDrawInteraction("Polygon"); break; case "undo": handleUndo(); break; case "redo": handleRedo(); break; case "delete": handleDelete(); break; case "save": handleSave(); break; default: if (drawInteractionRef.current && map) { map.removeInteraction(drawInteractionRef.current); drawInteractionRef.current = null; } } }; // 撤销功能 const handleUndo = () => { if (historyIndex > 0) { const newIndex = historyIndex - 1; const previousFeatures = historyStack[newIndex]; updateDrawLayer(previousFeatures); setDrawnFeatures(previousFeatures); setHistoryIndex(newIndex); } }; // 重做功能 const handleRedo = () => { if (historyIndex < historyStack.length - 1) { const newIndex = historyIndex + 1; const nextFeatures = historyStack[newIndex]; updateDrawLayer(nextFeatures); setDrawnFeatures(nextFeatures); setHistoryIndex(newIndex); } }; // 删除所有绘制的要素 const handleDelete = () => { if (!drawLayer) return; const source = drawLayer.getSource(); if (source) { source.clear(); const emptyFeatures: Feature[] = []; setDrawnFeatures(emptyFeatures); saveToHistory(emptyFeatures); } }; // 保存绘制的要素 const handleSave = () => {}; // 更新绘图图层 const updateDrawLayer = (features: Feature[]) => { if (!drawLayer) return; const source = drawLayer.getSource(); if (source) { source.clear(); source.addFeatures(features); } }; // 初始化历史记录 useEffect(() => { // 初始化空的历史记录 if (historyStack.length === 0) { saveToHistory([]); } }, [historyStack.length, saveToHistory]); // 判断按钮是否应该禁用 const isUndoDisabled = historyIndex <= 0; const isRedoDisabled = historyIndex >= historyStack.length - 1; const isDeleteDisabled = drawnFeatures.length === 0; const isSaveDisabled = drawnFeatures.length === 0; return (
} name="平移地图" isActive={activeTool === "pan"} onClick={() => handleToolClick("pan")} /> } name="矢量编辑" isActive={activeTool === "edit"} onClick={() => handleToolClick("edit")} /> } name="绘制点" isActive={activeTool === "point"} onClick={() => handleToolClick("point")} /> } name="绘制线" isActive={activeTool === "line"} onClick={() => handleToolClick("line")} /> } name="绘制圆" isActive={activeTool === "circle"} onClick={() => handleToolClick("circle")} /> } name="绘制框" isActive={activeTool === "box"} onClick={() => handleToolClick("box")} /> } name="绘制多边形" isActive={activeTool === "polygon"} onClick={() => handleToolClick("polygon")} />
} name="撤销" isActive={false} onClick={() => handleToolClick("undo")} disabled={isUndoDisabled} /> } name="重做" isActive={false} onClick={() => handleToolClick("redo")} disabled={isRedoDisabled} /> } name="删除" isActive={false} onClick={() => handleToolClick("delete")} disabled={isDeleteDisabled} /> {/* } name="保存" isActive={false} onClick={() => handleToolClick("save")} disabled={isSaveDisabled} /> */}
); }; export default DrawPanel;