新增contourLayer触发器;更新官网数据的缓存逻辑

This commit is contained in:
JIANG
2025-12-30 14:34:39 +08:00
parent 7285a3315f
commit 744a340f00

View File

@@ -5,6 +5,7 @@ import React, {
useContext, useContext,
useState, useState,
useEffect, useEffect,
useMemo,
useRef, useRef,
} from "react"; } from "react";
import { Map as OlMap, VectorTile } from "ol"; import { Map as OlMap, VectorTile } from "ol";
@@ -137,6 +138,30 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
const [showWaterflowLayer, setShowWaterflowLayer] = useState(false); // 控制等高线图层显示 const [showWaterflowLayer, setShowWaterflowLayer] = useState(false); // 控制等高线图层显示
const [currentZoom, setCurrentZoom] = useState(11); // 当前缩放级别 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< const [diameterRange, setDiameterRange] = useState<
[number, number] | undefined [number, number] | undefined
>(); >();
@@ -742,15 +767,13 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
useEffect(() => { useEffect(() => {
const deckLayer = deckLayerRef.current; const deckLayer = deckLayerRef.current;
if (!deckLayer) return; // 如果 deck 实例还未创建,则退出 if (!deckLayer) return; // 如果 deck 实例还未创建,则退出
if (!junctionData.length) return; if (!mergedJunctionData.length) return;
if (!pipeData.length) return; if (!mergedPipeData.length) return;
console.log(showJunctionId, showJunctionTextLayer, junctionText);
console.log(showPipeId, showPipeTextLayer, pipeText);
const junctionTextLayer = new TextLayer({ const junctionTextLayer = new TextLayer({
id: "junctionTextLayer", id: "junctionTextLayer",
name: "节点文字", name: "节点文字",
zIndex: 10, zIndex: 10,
data: junctionData, data: mergedJunctionData,
getPosition: (d: any) => d.position, getPosition: (d: any) => d.position,
fontFamily: "Monaco, monospace", fontFamily: "Monaco, monospace",
getText: (d: any) => { getText: (d: any) => {
@@ -803,7 +826,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
id: "pipeTextLayer", id: "pipeTextLayer",
name: "管道文字", name: "管道文字",
zIndex: 10, zIndex: 10,
data: pipeData, data: mergedPipeData,
getPosition: (d: any) => d.position, getPosition: (d: any) => d.position,
fontFamily: "Monaco, monospace", fontFamily: "Monaco, monospace",
getText: (d: any) => { getText: (d: any) => {
@@ -856,7 +879,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
const contourLayer = new ContourLayer({ const contourLayer = new ContourLayer({
id: "junctionContourLayer", id: "junctionContourLayer",
name: "等值线", name: "等值线",
data: junctionData, data: mergedJunctionData,
aggregation: "MEAN", aggregation: "MEAN",
cellSize: 600, cellSize: 600,
strokeWidth: 0, strokeWidth: 0,
@@ -866,6 +889,10 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
(d[junctionText] as number) < 0 ? 0 : (d[junctionText] as number), (d[junctionText] as number) < 0 ? 0 : (d[junctionText] as number),
opacity: 1, opacity: 1,
visible: showContourLayer && currentZoom >= 11 && currentZoom <= 24, visible: showContourLayer && currentZoom >= 11 && currentZoom <= 24,
updateTriggers: {
// 当 mergedJunctionData 内部数据更新时,通知 getWeight 重新计算
getWeight: [mergedJunctionData, junctionText],
},
}); });
if (deckLayer.getDeckLayerById("junctionTextLayer")) { if (deckLayer.getDeckLayerById("junctionTextLayer")) {
// 传入完整 layer 实例以保证 clone/替换时保留 layer 类型和方法 // 传入完整 layer 实例以保证 clone/替换时保留 layer 类型和方法
@@ -874,7 +901,6 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
deckLayer.addDeckLayer(junctionTextLayer); deckLayer.addDeckLayer(junctionTextLayer);
} }
if (deckLayer.getDeckLayerById("pipeTextLayer")) { if (deckLayer.getDeckLayerById("pipeTextLayer")) {
console.log("更新管道文字图层");
deckLayer.updateDeckLayer("pipeTextLayer", pipeTextLayer); deckLayer.updateDeckLayer("pipeTextLayer", pipeTextLayer);
} else { } else {
deckLayer.addDeckLayer(pipeTextLayer); deckLayer.addDeckLayer(pipeTextLayer);
@@ -885,16 +911,16 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
deckLayer.addDeckLayer(contourLayer); deckLayer.addDeckLayer(contourLayer);
} }
}, [ }, [
junctionData, mergedJunctionData,
pipeData, mergedPipeData,
junctionText,
pipeText,
currentZoom, currentZoom,
showJunctionTextLayer, showJunctionTextLayer,
showPipeTextLayer, showPipeTextLayer,
showJunctionId, showJunctionId,
showPipeId, showPipeId,
showContourLayer, showContourLayer,
junctionText,
pipeText,
contours, contours,
]); ]);
@@ -921,7 +947,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
return; return;
} }
// 动画总时长(秒) // 动画总时长(秒)
if (pipeData.length === 0) { if (mergedPipeData.length === 0) {
animationFrameId = requestAnimationFrame(animate); animationFrameId = requestAnimationFrame(animate);
return; return;
} }
@@ -936,7 +962,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
const waterflowLayer = new TripsLayer({ const waterflowLayer = new TripsLayer({
id: "waterflowLayer", id: "waterflowLayer",
name: "水流", name: "水流",
data: pipeData, data: mergedPipeData,
getPath: (d) => d.path, getPath: (d) => d.path,
getTimestamps: (d) => { getTimestamps: (d) => {
return d.timestamps; // 这些应该是与 currentTime 匹配的数值 return d.timestamps; // 这些应该是与 currentTime 匹配的数值
@@ -955,11 +981,11 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
trailLength: 2, // 水流尾迹淡出时间 trailLength: 2, // 水流尾迹淡出时间
currentTime: currentTime, currentTime: currentTime,
}); });
// if (deckLayer.getDeckLayerById("waterflowLayer")) { if (deckLayer.getDeckLayerById("waterflowLayer")) {
// deckLayer.updateDeckLayer("waterflowLayer", waterflowLayer); deckLayer.updateDeckLayer("waterflowLayer", waterflowLayer);
// } else { } else {
// deckLayer.addDeckLayer(waterflowLayer); deckLayer.addDeckLayer(waterflowLayer);
// } }
// 继续请求动画帧,每帧执行一次函数 // 继续请求动画帧,每帧执行一次函数
animationFrameId = requestAnimationFrame(animate); animationFrameId = requestAnimationFrame(animate);
}; };
@@ -973,66 +999,12 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
}; };
}, [ }, [
currentZoom, currentZoom,
currentPipeCalData, mergedPipeData,
pipeText, pipeText,
pipeData.length,
isWaterflowLayerAvailable, isWaterflowLayerAvailable,
showWaterflowLayer, showWaterflowLayer,
]); ]);
// 计算值更新时,更新 junctionData 和 pipeData
useEffect(() => {
const junctionProperties = junctionText;
const pipeProperties = pipeText;
// 将 nodeRecords 转换为 Map 以提高查找效率
const nodeMap: Map<string, any> = new Map(
currentJunctionCalData.map((r: any) => [r.ID, r])
);
// 将 linkRecords 转换为 Map 以提高查找效率
const linkMap: Map<string, any> = 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 ( return (
<> <>
<DataContext.Provider <DataContext.Provider