Merge branch 'master-dev' of http://git.hivekion.com:3000/xiaoguangbin/AnalysisSystemForRadionuclide_vue into master-dev
This commit is contained in:
commit
d8987d28c2
BIN
src/assets/images/station-operation/icon-route-active.png
Normal file
BIN
src/assets/images/station-operation/icon-route-active.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/images/station-operation/icon-route.png
Normal file
BIN
src/assets/images/station-operation/icon-route.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -32,7 +32,9 @@ const sample = {
|
|||
|
||||
REMOVE_SAMPLE_DATA: (state, inputFileName) => {
|
||||
const findIndex = state.sampleList.findIndex(item => item.inputFileName == inputFileName)
|
||||
state.sampleList.splice(findIndex, 1)
|
||||
if(-1 !== findIndex) {
|
||||
state.sampleList.splice(findIndex, 1)
|
||||
}
|
||||
},
|
||||
|
||||
CLEAR_SAMPLE_DATA: (state) => {
|
||||
|
|
|
@ -525,7 +525,10 @@ export default {
|
|||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
this.isLoading = false
|
||||
const isCancel = axios.isCancel(error)
|
||||
if(!isCancel) {
|
||||
this.isLoading = false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -561,6 +564,7 @@ export default {
|
|||
cancelLastRequest() {
|
||||
if (this._cancelToken && typeof this._cancelToken == 'function') {
|
||||
this._cancelToken()
|
||||
this._cancelToken = undefined
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -2058,6 +2062,8 @@ export default {
|
|||
this.handleResetState()
|
||||
const sampleData = await this.$store.dispatch('GET_SAMPLE_DATA', newVal.inputFileName)
|
||||
if (sampleData) {
|
||||
this.cancelLastRequest()
|
||||
this.isLoading = false
|
||||
this.dataProcess(sampleData.data, sampleData.from)
|
||||
} else {
|
||||
if (newVal.sampleId) {
|
||||
|
|
|
@ -11,6 +11,14 @@ import Map from 'ol/Map'
|
|||
import XYZ from 'ol/source/XYZ'
|
||||
import View from 'ol/View'
|
||||
import { fromLonLat } from 'ol/proj'
|
||||
import Stroke from 'ol/style/Stroke'
|
||||
import { MarkerIcon, MarkerType } from './markerEnum'
|
||||
import Icon from 'ol/style/Icon'
|
||||
import VectorSource from 'ol/source/Vector'
|
||||
import VectorLayer from 'ol/layer/Vector'
|
||||
import { LineString, Point } from 'ol/geom'
|
||||
import { Feature } from 'ol'
|
||||
import Style from 'ol/style/Style'
|
||||
|
||||
const mapSourceUrl = process.env.VUE_APP_MAP_BASE_URL
|
||||
export default {
|
||||
|
@ -57,21 +65,29 @@ export default {
|
|||
}),
|
||||
})
|
||||
|
||||
const layers = [this.tileLayer]
|
||||
this.animationSource = new VectorSource({
|
||||
features: [],
|
||||
})
|
||||
|
||||
const view = new View({
|
||||
this.animationLayer = new VectorLayer({
|
||||
source: this.animationSource,
|
||||
})
|
||||
|
||||
const layers = [this.tileLayer, this.animationLayer]
|
||||
|
||||
this.view = new View({
|
||||
projection: 'EPSG:3857', // 使用这个坐标系
|
||||
center: fromLonLat([longitude, latitude]),
|
||||
zoom: this.zoom,
|
||||
maxZoom: this.maxZoom,
|
||||
minZoom: this.minZoom,
|
||||
extent: [-20037508.34 - 3500000, -20037508.34 , 20037508.34 + 3500000, 20037508.34],
|
||||
extent: [-20037508.34 - 3500000, -20037508.34, 20037508.34 + 3500000, 20037508.34],
|
||||
})
|
||||
|
||||
this.map = new Map({
|
||||
target: this.$refs.mapContainerRef,
|
||||
layers,
|
||||
view,
|
||||
view: this.view,
|
||||
controls: [],
|
||||
})
|
||||
},
|
||||
|
@ -120,6 +136,110 @@ export default {
|
|||
})
|
||||
)
|
||||
},
|
||||
|
||||
// 按路线运动
|
||||
animateByRoute(coordinates) {
|
||||
if (!coordinates) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!coordinates.length) {
|
||||
this.stopRouteAnimation()
|
||||
this.removeAnimationFeatures()
|
||||
return
|
||||
}
|
||||
|
||||
this.startRouteAnimation(
|
||||
coordinates,
|
||||
{
|
||||
stroke: new Stroke({
|
||||
color: '#17f85c',
|
||||
lineDash: [6],
|
||||
width: 2,
|
||||
}),
|
||||
},
|
||||
{
|
||||
image: new Icon({
|
||||
src: MarkerIcon[MarkerType.Car],
|
||||
anchor: [0.65, 0.5],
|
||||
}),
|
||||
},
|
||||
[100, 430, 100, 450]
|
||||
)
|
||||
},
|
||||
/**
|
||||
* 沿轨迹运动
|
||||
* @param {Array<any>} 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
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -32,6 +32,14 @@
|
|||
/>
|
||||
<img v-else src="@/assets/images/station-operation/filter-station.png" @click="onPaneChange(2)" />
|
||||
</div>
|
||||
<div title="Route">
|
||||
<img
|
||||
v-if="active == 3 && showPane"
|
||||
src="@/assets/images/station-operation/icon-route-active.png"
|
||||
@click="showPane = !showPane"
|
||||
/>
|
||||
<img v-else src="@/assets/images/station-operation/icon-route.png" @click="onPaneChange(3)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="map-pane-operators-zoom">
|
||||
|
@ -149,6 +157,41 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- 站点筛选结束 -->
|
||||
|
||||
<!-- 路径 -->
|
||||
<div class="route" v-show="active == 3">
|
||||
<div class="map-pane-content-header">Route</div>
|
||||
<div class="map-pane-content-main">
|
||||
<div class="route-form-item">
|
||||
<div class="label">Station</div>
|
||||
<custom-select v-model="routeParams.stationCode" :options="stationSelectOptions"></custom-select>
|
||||
</div>
|
||||
<div class="route-form-item">
|
||||
<div class="label">Start Date</div>
|
||||
<custom-date-picker
|
||||
show-time
|
||||
format="YYYY/MM/DD HH:mm:ss"
|
||||
valueFormat="YYYY/MM/DD HH:mm:ss"
|
||||
v-model="routeParams.startDate"
|
||||
></custom-date-picker>
|
||||
</div>
|
||||
<div class="route-form-item">
|
||||
<div class="label">End Date</div>
|
||||
<custom-date-picker
|
||||
show-time
|
||||
format="YYYY/MM/DD HH:mm:ss"
|
||||
valueFormat="YYYY/MM/DD HH:mm:ss"
|
||||
v-model="routeParams.endDate"
|
||||
></custom-date-picker>
|
||||
</div>
|
||||
<div class="route-form-item">
|
||||
<a-button class="btn" type="primary" :loading="isSearchingRoute" @click="handleRouteSearch"
|
||||
>Search</a-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 路径结束 -->
|
||||
</div>
|
||||
<!-- 主体部分结束 -->
|
||||
|
||||
|
@ -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,
|
||||
}))
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
@ -868,6 +981,8 @@ export default {
|
|||
|
||||
img {
|
||||
cursor: pointer;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
&-main-operator {
|
||||
margin-top: 5px;
|
||||
|
@ -1057,17 +1172,12 @@ export default {
|
|||
}
|
||||
|
||||
.ant-table-thead > tr th {
|
||||
padding-top: 2px !important;
|
||||
padding-bottom: 2px !important;
|
||||
padding-top: 2px 6px !important;
|
||||
}
|
||||
|
||||
.ant-table-tbody .ant-table-row td {
|
||||
padding: 6px !important;
|
||||
}
|
||||
|
||||
.ant-table-placeholder {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1135,6 +1245,27 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 路径
|
||||
.route {
|
||||
pointer-events: all;
|
||||
|
||||
&-form-item {
|
||||
.label {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
margin-top: 50px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 地图右侧操作栏结束
|
||||
|
|
|
@ -152,11 +152,13 @@
|
|||
<MapPane
|
||||
ref="mapPane"
|
||||
:treeData="treeData"
|
||||
:originalDataList="originalDataList"
|
||||
@changeMarker="onChangeMarker"
|
||||
@filterMarker="onFilterMarker"
|
||||
@drawCircle="onDrawCircle"
|
||||
@mapSourceChange="handleMapSourceChange"
|
||||
@focusStationChange="getFollowedStationList"
|
||||
@drawRoute="handleDrawRoute"
|
||||
/>
|
||||
</Map>
|
||||
</div>
|
||||
|
@ -240,6 +242,7 @@ export default {
|
|||
updataFilterType: [],
|
||||
updataFilterDataQuality: [],
|
||||
httpNum: 0,
|
||||
originalDataList: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -546,8 +549,8 @@ export default {
|
|||
// 地图图标点击
|
||||
onMarkerClick(stationInfo) {
|
||||
const { stationType, stationName } = stationInfo
|
||||
const find = this.orgStationList.find(item => item.stationCode == stationName)
|
||||
if(!find) {
|
||||
const find = this.orgStationList.find((item) => item.stationCode == stationName)
|
||||
if (!find) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -577,6 +580,11 @@ export default {
|
|||
getDictSelectTagContainer() {
|
||||
return document.body
|
||||
},
|
||||
|
||||
// 绘制轨迹
|
||||
handleDrawRoute(routes) {
|
||||
this.$refs.mapRef.animateByRoute(routes)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue
Block a user