import type { mapPalyUiEvet } from './interface/common'; import type { MapOptions } from './interface/olBussiness'; import { transform, transformExtent } from 'ol/proj'; import { clearGridFeatures } from '@/gis/ol/olGirdHeatmap'; import { clearHeatmapFeatures } from '@/gis/ol/olHeatmap'; import { sendPlaybackPostMassage } from '@/gis/worker/playbackWorkerMa'; import JulianDate from '../common/clock/JulianData/JulianDate'; import { obtainViewer2D } from './map'; import { setMoudelMenu } from './mapEventListen'; import { initClock, removeClockOnTickEvent, setAnimationTime, setClockOnTickEvent, setShouldAnimate } from './olClock'; import { classInstances, initClassAll } from './olHandleEntry'; import { addBaseJSON } from './tool/addGeoJson'; import { exportImage } from './tool/exportImg'; import { bayesProbLocDataHandle, removeeBayesProbLocLayer } from './tool/handle/bayesProbLoc'; import { handleWeathData } from './tool/handle/weathDataHandle'; import { windDataHandle } from './tool/handle/windDataHandle'; import { addHeadMap, removeHeadMap } from './tool/heatMap'; import { addWeathLayer, removeWeathLayer, setWeathLayerVisity } from './tool/weath'; import { addWindLayer, removeWindLayer, setWindLayerVisity } from './tool/wind'; import { clearFlexpartContourLayer } from './flexpartContour/flexpartContourLayer'; // 当前模块信息 let activeMoudleInf: any = { activeMenu: '输运模拟', initFalg: false, isyxcjGisData: false, }; export function setActiveMenu(value) { activeMoudleInf.activeMenu = value; } // gis图层参数 let gisImgOpt: any = { }; // 气象预测数据动画类型标识,回放显示动画轴,预览不显示动画轴 let tqycAnimationType: any = 0; const defaultGeosion: any = { url0: 'http://localhost:8888/ol/haiyang.geojson', url1: 'http://localhost:8888/ol/custom.geojson', url2: 'http://localhost:8888/ol/chinaGeoJson.json', defau0: false, defau1: false, defau2: false, }; // 风场是否开启 const weathFlag: any = { 0: false, 1: false, 2: false, 3: true }; let weathRequesTime = ''; export function setWeathRequesTime(value: any) { weathRequesTime = value; } // 回放业务更新事件 const palyDateEvent: any = { // 不同模块切换 进行初始化 init(map: any, eventOpt: any) { // 业务逻辑---当前先使用一个热力图 // 初始化时间 -业务后期变动 setAnimationTime({ startTime: '2025-01-01 00:00:00', endTime: '2025-01-02 00:00:00', }); // 添加基础矢量地图 if (!defaultGeosion.defau0) { addBaseJSON(map, defaultGeosion.url0, { color: 'rgba(50, 50, 50, 0.8)', minZoom: 0, maxZoom: 7, zIndex: 3 }); defaultGeosion.defau0 = true; } // if (!defaultGeosion.defau1) { // addBaseJSON(map, defaultGeosion.url1, { color: 'rgba(211, 185, 80, 0.5)', minZoom: 2, maxZoom: 7 }); // defaultGeosion.defau1 = true; // } // if (!defaultGeosion.defau2) { // addBaseJSON(map, defaultGeosion.url2, { color: 'rgba(220, 231, 185, 0.6)', minZoom: 5, maxZoom: 12 }); // defaultGeosion.defau2 = true; // } // https://t1.tianditu.gov.cn/cia_w/wmts? // SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia // &STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=4&TILEROW=6&TILECOL=3&tk=a76b9ea6e49fb0eecdb1ed34d1e75930 // 注册业务帧回调函数 setClockOnTickEvent({ key: activeMoudleInf.activeMenu, callback(timeClock: any) { // 1. 获取当前时间和结束时间(转换为 Date 对象方便对比) const currentDate = JulianDate.toDate(timeClock.currentTime); const endDate = JulianDate.toDate(timeClock.stopTime); // 注意:olClock 是全局变量,需确保能访问到 // 2. 核心判断:当前时间 ≥ 结束时间 → 到达最后一刻 const isReachEnd = currentDate.getTime() >= endDate.getTime(); if (isReachEnd) { // 到达终点:暂停播放 + 执行收尾逻辑 setShouldAnimate(false); // 停止播放 return; // 终止后续业务逻辑,避免重复执行 } if (timeClock.shouldAnimate) { if (activeMoudleInf.activeMenu === '输运模拟') { sendPlaybackPostMassage({ code: 'drawSYMN', data: JulianDate.toDate(timeClock.currentTime).getTime() }, {}); } if (activeMoudleInf.activeMenu === '核事件模拟') { sendPlaybackPostMassage({ code: 'drawHSJMN', data: JulianDate.toDate(timeClock.currentTime).getTime() }, {}); } } }, }); // 修改初始化标识 activeMoudleInf.initFalg = true; resetMapView(map, false); }, // 清理图层 clear(map: any, eventOpt: any) { console.log(eventOpt); // 清理UI const eventbus = EventBusTool.getEventBus(); eventbus.publish('playUI', { key: 'stop', }); // 清理标牌 classInstances.olPopup?.clearAllPopups(); // 清理图层数据 activeMoudleInf.isyxcjGisData = false; removeHeadMap(map); removeWindLayer(map); removeeBayesProbLocLayer(map); removeWeathLayer(map); // 清理时钟 分为停止事件,清除业务回调事件 setShouldAnimate(false); // 清理自定义热力图 clearGridFeatures(); // 清空画面,图层保留 clearFlexpartContourLayer(); // 清理热力图 clearHeatmapFeatures(); // 移除标记点 classInstances.olTarget?.clearMarkers(); // 清理缓存 sendPlaybackPostMassage({ code: 'clearCache' }, {}); // 终止请求 sendPlaybackPostMassage({ code: 'abortSYMN', data: false }, {}); // 清理业务帧回调函数 removeClockOnTickEvent(activeMoudleInf.activeMenu); // 进行业务态势逻辑逻辑初始化 if (eventOpt.activeMenu) { activeMoudleInf = { activeMenu: eventOpt.activeMenu, initFalg: false, }; setMoudelMenu(eventOpt.activeMenu); } // 进行业务初始化 palyDateEvent.init(map, eventOpt); }, show(map: any, eventOpt: any) { // UI界面初始化 显示动画轴 const eventbus = EventBusTool.getEventBus(); eventbus.publish('playUI', { key: 'start', activeMenu: activeMoudleInf.activeMenu, eventOpt, }); resetMapView(map, false); }, hide(map: any, eventOpt: any) { const eventbus = EventBusTool.getEventBus(); eventbus.publish('playUI', { key: 'stop', }); }, // 添加热力图 addHeatMap(map: any, eventOpt?: any) { removeHeadMap(map); addHeadMap(map, eventOpt.data); }, // 删除热力图 removeHeatMap(map: any, eventOpt?: any) { removeHeadMap(map); }, // 添加风场 addWindLayer(map: any, eventOpt?: any) { removeWindLayer(map); addWindLayer(map); }, // 删除风场 removeWindLayer(map: any, eventOpt?: any) { removeWindLayer(map); }, // 导出图片 exportImage(map: any, eventOpt?: any) { exportImage(map, eventOpt); }, // 添加源项重建的热力图数据 addyxcjGis(map: any, eventOpt?: any) { removeeBayesProbLocLayer(map); const legengOpt = bayesProbLocDataHandle(map, eventOpt.data); activeMoudleInf.isyxcjGisData = true; // 清理UI const eventbus = EventBusTool.getEventBus(); eventbus.publish('playUI', { key: 'showLegeng', legengOpt, }); }, // 添加天气运算接口 animationType: 0 回放 1预览 addyctqjsGis(map: any, eventOpt?: any) { // 清理UI if (eventOpt.weatherType === 3) { removeWindLayer(map); addWindLayer(map, windDataHandle(eventOpt.data)); } else { handleWeathData(eventOpt.data, gisImgOpt.weatherType).then((weathOpt: any) => { removeWeathLayer(map); addWeathLayer(map, weathOpt.imageUrl); // 清理UI const eventbus = EventBusTool.getEventBus(); console.log(weathOpt,gisImgOpt,"222222222222222222") if(gisImgOpt.weatherType==0){ weathOpt.legengOpt.unit = "℃"; }else if(gisImgOpt.weatherType==1){ weathOpt.legengOpt.unit = "kPa"; }else if(gisImgOpt.weatherType==2){ weathOpt.legengOpt.unit = "%"; } eventbus.publish('playUI', { key: 'showWeathLength', legengOpt: weathOpt.legengOpt, }); }); } // 设置当前气象预测数据类型 if (eventOpt.animationType) { tqycAnimationType = eventOpt.animationType; } }, // 清除天气预报计算其他图层 removeGisWindLayer(map: any, eventOpt?: any) { removeWeathLayer(map); }, // 设置态势图层参数 setTaishiParam(map: any, eventOpt?: any) { gisImgOpt = { ...eventOpt }; console.log(gisImgOpt,"1") weathRequesTime = eventOpt.startTime; // 设置时间 setAnimationTime({ startTime: eventOpt.startTime, endTime: eventOpt.endTime, }); }, // 设置气象类型参数 setWeathTypeParam(map: any, eventOpt?: any) { gisImgOpt.weatherType = eventOpt.weatherType; weathFlag[gisImgOpt.weatherType] = eventOpt.isActive; }, // 设置图层可见 setWeatherLayerVisity(map: any, eventOpt?: any) { // 风场 if (eventOpt.weatherType === 3) { setWindLayerVisity(eventOpt.isActive); } else { // 气象 setWeathLayerVisity(eventOpt.isActive); } }, updateTimeCurrentIndex(map: any, eventOpt?: any){ gisImgOpt.hour = eventOpt.hour; console.log(gisImgOpt,"2") } }; // 初始化地图 export function initMap(domId: string, options?: MapOptions | any) { // 初始地图实例 const map: any = obtainViewer2D(domId, options); // const switcher = new LayerSwitcher(); // You can add it to the map // map.addControl(switcher); // 初始化时钟 initClock({ startTime: '2025-09-15 00:00:00', endTime: '2025-09-16 00:00:00', }); // 初始化工具类 initClassAll(); const eventbus = EventBusTool.getEventBus(); // 主题其它模块与gis交互全局事件 eventbus.subscribe('playData', (opt: mapPalyUiEvet) => { // 调用回放事件 palyDateEvent[opt.key] && palyDateEvent[opt.key](map, opt); }); // 初始化模块 palyDateEvent.clear(map, {}); } /** * 重置地图视图到初始状态 * @param map OpenLayers Map 实例 * @param hasAnimation 是否带动画(默认:true,可选 false 无动画) */ export function resetMapView(map, hasAnimation = true) { // 2. 初始视图配置(和你的 initMap2D 保持一致) const defaultViewConfig = { // 经纬度 [113.804, 22.405] 转换为墨卡托投影(EPSG:3857) center: transform([113.804, 22.405], 'EPSG:4326', 'EPSG:3857'), zoom: 0, // 初始缩放等级 rotation: 0, // 初始旋转角度(正北) }; // 3. 获取地图视图实例 const mapView = map.getView(); // 4. 重置视图(带动画/无动画可选) if (hasAnimation) { // 带动画平滑重置(体验更好) mapView.animate({ center: defaultViewConfig.center, zoom: defaultViewConfig.zoom, rotation: defaultViewConfig.rotation, duration: 800, // 动画时长(毫秒),可调整 }); } else { // 无动画瞬间重置 mapView.setCenter(defaultViewConfig.center); mapView.setZoom(defaultViewConfig.zoom); mapView.setRotation(defaultViewConfig.rotation); } } export function fitViewByExtent(extent) { const map = obtainViewer2D('olContainer'); if (map) { const view = map.getView(); // 3. 转换 extent 投影:经纬度(EPSG:4326)→ 墨卡托(EPSG:3857) const mercatorExtent = transformExtent( extent, 'EPSG:4326', // 源投影(经纬度) 'EPSG:3857', // 目标投影(地图默认投影) ); // 4. 定位到该范围(带动画,添加内边距) view.fit(mercatorExtent, { padding: [80, 80, 80, 80], // 视图内边距(避免点贴边,单位:像素) duration: 1000, // 定位动画时长(毫秒) }); } } export { activeMoudleInf, gisImgOpt, tqycAnimationType, weathFlag, weathRequesTime };