<template>
|
<div style="height:100%">
|
<div id="container" style="width:100%;height:100%" />
|
|
<div class="top">
|
<span
|
v-for="(item, index) in params"
|
:key="index"
|
class="left"
|
:class="{ click: changeColor == index }"
|
@click="change(index)"
|
>{{ item }}</span>
|
<div style="float:right">
|
<el-radio-group v-model="dateRadio" size="small" style="margin-left:20px">
|
<el-radio-button label="小时" />
|
<el-radio-button label="日报" />
|
<el-radio-button label="月报" />
|
<el-radio-button label="自定义" />
|
</el-radio-group>
|
<!-- <component :is="dataType" :value="currentTimeD" :class="{'w160':w160,'w400':w400}" style="padding-left:0;margin-left:10px" @sendPickerChild="showPickerChild" /> -->
|
<TimePicker1 v-if="dataType==='TimePicker1'" :input-size="inputSize" :value1="currentHourD" :class="{'w160':w160,}" @sendPickerChild="showPickerChild" />
|
<TimePicker v-else-if="dataType==='TimePicker'" :value1="currentDayD" :class="{'w160':w160,}" @sendPickerChild="showPickerChild" />
|
<DatePicker v-else-if="dataType==='DatePicker'" :value1="currentMonthD" :class="{'w160':w160,}" @sendPickerChild="showPickerChild" />
|
<CustomPicker1 v-else :value1="currentTimeD" :class="{'w400':w400,}" @sendPickerChild="showPickerChild" />
|
<el-button type="primary" @click="clickGetData()">查询</el-button>
|
</div>
|
</div>
|
<!-- <baidu-map id="main" style="width:100%;height:100%" /> -->
|
</div>
|
</template>
|
|
<script>
|
// import 'leaflet/dist/leaflet.css'
|
// import L from 'leaflet'
|
import $ from 'jquery'
|
import * as echarts from 'echarts'
|
import 'echarts/extension/bmap/bmap'
|
import { kriging } from '@/utils/kriging.js'
|
import { getToken } from '@/utils/auth'
|
import DatePicker from '@/components/Form/DatePicker'
|
import TimePicker from '@/components/Form/TimePicker'
|
import TimePicker1 from '@/components/Form/TimePicker1'
|
import CustomPicker1 from '@/components/Form/CustomPicker1'
|
export default {
|
components: {
|
DatePicker,
|
TimePicker,
|
CustomPicker1,
|
TimePicker1
|
},
|
data() {
|
return {
|
map: null,
|
cellSizeCoord: [],
|
latExtent: [],
|
lngExtent: [],
|
response: null,
|
pointsData: [],
|
extentData: [],
|
valuesData: [],
|
params: [
|
'PM10',
|
'PM2.5',
|
'SO2',
|
'NO2',
|
'CO',
|
'O3',
|
'TVOC'
|
],
|
changeColor: 0,
|
sensorKey: 'a34002',
|
currentDate: '',
|
dataType: 'TimePicker1',
|
dateRadio: '小时',
|
unit: 'hourly',
|
w160: true,
|
w400: false,
|
currentHourD: '',
|
currentDayD: '',
|
currentMonthD: '',
|
currentTimeD: [],
|
inputSize: 'small',
|
resTimes: 0
|
}
|
},
|
watch: {
|
// 日期切换组件
|
dateRadio(nv, ov) {
|
this.w160 = true
|
this.w400 = false
|
console.log(nv)
|
if (nv === '小时') {
|
this.dataType = 'TimePicker1'
|
this.unit = 'hourly'
|
this.currentHour()
|
} else if (nv === '日报') {
|
this.dataType = 'TimePicker'
|
this.unit = 'daily'
|
this.currentDay()
|
} else if (nv === '月报') {
|
this.dataType = 'DatePicker'
|
this.unit = 'monthly'
|
this.currentMonth()
|
} else {
|
this.dataType = 'CustomPicker1'
|
this.unit = 'custom'
|
this.w160 = !this.w160
|
this.w400 = !this.w400
|
this.currentTime()
|
}
|
}
|
},
|
mounted() {
|
this.$nextTick(() => {
|
this.clickGetData()
|
})
|
},
|
beforeDestroy() {
|
this.map && this.map.destroy()
|
},
|
created() {
|
this.currentHour()
|
},
|
methods: {
|
// 获得子组件时间选择器传递的数据
|
showPickerChild(data) {
|
if (typeof data === Array) {
|
this.currentTimeD = data
|
} else {
|
this.currentHourD = data
|
this.currentDayD = data
|
this.currentMonthD = data
|
}
|
this.currentDate = data
|
console.log('当前日期' + this.currentDate)
|
},
|
clickGetData() {
|
this.getData().then(() => {
|
console.log('this.CustomPicker1')
|
console.log(this.dataType)
|
if (this.dataType === 'CustomPicker1') {
|
setInterval(() => {
|
this.initMap()
|
console.log('执行播放')
|
}, 2000)
|
} else {
|
console.log('执行单条')
|
this.initMap()
|
}
|
})
|
},
|
getData() {
|
if (this.map) {
|
console.log('初始化map对象')
|
this.map = null
|
this.pointsData = []
|
this.valuesData = []
|
}
|
console.log(this.currentDate)
|
console.log('this.currentDate')
|
return this.$axios.get('http://192.168.0.25:8081/chart/getThermodynamicDiagramDataByCondition', {
|
params: {
|
// organization_id: this.$store.state.orgId,
|
organization_id: 44,
|
sensor_code: this.sensorKey,
|
type: this.unit,
|
time: typeof this.currentDate === 'string' ? this.currentDate : null,
|
startTime: typeof this.currentDate === 'string' ? null : this.currentDate[0],
|
endTime: typeof this.currentDate === 'string' ? null : this.currentDate[1]
|
},
|
headers: {
|
'token': getToken()
|
}
|
})
|
.then((res) => {
|
console.log('getThermodynamicDiagramDataByCondition')
|
console.log(res)
|
var response = res.data.data
|
console.log(response instanceof Array)
|
if (response instanceof Array) {
|
this.response = res.data.data[this.resTimes]
|
this.resTimes += 1
|
console.log('执行第' + this.resTimes + '次')
|
} else {
|
this.response = res.data.data
|
}
|
if (this.response.list.length < 1) {
|
this.$message({
|
message: '当前时间没有数据',
|
type: 'warning'
|
})
|
}
|
console.log('this.response')
|
console.log(this.response)
|
for (let i = 0; i < this.response.list.length; i++) {
|
this.pointsData.push(this.response.list[i].slice(0, 2))
|
this.valuesData.push(this.response.list[i].pop())
|
}
|
console.log(1)
|
}).catch((err) => {
|
console.log(err)
|
console.log(2)
|
})
|
},
|
initMap() {
|
console.log(this.pointsData)
|
console.log(this.valuesData)
|
// 克里金插值数据封装
|
const paramsK = {
|
mapCenter: this.response.centerPoint,
|
maxValue: 100,
|
krigingModel: 'exponential', // model还可选'gaussian','spherical'
|
krigingSigma2: 0,
|
krigingAlpha: 100,
|
canvasAlpha: 0.5, // canvas图层透明度
|
colors: ['#006837', '#1a9850', '#66bd63', '#a6d96a', '#d9ef8b', '#ffffbf', '#fee08b', '#fdae61', '#f46d43', '#d73027', '#a50026']
|
}
|
// 地区范围
|
const points = this.pointsData
|
// 逆时针,左 下 右 上 (观测点最边缘的经纬度)
|
const extent = this.response.bound
|
const values = this.valuesData; const lngs = []; const lats = []
|
const maxValue = this.getMaxMin(values, 'max')
|
const minValue = this.getMaxMin(values, 'min')
|
points.forEach(function(v) {
|
lngs.push(v[0])
|
lats.push(v[1])
|
})
|
// 变差图;取样间隔有关的变分量 //"exponential", 0, 100
|
const variogram = kriging.train(values, lngs, lats, paramsK.krigingModel, paramsK.krigingSigma2, paramsK.krigingAlpha)
|
// 绘制多边形
|
const polygons = []
|
polygons.push([[extent[0], extent[1]], [extent[0], extent[3]], [extent[2], extent[3]], [extent[2], extent[1]]])
|
// 范围经度右-范围经纬左
|
const grid = kriging.grid(polygons, variogram, (extent[2] - extent[0]) / 80)
|
|
const myChart = echarts.init(document.getElementById('container'))
|
// const COLORS = ['#006837', '#1a9850', '#66bd63', '#a6d96a', '#d9ef8b', '#ffffbf', '#fee08b', '#fdae61', '#f46d43', '#d73027', '#a50026']
|
// var COLORS = ['#7e0023', '#99004c', '#ff0000', '#ff7e00', '#ffff00', '#00e400']
|
var COLORS = ['#00e400', '#ffff00', '#ff7e00', '#ff0000', '#99004c', '#7e0023']
|
this.lngExtent = [extent[1], extent[3]]
|
this.latExtent = [extent[0], extent[2]]
|
const cellCount = [grid[0].length, grid.length]
|
// 单元格坐标
|
this.cellSizeCoord = [(this.latExtent[1] - this.latExtent[0]) / cellCount[1], (this.lngExtent[1] - this.lngExtent[0]) / cellCount[0]]
|
const data = []
|
for (let i = 0; i < grid[0].length - 1; i++) { // 宽
|
for (let j = 0; j < grid.length - 1; j++) { // 高
|
const d = [j, i, grid[j][i].toFixed(0)]
|
// let d = [j,i,grid[i][j].toFixed(0)]
|
data.push(d)
|
}
|
}
|
|
let mapStyle
|
this.map = null
|
$.ajaxSettings.async = false // (同步执行) 获取地图样式
|
// $.get('lib/custom_map_config.json', function(data) {
|
// mapStyle = data
|
// })
|
$.ajaxSettings.async = true // (异步执行)
|
var option = {
|
tooltip: {},
|
visualMap: {
|
inverse: true,
|
top: 10,
|
left: 10,
|
min: minValue,
|
max: maxValue,
|
inRange: {
|
color: COLORS,
|
opacity: 0.7
|
}
|
},
|
bmap: {
|
center: this.response.centerPoint,
|
zoom: 14,
|
roam: true,
|
mapStyle: { styleJson: mapStyle }
|
},
|
series: [
|
{
|
type: 'custom',
|
coordinateSystem: 'bmap',
|
renderItem: this.renderItem,
|
animation: false,
|
emphasis: {// 强调
|
itemStyle: {
|
color: 'yellow'
|
}
|
},
|
encode: {
|
tooltip: 2
|
},
|
data: data
|
}
|
]
|
}
|
myChart.setOption(option)
|
|
setTimeout(function() {
|
// getAera()
|
addlabel()
|
})
|
// 这里获取百度地图对象,用这个对象以后可以使用百度地图API操作地图,获取到对象就可以添加标注,设置监听了**
|
this.map = myChart.getModel().getComponent('bmap').getBMap()
|
function addlabel() {
|
// let points=[[115.78919,33.863132],[116.515884,31.765982],
|
// [117.228779,31.826871],[115.807588,32.915904],[116.396301,32.877101]]
|
const pointArray = [
|
new BMap.Point(115.78919, 33.863132),
|
new BMap.Point(116.515884, 31.765982),
|
new BMap.Point(117.228779, 31.826871),
|
new BMap.Point(115.807588, 32.915904),
|
new BMap.Point(116.396301, 32.877101)]
|
const contentArray = ['亳州', '六安', '合肥', '阜阳', '阜阳2']
|
for (let i = 0; i < pointArray.length; i++) {
|
const opts = { position: pointArray[i], offset: new BMap.Size(0, -0) }
|
const label = new BMap.Label(contentArray[i], opts)
|
label.setStyle({
|
color: 'rgba(43, 185, 163)',
|
width: '30px',
|
fontSize: '14px',
|
height: '20px',
|
lineHeight: '20px',
|
fontFamily: '微软雅黑'
|
})
|
this.map.addOverlay(label)
|
}
|
}
|
},
|
/**
|
* 获取数组中的最大值和最小值函数
|
* */
|
getMaxMin(arr, param) {
|
try {
|
if (param == 'max') {
|
if (typeof (Math.max.apply(null, arr)) !== 'number') {
|
return 'Error:element in arr is not a number!'
|
} else {
|
return Math.max.apply(null, arr)
|
}
|
} else if (param == 'min') {
|
if (typeof (Math.min.apply(null, arr)) !== 'number') {
|
return 'Error:element in arr is not a number!'
|
} else {
|
return Math.min.apply(null, arr)
|
}
|
} else {
|
return 'Error:param is unsupported!'
|
}
|
} catch (e) {
|
return 'Error:' + e
|
}
|
},
|
renderItem(params, api) {
|
const lngIndex = api.value(0)
|
const latIndex = api.value(1)
|
const pointLeftTop = this.getCoord(params, api, lngIndex, latIndex)
|
const pointRightBottom = this.getCoord(params, api, lngIndex + 1, latIndex + 1)
|
return {
|
type: 'rect',
|
shape: {
|
x: pointLeftTop[0],
|
y: pointLeftTop[1],
|
width: pointRightBottom[0] - pointLeftTop[0],
|
height: pointRightBottom[1] - pointLeftTop[1]
|
},
|
style: api.style({
|
stroke: 'rgba(0,0,0,0)' // 笔画,网格线
|
}),
|
styleEmphasis: api.styleEmphasis() // 风格强调
|
}
|
},
|
getCoord(params, api, lngIndex, latIndex) {
|
var coords = params.context.coords || (params.context.coords = [])
|
var key = lngIndex + '-' + latIndex
|
|
// bmap returns point in integer, which makes cell width unstable.
|
// 返回整数形式的点,这使得单元格宽度不稳定。
|
// So we have to use right bottom point. 所以我们必须使用正确的底线
|
return coords[key] || (coords[key] = api.coord([+(this.latExtent[0] + lngIndex * this.cellSizeCoord[0]).toFixed(6), +(this.lngExtent[0] + latIndex * this.cellSizeCoord[1]).toFixed(6)
|
]))
|
},
|
|
change(index) {
|
this.changeColor = index
|
var pr = ''
|
switch (index) {
|
case 0: pr = 'a34002'
|
break
|
case 1: pr = 'a34004'
|
break
|
case 2: pr = 'a21026'
|
break
|
case 3: pr = 'a21004'
|
break
|
case 4: pr = 'a21005'
|
break
|
case 5: pr = 'a05024'
|
break
|
case 6: pr = 'a99054'
|
break
|
}
|
this.sensorKey = pr
|
// this.initMap()
|
},
|
// 当前时间份初始化
|
currentHour() {
|
var aData = new Date()
|
var month = aData.getMonth() < 9 ? '0' + (aData.getMonth() + 1) : aData.getMonth() + 1
|
var date = aData.getDate() <= 9 ? '0' + aData.getDate() : aData.getDate()
|
var hour = aData.getHours() <= 9 ? '0' + aData.getHours() - 1 : aData.getHours() - 1
|
var currentDate = aData.getFullYear() + '-' + month + '-' + date + ' ' + hour
|
this.currentHourD = currentDate.toString()
|
this.currentDate = this.currentHourD
|
console.log(323123123123)
|
console.log(currentDate)
|
},
|
// 当日初始化
|
currentDay() {
|
var aData = new Date()
|
var month = aData.getMonth() < 9 ? '0' + (aData.getMonth() + 1) : aData.getMonth() + 1
|
var date = aData.getDate() <= 9 ? '0' + aData.getDate() - 1 : aData.getDate() - 1
|
var currentDate = aData.getFullYear() + '-' + month + '-' + date
|
this.currentDayD = currentDate.toString()
|
this.currentDate = this.currentDayD
|
},
|
// 当月份初始化
|
currentMonth() {
|
var aData = new Date()
|
var month = aData.getMonth() < 9 ? '0' + (aData.getMonth()) : aData.getMonth()
|
var currentDate = aData.getFullYear() + '-' + month
|
this.currentMonthD = currentDate.toString()
|
this.currentDate = this.currentMonthD
|
},
|
// 当前自定义初始化
|
currentTime() {
|
var aData = new Date()
|
var month = aData.getMonth() < 9 ? '0' + (aData.getMonth() + 1) : aData.getMonth() + 1
|
var date = aData.getDate() <= 9 ? '0' + aData.getDate() : aData.getDate()
|
var currentDate = aData.getFullYear() + '-' + month + '-' + date
|
this.currentTimeD = [currentDate, currentDate]
|
this.currentDate = this.currentTimeD
|
}
|
}
|
}
|
</script>
|
|
<style lang="less" scoped>
|
|
#container {
|
margin: 0;
|
padding: 0;
|
width: 100%;
|
height: 100%;
|
}
|
.input-card .btn {
|
margin-right: 1.2rem;
|
width: 9rem;
|
}
|
.top {
|
position: absolute;
|
top: 0;
|
width: 100%;
|
padding: 5px 10px;
|
z-index: 999;
|
/* background: #ccc; */
|
background: rgba(204, 204, 204, 0.5);
|
box-shadow: 1px 1px 5px #666;
|
}
|
.top > .left {
|
padding: 5px 10px;
|
border: 1px solid #aaa;
|
border-right: none;
|
background: #fff;
|
/* border-radius: 3px; */
|
cursor: pointer;
|
font-size: 16px;
|
float: left;
|
margin-top: 4px;
|
-webkit-transform-origin-x: 0;
|
/* -webkit-transform: scale(0.90); */
|
}
|
.top > .left:nth-child(1) {
|
border-radius: 5px 0 0 5px;
|
}
|
.top > .left:nth-last-child(1) {
|
border-radius: 0 5px 5px 0;
|
border-right: 1px solid #aaa;
|
}
|
.top > .left:hover {
|
background: #666;
|
color: #fff;
|
}
|
.click {
|
color: #fff;
|
background-color: #666 !important;
|
}
|
.w160{
|
width: 160px;
|
}
|
.w400{
|
width: 400px;
|
}
|
</style>
|