import React, { useState, useEffect, useCallback } from "react"; import { useData, useMap } from "../MapComponent"; import { Checkbox, FormControlLabel } from "@mui/material"; import WebGLVectorTileLayer from "ol/layer/WebGLVectorTile"; import VectorLayer from "ol/layer/Vector"; import VectorTileLayer from "ol/layer/VectorTile"; import { DeckLayer } from "@utils/layers"; // 定义统一的图层项接口 interface LayerItem { id: string; name: string; visible: boolean; type: "ol" | "deck"; layerRef: any; // OpenLayers Layer 实例或 deck.gl layer 对象 } const LayerControl: React.FC = () => { const map = useMap(); const data = useData(); if (!data) return; const { deckLayer, isContourLayerAvailable, isWaterflowLayerAvailable, setShowWaterflowLayer, setShowContourLayer, } = data; const [layerItems, setLayerItems] = useState([]); // 更新图层列表 const updateLayers = useCallback(() => { if (!map || !data) return; const { deckLayer } = data; const items: LayerItem[] = []; // 1. 获取 OpenLayers 图层 const mapLayers = map.getLayers().getArray(); mapLayers.forEach((layer) => { // 筛选特定类型的 OpenLayers 图层 if ( layer instanceof WebGLVectorTileLayer || layer instanceof VectorTileLayer || layer instanceof VectorLayer ) { const value = layer.get("value"); const name = layer.get("name"); // 只有设置了 value (作为 ID) 的图层才会被纳入控制 if (value) { items.push({ id: value, name: name || value, visible: layer.getVisible(), type: "ol", layerRef: layer, }); } } }); // 2. 获取 DeckLayer 中的子图层 if (deckLayer && deckLayer instanceof DeckLayer) { const deckLayers = deckLayer.getDeckLayers(); deckLayers.forEach((layer: any) => { if (layer && layer.id) { // 仅处理 junctionContourLayer 和 waterflowLayer if ( layer.id !== "junctionContourLayer" && layer.id !== "waterflowLayer" ) { return; } // 检查可用性 if ( (layer.id === "junctionContourLayer" && !isContourLayerAvailable) || (layer.id === "waterflowLayer" && !isWaterflowLayerAvailable) ) { return; // 跳过不可用图层 } const visible = deckLayer.getDeckLayerVisible(layer.id) ?? layer.props?.visible ?? true; items.push({ id: layer.props.id, name: layer.props.name, // 使用 name 属性作为显示名称 visible: visible, type: "deck", layerRef: layer, }); } }); } // 3. 定义图层显示顺序和过滤白名单 const layerOrder = [ "junctions", "reservoirs", "tanks", "pipes", "pumps", "valves", "scada", "waterflowLayer", "junctionContourLayer", ]; // 过滤并排序 const sortedItems = items .filter((item) => layerOrder.includes(item.id)) .sort((a, b) => { const indexA = layerOrder.indexOf(a.id); const indexB = layerOrder.indexOf(b.id); return indexA - indexB; }); setLayerItems(sortedItems); }, [map, isWaterflowLayerAvailable, isContourLayerAvailable]); useEffect(() => { updateLayers(); if (map) { const layerCollection = map.getLayers(); layerCollection.on("change:length", updateLayers); } return () => { if (map) { map.getLayers().un("change:length", updateLayers); } }; }, [map, updateLayers]); const handleVisibilityChange = (item: LayerItem, checked: boolean) => { if (item.type === "ol") { item.layerRef.setVisible(checked); } else if (item.type === "deck" && deckLayer) { if (item.id === "junctionContourLayer") { setShowContourLayer && setShowContourLayer(checked); } if (item.id === "waterflowLayer") { setShowWaterflowLayer && setShowWaterflowLayer(checked); } } setLayerItems((prev) => prev.map((i) => (i.id === item.id ? { ...i, visible: checked } : i)) ); }; if (!data) { return
Loading...
; } return (
{layerItems.map((item) => ( handleVisibilityChange(item, e.target.checked)} size="small" /> } label={item.name} sx={{ fontSize: "0.7rem", "& .MuiFormControlLabel-label": { fontSize: "0.7rem" }, }} /> ))}
); }; export default LayerControl;