diff --git a/package.json b/package.json index f17f7e0..445771c 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "axios": "^1.6.7", "cesium": "1.108", "cesium-navigation-es6": "^3.0.8", + "crypto-js": "^4.2.0", "echarts": "^5.5.0", "fs": "0.0.1-security", "kml-geojson": "^2.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5bd328..389092e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ dependencies: cesium-navigation-es6: specifier: ^3.0.8 version: 3.0.8 + crypto-js: + specifier: ^4.2.0 + version: 4.2.0 echarts: specifier: ^5.5.0 version: 5.5.0 @@ -3003,6 +3006,10 @@ packages: which: 2.0.2 dev: true + /crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==, tarball: https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz} + dev: false + /css-functions-list@3.2.1: resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} engines: {node: '>=12 || >=16'} diff --git a/src/assets/js/weatherRequest.ts b/src/assets/js/weatherRequest.ts index 9e818bc..3f80d26 100644 --- a/src/assets/js/weatherRequest.ts +++ b/src/assets/js/weatherRequest.ts @@ -1,4 +1,5 @@ import axios from "axios"; +import CryptoJS from "crypto-js" type WeatherResponse = { success: boolean, @@ -7,13 +8,22 @@ type WeatherResponse = { data: any //响应数据 } -//查询未来24小时,指定位置的地面气象变量信息 -function query_surface_forecast(lat:number, lon: number) +/**查询未来24小时,指定位置的地面气象变量信息 + * + * @param lon 经度 + * @param lat 纬度 + */ +function query_surface_forecast(lon: number,lat:number) { + let timestamp = Date.now().toString() return axios({ method: "POST", - url: "/onlinetest/htfp/weather/v1surface/querySurfaceForecast", - headers: {"Content-Type": "application/json"}, + url: "/onlinetest/htfp/weather/v1/surface/querySurfaceForecast", + headers: { + "Content-Type": "application/json", + "timestamp": timestamp, + "signature": CryptoJS.HmacSHA1('/htfp/weather/v1/surface/querySurfaceForecast', timestamp) + }, data: { latitude: lat, longitude: lon, @@ -23,10 +33,15 @@ function query_surface_forecast(lat:number, lon: number) //查询未来24小时,指定位置和高度的高空气象变量信息 function query_upper_forecast(lat:number, lon: number, level:number){ + let timestamp = Date.now().toString() return axios({ method: "POST", - url: "/onlinetest/htfp/weather/v1upper/queryUpperForecast", - headers: {"Content-Type": "application/json"}, + url: "/onlinetest/htfp/weather/v1/upper/queryUpperForecast", + headers: { + "Content-Type": "application/json", + "timestamp": timestamp, + "signature": CryptoJS.HmacSHA1('/htfp/weather/v1/upper/queryUpperForecast', timestamp) + }, data: { latitude: lat, longitude:lon, diff --git a/src/components/page/RouteManagePage.vue b/src/components/page/RouteManagePage.vue index f8ddbbc..3f92758 100644 --- a/src/components/page/RouteManagePage.vue +++ b/src/components/page/RouteManagePage.vue @@ -2,7 +2,7 @@ import SceneViewer from "@/components/SceneViewer.vue"; import BottomBar from "@/components/BottomBar.vue"; import {ArrowBackOutline,ArrowForwardOutline,Save,Add, SaveOutline} from "@vicons/ionicons5"; -import {nextTick, onMounted, ref} from "vue"; +import {nextTick, onBeforeUnmount, onMounted, ref} from "vue"; import {darkTheme, useMessage} from "naive-ui"; import {route,route2,route3} from "@/assets/js/testData.ts"; import {useRouteStore} from "@/store/RouteStore.ts"; @@ -13,8 +13,10 @@ 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"; let myChart: EChartsType = undefined +let weatherChart: EChartsType = undefined let routeStore = useRouteStore() let selectedRouteCode = ref(null) let showPtList = ref(true) @@ -23,7 +25,8 @@ let routesInstore = ref<{ value: string|number; label: string}[]>(null) let routeViewer = null let routePtNumber = ref(1) let uiMsg = useMessage() - +let nowTime = ref('') +let timer = null let PtOptions = [ {label: '删除航点', key: 'deletePt'}, {label: '插入航点', key: 'insertPt'}, @@ -46,10 +49,14 @@ let routeCode = [ value: 5, } ] - +let levelOptions :any[] = [] +onBeforeUnmount(()=>{ + clearInterval(timer) +}) onMounted(()=>{ + getTime() myChart = echarts.init(document.getElementById('echarts-profile'),'dark') - + weatherChart = echarts.init(document.getElementById('weatherChart'),'dark') routeStore.addRoute(route) routeStore.addRoute(route2) routeStore.addRoute(route3) @@ -63,6 +70,23 @@ onMounted(()=>{ }) +function getTime(){ + timer = setInterval(getTimesInterval, 1000); +} + +function getTimesInterval() { + let now = new Date(); + let year = now.getFullYear(); // 年 + let month = (now.getMonth() + 1).toString().padStart(2, '0'); // 月 + let day = now.getDate().toString().padStart(2, '0'); // 日 + let hours = now.getHours().toString().padStart(2, '0'); // 时 + let minutes = now.getMinutes().toString().padStart(2, '0'); // 分 + let seconds = now.getSeconds().toString().padStart(2, '0'); // 秒 + +// 格式化时间 + nowTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} + // 航线选择回调 function checkRoute(key:number|string){ new Promise((resolve,reject)=>{ @@ -141,22 +165,184 @@ function handlePtSelect(key:any, index:number) { selectedRoute.value.points.splice(index,0,newPt) showPtList.value = true }) - } } //查询上一航点的气象信息 function prevPtWeather() { routePtNumber.value -= 1 - //TODO: 查询气象接口,使用返回值promise + let lat = selectedRoute.value.points[routePtNumber.value-1].lat + let lon = selectedRoute.value.points[routePtNumber.value-1].lon + if(lat && lon){ + queryWeather(lon,lat) + } } //查询下一航点的气象信息 function nextPtWeather() { routePtNumber.value += 1 - console.log(selectedRoute.value.points.length) - //TODO: 查询气象接口,使用返回值promise + let lat = selectedRoute.value.points[routePtNumber.value-1].lat + let lon = selectedRoute.value.points[routePtNumber.value-1].lon + if(lat && lon){ + queryWeather(lon,lat) + } + // 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 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 + } + ] + }) +} +