SourceTermAnalysisSystem_vue/src/gis/ol/index.ts
2026-08-11 18:24:37 +08:00

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