"use client"; import { config } from "@/config/config"; import React, { createContext, useContext, useState, useEffect, useRef, } from "react"; import { Map as OlMap, VectorTile } from "ol"; import View from "ol/View.js"; import "ol/ol.css"; import MapTools from "./MapTools"; import { Layer } from "ol/layer"; // 保留导入,但用于继承 import VectorTileSource from "ol/source/VectorTile"; import WebGLVectorTileLayer from "ol/layer/WebGLVectorTile"; import MVT from "ol/format/MVT"; import { FlatStyleLike } from "ol/style/flat"; import { toLonLat } from "ol/proj"; import { along, bearing, lineString, length, toMercator } from "@turf/turf"; import { Deck } from "@deck.gl/core"; import { TextLayer } from "@deck.gl/layers"; import { TripsLayer } from "@deck.gl/geo-layers"; import { CollisionFilterExtension } from "@deck.gl/extensions"; import VectorSource from "ol/source/Vector"; import GeoJson from "ol/format/GeoJSON"; import VectorLayer from "ol/layer/Vector"; import { Icon, Style } from "ol/style.js"; import { FeatureLike } from "ol/Feature"; import { Point } from "ol/geom"; interface MapComponentProps { children?: React.ReactNode; } interface DataContextType { currentTime?: number; // 当前时间 setCurrentTime?: React.Dispatch>; selectedDate?: Date; // 选择的日期 schemeName?: string; // 当前方案名称 setSchemeName?: React.Dispatch>; setSelectedDate?: React.Dispatch>; currentJunctionCalData?: any[]; // 当前计算结果 setCurrentJunctionCalData?: React.Dispatch>; currentPipeCalData?: any[]; // 当前计算结果 setCurrentPipeCalData?: React.Dispatch>; showJunctionText?: boolean; // 是否显示节点文本 showPipeText?: boolean; // 是否显示管道文本 setShowJunctionText?: React.Dispatch>; setShowPipeText?: React.Dispatch>; junctionText: string; pipeText: string; setJunctionText?: React.Dispatch>; setPipeText?: React.Dispatch>; scadaData?: any[]; // SCADA 数据 } // 创建自定义Layer类来包装deck.gl class DeckLayer extends Layer { private deck: Deck; constructor(deckInstance: Deck) { super({}); this.deck = deckInstance; } render(frameState: any): HTMLElement { const { size, viewState } = frameState; const [width, height] = size; const [longitude, latitude] = toLonLat(viewState.center); const zoom = viewState.zoom - 1; // 调整 zoom 以匹配 const bearing = (-viewState.rotation * 180) / Math.PI; const deckViewState = { bearing, longitude, latitude, zoom }; this.deck.setProps({ width, height, viewState: deckViewState }); this.deck.redraw(); // 返回deck.gl的canvas元素 return document.getElementById("deck-canvas") as HTMLElement; } } // 跨组件传递 const MapContext = createContext(undefined); const DataContext = createContext(undefined); const MAP_EXTENT = config.MAP_EXTENT; const MAP_URL = config.MAP_URL; const MAP_WORKSPACE = config.MAP_WORKSPACE; // 添加防抖函数 function debounce any>(func: F, waitFor: number) { let timeout: ReturnType | null = null; return (...args: Parameters): void => { if (timeout !== null) { clearTimeout(timeout); } timeout = setTimeout(() => func(...args), waitFor); }; } export const useMap = () => { return useContext(MapContext); }; export const useData = () => { return useContext(DataContext); }; const MapComponent: React.FC = ({ children }) => { const mapRef = useRef(null); const deckRef = useRef(null); const [map, setMap] = useState(); // currentCalData 用于存储当前计算结果 const [currentTime, setCurrentTime] = useState(-1); // 默认选择当前时间 // const [selectedDate, setSelectedDate] = useState(new Date("2025-9-17")); const [selectedDate, setSelectedDate] = useState(new Date()); // 默认今天 const [schemeName, setSchemeName] = useState(""); // 当前方案名称 const [currentJunctionCalData, setCurrentJunctionCalData] = useState( [] ); const [currentPipeCalData, setCurrentPipeCalData] = useState([]); // junctionData 和 pipeData 分别缓存瓦片解析后节点和管道的数据,用于 deck.gl 定位、标签渲染 const [junctionData, setJunctionDataState] = useState([]); const [pipeData, setPipeDataState] = useState([]); const junctionDataIds = useRef(new Set()); const pipeDataIds = useRef(new Set()); const tileJunctionDataBuffer = useRef([]); const tilePipeDataBuffer = useRef([]); const [showJunctionText, setShowJunctionText] = useState(false); // 控制节点文本显示 const [showPipeText, setShowPipeText] = useState(false); // 控制管道文本显示 const [showJunctionTextLayer, setShowJunctionTextLayer] = useState(true); // 控制节点文本图层显示 const [showPipeTextLayer, setShowPipeTextLayer] = useState(true); // 控制管道文本图层显示 const [junctionText, setJunctionText] = useState("pressure"); const [pipeText, setPipeText] = useState("flow"); const flowAnimation = useRef(false); // 添加动画控制标志 const [currentZoom, setCurrentZoom] = useState(12); // 当前缩放级别 // 防抖更新函数 const debouncedUpdateData = useRef( debounce(() => { if (tileJunctionDataBuffer.current.length > 0) { setJunctionData(tileJunctionDataBuffer.current); tileJunctionDataBuffer.current = []; } if (tilePipeDataBuffer.current.length > 0) { setPipeData(tilePipeDataBuffer.current); tilePipeDataBuffer.current = []; } }, 100) ); const setJunctionData = (newData: any[]) => { const uniqueNewData = newData.filter((item) => { if (!item || !item.id) return false; if (!junctionDataIds.current.has(item.id)) { junctionDataIds.current.add(item.id); return true; } return false; }); if (uniqueNewData.length > 0) { setJunctionDataState((prev) => [...prev, ...uniqueNewData]); } }; const setPipeData = (newData: any[]) => { const uniqueNewData = newData.filter((item) => { if (!item || !item.id) return false; if (!pipeDataIds.current.has(item.id)) { pipeDataIds.current.add(item.id); return true; } return false; }); if (uniqueNewData.length > 0) { setPipeDataState((prev) => [...prev, ...uniqueNewData]); } }; // 配置地图数据源、图层和样式 const defaultFlatStyle: FlatStyleLike = config.MAP_DEFAULT_STYLE; // 定义 SCADA 图层的样式函数,根据 type 字段选择不同图标 const scadaStyle = (feature: any) => { const type = feature.get("type"); const scadaPressureIcon = "/icons/scada_pressure.svg"; const scadaFlowIcon = "/icons/scada_flow.svg"; // 如果 type 不匹配,可以设置默认图标或不显示 return new Style({ image: new Icon({ src: type === "pipe_flow" ? scadaFlowIcon : scadaPressureIcon, scale: 0.1, // 根据需要调整图标大小 anchor: [0.5, 0.5], // 图标锚点居中 }), }); }; // 定义 reservoirs 图层的样式函数,使用固定图标 const reservoirStyle = () => { const reserviorIcon = "/icons/reservior.svg"; return new Style({ image: new Icon({ src: reserviorIcon, scale: 0.1, // 根据需要调整图标大小 anchor: [0.5, 0.5], // 图标锚点居中 }), }); }; // 定义 tanks 图层的样式函数,使用固定图标 const tankStyle = () => { const tankIcon = "/icons/tank.svg"; return new Style({ image: new Icon({ src: tankIcon, scale: 0.1, // 根据需要调整图标大小 anchor: [0.5, 0.5], // 图标锚点居中 }), }); }; // 定义 valves 图层的样式函数,使用固定图标 // const valveStyle = () => { // const valveIcon = "/icons/valve.svg"; // return new Style({ // image: new Icon({ // src: valveIcon, // scale: 0.1, // 根据需要调整图标大小 // anchor: [0.5, 0.5], // 图标锚点居中 // }), // }); // }; const valveStyle = { "icon-src": "/icons/valve.svg", "icon-scale": 0.1, }; // 定义 pumps 图层的样式函数,使用固定图标 const pumpStyle = function (feature: FeatureLike) { const styles = []; const pumpIcon = "/icons/pump.svg"; const geometry = feature.getGeometry(); const lineCoords = geometry?.getType() === "LineString" ? (geometry as any).getCoordinates() : null; if (geometry) { const lineCoordsWGS84 = lineCoords.map((coord: []) => { const [lon, lat] = toLonLat(coord); return [lon, lat]; }); // 计算中点 const lineStringFeature = lineString(lineCoordsWGS84); const lineLength = length(lineStringFeature); const midPoint = along(lineStringFeature, lineLength / 2).geometry .coordinates; // 在中点添加 icon 样式 const midPointMercator = toMercator(midPoint); styles.push( new Style({ geometry: new Point(midPointMercator), image: new Icon({ src: pumpIcon, scale: 0.12, anchor: [0.5, 0.5], }), }) ); } return styles; }; // 矢量瓦片数据源和图层 const junctionSource = new VectorTileSource({ url: `${MAP_URL}/gwc/service/tms/1.0.0/${MAP_WORKSPACE}:geo_junctions@WebMercatorQuad@pbf/{z}/{x}/{-y}.pbf`, // 替换为你的 MVT 瓦片服务 URL format: new MVT(), projection: "EPSG:3857", }); const pipeSource = new VectorTileSource({ url: `${MAP_URL}/gwc/service/tms/1.0.0/${MAP_WORKSPACE}:geo_pipes@WebMercatorQuad@pbf/{z}/{x}/{-y}.pbf`, // 替换为你的 MVT 瓦片服务 URL format: new MVT(), projection: "EPSG:3857", }); const valveSource = new VectorTileSource({ url: `${MAP_URL}/gwc/service/tms/1.0.0/${MAP_WORKSPACE}:geo_valves@WebMercatorQuad@pbf/{z}/{x}/{-y}.pbf`, // 替换为你的 MVT 瓦片服务 URL format: new MVT(), projection: "EPSG:3857", }); const reservoirSource = new VectorSource({ url: `${MAP_URL}/${MAP_WORKSPACE}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${MAP_WORKSPACE}:geo_reservoirs&outputFormat=application/json`, format: new GeoJson(), }); const pumpSource = new VectorSource({ url: `${MAP_URL}/${MAP_WORKSPACE}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${MAP_WORKSPACE}:geo_pumps&outputFormat=application/json`, format: new GeoJson(), }); const tankSource = new VectorSource({ url: `${MAP_URL}/${MAP_WORKSPACE}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${MAP_WORKSPACE}:geo_tanks&outputFormat=application/json`, format: new GeoJson(), }); const scadaSource = new VectorSource({ url: `${MAP_URL}/${MAP_WORKSPACE}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${MAP_WORKSPACE}:geo_scada&outputFormat=application/json`, format: new GeoJson(), }); // WebGL 渲染优化显示 const junctionsLayer = new WebGLVectorTileLayer({ source: junctionSource as any, // 使用 WebGL 渲染 style: defaultFlatStyle, extent: MAP_EXTENT, // 设置图层范围 maxZoom: 24, minZoom: 12, properties: { name: "节点", // 设置图层名称 value: "junctions", type: "point", properties: [ // { name: "需求量", value: "demand" }, // { name: "海拔高度", value: "elevation" }, { name: "实际需求量", value: "actualdemand" }, { name: "水头", value: "head" }, { name: "压力", value: "pressure" }, { name: "水质", value: "quality" }, ], }, }); const pipesLayer = new WebGLVectorTileLayer({ source: pipeSource as any, // 使用 WebGL 渲染 style: defaultFlatStyle, extent: MAP_EXTENT, // 设置图层范围 maxZoom: 24, minZoom: 12, properties: { name: "管道", // 设置图层名称 value: "pipes", type: "linestring", properties: [ // { name: "直径", value: "diameter" }, // { name: "粗糙度", value: "roughness" }, // { name: "局部损失", value: "minor_loss" }, { name: "流量", value: "flow" }, { name: "摩阻系数", value: "friction" }, { name: "水头损失", value: "headloss" }, { name: "水质", value: "quality" }, { name: "反应速率", value: "reaction" }, { name: "设置值", value: "setting" }, { name: "状态", value: "status" }, { name: "流速", value: "velocity" }, ], }, }); const valvesLayer = new WebGLVectorTileLayer({ source: valveSource as any, style: valveStyle, extent: MAP_EXTENT, // 设置图层范围 maxZoom: 24, minZoom: 12, properties: { name: "阀门", // 设置图层名称 value: "valves", type: "linestring", properties: [], }, }); const reservoirsLayer = new VectorLayer({ source: reservoirSource, style: reservoirStyle, extent: MAP_EXTENT, // 设置图层范围 maxZoom: 24, minZoom: 12, properties: { name: "水库", // 设置图层名称 value: "reservoirs", type: "point", properties: [], }, }); const pumpsLayer = new VectorLayer({ source: pumpSource, style: pumpStyle, extent: MAP_EXTENT, // 设置图层范围 maxZoom: 24, minZoom: 12, properties: { name: "水泵", // 设置图层名称 value: "pumps", type: "linestring", properties: [], }, }); const tanksLayer = new VectorLayer({ source: tankSource, style: tankStyle, extent: MAP_EXTENT, // 设置图层范围 maxZoom: 24, minZoom: 12, properties: { name: "水箱", // 设置图层名称 value: "tanks", type: "point", properties: [], }, }); const scadaLayer = new VectorLayer({ source: scadaSource, style: scadaStyle, // extent: extent, // 设置图层范围 maxZoom: 24, minZoom: 12, properties: { name: "SCADA", // 设置图层名称 value: "scada", type: "point", properties: [], }, }); useEffect(() => { if (!mapRef.current) return; // 缓存 junction、pipe 数据,提供给 deck.gl 显示标签使用 junctionSource.on("tileloadend", (event) => { try { if (event.tile instanceof VectorTile) { const renderFeatures = event.tile.getFeatures(); const data = new Map(); renderFeatures.forEach((renderFeature) => { const props = renderFeature.getProperties(); const featureId = props.id; if (featureId && !junctionDataIds.current.has(featureId)) { const geometry = renderFeature.getGeometry(); if (geometry) { const coordinates = geometry.getFlatCoordinates(); const coordWGS84 = toLonLat(coordinates); data.set(featureId, { id: featureId, position: coordWGS84, elevation: props.elevation || 0, demand: props.demand || 0, }); } } }); const uniqueData = Array.from(data.values()); if (uniqueData.length > 0) { tileJunctionDataBuffer.current.push(...uniqueData); debouncedUpdateData.current(); } } } catch (error) { console.error("Junction tile load error:", error); } }); pipeSource.on("tileloadend", (event) => { try { if (event.tile instanceof VectorTile) { const renderFeatures = event.tile.getFeatures(); const data = new Map(); renderFeatures.forEach((renderFeature) => { try { const props = renderFeature.getProperties(); const featureId = props.id; if (featureId && !pipeDataIds.current.has(featureId)) { const geometry = renderFeature.getGeometry(); if (geometry) { const flatCoordinates = geometry.getFlatCoordinates(); const stride = geometry.getStride(); // 获取步长,通常为 2 // 重建为 LineString GeoJSON 格式的 coordinates: [[x1, y1], [x2, y2], ...] const lineCoords = []; for (let i = 0; i < flatCoordinates.length; i += stride) { lineCoords.push([ flatCoordinates[i], flatCoordinates[i + 1], ]); } const lineCoordsWGS84 = lineCoords.map((coord) => { const [lon, lat] = toLonLat(coord); return [lon, lat]; }); // 添加验证:确保至少有 2 个坐标点 if (lineCoordsWGS84.length < 2) return; // 跳过此特征 // 计算中点 const lineStringFeature = lineString(lineCoordsWGS84); const lineLength = length(lineStringFeature); const midPoint = along(lineStringFeature, lineLength / 2) .geometry.coordinates; // 计算角度 const prevPoint = along(lineStringFeature, lineLength * 0.49) .geometry.coordinates; const nextPoint = along(lineStringFeature, lineLength * 0.51) .geometry.coordinates; let lineAngle = bearing(prevPoint, nextPoint); lineAngle = -lineAngle + 90; if (lineAngle < -90 || lineAngle > 90) { lineAngle += 180; } // 计算时间戳(可选) const numSegments = lineCoordsWGS84.length - 1; const timestamps = [0]; if (numSegments > 0) { for (let i = 1; i <= numSegments; i++) { timestamps.push((i / numSegments) * 10); } } data.set(featureId, { id: featureId, diameter: props.diameter || 0, path: lineCoordsWGS84, // 使用重建后的坐标 position: midPoint, angle: lineAngle, timestamps, }); } } } catch (geomError) { console.error("Geometry calculation error:", geomError); } }); const uniqueData = Array.from(data.values()); if (uniqueData.length > 0) { tilePipeDataBuffer.current.push(...uniqueData); debouncedUpdateData.current(); } } } catch (error) { console.error("Pipe tile load error:", error); } }); // 监听 junctionsLayer 的 visible 变化 const handleJunctionVisibilityChange = () => { const isVisible = junctionsLayer.getVisible(); setShowJunctionTextLayer(isVisible); }; // 监听 pipesLayer 的 visible 变化 const handlePipeVisibilityChange = () => { const isVisible = pipesLayer.getVisible(); setShowPipeTextLayer(isVisible); }; // 添加事件监听器 junctionsLayer.on("change:visible", handleJunctionVisibilityChange); pipesLayer.on("change:visible", handlePipeVisibilityChange); const availableLayers: any[] = []; config.MAP_AVAILABLE_LAYERS.forEach((layerValue) => { switch (layerValue) { case "junctions": availableLayers.push(junctionsLayer); break; case "pipes": availableLayers.push(pipesLayer); break; case "valves": availableLayers.push(valvesLayer); break; case "reservoirs": availableLayers.push(reservoirsLayer); break; case "pumps": availableLayers.push(pumpsLayer); break; case "tanks": availableLayers.push(tanksLayer); break; case "scada": availableLayers.push(scadaLayer); break; } }); // 重新排列图层顺序,确保顺序 点>线>面 availableLayers.sort((a, b) => { // 明确顺序(点类优先) const order = [ "junctions", "scada", "reservoirs", "pumps", "tanks", "valves", "pipes", ].reverse(); // 取值时做安全检查,兼容不同写法(properties.value 或 直接 value) const getValue = (layer: any) => { const props = layer.get ? layer.get("properties") : undefined; return (props && props.value) || layer.get?.("value") || ""; }; const aVal = getValue(a); const bVal = getValue(b); let ia = order.indexOf(aVal); let ib = order.indexOf(bVal); // 如果未在 order 中找到,放到末尾 if (ia === -1) ia = order.length; if (ib === -1) ib = order.length; return ia - ib; }); const map = new OlMap({ target: mapRef.current, view: new View({ maxZoom: 24, projection: "EPSG:3857", }), // 图层依面、线、点、标注次序添加 layers: [...availableLayers], controls: [], }); setMap(map); map.getView().fit(MAP_EXTENT, { padding: [50, 50, 50, 50], // 添加一些内边距 duration: 1000, // 动画持续时间 }); // 监听缩放变化 map.getView().on("change", () => { setTimeout(() => { const zoom = map.getView().getZoom() || 0; setCurrentZoom(zoom); }, 0); }); // 初始化 deck.gl const deck = new Deck({ initialViewState: { longitude: 0, latitude: 0, zoom: 1, }, canvas: "deck-canvas", controller: false, // 由 OpenLayers 控制视图 layers: [], }); deckRef.current = deck; const deckLayer = new DeckLayer(deck); // deckLayer.setZIndex(1000); // 确保在最上层 map.addLayer(deckLayer); // 清理函数 return () => { junctionsLayer.un("change:visible", handleJunctionVisibilityChange); pipesLayer.un("change:visible", handlePipeVisibilityChange); map.setTarget(undefined); map.dispose(); deck.finalize(); }; }, []); // 当数据变化时,更新 deck.gl 图层 useEffect(() => { const deck = deckRef.current; if (!deck) return; // 如果 deck 实例还未创建,则退出 const newLayers = [ new TextLayer({ id: "junctionTextLayer", zIndex: 10, data: showJunctionText ? junctionData : [], getPosition: (d: any) => d.position, fontFamily: "Monaco, monospace", getText: (d: any) => d[junctionText] ? (d[junctionText] as number).toFixed(3) : "", getSize: 18, fontWeight: "bold", getColor: [0, 0, 0], getAngle: 0, getTextAnchor: "middle", getAlignmentBaseline: "center", getPixelOffset: [0, -10], visible: showJunctionTextLayer && currentZoom >= 15 && currentZoom <= 24, extensions: [new CollisionFilterExtension()], collisionTestProps: { sizeScale: 3, // 增加碰撞检测的尺寸以提供更大间距 }, // 可读性设置 characterSet: "auto", fontSettings: { sdf: true, fontSize: 64, buffer: 6, }, // outlineWidth: 10, // outlineColor: [242, 244, 246, 255], }), new TextLayer({ id: "pipeTextLayer", zIndex: 10, data: showPipeText ? pipeData : [], getPosition: (d: any) => d.position, fontFamily: "Monaco, monospace", getText: (d: any) => d[pipeText] ? (d[pipeText] as number).toFixed(3) : "", getSize: 18, fontWeight: "bold", getColor: [0, 0, 0], getAngle: (d: any) => d.angle || 0, getPixelOffset: [0, -8], getTextAnchor: "middle", getAlignmentBaseline: "bottom", visible: showPipeTextLayer && currentZoom >= 15 && currentZoom <= 24, extensions: [new CollisionFilterExtension()], collisionTestProps: { sizeScale: 3, // 增加碰撞检测的尺寸以提供更大间距 }, // 可读性设置 characterSet: "auto", fontSettings: { sdf: true, fontSize: 64, buffer: 6, }, // outlineWidth: 10, // outlineColor: [242, 244, 246, 255], }), ]; deck.setProps({ layers: newLayers }); // 动画循环 const animate = () => { if (!deck || !flowAnimation.current) return; // 添加检查,防止空数据或停止旧循环 // 动画总时长(秒) if (pipeData.length === 0) { requestAnimationFrame(animate); return; } const animationDuration = 10; // 缓冲时间(秒) const bufferTime = 2; // 完整循环周期 const loopLength = animationDuration + bufferTime; // 确保时间范围与你的时间戳数据匹配 const currentTime = (Date.now() / 1000) % loopLength; // (0,12) 之间循环 // console.log("Current Time:", currentTime); const waterflowLayer = new TripsLayer({ id: "waterflowLayer", data: pipeData, getPath: (d) => d.path, getTimestamps: (d) => { return d.timestamps; // 这些应该是与 currentTime 匹配的数值 }, getColor: [0, 220, 255], opacity: 0.8, visible: flowAnimation.current && currentZoom >= 12 && currentZoom <= 24, widthMinPixels: 5, jointRounded: true, // 拐角变圆 // capRounded: true, // 端点变圆 trailLength: 2, // 水流尾迹淡出时间 currentTime: currentTime, }); // 获取当前除 waterflowLayer 之外的所有图层 const otherLayers = deck.props.layers.filter( (layer: any) => layer && layer.id !== "waterflowLayer" ); deck.setProps({ layers: [...otherLayers, waterflowLayer], }); // 继续请求动画帧,每帧执行一次函数 requestAnimationFrame(animate); }; animate(); }, [ flowAnimation, junctionData, pipeData, currentZoom, showJunctionText, showPipeText, showJunctionTextLayer, showPipeTextLayer, junctionText, pipeText, ]); // 控制流动动画开关 useEffect(() => { if (pipeText === "flow" && currentPipeCalData.length > 0) { flowAnimation.current = true; } else { flowAnimation.current = false; } }, [currentPipeCalData, pipeText]); // 计算值更新时,更新 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]) ); // 更新junctionData setJunctionDataState((prev: any[]) => prev.map((j) => { const record = nodeMap.get(j.id); if (record) { return { ...j, [junctionProperties]: record.value, }; } return j; }) ); // 更新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].reverse() : p.path, [pipeProperties]: record.value, }; } return p; }) ); }, [currentJunctionCalData, currentPipeCalData]); return ( <>
{children}
); }; export default MapComponent;