为图层添加属性;新增水流动画图层的显示隐藏

This commit is contained in:
JIANG
2025-11-19 16:10:40 +08:00
parent 538b9fe177
commit 1ca2e80645
5 changed files with 356 additions and 62 deletions

121
src/utils/layers.ts Normal file
View File

@@ -0,0 +1,121 @@
import { Layer } from "ol/layer";
import { Deck } from "@deck.gl/core";
import { toLonLat } from "ol/proj";
/**
* 自定义 Layer 类来包装 deck.gl
* 将 deck.gl 图层集成到 OpenLayers 地图中
*/
export class DeckLayer extends Layer {
private deck: Deck;
private onVisibilityChange?: (layerId: string, visible: boolean) => void;
private userVisibility: Map<string, boolean> = new Map(); // 存储用户设置的可见性
constructor(deckInstance: Deck) {
super({});
this.deck = deckInstance;
}
// 设置可见性变化回调
setVisibilityChangeCallback(
callback: (layerId: string, visible: boolean) => void
): void {
this.onVisibilityChange = callback;
}
// 初始化用户可见性状态
initUserVisibility(layerId: string, visible: boolean): void {
this.userVisibility.set(layerId, visible);
}
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();
return document.getElementById("deck-canvas") as HTMLElement;
}
// 获取 Deck 实例
getDeck(): Deck {
return this.deck;
}
// 设置图层
setDeckLayers(layers: any[]): void {
this.deck.setProps({ layers });
}
// 获取当前图层
getDeckLayers(): any[] {
return this.deck.props.layers || [];
}
// 添加图层
addDeckLayer(layer: any): void {
const currentLayers = this.getDeckLayers();
this.deck.setProps({ layers: [...currentLayers, layer] });
}
// 移除图层
removeDeckLayer(layerId: string): void {
const currentLayers = this.getDeckLayers();
const filteredLayers = currentLayers.filter(
(layer: any) => layer && layer.id !== layerId
);
this.deck.setProps({ layers: filteredLayers });
}
// 根据 ID 查找图层
getDeckLayerById(layerId: string): any | undefined {
const layers = this.getDeckLayers();
return layers.find((layer: any) => layer && layer.id === layerId);
}
// 更新特定图层
updateDeckLayer(layerId: string, props: any): void {
const layers = this.getDeckLayers();
const updatedLayers = layers.map((layer: any) => {
if (layer && layer.id === layerId) {
return layer.clone(props);
}
return layer;
});
this.deck.setProps({ layers: updatedLayers });
}
// 获取图层的可见性(用户设置的状态,不受其他条件影响)
getDeckLayerVisible(layerId: string): boolean | undefined {
// 优先返回用户设置的可见性
if (this.userVisibility.has(layerId)) {
return this.userVisibility.get(layerId);
}
// 如果没有用户设置,返回实际图层的可见性
const layer = this.getDeckLayerById(layerId);
return layer ? layer.props.visible : undefined;
}
// 设置图层的可见性
setDeckLayerVisible(layerId: string, visible: boolean): void {
// 存储用户设置的可见性
this.userVisibility.set(layerId, visible);
// 更新图层(注意:实际的 visible 可能还受其他条件控制)
this.updateDeckLayer(layerId, { visible });
// 触发回调通知外部
if (this.onVisibilityChange) {
this.onVisibilityChange(layerId, visible);
}
}
// 切换图层的可见性
toggleDeckLayerVisible(layerId: string): void {
const currentVisible = this.getDeckLayerVisible(layerId);
if (currentVisible !== undefined) {
this.setDeckLayerVisible(layerId, !currentVisible);
}
}
}