From 5c66f2b6f423d0686859d54f047fed7a51c91107 Mon Sep 17 00:00:00 2001 From: Xu Zhimeng Date: Fri, 8 Mar 2024 16:51:31 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=BB=98?= =?UTF-8?q?=E5=88=B6=E8=BD=A8=E8=BF=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../station-operation/icon-route-active.png | Bin 0 -> 1431 bytes .../images/station-operation/icon-route.png | Bin 0 -> 1419 bytes src/views/stationOperation/components/Map.vue | 128 ++++++++++++++- .../stationOperation/components/MapPane.vue | 155 ++++++++++++++++-- src/views/stationOperation/index.vue | 12 +- 5 files changed, 277 insertions(+), 18 deletions(-) create mode 100644 src/assets/images/station-operation/icon-route-active.png create mode 100644 src/assets/images/station-operation/icon-route.png diff --git a/src/assets/images/station-operation/icon-route-active.png b/src/assets/images/station-operation/icon-route-active.png new file mode 100644 index 0000000000000000000000000000000000000000..dc3feb64cd70615e8d1fd5986c03ceb48540b895 GIT binary patch literal 1431 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1|+Qw)-3{3k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xd_B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!WpKsVXIz(~Q|QqR!L z#Kg=%N5ROz$Uxt~RNv4@*U-$$z{JYXTmcG{fVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr62to{@q^cxGNo zetEGbSc9*xm1kaYNn&1ds;7&s63_^}%*+&Ea2mL{7&XJ2$+08OnABla^NXHH4m8Fi-76+9z%^40|OJ6r;B4q z#jT_#Tpxd*H(+RBbtz~OwOPJ=sePF5gp?!+1%s@QD~@V7OrAgc>6G@JE1Gu*NZ-{7 zd;B=*=92`CKObKA?@zy1_s3VfduxMTY<{{z$=Acv@1Im(x9|Vg_y6n5($w7CytoCN z5*AKfw}3_6`t$q$|0Vl&&hFggu=dZl@AveB2t-O z`|Dfv*~QcCEoLY(s}!+ZXE!!ZzI)Vq{>r?<_g~rL|NZ&@eSeJi#PXZX&+muZ z)_i1E`~Ks0|9;(HS~VscC0Nw%ReYH$DRHD&cMEI$-ydJU-FVHv-{H}9`?|l*n=RTJ z_W`+aKR-M@|5yM1!)Y504UPURcU|Rne)sNq`~Uv@^ZR^#$VxHJr+2yE+x;D@r=r(WI|dJD7<9GW-WI>78T8)#ekMyfQJc@q2ba(uTQ^#)rbuf7CJ(`|h x$CS8AL}9@m>swzWw^p2pIAako*Q|konc?qW`G&3Wv#x@QN>5immvv4FO#q9NE7$-4 literal 0 HcmV?d00001 diff --git a/src/assets/images/station-operation/icon-route.png b/src/assets/images/station-operation/icon-route.png new file mode 100644 index 0000000000000000000000000000000000000000..34ad7fb7d40f7a953ca3db63edfa611ab160ca69 GIT binary patch literal 1419 zcmaJ>ZA=?=9KMazVPTq$MZv{!TtB!?+Phw%tT(y>y)v3uU{C|em~w58QlP!#?x2O3 zb%@)7jLjvEWWkCuKOjNgJ~(BIbu4YdNF2rx;+P`iZEB0m7JIN8C%UYA6J?6hnea86q_!2nuGXWO8L%ni5F`Q3OR`BpsHcQn?aC(lB`jxcNXr zG{#ba72&y?v4oQvs^mBtgJGxBDRU}h6k~x6mwCL_W*+ zKZRLi15Lt3BumvXW?^s@l1L~T(=sH%QH+tIYNA~%tfV-Kt)yrWmCI1@V2RCPp`7fY z4T8ad=^ZRbILxFTS3`n?%x1G-TBTNp+Gb1i*hZ`xVmk*5ii(jAu>)fwtCW%%TRW3qh`#ueJ(lM>TPl@+vlR)mJ18Xz>&%R zYtqpx!9J1gmT!f_mh(x6V0T9F^~vESJpk+o>+x)(>z-*&yd1oX0B1z_`jPsuN-doq zKtHsY5<#SDx!c#BrSr^Bp9^*I(wZM1S_iwtV_wzkXOlXQg~wb^?o)r4_V(Obp%%~- zf5)U-(Qfrx*H#~CV)h@E#7HEhC^luO-+B&g?mqG-uW=`a`+t($`8Iyy@odoTx9|T( z@!iAV$WkDARa$X>=y8zm-TRh5c-^h2nObXZ^1KSA$VS&S^49ZB&CQnw`{xy_(vQ_o z;%;|pc;32i1$C5#JhhL8lj+gLf^Zn_o4wZJD<4}d;Kkwxyr)={G=1~*82!f_Jh0|D z=??#J_~K0a-K*zi@dXFMO>sj*D6-BMG#lI6ok=eSf}=~n`ZV_{UNf!8Bngu7 z$q(M~`Tc9&;kLl^r(+NJ7vA2pYcSjNnJE2WApg{RSDnN!lLdKer$g(PW^SqJaUTAB zHWWzq`@X9Bz68;vUhJ4zyu@En8#-IQOtk(iiuuIj=25UUG{xq|&msPaR_};(=Sv75 z%K18PNI;xz>eM8S`@%09mrs1uv%GMsEKA$5>aI-9=-n4Hn4OZv)Q?MBELtyE+6m9DS!7Lz} route 轨迹路线 + * @param {Object} marker 运动的物体 + */ + startRouteAnimation(route, lineStyleOptions, markerStyleOptions, padding = []) { + // 清理上次的动画 + this.stopRouteAnimation() + + // 清理动画图层 + this.removeAnimationFeatures() + + const lineString = new LineString(route.map((item) => fromLonLat(item))) + const extent = lineString.getExtent() + this.view.fit(extent, { + padding, + duration: 1000, + }) + + // 创建轨迹线 + const routeFeature = new Feature({ + geometry: lineString, + }) + + // 设置轨迹线样式,并添加到地图上 + routeFeature.setStyle(new Style(lineStyleOptions)) + this.animationSource.addFeature(routeFeature) + + // 创建标记物,并设置位置到轨迹路线的初始位置 + const markerFeature = new Feature({ + geometry: new Point(lineString.getFirstCoordinate()), + }) + + // 设置标记物样式,并添加到地图上 + markerFeature.setStyle(new Style(markerStyleOptions)) + this.animationSource.addFeature(markerFeature) + + let lastTime = Date.now(), + distance = 0 + this.postRenderCallback = (event) => { + const speed = 60 + const time = event.frameState.time + const elapsedTime = time - lastTime + distance = (distance + (speed * elapsedTime) / 1e6) % 2 + lastTime = time + + if (distance >= 1) { + this.stopRouteAnimation() + return + } + + const currentCoordinate = lineString.getCoordinateAt(distance > 1 ? 2 - distance : distance) + markerFeature.setGeometry(new Point(currentCoordinate)) + + // tell OpenLayers to continue the postrender animation + this.map.render() + } + + this.animationLayer.on('postrender', this.postRenderCallback) + }, + + // 移除动画层所有元素 + removeAnimationFeatures() { + this.animationSource.clear() + }, + + // 停止轨迹动画 + stopRouteAnimation() { + if (this.postRenderCallback) { + this.animationLayer.un('postrender', this.postRenderCallback) + this.postRenderCallback = null + } + }, }, } diff --git a/src/views/stationOperation/components/MapPane.vue b/src/views/stationOperation/components/MapPane.vue index 907df4a..6a3a189 100644 --- a/src/views/stationOperation/components/MapPane.vue +++ b/src/views/stationOperation/components/MapPane.vue @@ -32,6 +32,14 @@ /> +
+ + +
@@ -149,6 +157,41 @@
+ + +
+
Route
+
+
+
Station
+ +
+
+
Start Date
+ +
+
+
End Date
+ +
+
+ Search +
+
+
+ @@ -274,6 +317,7 @@ import { MarkerType, FilterIcon } from './markerEnum' import { Vector as VectorLayer } from 'ol/layer' import VectorSource from 'ol/source/Vector' import { cloneDeep } from 'lodash' +import dayjs from 'dayjs' // Filter中的筛选列表 const filterList = [ @@ -393,10 +437,13 @@ export default { type: Number, default: 500, }, - treeData: { type: Array, }, + originalDataList: { + type: Array, + default: () => [], + }, }, components: { CustomModal, @@ -445,6 +492,14 @@ export default { stationInfo: undefined, mapSource: 'online', + + routeParams: { + stationCode: undefined, + startDate: dayjs().subtract(7, 'd').format('YYYY-MM-DD'), + endDate: dayjs().format('YYYY-MM-DD'), + }, + + isSearchingRoute: false, } }, created() { @@ -492,18 +547,33 @@ export default { // 面板改变 onPaneChange(active) { this.showPane = true + this.prevPane = this.active // 记录上次是哪个面板 this.active = active const source = this.circleLayer.getSource() source.clear() // 清理图层 - switch (active) { - case 1: // 核设施查询面板 + + // 如果切换到轨迹绘制页面,则使用上一次的轨迹先绘制一遍 + if (active == 3) { + if (this.lastRoute) { + this.$emit('drawRoute', this.lastRoute) + } + + this.$emit('changeMarker', []) + } else { + // 如果是从轨迹绘制切换到其他页面 + if (this.prevPane == 3) { + this.$emit('drawRoute', []) + } + + if (active == 1) { this.emitDrawCircle(2) this.emitStationChange() - break - case 2: // 筛选面板 + } + + if (active == 2) { this.emitDrawCircle(1) this.emitFilter() - break + } } }, @@ -822,6 +892,39 @@ export default { handleResize() { this.$refs.realtimeChartRef.resize() }, + + // 查询路径 + async handleRouteSearch() { + if (!this.routeParams.stationCode) { + this.$message.warn('Station Code Cannot Be Null') + return + } + + this.isSearchingRoute = true + + try { + const { success, result, message } = await getAction('/stationOperation/getSelfStationGPS', { + ...this.routeParams, + }) + + if (success) { + if (!result.length) { + this.$message.warn('No Route Found') + return + } + + this.lastRoute = result.map(({ lon, lat }) => [lon, lat]) + + this.$emit('drawRoute', this.lastRoute) + } else { + this.$message.error(message) + } + } catch (e) { + console.error(e) + } finally { + this.isSearchingRoute = false + } + }, }, watch: { async dataStatusModalVisible(val) { @@ -840,6 +943,16 @@ export default { } }, }, + computed: { + stationSelectOptions() { + return this.originalDataList + .filter(({ stationType }) => stationType == 'Car') + .map(({ stationName: label }) => ({ + label, + value: label, + })) + }, + }, }