更新历史数据面板显示和设计;更新scada数据全部清洗api数据格式;更新scada数据显示模拟数据;更新scada数据面板,非清洗状态下能显示两条数据;新增注释,未来准备修复矢量瓦片样式更新时闪烁的问题;

This commit is contained in:
JIANG
2025-12-15 17:40:05 +08:00
parent 2fc9075cce
commit fd064f3aa9
5 changed files with 437 additions and 413 deletions

View File

@@ -46,6 +46,7 @@ interface DataContextType {
setCurrentJunctionCalData?: React.Dispatch<React.SetStateAction<any[]>>;
currentPipeCalData?: any[]; // 当前计算结果
setCurrentPipeCalData?: React.Dispatch<React.SetStateAction<any[]>>;
pipeData?: any[]; // 管道数据(含坐标)
showJunctionText?: boolean; // 是否显示节点文本
showPipeText?: boolean; // 是否显示管道文本
setShowJunctionTextLayer?: React.Dispatch<React.SetStateAction<boolean>>;
@@ -67,7 +68,7 @@ interface DataContextType {
const MapContext = createContext<OlMap | undefined>(undefined);
const DataContext = createContext<DataContextType | undefined>(undefined);
const MAP_EXTENT = config.MAP_EXTENT;
const MAP_EXTENT = config.MAP_EXTENT as [number, number, number, number];
const MAP_URL = config.MAP_URL;
const MAP_WORKSPACE = config.MAP_WORKSPACE;
const MAP_VIEW_STORAGE_KEY = `${MAP_WORKSPACE}_map_view`; // 持久化 key
@@ -101,12 +102,13 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
// const [selectedDate, setSelectedDate] = useState<Date>(new Date("2025-9-17"));
const [selectedDate, setSelectedDate] = useState<Date>(new Date()); // 默认今天
const [schemeName, setSchemeName] = useState<string>(""); // 当前方案名称
// 记录 id、对应属性的计算值
const [currentJunctionCalData, setCurrentJunctionCalData] = useState<any[]>(
[]
);
const [currentPipeCalData, setCurrentPipeCalData] = useState<any[]>([]);
// junctionData 和 pipeData 分别缓存瓦片解析后节点和管道的数据,用于 deck.gl 定位、标签渲染
// currentJunctionCalData 和 currentPipeCalData 变化时会新增并更新 junctionData 和 pipeData 的计算属性值
const [junctionData, setJunctionDataState] = useState<any[]>([]);
const [pipeData, setPipeDataState] = useState<any[]>([]);
const junctionDataIds = useRef(new Set<string>());
@@ -307,7 +309,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
value: "pipes",
type: "linestring",
properties: [
// { name: "直径", value: "diameter" },
{ name: "管径", value: "diameter" },
// { name: "粗糙度", value: "roughness" },
// { name: "局部损失", value: "minor_loss" },
{ name: "流量", value: "flow" },
@@ -589,7 +591,9 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
viewState &&
Array.isArray(viewState.center) &&
viewState.center.length === 2 &&
typeof viewState.zoom === "number"
typeof viewState.zoom === "number" &&
viewState.zoom >= 11 &&
viewState.zoom <= 24
) {
map.getView().setCenter(viewState.center);
map.getView().setZoom(viewState.zoom);
@@ -635,7 +639,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
const zoom = map.getView().getZoom() || 0;
setCurrentZoom(zoom);
persistView();
}, 0);
}, 250);
};
map.getView().on("change", handleViewChange);
@@ -689,11 +693,22 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
data: junctionData,
getPosition: (d: any) => d.position,
fontFamily: "Monaco, monospace",
getText: (d: any) =>
d[junctionText] ? (d[junctionText] as number).toFixed(3) : "",
getSize: 18,
getText: (d: any) => {
if (!d[junctionText]) return "";
const value = (d[junctionText] as number).toFixed(3);
// 根据属性类型添加符号前缀
const prefix =
{
pressure: "P:",
head: "H:",
quality: "Q:",
actualdemand: "D:",
}[junctionText] || "";
return `${prefix}${value}`;
},
getSize: 14,
fontWeight: "bold",
getColor: [0, 0, 0],
getColor: [33, 37, 41], // 深灰色,在灰白背景上清晰可见
getAngle: 0,
getTextAnchor: "middle",
getAlignmentBaseline: "center",
@@ -701,18 +716,18 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
visible: showJunctionTextLayer && currentZoom >= 15 && currentZoom <= 24,
extensions: [new CollisionFilterExtension()],
collisionTestProps: {
sizeScale: 3, // 增加碰撞检测的尺寸以提供更大间距
sizeScale: 3,
},
// 可读性设置
characterSet: "auto",
fontSettings: {
sdf: true,
fontSize: 64,
buffer: 6,
},
// outlineWidth: 10,
// outlineColor: [242, 244, 246, 255],
// outlineWidth: 3,
// outlineColor: [255, 255, 255, 220],
});
const pipeTextLayer = new TextLayer({
id: "pipeTextLayer",
name: "管道文字",
@@ -720,11 +735,23 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
data: pipeData,
getPosition: (d: any) => d.position,
fontFamily: "Monaco, monospace",
getText: (d: any) =>
d[pipeText] ? Math.abs(d[pipeText] as number).toFixed(3) : "",
getSize: 18,
getText: (d: any) => {
if (!d[pipeText]) return "";
const value = Math.abs(d[pipeText] as number).toFixed(3);
// 根据属性类型添加符号前缀
const prefix =
{
flow: "F:",
velocity: "V:",
headloss: "HL:",
diameter: "D:",
friction: "FR:",
}[pipeText] || "";
return `${prefix}${value}`;
},
getSize: 14,
fontWeight: "bold",
getColor: [0, 0, 0],
getColor: [33, 37, 41], // 深灰色
getAngle: (d: any) => d.angle || 0,
getPixelOffset: [0, -8],
getTextAnchor: "middle",
@@ -732,36 +759,40 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
visible: showPipeTextLayer && currentZoom >= 15 && currentZoom <= 24,
extensions: [new CollisionFilterExtension()],
collisionTestProps: {
sizeScale: 3, // 增加碰撞检测的尺寸以提供更大间距
sizeScale: 3,
},
// 可读性设置
characterSet: "auto",
fontSettings: {
sdf: true,
fontSize: 64,
buffer: 6,
},
// outlineWidth: 10,
// outlineColor: [242, 244, 246, 255],
// outlineWidth: 3,
// outlineColor: [255, 255, 255, 220],
});
const ALPHA = 102;
const contourLayer = new ContourLayer({
id: "junctionContourLayer",
name: "等值线",
data: junctionData,
aggregation: "MEAN",
cellSize: 200,
cellSize: 600,
strokeWidth: 0,
contours: [
{ threshold: [0, 16], color: [255, 0, 0] },
{ threshold: [16, 20], color: [255, 127, 0] },
{ threshold: [20, 22], color: [255, 215, 0] },
{ threshold: [22, 24], color: [199, 224, 0] },
{ threshold: [24, 26], color: [76, 175, 80] },
// { threshold: [0, 16], color: [255, 0, 0, ALPHA], strokeWidth: 0 },
{ threshold: [16, 18], color: [255, 0, 0, 0], strokeWidth: 0 },
{ threshold: [18, 20], color: [255, 127, 0, ALPHA], strokeWidth: 0 },
{ threshold: [20, 22], color: [255, 215, 0, ALPHA], strokeWidth: 0 },
{ threshold: [22, 24], color: [199, 224, 0, ALPHA], strokeWidth: 0 },
{ threshold: [24, 26], color: [76, 175, 80, ALPHA], strokeWidth: 0 },
{ threshold: [26, 30], color: [63, 81, 181, ALPHA], strokeWidth: 0 },
],
getPosition: (d) => d.position,
getWeight: (d: any) =>
d[junctionText] ? Math.abs(d[junctionText] as number) : -1,
opacity: 0.4,
visible: showContourLayer && currentZoom >= 12 && currentZoom <= 24,
(d[junctionText] as number) < 0 ? 0 : (d[junctionText] as number),
opacity: 1,
visible: showContourLayer && currentZoom >= 11 && currentZoom <= 24,
});
if (deckLayer.getDeckLayerById("junctionTextLayer")) {
// 传入完整 layer 实例以保证 clone/替换时保留 layer 类型和方法
@@ -835,7 +866,10 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
getColor: [0, 220, 255],
opacity: 0.8,
visible:
flowAnimation.current && currentZoom >= 12 && currentZoom <= 24,
isWaterflowLayerAvailable &&
flowAnimation.current &&
currentZoom >= 12 &&
currentZoom <= 24,
widthMinPixels: 5,
jointRounded: true, // 拐角变圆
// capRounded: true, // 端点变圆
@@ -858,7 +892,13 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
cancelAnimationFrame(animationFrameId);
}
};
}, [currentZoom, currentPipeCalData, pipeText, pipeData.length]);
}, [
currentZoom,
currentPipeCalData,
pipeText,
pipeData.length,
isWaterflowLayerAvailable,
]);
// 计算值更新时,更新 junctionData 和 pipeData
useEffect(() => {
@@ -923,6 +963,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
setCurrentJunctionCalData,
currentPipeCalData,
setCurrentPipeCalData,
pipeData,
setShowJunctionTextLayer,
setShowPipeTextLayer,
setShowContourLayer,