<template>
|
<div class="p-events-none m-t-2">
|
<el-row justify="center" align="middle" class="top-wrap">
|
<SearchBar
|
v-show="status == 0"
|
:search-time="searchTime"
|
:loading="loading || thirdPartyLoading"
|
@search="onSearch"
|
></SearchBar>
|
<TrajectoryState v-show="status != 0" :status="status"></TrajectoryState>
|
<!-- <el-button
|
type="primary"
|
class="p-events-auto el-button-custom"
|
@click="handleClick"
|
>
|
分析
|
</el-button> -->
|
</el-row>
|
<el-row class="m-t-2">
|
<FactorRadio
|
:device-type="deviceType"
|
@change="(e) => (factorType = e)"
|
></FactorRadio>
|
</el-row>
|
<el-row class="m-t-2">
|
<FactorLegend
|
class="m-t-2"
|
:factor="factorDatas.factor[factorType]"
|
@change="handleLegendTypeChange"
|
></FactorLegend>
|
<!-- <SourceTrace></SourceTrace> -->
|
</el-row>
|
<el-row class="historical" justify="center">
|
<HistoricalTrajectory
|
:factor-datas="factorDatas"
|
:factor-type="factorType"
|
@change="(e) => (status = e)"
|
@stop="draw"
|
></HistoricalTrajectory>
|
</el-row>
|
<TrendAnalysis
|
class="trend-analysis"
|
:locate-index="locateIndex"
|
@chart-click="handelIndexChange"
|
:factor-datas="factorDatas"
|
:device-type="deviceType"
|
></TrendAnalysis>
|
<DataSheet
|
class="data-sheet"
|
:locate-index="locateIndex"
|
@table-click="handelIndexChange"
|
:factor-datas="factorDatas"
|
:device-type="deviceType"
|
:device-code="deviceCode"
|
></DataSheet>
|
</div>
|
</template>
|
|
<script>
|
import Layer from '@/utils/map/3dLayer';
|
import mapLine from '@/utils/map/line';
|
import marks from '@/utils/map/marks';
|
import sector from '@/utils/map/sector';
|
import mapUtil from '@/utils/map/util';
|
import { DialogUtil } from '@/utils/map/dialog';
|
import { useFetchData } from '@/composables/fetchData';
|
import moment from 'moment';
|
import { TYPE0 } from '@/constant/device-type';
|
import { defaultOptions } from '@/constant/radio-options';
|
import { FactorDatas } from '@/model/FactorDatas';
|
import TrendAnalysis from './component/TrendAnalysis.vue';
|
import DataSheet from './component/DataSheet.vue';
|
import SourceTrace from '@/views/sourcetrace/SourceTrace.vue';
|
import { ElMessage } from 'element-plus';
|
import { fetchHistoryData } from '@/utils/factor/data';
|
import dataAnalysisApi from '@/api/dataAnalysisApi';
|
import thirdPartyDataApi from '@/api/thirdPartyDataApi';
|
import { mapStores } from 'pinia';
|
import { useSceneStore } from '@/stores/scene';
|
|
export default {
|
components: { TrendAnalysis, DataSheet, SourceTrace },
|
setup() {
|
// 限定分页数据量为10000
|
const { loading, fetchData } = useFetchData(10000);
|
return { loading, fetchData };
|
},
|
data() {
|
return {
|
// 监测设备类型
|
deviceType: TYPE0,
|
// 监测设备编号
|
deviceCode: '',
|
// 监测因子的类型编号
|
factorType: defaultOptions(TYPE0).value,
|
// 监测数据
|
factorDatas: new FactorDatas(),
|
// 污染溯源结果
|
pollutionData: undefined,
|
// 决定绘制3D图形时是否与原图像合并
|
merge: false,
|
// 决定绘制完3D图形后地图视角是否自动回中
|
setCenter: true,
|
// 绘制模式,0:自动模式,自动计算当前数据的范围,绘制合适的比例;1:手动模式,根据页面设置的绘图范围进行绘制
|
drawMode: 0,
|
searchTime: [],
|
// 当前选中高亮的数据点索引
|
locateIndex: undefined,
|
// 轨迹动画状态
|
status: 0,
|
// 是否页面已跳转
|
isUnmounted: false,
|
// 第三方数据获取是否尝试
|
isFetchThirdParty: false,
|
thirdPartyLoading: false
|
};
|
},
|
watch: {
|
factorType(nValue, oValue) {
|
if (nValue != oValue && this.status == 0) {
|
Layer.clear();
|
this.draw();
|
// this.drawHighlightPollution();
|
}
|
}
|
},
|
computed: {
|
...mapStores(useSceneStore)
|
},
|
methods: {
|
// 检查数据经纬度是否合法
|
checkDataIsValid(index) {
|
const lnglats_GD = this.factorDatas.lnglats_GD[index];
|
const time = this.factorDatas.times[index];
|
if (lnglats_GD[0] == 0 && lnglats_GD[1] == 0) {
|
ElMessage({
|
message: `${time}的数据经纬度无效`,
|
type: 'warning'
|
});
|
return false;
|
} else {
|
this.locateIndex = index;
|
return true;
|
}
|
},
|
// 监听折线图和表格的点击事件
|
handelIndexChange(index) {
|
if (this.checkDataIsValid(index)) {
|
// 绘制溯源扇形
|
this.drawSector(index);
|
// 查询范围内的监测站点
|
const [lng, lat] = this.factorDatas.lnglats_GD[index];
|
this.sceneStore.searchScene(lng, lat);
|
}
|
},
|
handleLegendTypeChange(value, done) {
|
if (value) {
|
this.factorDatas.resetRange();
|
} else {
|
this.factorDatas.standardRange();
|
}
|
done();
|
this.draw();
|
},
|
draw() {
|
// 刷新图例
|
const factor = this.factorDatas.factor[this.factorType];
|
sector.clearSector();
|
// this.drawRoadLine(factor);
|
this.drawRoadMap(factor);
|
this.drawMassMarks(factor);
|
},
|
// 绘制3D走行路线图
|
drawRoadMap(e) {
|
this.factorDatas.refreshHeight(this.factorType);
|
Layer.drawRoadMap(this.factorDatas, e, this.merge, this.setCenter);
|
},
|
drawRoadLine(e) {
|
this.factorDatas.refreshHeight(this.factorType);
|
mapLine.drawLine(this.factorDatas, e);
|
},
|
drawMassMarks(e) {
|
marks.drawMassMarks(this.factorDatas, e, (index) => {
|
this.handelIndexChange(index);
|
});
|
// 调整地图视角
|
mapUtil.setBound(this.factorDatas.lnglats_GD);
|
},
|
drawSector(index) {
|
// 1. 绘制新扇形区域
|
const pr = sector.drawSector(this.factorDatas, index);
|
// 调整视角居中显示
|
mapUtil.setCenter(pr.p);
|
// mapUtil.setFitSector(pr);
|
// 2. 绘制对话框
|
DialogUtil.openNewWindow(
|
this.deviceType,
|
this.deviceCode,
|
this.factorDatas,
|
index,
|
() => {
|
// 移除扇形区域
|
sector.clearSector();
|
}
|
);
|
},
|
drawHighlightPollution() {
|
this.pollutionData.forEach((e) => {
|
if (this.factorType == e.factorId + '') {
|
const fDatas = this.factorDatas.getByDate(e.startDate, e.endDate);
|
Layer.drawHighLight3DLayer(fDatas, fDatas.factor[this.factorType]);
|
}
|
});
|
},
|
onFetchData(deviceType, data) {
|
if (this.isUnmounted) return;
|
// todo 根据设备类型切换地图监测因子展示单选框、折线图复选框、数据表格复选框的因子类型
|
this.deviceType = deviceType;
|
this.factorDatas.setData(data, this.drawMode, () => {
|
this.factorDatas.refreshHeight(this.factorType);
|
Layer.clear();
|
this.draw();
|
});
|
},
|
onSearch(option) {
|
const { deviceType, deviceCode, timeArray, mission } = option;
|
this.deviceType = deviceType;
|
this.deviceCode = deviceCode;
|
this.mission = mission;
|
let startTime, endTime;
|
if (timeArray && timeArray.length == 2) {
|
startTime = moment(timeArray[0]).format('YYYY-MM-DD HH:mm:ss');
|
endTime = moment(timeArray[1]).format('YYYY-MM-DD HH:mm:ss');
|
}
|
this.fetchData((page, pageSize) => {
|
return fetchHistoryData({
|
deviceType,
|
deviceCode,
|
startTime,
|
endTime,
|
page,
|
perPage: pageSize
|
}).then((res) => {
|
this.onFetchData(deviceType, res.data);
|
if (
|
res.data.length == 0 &&
|
this.isFetchThirdParty != mission.missionCode
|
) {
|
this.onThirdPartyFetch(option);
|
}
|
});
|
});
|
},
|
onThirdPartyFetch(option) {
|
const { mission } = option;
|
if (import.meta.env.VITE_DATA_MODE == 'jingan') {
|
this.thirdPartyLoading = true;
|
this.isFetchThirdParty = mission.missionCode;
|
// 通知服务端启动任务范围内的第三方数据获取任务
|
thirdPartyDataApi
|
.fetchMissionData(mission.missionCode)
|
.then((res) => {
|
if (res.data) {
|
this.onSearch(option);
|
}
|
})
|
.finally(() => (this.thirdPartyLoading = false));
|
}
|
},
|
handleClick() {
|
const { missionCode } = this.mission;
|
dataAnalysisApi.pollutionTrace(missionCode).then((res) => {
|
this.pollutionData = res.data;
|
this.drawHighlightPollution();
|
});
|
}
|
},
|
mounted() {
|
this.isUnmounted = false;
|
},
|
unmounted() {
|
mapUtil.clearMap();
|
this.isUnmounted = true;
|
}
|
};
|
</script>
|
<style scoped>
|
.top-wrap {
|
height: 40px;
|
}
|
|
.trend-analysis {
|
position: absolute;
|
left: 0;
|
bottom: 2px;
|
}
|
|
.data-sheet {
|
position: absolute;
|
right: 0;
|
top: 0;
|
}
|
|
.historical {
|
position: absolute;
|
bottom: 10px;
|
left: 0;
|
right: 0;
|
}
|
</style>
|