From 744a340f00cec22a95158edadd0de673d5b73178 Mon Sep 17 00:00:00 2001 From: JIANG Date: Tue, 30 Dec 2025 14:34:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EcontourLayer=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=99=A8=EF=BC=9B=E6=9B=B4=E6=96=B0=E5=AE=98=E7=BD=91?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=9A=84=E7=BC=93=E5=AD=98=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/OlMap/MapComponent.tsx | 120 +++++++++++++-------------------- 1 file changed, 46 insertions(+), 74 deletions(-) diff --git a/src/app/OlMap/MapComponent.tsx b/src/app/OlMap/MapComponent.tsx index 8aa8d28..322bdbd 100644 --- a/src/app/OlMap/MapComponent.tsx +++ b/src/app/OlMap/MapComponent.tsx @@ -5,6 +5,7 @@ import React, { useContext, useState, useEffect, + useMemo, useRef, } from "react"; import { Map as OlMap, VectorTile } from "ol"; @@ -137,6 +138,30 @@ const MapComponent: React.FC = ({ children }) => { const [showWaterflowLayer, setShowWaterflowLayer] = useState(false); // 控制等高线图层显示 const [currentZoom, setCurrentZoom] = useState(11); // 当前缩放级别 + // 实时合并计算结果到基础地理数据中 + const mergedJunctionData = useMemo(() => { + const nodeMap = new Map(currentJunctionCalData.map((r: any) => [r.ID, r])); + return junctionData.map((j) => { + const record = nodeMap.get(j.id); + return record ? { ...j, [junctionText]: record.value } : j; + }); + }, [junctionData, currentJunctionCalData, junctionText]); + + const mergedPipeData = useMemo(() => { + const linkMap = new Map(currentPipeCalData.map((r: any) => [r.ID, r])); + return pipeData.map((p) => { + const record = linkMap.get(p.id); + if (!record) return p; + const isFlow = pipeText === "flow"; + return { + ...p, + [pipeText]: isFlow ? Math.abs(record.value) : record.value, + flowFlag: isFlow && record.value < 0 ? -1 : 1, + path: isFlow && record.value < 0 ? [...p.path].reverse() : p.path, + }; + }); + }, [pipeData, currentPipeCalData, pipeText]); + const [diameterRange, setDiameterRange] = useState< [number, number] | undefined >(); @@ -742,15 +767,13 @@ const MapComponent: React.FC = ({ children }) => { useEffect(() => { const deckLayer = deckLayerRef.current; if (!deckLayer) return; // 如果 deck 实例还未创建,则退出 - if (!junctionData.length) return; - if (!pipeData.length) return; - console.log(showJunctionId, showJunctionTextLayer, junctionText); - console.log(showPipeId, showPipeTextLayer, pipeText); + if (!mergedJunctionData.length) return; + if (!mergedPipeData.length) return; const junctionTextLayer = new TextLayer({ id: "junctionTextLayer", name: "节点文字", zIndex: 10, - data: junctionData, + data: mergedJunctionData, getPosition: (d: any) => d.position, fontFamily: "Monaco, monospace", getText: (d: any) => { @@ -803,7 +826,7 @@ const MapComponent: React.FC = ({ children }) => { id: "pipeTextLayer", name: "管道文字", zIndex: 10, - data: pipeData, + data: mergedPipeData, getPosition: (d: any) => d.position, fontFamily: "Monaco, monospace", getText: (d: any) => { @@ -856,7 +879,7 @@ const MapComponent: React.FC = ({ children }) => { const contourLayer = new ContourLayer({ id: "junctionContourLayer", name: "等值线", - data: junctionData, + data: mergedJunctionData, aggregation: "MEAN", cellSize: 600, strokeWidth: 0, @@ -866,6 +889,10 @@ const MapComponent: React.FC = ({ children }) => { (d[junctionText] as number) < 0 ? 0 : (d[junctionText] as number), opacity: 1, visible: showContourLayer && currentZoom >= 11 && currentZoom <= 24, + updateTriggers: { + // 当 mergedJunctionData 内部数据更新时,通知 getWeight 重新计算 + getWeight: [mergedJunctionData, junctionText], + }, }); if (deckLayer.getDeckLayerById("junctionTextLayer")) { // 传入完整 layer 实例以保证 clone/替换时保留 layer 类型和方法 @@ -874,7 +901,6 @@ const MapComponent: React.FC = ({ children }) => { deckLayer.addDeckLayer(junctionTextLayer); } if (deckLayer.getDeckLayerById("pipeTextLayer")) { - console.log("更新管道文字图层"); deckLayer.updateDeckLayer("pipeTextLayer", pipeTextLayer); } else { deckLayer.addDeckLayer(pipeTextLayer); @@ -885,16 +911,16 @@ const MapComponent: React.FC = ({ children }) => { deckLayer.addDeckLayer(contourLayer); } }, [ - junctionData, - pipeData, + mergedJunctionData, + mergedPipeData, + junctionText, + pipeText, currentZoom, showJunctionTextLayer, showPipeTextLayer, showJunctionId, showPipeId, showContourLayer, - junctionText, - pipeText, contours, ]); @@ -921,7 +947,7 @@ const MapComponent: React.FC = ({ children }) => { return; } // 动画总时长(秒) - if (pipeData.length === 0) { + if (mergedPipeData.length === 0) { animationFrameId = requestAnimationFrame(animate); return; } @@ -936,7 +962,7 @@ const MapComponent: React.FC = ({ children }) => { const waterflowLayer = new TripsLayer({ id: "waterflowLayer", name: "水流", - data: pipeData, + data: mergedPipeData, getPath: (d) => d.path, getTimestamps: (d) => { return d.timestamps; // 这些应该是与 currentTime 匹配的数值 @@ -955,11 +981,11 @@ const MapComponent: React.FC = ({ children }) => { trailLength: 2, // 水流尾迹淡出时间 currentTime: currentTime, }); - // if (deckLayer.getDeckLayerById("waterflowLayer")) { - // deckLayer.updateDeckLayer("waterflowLayer", waterflowLayer); - // } else { - // deckLayer.addDeckLayer(waterflowLayer); - // } + if (deckLayer.getDeckLayerById("waterflowLayer")) { + deckLayer.updateDeckLayer("waterflowLayer", waterflowLayer); + } else { + deckLayer.addDeckLayer(waterflowLayer); + } // 继续请求动画帧,每帧执行一次函数 animationFrameId = requestAnimationFrame(animate); }; @@ -973,66 +999,12 @@ const MapComponent: React.FC = ({ children }) => { }; }, [ currentZoom, - currentPipeCalData, + mergedPipeData, pipeText, - pipeData.length, isWaterflowLayerAvailable, showWaterflowLayer, ]); - // 计算值更新时,更新 junctionData 和 pipeData - useEffect(() => { - const junctionProperties = junctionText; - const pipeProperties = pipeText; - - // 将 nodeRecords 转换为 Map 以提高查找效率 - const nodeMap: Map = new Map( - currentJunctionCalData.map((r: any) => [r.ID, r]) - ); - // 将 linkRecords 转换为 Map 以提高查找效率 - const linkMap: Map = new Map( - currentPipeCalData.map((r: any) => [r.ID, r]) - ); - if (nodeMap.size > 0) { - // 更新junctionData - setJunctionDataState((prev: any[]) => - prev.map((j) => { - const record = nodeMap.get(j.id); - if (record) { - return { - ...j, - [junctionProperties]: record.value, - }; - } - return j; - }) - ); - } - if (linkMap.size > 0) { - // 更新pipeData - setPipeDataState((prev: any[]) => - prev.map((p) => { - const record = linkMap.get(p.id); - if (record) { - return { - ...p, - flowFlag: pipeProperties === "flow" && record.value < 0 ? -1 : 1, - path: - pipeProperties === "flow" && record.value < 0 && p.flowFlag > 0 - ? p.path.slice().reverse() - : p.path, - // 流量数值 - [pipeProperties]: - pipeProperties === "flow" - ? Math.abs(record.value) - : record.value, - }; - } - return p; - }) - ); - } - }, [currentJunctionCalData, currentPipeCalData]); return ( <>