WholeProcessPlatform/frontend/src/modules/map/application/map-orchestrator.ts
2026-07-14 16:09:01 +08:00

807 lines
25 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { watch, type WatchStopHandle, ref } from 'vue';
import { useRoute } from 'vue-router';
import { unByKey } from 'ol/Observable';
import dayjs from 'dayjs';
import { MapClass } from '@/components/gis/map.class';
import { getMapConfig, layerConfig2Flat } from '@/components/gis/gisUtils';
import { useMapConfigStore } from '@/modules/map/stores/map-config.store';
import { useMapDataStore } from '@/modules/map/stores/map-data.store';
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
import { useMapStore } from '@/store/modules/map';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
type InitializeOptions = {
container: HTMLElement;
popupContainer?: HTMLDivElement | null;
pageKey: string;
};
type LoadPageOptions = {
pageKey: string;
isInitialLoad?: boolean;
};
type ApplyLayerSelectionOptions = {
checkedKeys: string[];
triggerKey?: string;
checked?: boolean;
};
const SYSTEM_ID = 'qgc';
const HYDRO_DYNAMIC_LAYER_KEYS = [
'dw_point',
'stinfo_video_point',
'stinfo_gjllz_point',
'wt_point',
'wq_ownWq_point',
'wq_countryWq_point',
'fp_point',
'eq_point',
'fb_point',
'vp_point',
'va_point',
'sg_point'
];
const ENG_POINT_LAYER_KEY = 'eng_point';
const ENG_POINT_MEDIUM_VISIBLE_ZOOM = 7.5;
const CESIUM_ZOOM_SYNC_DEBOUNCE_MS = 80;
const LARGE_ENG_LEGEND_PREFIX = 'large_eng_';
const MID_ENG_LEGEND_PREFIX = 'mid_eng_';
export const useMapOrchestrator = () => {
const route = useRoute();
const mapClass = MapClass.getInstance();
const mapStore = useMapStore();
const mapConfigStore = useMapConfigStore();
const mapDataStore = useMapDataStore();
const mapViewStore = useMapViewStore();
const jidiSelectEventStore = useJidiSelectEventStore();
let activePageLoadRequestId = 0;
let removeZoomListener: (() => void) | null = null;
let stopBaseSelectionWatch: WatchStopHandle | null = null;
const initializedBaseLayerKeys = new Set<string>();
const baseSelectionDebounceTimer = ref<ReturnType<typeof setTimeout> | null>(
null
);
const zoomSyncDebounceTimer = ref<ReturnType<typeof setTimeout> | null>(null);
let latestHydroMenuGetter: (() => boolean) | null = null;
let currentMapType: '2D' | '3D' = '2D';
let hydroMenuDefaultCheckedKeys = new Set<string>();
let hydroDynamicLayerSyncTask: {
visible: boolean;
promise: Promise<string[] | void>;
} | null = null;
// 备注:统一获取当前地图视图对象,避免在多个组件里重复兼容 2D/3D view 访问方式。
const getCurrentView = () => {
return mapClass.view?.getView ? mapClass.view.getView() : mapClass.view;
};
// 备注:统一获取当前地图缩放级别,供页面切换和缩放监听复用。
const getCurrentZoom = (): number | undefined => {
return mapClass.getCurrentZoom();
};
const clearZoomSyncDebounceTimer = () => {
if (zoomSyncDebounceTimer.value) {
clearTimeout(zoomSyncDebounceTimer.value);
zoomSyncDebounceTimer.value = null;
}
};
// 备注:统一把当前页面中的 GIS 基础图层初始化到地图实例,避免在图层树组件里做配置解析和加层编排。
const ensureBaseLayersInitialized = (configs: any[] = []) => {
const flatLayerConfigs = layerConfig2Flat(configs);
flatLayerConfigs.forEach((item: any) => {
if (item.type !== 'GISMap' || !item.key) {
return;
}
if (!item.config && item.paramJson) {
try {
const jsonObj = JSON.parse(item.paramJson);
item.config = getMapConfig(jsonObj);
} catch {
item.config = null;
}
}
if (!item.config) {
return;
}
if (item.key === 'customBaseLayer') {
const serializableBaseLayerConfig = {
key: item.config?.key,
id: item.config?.id,
name: item.config?.name,
type: item.config?.type,
url: item.config?.url,
url_3d: item.config?.url_3d,
layers: item.config?.layers,
rasteropacity: item.config?.rasteropacity
};
sessionStorage.setItem(
'customBaseLayer',
JSON.stringify(serializableBaseLayerConfig)
);
}
if (!initializedBaseLayerKeys.has(item.key)) {
mapClass.addBaseDataLayer(item.config, item.checked === 1);
initializedBaseLayerKeys.add(item.key);
}
mapClass.controlBaseLayerTreeShowAndHidden(
item.key,
item.config?.id || item.key,
item.checked === 1
);
});
};
// 备注:统一加载当前页面所需的图层配置、图例配置以及首批锚点数据。
const loadPage = async ({
pageKey,
isInitialLoad = false
}: LoadPageOptions) => {
let backgroundLoadStarted = false;
const pageLoadRequestId = ++activePageLoadRequestId;
try {
mapDataStore.setLoading(true);
const hasGlobalLegendConfig =
Array.isArray(mapConfigStore.legendConfigOriginal) &&
mapConfigStore.legendConfigOriginal.length > 0;
const shouldLoadGlobalLegend = isInitialLoad && !hasGlobalLegendConfig;
const previousPageKey = mapConfigStore.lastLoadOptions?.pageKey || '';
const previousCheckedKeys = mapViewStore.getCheckedLayerKeys();
const moduleId = (route.meta?.moduleId as string) || '';
const loadOptions = {
systemId: SYSTEM_ID,
moduleId,
pageKey,
description: 'true'
};
const layerConfigPromise =
mapConfigStore.loadPageLayerConfig(loadOptions);
const legendConfigPromise = mapConfigStore.loadPageLegendConfig(
moduleId,
{
includeGlobal: shouldLoadGlobalLegend
}
);
// 同时等待两个 promise
const [{ layerConfig }, { legendOriginal, pageLegend }] =
await Promise.all([layerConfigPromise, legendConfigPromise]);
if (pageLoadRequestId !== activePageLoadRequestId) {
return;
}
// 先设置图层数据(更新 checkedLayerKeys再设置图例数据
if (layerConfig.length > 0) {
hydroMenuDefaultCheckedKeys = new Set(
mapConfigStore.extractCheckedLayerKeys(layerConfig)
);
mapStore.setLayerData(layerConfig);
ensureBaseLayersInitialized(layerConfig);
let checkedKeys = mapViewStore.getCheckedLayerKeys();
if (previousPageKey === pageKey && previousCheckedKeys.length > 0) {
const getAllLayerKeys = (items: any[]): string[] => {
const keys: string[] = [];
const walk = (nodes: any[]) => {
nodes.forEach(item => {
if (item?.key) {
keys.push(item.key);
}
if (item?.children?.length > 0) {
walk(item.children);
}
});
};
walk(items);
return keys;
};
const currentLayerKeys = new Set(getAllLayerKeys(layerConfig));
const runtimeCheckedKeys = previousCheckedKeys.filter(key =>
currentLayerKeys.has(key)
);
if (runtimeCheckedKeys.length > 0) {
mapViewStore.setCheckedLayerKeys(runtimeCheckedKeys);
checkedKeys = runtimeCheckedKeys;
}
}
// 设置图例数据(此时 checkedLayerKeys 已正确设置)
if (legendOriginal.length > 0) {
mapStore.setLegendData(legendOriginal, pageLegend);
}
const activePageToken = mapStore.activatePageContext(
pageKey,
layerConfig
);
await mapStore.updateLayerData(checkedKeys, true);
mapStore.setSelectedLegendData();
const backgroundLoadPromise = isInitialLoad
? mapStore.loadAllLayerData(layerConfig, checkedKeys, {
pageToken: activePageToken,
skipSessionCheck: true,
pageKey
})
: mapStore.loadCurrentPageLayerData(layerConfig, checkedKeys, {
pageToken: activePageToken,
skipSessionCheck: true
});
void backgroundLoadPromise.catch(error => {
console.error(`页面锚点后台加载失败 [${pageKey}]`, error);
});
backgroundLoadStarted = true;
}
} finally {
if (
!backgroundLoadStarted &&
pageLoadRequestId === activePageLoadRequestId
) {
mapDataStore.setLoading(false);
}
}
};
// 备注:统一完成地图实例初始化和弹窗挂载,确保后续事件监听可以在图层数据加载前生效。
const initializeMapShell = async ({
container,
popupContainer
}: InitializeOptions) => {
await mapClass.init(container);
if (popupContainer) {
const popupHost = container.parentElement;
if (popupHost && popupContainer.parentElement !== popupHost) {
popupHost.appendChild(popupContainer);
}
popupContainer.style.display = 'none';
mapClass.initPopupOverlay(popupContainer);
}
};
const replayCurrentMapState = async (
options: Pick<InitializeOptions, 'popupContainer'> & {
getIsHydroMenu: () => boolean;
}
) => {
initializedBaseLayerKeys.clear();
const currentZoom = getCurrentZoom();
if (currentZoom !== undefined) {
mapViewStore.setCurrentZoomLevel(currentZoom);
}
if (options.popupContainer) {
const container = document.getElementById('mapContainer');
const popupHost = container?.parentElement || null;
if (popupHost && options.popupContainer.parentElement !== popupHost) {
popupHost.appendChild(options.popupContainer);
}
options.popupContainer.style.display = 'none';
mapClass.initPopupOverlay(options.popupContainer);
}
ensureBaseLayersInitialized(mapStore.layerData || []);
const checkedKeys = mapViewStore.getCheckedLayerKeys();
await mapStore.updateLayerData(checkedKeys, true);
mapStore.setSelectedLegendData();
await syncZoomSensitiveState({
isHydroMenu: options.getIsHydroMenu(),
refreshEngPoint: true
});
const selectedBaseId = mapViewStore.selectedBaseId;
mapClass.jdPanelControlShowAndHidden(
selectedBaseId || 'all',
!!selectedBaseId
);
bindZoomListener(options.getIsHydroMenu);
};
// 备注:统一完成首屏页面配置加载,供挂载阶段和后续页面重载复用。
const initialize = async ({
container,
popupContainer,
pageKey
}: InitializeOptions) => {
await initializeMapShell({
container,
popupContainer,
pageKey
});
await loadPage({ pageKey, isInitialLoad: true });
};
// 备注:统一绑定地图缩放监听,让页面组件只负责触发初始化,不再直接处理缩放联动细节。
const bindZoomListener = (getIsHydroMenu: () => boolean) => {
if (removeZoomListener) {
removeZoomListener();
removeZoomListener = null;
}
clearZoomSyncDebounceTimer();
const currentZoom = getCurrentZoom();
if (currentZoom !== undefined) {
mapViewStore.setCurrentZoomLevel(currentZoom);
}
const emitZoomChange = async () => {
const zoom = getCurrentZoom();
if (zoom === undefined) return;
await handleZoomLevelChange(
mapViewStore.currentZoomLevel,
zoom,
getIsHydroMenu()
);
};
if (currentMapType === '3D') {
const removeCesiumListener =
mapClass.view?.camera?.changed?.addEventListener(() => {
clearZoomSyncDebounceTimer();
zoomSyncDebounceTimer.value = setTimeout(() => {
zoomSyncDebounceTimer.value = null;
void emitZoomChange();
}, CESIUM_ZOOM_SYNC_DEBOUNCE_MS);
});
if (typeof removeCesiumListener === 'function') {
removeZoomListener = () => {
clearZoomSyncDebounceTimer();
removeCesiumListener();
};
}
return;
}
const view = getCurrentView();
if (!view?.on) return;
const zoomListenerKey = view.on('change:resolution', () => {
void emitZoomChange();
});
removeZoomListener = () => {
unByKey(zoomListenerKey);
};
};
// 备注:统一绑定基地切换事件,让页面组件不再直接 watch 外部基地选择源。
const bindBaseSelection = () => {
if (stopBaseSelectionWatch) {
stopBaseSelectionWatch();
stopBaseSelectionWatch = null;
}
stopBaseSelectionWatch = watch(
() => jidiSelectEventStore.selectedItem?.wbsCode,
newWbsCode => {
if (!newWbsCode) {
changeBaseId('');
return;
}
if (baseSelectionDebounceTimer.value) {
clearTimeout(baseSelectionDebounceTimer.value);
}
baseSelectionDebounceTimer.value = setTimeout(() => {
changeBaseId(newWbsCode);
baseSelectionDebounceTimer.value = null;
}, 100);
},
{ immediate: true }
);
};
// 备注:统一挂载地图页面生命周期,初始化后自动接管缩放监听和基地切换监听。
const mountView = async (
options: InitializeOptions & {
getIsHydroMenu: () => boolean;
}
) => {
currentMapType = '2D';
latestHydroMenuGetter = options.getIsHydroMenu;
await initializeMapShell(options);
bindBaseSelection();
bindZoomListener(options.getIsHydroMenu);
await loadPage({ pageKey: options.pageKey, isInitialLoad: true });
await syncZoomSensitiveState({
isHydroMenu: options.getIsHydroMenu(),
refreshEngPoint: true
});
};
const switchMapType = async (
type: '2D' | '3D',
options: Pick<InitializeOptions, 'popupContainer'> & {
getIsHydroMenu?: () => boolean;
} = {}
) => {
const hydroMenuGetter =
options.getIsHydroMenu || latestHydroMenuGetter || (() => false);
latestHydroMenuGetter = hydroMenuGetter;
currentMapType = type;
await mapClass.switchView(type);
await replayCurrentMapState({
popupContainer: options.popupContainer,
getIsHydroMenu: hydroMenuGetter
});
};
// 备注:统一处理菜单切换后的页面配置重载,供页面 watch 直接复用。
const reloadPage = async (pageKey: string) => {
if (!pageKey) return;
await loadPage({ pageKey, isInitialLoad: false });
};
// 备注:菜单切换前只隐藏旧页面当前可见点图层,底图保持连续显示,避免切换时闪烁。
const hideCurrentVisibleLayers = () => {
const currentCheckedKeys = mapViewStore.getCheckedLayerKeys();
currentCheckedKeys.forEach(layerKey => {
const layerItem = mapStore.findLayerByKey(mapStore.layerData, layerKey);
if (!layerItem?.key) {
return;
}
if (layerItem.type === 'pointMap') {
if (mapClass.hasLayer(layerItem.key)) {
mapClass.mdLayerTreeShowOrHidden(layerItem.key, false);
}
}
});
};
// 备注:统一处理图层树勾选结果归一化和地图联动,供图层树组件复用。
const applyLayerSelection = async ({
checkedKeys,
triggerKey,
checked
}: ApplyLayerSelectionOptions) => {
const normalizedKeys = mapStore.normalizeCheckedLayerKeys(
checkedKeys,
triggerKey,
checked
);
await mapStore.updateLayerData(normalizedKeys);
return normalizedKeys;
};
// 备注:统一确保指定动态图层完成数据预加载,避免缩放切换时重复在页面组件里拼装加载逻辑。
const ensureDynamicLayersLoaded = async (layerKeys: string[] = []) => {
const layersToLoad = layerKeys
.map(layerKey => mapStore.findLayerByKey(mapStore.layerData, layerKey))
.filter(
(layer: any) => layer?.url && !mapDataStore.hasPointLayerData(layer.key)
);
if (layersToLoad.length === 0) {
return;
}
await Promise.all(layersToLoad.map(layer => mapStore.loadLayerData(layer)));
};
// 备注:统一控制水电开发菜单下的动态图层增删,避免页面组件直接操作加载和勾选细节。
const syncHydroDynamicLayers = async (visible: boolean) => {
if (
hydroDynamicLayerSyncTask &&
hydroDynamicLayerSyncTask.visible === visible
) {
return hydroDynamicLayerSyncTask.promise;
}
const task = (async () => {
const currentCheckedKeys = mapViewStore.getCheckedLayerKeys();
if (visible) {
const layersToAdd = HYDRO_DYNAMIC_LAYER_KEYS.filter(
key => !currentCheckedKeys.includes(key)
);
if (layersToAdd.length === 0) {
return currentCheckedKeys;
}
await ensureDynamicLayersLoaded(layersToAdd);
return applyLayerSelection({
checkedKeys: [...currentCheckedKeys, ...layersToAdd]
});
}
const nextCheckedKeys = currentCheckedKeys.filter(key => {
if (!HYDRO_DYNAMIC_LAYER_KEYS.includes(key)) {
return true;
}
return hydroMenuDefaultCheckedKeys.has(key);
});
if (nextCheckedKeys.length === currentCheckedKeys.length) {
return currentCheckedKeys;
}
return applyLayerSelection({
checkedKeys: nextCheckedKeys
});
})().finally(() => {
if (hydroDynamicLayerSyncTask?.promise === task) {
hydroDynamicLayerSyncTask = null;
}
});
hydroDynamicLayerSyncTask = {
visible,
promise: task
};
return task;
};
// 备注:统一按当前缩放对齐首页菜单的中型站过滤和 12 级动态图层状态。
const syncZoomSensitiveState = async ({
isHydroMenu,
refreshEngPoint = false
}: {
isHydroMenu: boolean;
refreshEngPoint?: boolean;
}) => {
const currentZoom = getCurrentZoom();
if (currentZoom !== undefined) {
mapViewStore.setCurrentZoomLevel(currentZoom);
}
if (
isHydroMenu &&
refreshEngPoint &&
mapViewStore.getCheckedLayerKeys().includes(ENG_POINT_LAYER_KEY)
) {
mapStore.refreshPointLayerDisplayData(ENG_POINT_LAYER_KEY);
}
await syncHydroDynamicLayers(
!!isHydroMenu && currentZoom !== undefined && currentZoom >= 12
);
};
// 备注:统一处理地图缩放联动,收口水电开发菜单下的动态图层阈值切换逻辑。
const handleZoomLevelChange = async (
previousZoom: number,
currentZoom: number,
isHydroMenu: boolean
) => {
mapViewStore.setCurrentZoomLevel(currentZoom);
const crossedEngPointMediumThreshold =
(previousZoom <= ENG_POINT_MEDIUM_VISIBLE_ZOOM &&
currentZoom > ENG_POINT_MEDIUM_VISIBLE_ZOOM) ||
(previousZoom > ENG_POINT_MEDIUM_VISIBLE_ZOOM &&
currentZoom <= ENG_POINT_MEDIUM_VISIBLE_ZOOM);
if (
isHydroMenu &&
crossedEngPointMediumThreshold &&
mapViewStore.getCheckedLayerKeys().includes(ENG_POINT_LAYER_KEY)
) {
mapStore.refreshPointLayerDisplayData(ENG_POINT_LAYER_KEY);
}
if (!isHydroMenu) {
return;
}
const oldZoomLevel = Math.floor(previousZoom);
const newZoomLevel = Math.floor(currentZoom);
if (oldZoomLevel < 12 && newZoomLevel >= 12) {
await syncHydroDynamicLayers(true);
return;
}
if (oldZoomLevel >= 12 && newZoomLevel < 12) {
await syncHydroDynamicLayers(false);
}
};
// 备注:统一处理菜单切换后的页面重载和动态图层收口,减少页面组件里的分支编排。
const handlePageChange = (pageKey: string, isHydroMenu: boolean) => {
if (!pageKey) return Promise.resolve();
const previousPageKey = mapConfigStore.lastLoadOptions?.pageKey || '';
if (previousPageKey && previousPageKey !== pageKey) {
hideCurrentVisibleLayers();
mapViewStore.setCheckedLayerKeys([]);
mapStore.setSelectedLegendData();
}
return reloadPage(pageKey).then(async () => {
await syncZoomSensitiveState({
isHydroMenu,
refreshEngPoint: true
});
});
};
// 备注:统一处理单个图层切换命令,供后续其他入口复用。
const toggleLayer = async (layerKey: string, checked?: boolean) => {
const currentKeys = mapViewStore.getCheckedLayerKeys();
const currentSet = new Set(currentKeys);
const nextChecked =
checked === undefined ? !currentSet.has(layerKey) : checked;
if (nextChecked) {
currentSet.add(layerKey);
} else {
currentSet.delete(layerKey);
}
return applyLayerSelection({
checkedKeys: Array.from(currentSet),
triggerKey: layerKey,
checked: nextChecked
});
};
// 备注:统一处理单个图例切换命令,供图例组件复用。
const toggleLegend = (nameEn: string, checked?: number) => {
if (!nameEn) return;
console.log('toggleLegend', nameEn, checked);
console.log(mapViewStore.getLegendChecked(nameEn));
const nextChecked =
checked === undefined
? mapViewStore.getLegendChecked(nameEn) === 1
? 0
: 1
: checked;
console.log(nextChecked);
mapStore.updateLegendChecked(nameEn, nextChecked);
};
// 备注:统一处理批量图例切换命令,供容量筛选和分组图例复用。
const toggleLegendBatch = (nameEns: string[] = [], checked: number) => {
const targetNameEns = nameEns.filter(Boolean);
if (targetNameEns.length === 0) return;
mapStore.updateLegendCheckedBatch(targetNameEns, checked);
};
// 备注:统一处理基地切换命令,同时驱动地图基地裁切联动。
const changeBaseId = (baseId: string) => {
const nextBaseId = !baseId || baseId === 'all' ? '' : baseId;
mapViewStore.setSelectedBaseId(nextBaseId);
mapClass.jdPanelControlShowAndHidden(
baseId || 'all',
baseId !== 'all' && !!baseId
);
};
// 备注:统一处理时间范围变更,并触发相关图层数据重载。
const changeTimeRange = async (range: [any, any]) => {
mapViewStore.setSearchTimeRange(range);
await mapStore.reloadBySearchTimeRange();
};
// 备注:统一处理装机容量筛选,让筛选器切换时同步更新 eng_point 图例运行态和点位显示。
const changeEngPointCapacity = (capacityType?: string | null) => {
const legendItems = mapStore.getLegendItemsByLayerCode(ENG_POINT_LAYER_KEY);
if (!legendItems.length) return;
const allEngLegendNames = legendItems
.map((item: any) => item?.nameEn)
.filter(Boolean);
if (!allEngLegendNames.length) return;
const normalizedCapacityType = capacityType || 'all';
let activePrefixes = [LARGE_ENG_LEGEND_PREFIX, MID_ENG_LEGEND_PREFIX];
if (normalizedCapacityType === 'large_eng_built') {
activePrefixes = [LARGE_ENG_LEGEND_PREFIX];
} else if (normalizedCapacityType === 'mid_eng_built') {
activePrefixes = [MID_ENG_LEGEND_PREFIX];
}
const visibleLegendNames = allEngLegendNames.filter((nameEn: string) =>
activePrefixes.some(prefix => nameEn.startsWith(prefix))
);
const hiddenLegendNames = allEngLegendNames.filter(
(nameEn: string) => !visibleLegendNames.includes(nameEn)
);
mapStore.updateLegendCheckedBatch(hiddenLegendNames, 0);
mapStore.updateLegendCheckedBatch(visibleLegendNames, 1);
mapStore.refreshPointLayerDisplayData(ENG_POINT_LAYER_KEY);
};
// 备注:统一重置地图筛选表单依赖的时间范围,供筛选组件在切页时复位默认输入。
const resetFilterState = () => {
mapViewStore.setSearchTimeRange([dayjs().subtract(1, 'M'), dayjs()]);
};
// 备注:统一处理搜索定位,按点位编码从缓存数据中查找并飞行到目标位置。
const focusPoint = (
pointId: string,
zoom = 15,
fallbackPoints: any[] = []
) => {
if (!pointId) return;
const pointMatcher = (item: any) => {
return item.stcd === pointId || item._id === pointId;
};
const targetPoint =
mapDataStore.pointData.find(pointMatcher) ||
fallbackPoints.find(pointMatcher);
if (!targetPoint?.lgtd || !targetPoint?.lttd) return;
const legendState = String(targetPoint?.anchoPointState || '');
if (legendState && mapViewStore.getLegendChecked(legendState) !== 1) {
mapStore.updateLegendChecked(legendState, 1);
}
const layerKey = String(targetPoint?.layerKey || '');
if (layerKey && mapClass.hasLayer(layerKey)) {
mapClass.mdLayerTreeShowOrHidden(layerKey, true);
}
mapClass.flyTopanto([targetPoint.lgtd, targetPoint.lttd], zoom);
};
// 备注:统一释放地图页面生命周期里注册的监听,避免页面卸载后残留联动。
const unmountView = () => {
if (removeZoomListener) {
removeZoomListener();
removeZoomListener = null;
}
clearZoomSyncDebounceTimer();
if (stopBaseSelectionWatch) {
stopBaseSelectionWatch();
}
if (baseSelectionDebounceTimer.value) {
clearTimeout(baseSelectionDebounceTimer.value);
baseSelectionDebounceTimer.value = null;
}
latestHydroMenuGetter = null;
currentMapType = '2D';
initializedBaseLayerKeys.clear();
hydroMenuDefaultCheckedKeys.clear();
};
return {
initialize,
mountView,
switchMapType,
unmountView,
loadPage,
reloadPage,
applyLayerSelection,
ensureDynamicLayersLoaded,
syncHydroDynamicLayers,
getCurrentZoom,
handleZoomLevelChange,
handlePageChange,
toggleLayer,
toggleLegend,
toggleLegendBatch,
changeBaseId,
changeTimeRange,
changeEngPointCapacity,
resetFilterState,
focusPoint
};
};