为图层添加属性;新增水流动画图层的显示隐藏
This commit is contained in:
@@ -65,6 +65,12 @@ const DrawPanel: React.FC = () => {
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
properties: {
|
||||
name: "绘制图层", // 设置图层名称
|
||||
value: "drawLayer",
|
||||
type: "multigeometry",
|
||||
properties: [],
|
||||
},
|
||||
});
|
||||
|
||||
map.addLayer(drawVectorLayer);
|
||||
|
||||
@@ -5,6 +5,7 @@ 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";
|
||||
|
||||
const LayerControl: React.FC = () => {
|
||||
const map = useMap();
|
||||
@@ -12,56 +13,126 @@ const LayerControl: React.FC = () => {
|
||||
const [layerVisibilities, setLayerVisibilities] = useState<
|
||||
Map<Layer, boolean>
|
||||
>(new Map());
|
||||
const userChangedRef = React.useRef<Set<Layer>>(new Set());
|
||||
|
||||
useEffect(() => {
|
||||
if (!map) return;
|
||||
const mapLayers = map
|
||||
.getLayers()
|
||||
.getArray()
|
||||
.filter(
|
||||
(layer) =>
|
||||
layer instanceof WebGLVectorTileLayer ||
|
||||
layer instanceof VectorTileLayer ||
|
||||
layer instanceof VectorLayer
|
||||
) as Layer[];
|
||||
|
||||
// 定义图层排序顺序
|
||||
const layerOrder = [
|
||||
"junctions",
|
||||
"reservoirs",
|
||||
"tanks",
|
||||
"pipes",
|
||||
"pumps",
|
||||
"valves",
|
||||
"scada",
|
||||
];
|
||||
const updateLayers = () => {
|
||||
const mapLayers = map
|
||||
.getLayers()
|
||||
.getArray()
|
||||
.filter(
|
||||
(layer) =>
|
||||
layer instanceof WebGLVectorTileLayer ||
|
||||
layer instanceof VectorTileLayer ||
|
||||
layer instanceof VectorLayer
|
||||
) as Layer[];
|
||||
|
||||
// 对图层进行排序
|
||||
const sortedLayers = mapLayers.sort((a, b) => {
|
||||
const nameA = a.get("value")?.toLowerCase() || "";
|
||||
const nameB = b.get("value")?.toLowerCase() || "";
|
||||
const indexA = layerOrder.indexOf(nameA);
|
||||
const indexB = layerOrder.indexOf(nameB);
|
||||
// 查找包含 waterflowLayer 的 DeckLayer
|
||||
const deckFlowLayers = map
|
||||
.getLayers()
|
||||
.getArray()
|
||||
.filter((layer) => {
|
||||
if (layer instanceof DeckLayer) {
|
||||
const deckLayers = layer.getDeckLayers();
|
||||
// 检查是否包含 waterflowLayer
|
||||
return deckLayers.some((dl: any) => dl.id === "waterflowLayer");
|
||||
}
|
||||
return false;
|
||||
}) as Layer[];
|
||||
|
||||
// 如果图层不在排序列表中,放到最后
|
||||
if (indexA === -1 && indexB === -1) return 0;
|
||||
if (indexA === -1) return 1;
|
||||
if (indexB === -1) return -1;
|
||||
// 合并所有可控制的图层
|
||||
const allLayers = [...mapLayers, ...deckFlowLayers];
|
||||
|
||||
return indexA - indexB;
|
||||
});
|
||||
// 定义图层排序顺序
|
||||
const layerOrder = [
|
||||
"junctions",
|
||||
"reservoirs",
|
||||
"tanks",
|
||||
"pipes",
|
||||
"pumps",
|
||||
"valves",
|
||||
"scada",
|
||||
"waterflow",
|
||||
];
|
||||
|
||||
setLayers(sortedLayers);
|
||||
const visible = new Map<Layer, boolean>();
|
||||
sortedLayers.forEach((layer) => {
|
||||
visible.set(layer, layer.getVisible());
|
||||
});
|
||||
setLayerVisibilities(visible);
|
||||
// 过滤并排序图层:只显示在 layerOrder 中的图层
|
||||
const sortedLayers = allLayers
|
||||
.filter((layer) => {
|
||||
const value = layer.get("value")?.toLowerCase();
|
||||
return layerOrder.includes(value);
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const nameA = a.get("value")?.toLowerCase();
|
||||
const nameB = b.get("value")?.toLowerCase();
|
||||
const indexA = layerOrder.indexOf(nameA);
|
||||
const indexB = layerOrder.indexOf(nameB);
|
||||
|
||||
return indexA - indexB;
|
||||
});
|
||||
|
||||
setLayers(sortedLayers);
|
||||
|
||||
setLayerVisibilities((prevVisibilities) => {
|
||||
const visible = new Map<Layer, boolean>();
|
||||
sortedLayers.forEach((layer) => {
|
||||
// 如果用户刚手动改变了这个图层,使用本地状态
|
||||
if (userChangedRef.current.has(layer)) {
|
||||
visible.set(layer, prevVisibilities.get(layer) ?? true);
|
||||
} else if (layer instanceof DeckLayer) {
|
||||
// 对于 DeckLayer,获取内部 deck.gl 图层的可见性
|
||||
const waterflowVisible =
|
||||
layer.getDeckLayerVisible("waterflowLayer");
|
||||
visible.set(layer, waterflowVisible ?? true);
|
||||
} else {
|
||||
// 对于普通 OpenLayers 图层
|
||||
visible.set(layer, layer.getVisible());
|
||||
}
|
||||
});
|
||||
return visible;
|
||||
});
|
||||
};
|
||||
|
||||
// 初始更新
|
||||
updateLayers();
|
||||
|
||||
// 监听图层集合的变化
|
||||
const layerCollection = map.getLayers();
|
||||
layerCollection.on("change:length", updateLayers);
|
||||
|
||||
// 设置定时器定期检查 DeckLayer 内部图层的变化
|
||||
const intervalId = setInterval(updateLayers, 500);
|
||||
|
||||
return () => {
|
||||
layerCollection.un("change:length", updateLayers);
|
||||
clearInterval(intervalId);
|
||||
};
|
||||
}, [map]);
|
||||
|
||||
const handleVisibilityChange = (layer: Layer, visible: boolean) => {
|
||||
layer.setVisible(visible);
|
||||
// 判断图层类型并调用相应的方法
|
||||
if (layer instanceof DeckLayer) {
|
||||
// 对于 DeckLayer,需要设置内部 deck.gl 图层的可见性
|
||||
const deckLayers = layer.getDeckLayers();
|
||||
deckLayers.forEach((deckLayer: any) => {
|
||||
if (deckLayer && deckLayer.id === "waterflowLayer") {
|
||||
layer.setDeckLayerVisible("waterflowLayer", visible);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 对于普通 OpenLayers 图层,使用 setVisible 方法
|
||||
layer.setVisible(visible);
|
||||
}
|
||||
|
||||
// 标记这个图层为用户手动改变
|
||||
userChangedRef.current.add(layer);
|
||||
setLayerVisibilities((prev) => new Map(prev).set(layer, visible));
|
||||
|
||||
// 1秒后移除标记,允许定时器更新
|
||||
setTimeout(() => {
|
||||
userChangedRef.current.delete(layer);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -142,6 +142,12 @@ const Toolbar: React.FC<ToolbarProps> = ({ hiddenButtons, queryType }) => {
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
properties: {
|
||||
name: "属性查询高亮图层", // 设置图层名称
|
||||
value: "info_highlight_layer",
|
||||
type: "multigeometry",
|
||||
properties: [],
|
||||
},
|
||||
});
|
||||
|
||||
map.addLayer(highLightLayer);
|
||||
|
||||
Reference in New Issue
Block a user