diff --git a/src/App.vue b/src/App.vue
index 3b43ef3..df40506 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,9 +1,11 @@
-
-
-
+
+
+
+
+
diff --git a/src/assets/js/RouteManageViewer.js b/src/assets/js/RouteManageViewer.js
index 4096064..76661d7 100644
--- a/src/assets/js/RouteManageViewer.js
+++ b/src/assets/js/RouteManageViewer.js
@@ -3,11 +3,11 @@ import * as Cesium from 'cesium'
export default class RouteManageViewer {
- constructor(viewer, isClose) {
+ constructor(viewer) {
this.viewer = viewer
this.scene = viewer.scene
this.routeParams = {
- isClose: isClose,
+ isClose: false,
height: 0,
}
this.positions = []
@@ -48,7 +48,7 @@ export default class RouteManageViewer {
this.viewer.entities.add(airlineEntity)
degreesArr.forEach((pt,index)=>{
let vertexEntity = new Cesium.Entity({
- id: line.unicode + "-航点" + index,
+ id: line.unicode + "-航点" + (index+1),
position: pt,
point: {
color: Cesium.Color.WHITE,
@@ -57,6 +57,19 @@ export default class RouteManageViewer {
outlineWidth: 2,
disableDepthTestDistance:99000000,
// heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
+ },
+ label:{
+ text: "航点 " + (index+1),
+ font: "2.5rem sans-serif",
+ fillColor: Cesium.Color.WHITE,
+ style: Cesium.LabelStyle.FILL,
+ eyeOffset: new Cartesian3(0,0,50),
+ horizontalOrigin: Cesium.HorizontalOrigin.RIGHT,
+ verticalOrigin: Cesium.VerticalOrigin.TOP,
+ scale: 0.4,
+ showBackground: true,
+ backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.99),
+ backgroundPadding: new Cesium.Cartesian2(15, 7),
}
});
this.viewer.entities.add(vertexEntity)
diff --git a/src/assets/js/measureViewer.js b/src/assets/js/measureViewer.js
index 05ae9fc..5a2b255 100644
--- a/src/assets/js/measureViewer.js
+++ b/src/assets/js/measureViewer.js
@@ -510,7 +510,6 @@ export default class MeasureViewer {
this._showResultArea()
this.stopAreaMeasure()
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
-
}
_showResultArea(){
diff --git a/src/assets/js/weatherCharts.ts b/src/assets/js/weatherCharts.ts
new file mode 100644
index 0000000..43d7b79
--- /dev/null
+++ b/src/assets/js/weatherCharts.ts
@@ -0,0 +1,153 @@
+import * as echarts from "echarts";
+import {EChartsType} from "echarts";
+
+/**
+ * 天气图表Echarts的配置函数
+ * @param wChart 图表对象
+ * @param timeSeries 时间序列
+ * @param temp 温度
+ * @param windSpeed 风速
+ * @param wind360 风向
+ * @param precip 降水
+ * @param humidity 湿度(暂未使用)
+ */
+export const setChartOptions = (wChart: EChartsType, timeSeries:string[], temp: number[], windSpeed:number[],
+ wind360: number[], precip:number[], humidity?:number[]) =>{
+
+ let windDirection = wind360.map(item=>{
+ let arr = [22.5, 22.5+45, 22.5+45*2, 22.5+45*3, 22.5+45*4, 22.5+45*5, 22.5+45*6, 22.5+45*7]
+ let str = ['北风','东北风','东风','东南风','南风','西南风','西风','西北风']
+ if(item<=arr[0] || item>arr[7]){
+ return str[0]+': '+ Math.round(item)+'°'
+ }else if(arr[0] <=item && item<=arr[1]){
+ return str[1]+' : '+ Math.round(item)+'°'
+ }else if(arr[1] <=item && item<=arr[2]){
+ return str[2]+' : '+ Math.round(item)+'°'
+ }else if(arr[2] <=item && item<=arr[3]){
+ return str[3]+' : '+ Math.round(item)+'°'
+ }else if(arr[3] <=item && item<=arr[4]){
+ return str[4]+' : '+ Math.round(item)+'°'
+ }else if(arr[4] <=item && item<=arr[5]){
+ return str[5]+' : '+ Math.round(item)+'°'
+ }else if(arr[5] <=item && item<=arr[6]){
+ return str[6]+' : '+ Math.round(item)+'°'
+ }else if(arr[6] <=item && item<=arr[7]){
+ return str[7]+' : '+ Math.round(item)+'°'
+ }
+ })
+ let colors = ['#5470C6', '#91CC75', '#EE6666'];
+ wChart.setOption({
+ backgroundColor:'#101014',
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'cross',
+ }
+ },
+ color: colors,
+ grid: [
+ {x: '7%', y: '7%', height: '40%', left: '12%',right: '15%'},
+ {x: '7%', y2: '7%', height: '38%', left: '12%',right: '15%', bottom: '10%'}
+ ],
+ legend: {
+ data:['风速','降水','温度']
+ },
+ xAxis: [
+ {
+ show: false,//隐藏了x轴
+ type: 'category',
+ gridIndex: 0,//对应前面grid的索引位置(第一个)
+ axisTick: {
+ alignWithLabel: true
+ },
+ data: windDirection,
+ },
+ {
+ type: 'category',
+ gridIndex: 1, //对应前面grid的索引位置(第二个)
+ axisTick: {
+ alignWithLabel: true
+ },
+ data: timeSeries,
+ }
+ ],
+ //y轴,不管有几个x轴,几个y轴,或者图,只要找到他对应的grid图的序号索引就可以精准匹配
+ yAxis: [
+ {
+ type: 'value',
+ gridIndex: 1,//对应前面grid的索引位置(第二个)
+ splitLine: {show: false},
+ position: 'right',
+ axisLine: {
+ lineStyle: {
+ color: colors[1]
+ }
+ },
+ axisLabel: {
+ formatter: '{value}ml'
+ }
+ },
+ {
+ type: 'value',
+ gridIndex: 1,
+ nameLocation: 'middle',
+ name: '温度',
+ nameTextStyle: {
+ padding: 25
+ },
+ splitLine: {show: false},
+ position: 'left',
+ axisLine: {
+ lineStyle: {
+ color: colors[2]
+ }
+ },
+ axisLabel: {
+ formatter: '{value}°C'
+ }
+ },
+ {
+ type: 'value',
+ gridIndex: 0,
+ name: '风速',
+ nameTextStyle: {
+ padding: 25
+ },
+ position: 'left',
+ splitLine: {show: false},
+ axisLine: {
+ lineStyle: {
+ color: colors[0]
+ }
+ },
+ axisLabel: {
+ formatter: '{value}',
+ fontSize: 12,//y轴坐标轴上的字体大小
+ }
+ }
+ ],
+ series: [
+ {
+ name:'风速',
+ type: "line",
+ xAxisIndex: 0,
+ yAxisIndex: 2,
+ data: windSpeed,
+ },
+ {
+ name:'降水',
+ type:'bar',
+ xAxisIndex: 1,
+ yAxisIndex: 0,
+ data: precip
+ },
+ {
+ name:'温度',
+ type:'line',
+ xAxisIndex: 1,
+ yAxisIndex: 1,
+ data:temp
+ }
+ ]
+ })
+}
diff --git a/src/assets/js/weatherRequest.ts b/src/assets/js/weatherRequest.ts
index 3f80d26..edc082e 100644
--- a/src/assets/js/weatherRequest.ts
+++ b/src/assets/js/weatherRequest.ts
@@ -31,8 +31,13 @@ function query_surface_forecast(lon: number,lat:number)
})
}
-//查询未来24小时,指定位置和高度的高空气象变量信息
-function query_upper_forecast(lat:number, lon: number, level:number){
+/** 查询未来24小时,指定位置和高度的高空气象变量信息
+ * @param lon 经度
+ * @param lat 纬度
+ * @param level 气压高度 hPa
+ */
+
+function query_upper_forecast(lon: number, lat:number, level:number){
let timestamp = Date.now().toString()
return axios({
method: "POST",
@@ -50,5 +55,20 @@ function query_upper_forecast(lat:number, lon: number, level:number){
})
}
-
-export {query_upper_forecast, query_surface_forecast}
+/**
+ * 查询高度层
+ */
+function requireWeatherLevel(){
+ let timestamp = Date.now().toString()
+ return axios({
+ method: "POST",
+ url: "/onlinetest/htfp/weather/v1/info/queryLevelsAvailable",
+ headers: {
+ "Content-Type": "application/json",
+ "timestamp": timestamp,
+ "signature": CryptoJS.HmacSHA1('/htfp/weather/v1/info/queryLevelsAvailable', timestamp)
+ },
+ data: { dataSource: "GFS" }
+ })
+}
+export {query_upper_forecast, query_surface_forecast,requireWeatherLevel}
diff --git a/src/components/page/RouteManagePage.vue b/src/components/page/RouteManagePage.vue
index 3f92758..ee73ac3 100644
--- a/src/components/page/RouteManagePage.vue
+++ b/src/components/page/RouteManagePage.vue
@@ -13,12 +13,16 @@ import {EChartsType} from "echarts";
import {transLonlat2Car3} from "@/utils/map/geocomputation.ts";
import {drawEcharts_RouteDetection, profileAnalyse} from "@/utils/map/SpatialAnalysis.ts";
import RouteManageViewer from "@/assets/js/RouteManageViewer.js";
-import {query_surface_forecast} from "@/assets/js/weatherRequest.ts";
+import {query_surface_forecast, query_upper_forecast, requireWeatherLevel} from "@/assets/js/weatherRequest.ts";
+import {setChartOptions} from "@/assets/js/weatherCharts.ts";
+import type { NotificationType } from 'naive-ui'
+import { useNotification } from 'naive-ui'
let myChart: EChartsType = undefined
let weatherChart: EChartsType = undefined
let routeStore = useRouteStore()
let selectedRouteCode = ref(null)
+let selectedLevel = ref(null)
let showPtList = ref(true)
let selectedRoute = ref(newAirline())
let routesInstore = ref<{ value: string|number; label: string}[]>(null)
@@ -49,14 +53,27 @@ let routeCode = [
value: 5,
}
]
-let levelOptions :any[] = []
+let levelOptions = ref()
+const notification = useNotification()
+const notify = (type: NotificationType, title: string, detail: string) =>{
+ notification[type]({
+ title: title,
+ meta: detail,
+ duration: 3000,
+ closable: true,
+ keepAliveOnHover: true
+ })
+}
onBeforeUnmount(()=>{
clearInterval(timer)
})
onMounted(()=>{
- getTime()
+ routeViewer = new RouteManageViewer(window.viewer)
myChart = echarts.init(document.getElementById('echarts-profile'),'dark')
weatherChart = echarts.init(document.getElementById('weatherChart'),'dark')
+
+ timer = setInterval(getTimesInterval, 1000);
+
routeStore.addRoute(route)
routeStore.addRoute(route2)
routeStore.addRoute(route3)
@@ -67,12 +84,25 @@ onMounted(()=>{
label: route.name
}
})
-
+ requireWeatherLevel().then(res=>{
+ console.log(res)
+ // 查询失败
+ if(!res.data.success){
+ notify('error', '气象信息查询失败', res.data.message)
+ return
+ }
+ levelOptions.value = res.data.data.levelsAvailableList[0].pressureLevels.map((level,index)=>{
+ return {
+ value: level,
+ label: level+'hPa/ '+ res.data.data.levelsAvailableList[0].heightLevels[index] + 'm'
+ }
+ })
+ levelOptions.value.reverse()
+ levelOptions.value.unshift({value: -1, label: '地面'})
+ selectedLevel.value = -1
+ })
})
-function getTime(){
- timer = setInterval(getTimesInterval, 1000);
-}
function getTimesInterval() {
let now = new Date();
@@ -84,7 +114,7 @@ function getTimesInterval() {
let seconds = now.getSeconds().toString().padStart(2, '0'); // 秒
// 格式化时间
- nowTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+ nowTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
// 航线选择回调
@@ -92,13 +122,12 @@ function checkRoute(key:number|string){
new Promise((resolve,reject)=>{
selectedRoute.value = routeStore.flyRoute.filter(element => element.unicode === String(key))[0]
if(selectedRoute.value == null) reject('未找到航线')
-
- routeViewer = new RouteManageViewer(window.viewer,selectedRoute.value.isClose)
+ routeViewer.routeParams.isClose = selectedRoute.value.isClose
window.viewer.flyTo(routeViewer.addAirLine(selectedRoute.value), {duration: 2})
+ queryWeather(selectedRoute.value.points[0].lon,selectedRoute.value.points[0].lat)
setTimeout(()=>resolve('success'),2500)
-
}).then((result)=>{
- //绘制图表
+ //绘制地形图表
let Cartain3 = transLonlat2Car3(selectedRoute.value.points)
// 计算地形剖面,默认采样间隔为1km
let res = profileAnalyse(window.viewer, Cartain3, 1000)
@@ -112,6 +141,7 @@ function checkRoute(key:number|string){
console.log(orderArr,hArr)
// 弹出图表窗口
drawEcharts_RouteDetection(myChart, res.distanceArray, res.elevationArray, orderArr, hArr)
+
}).catch((err)=>{
uiMsg.error(err)
})
@@ -171,178 +201,62 @@ function handlePtSelect(key:any, index:number) {
//查询上一航点的气象信息
function prevPtWeather() {
routePtNumber.value -= 1
+ window.viewer.flyTo(window.viewer.entities.getById(selectedRoute.value.unicode + "-航点" + (routePtNumber.value).toString()),
+ {duration: 1})
let lat = selectedRoute.value.points[routePtNumber.value-1].lat
let lon = selectedRoute.value.points[routePtNumber.value-1].lon
if(lat && lon){
- queryWeather(lon,lat)
+ queryWeather(lon,lat, selectedLevel.value)
}
}
//查询下一航点的气象信息
function nextPtWeather() {
routePtNumber.value += 1
+ window.viewer.flyTo(window.viewer.entities.getById(selectedRoute.value.unicode + "-航点" + (routePtNumber.value).toString()),
+ {duration: 1})
+
let lat = selectedRoute.value.points[routePtNumber.value-1].lat
let lon = selectedRoute.value.points[routePtNumber.value-1].lon
if(lat && lon){
- queryWeather(lon,lat)
+ queryWeather(lon,lat, selectedLevel.value)
}
- // TODO: 考虑高度
}
function queryWeather(lon:number,lat:number,level?: number) {
- query_surface_forecast(lon,lat)
- .then(res=>{
- let weatherData = res.data.data
- let timeArr = weatherData.time.map(item=>{
- let i = item.indexOf('T')
- return item.slice(i+1,i+3) + '时'
- })
- setChartOptions(timeArr.slice(0,8),weatherData.temp.slice(0,8),weatherData.windSpeed.slice(0,8),
- weatherData.wind360.slice(0,8), weatherData.precip.slice(0,8),weatherData.humidity.slice(0,8))
- })
-}
-
-function setChartOptions(timeSeries:string[], temp: number[], windSpeed:number[], wind360: number[], precip:number[], humidity?:number[]) {
- let windDirection = wind360.map(item=>{
- let arr = [22.5, 22.5+45, 22.5+45*2, 22.5+45*3, 22.5+45*4, 22.5+45*5, 22.5+45*6, 22.5+45*7]
- let str = ['北风','东北风','东风','东南风','南风','西南风','西风','西北风']
- if(item<=arr[0] || item>arr[7]){
- return str[0]+': '+ Math.round(item)+'°'
- }else if(arr[0] <=item && item<=arr[1]){
- return str[1]+' : '+ Math.round(item)+'°'
- }else if(arr[1] <=item && item<=arr[2]){
- return str[2]+' : '+ Math.round(item)+'°'
- }else if(arr[2] <=item && item<=arr[3]){
- return str[3]+' : '+ Math.round(item)+'°'
- }else if(arr[3] <=item && item<=arr[4]){
- return str[4]+' : '+ Math.round(item)+'°'
- }else if(arr[4] <=item && item<=arr[5]){
- return str[5]+' : '+ Math.round(item)+'°'
- }else if(arr[5] <=item && item<=arr[6]){
- return str[6]+' : '+ Math.round(item)+'°'
- }else if(arr[6] <=item && item<=arr[7]){
- return str[7]+' : '+ Math.round(item)+'°'
+ let response : Promise
+ if(level==null|| level==-1){ //地面
+ response = query_surface_forecast(lon,lat)
+ }else{
+ response = query_upper_forecast(lon,lat, level)
+ }
+ response.then(res=>{
+ // 查询失败
+ if(!res.data.success){
+ notify('error', '气象信息查询失败', res.data.message)
+ return
}
- })
- let colors = ['#5470C6', '#91CC75', '#EE6666'];
- weatherChart.setOption({
- backgroundColor:'#101014',
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'cross',
- }
- },
- color: colors,
- grid: [
- {x: '7%', y: '7%', height: '40%', left: '12%',right: '15%'},
- {x: '7%', y2: '7%', height: '38%', left: '12%',right: '15%', bottom: '10%'}
- ],
- legend: {
- data:['风速','降水','温度']
- },
- xAxis: [
- {
- show: false,//隐藏了x轴
- type: 'category',
- gridIndex: 0,//对应前面grid的索引位置(第一个)
- axisTick: {
- alignWithLabel: true
- },
- data: windDirection,
- },
- {
- type: 'category',
- gridIndex: 1, //对应前面grid的索引位置(第二个)
- axisTick: {
- alignWithLabel: true
- },
- data: timeSeries,
- }
- ],
- //y轴,不管有几个x轴,几个y轴,或者图,只要找到他对应的grid图的序号索引就可以精准匹配
- yAxis: [
- {
- type: 'value',
- gridIndex: 1,//对应前面grid的索引位置(第二个)
- splitLine: {show: false},
- position: 'right',
- axisLine: {
- lineStyle: {
- color: colors[1]
- }
- },
- axisLabel: {
- formatter: '{value}ml'
- }
- },
- {
- type: 'value',
- gridIndex: 1,
- nameLocation: 'middle',
- name: '温度',
- nameTextStyle: {
- padding: 25
- },
- splitLine: {show: false},
- position: 'left',
- axisLine: {
- lineStyle: {
- color: colors[2]
- }
- },
- axisLabel: {
- formatter: '{value}°C'
- }
- },
- {
- type: 'value',
- gridIndex: 0,
- name: '风速',
- nameTextStyle: {
- padding: 25
- },
- position: 'left',
- splitLine: {show: false},
- axisLine: {
- lineStyle: {
- color: colors[0]
- }
- },
- axisLabel: {
- formatter: '{value}',
- textStyle: {
- fontSize: 12//y轴坐标轴上的字体大小
- }
- }
- }
- ],
- series: [
- {
- name:'风速',
- type: "line",
- xAxisIndex: 0,
- yAxisIndex: 2,
- data: windSpeed,
- },
- {
- name:'降水',
- type:'bar',
- xAxisIndex: 1,
- yAxisIndex: 0,
- data: precip
- },
- {
- name:'温度',
- type:'line',
- xAxisIndex: 1,
- yAxisIndex: 1,
- data:temp
- }
- ]
+ let weatherData = res.data.data
+ let timeArr = weatherData.time.map(item=>{
+ let i = item.indexOf('T')
+ return item.slice(i+1,i+3) + '时'
+ })
+ if(!Reflect.has(weatherData,'precip')){
+ weatherData.precip = Array.from({length:timeArr.length},(v,k)=>0)
+ }
+ setChartOptions(weatherChart, timeArr.slice(0,8),weatherData.temp.slice(0,8),weatherData.windSpeed.slice(0,8),
+ weatherData.wind360.slice(0,8), weatherData.precip.slice(0,8),weatherData.humidity.slice(0,8))
})
}
+function levelChanged(key: string | number) {
+ selectedLevel.value = key
+ let lat = selectedRoute.value.points[routePtNumber.value-1].lat
+ let lon = selectedRoute.value.points[routePtNumber.value-1].lon
+ if(lat && lon){
+ queryWeather(lon,lat, Number(key))
+ }
+}
@@ -383,7 +297,11 @@ function setChartOptions(timeSeries:string[], temp: number[], windSpeed:number[]
{{ r.label }}
- 删除
+
+
+ 下发
+ 删除
+
@@ -430,7 +348,7 @@ function setChartOptions(timeSeries:string[], temp: number[], windSpeed:number[]
重新绘图
-
+
@@ -497,7 +415,7 @@ function setChartOptions(timeSeries:string[], temp: number[], windSpeed:number[]
-
+
气象信息
@@ -511,22 +429,11 @@ function setChartOptions(timeSeries:string[], temp: number[], windSpeed:number[]
{{nowTime}}
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -572,11 +479,7 @@ function setChartOptions(timeSeries:string[], temp: number[], windSpeed:number[]
.routePtSelector:hover{
background: rgb(24, 24, 28);
}
-.wCard {
- width: 4vw;
- height: 39vh;
- display: inline-block
-}
+
.border{
border: #22ee22 solid 1px;
}
diff --git a/src/components/toolbar.vue b/src/components/toolbar.vue
index 2860f13..c88a4fe 100644
--- a/src/components/toolbar.vue
+++ b/src/components/toolbar.vue
@@ -287,7 +287,8 @@ function manageLayer(){
*/
function startDrawRoute(routeParams) {
showRouteModal.value = false
- let drawLine = new RouteManageViewer(window.viewer, routeParams.isClose)
+ let drawLine = new RouteManageViewer(window.viewer)
+ drawLine.routeParams.isClose =routeParams.isClose
drawLine.routeParams.height = routeParams.height
drawLine.start().then(result => {
console.log(result)
diff --git a/vite.config.ts b/vite.config.ts
index d356664..c88193d 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -30,7 +30,7 @@ export default defineConfig({
server: {
proxy: {
'/onlinetest': {
- target: 'http://123.57.54.1:10323/',
+ target: 'http://172.10.0.195:10323/',
changeOrigin: true,
rewrite: path => path.replace(/^\/onlinetest/,'')
}