365 lines
12 KiB
TypeScript
365 lines
12 KiB
TypeScript
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 };
|