<template>
|
<div
|
ref="content"
|
class="content"
|
>
|
<div class="formInBox ">
|
<el-form
|
:inline="true"
|
:model="formInline"
|
>
|
<el-form-item>
|
<el-radio-group
|
v-model="formInline.pollutant"
|
size="small"
|
@input="getPollutant"
|
>
|
<el-radio-button
|
v-for="item in sensorArr"
|
:key="item.code"
|
:label="item.name"
|
/>
|
</el-radio-group>
|
</el-form-item>
|
<el-form-item>
|
<el-select
|
v-model="orgId"
|
size="small"
|
placeholder="请选择"
|
disabled
|
@change="regionData"
|
>
|
<el-option
|
v-for="item in orgData"
|
:key="item.id"
|
:label="item.name"
|
:value="item.id"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item>
|
<el-radio-group
|
v-model="formInline.dateRadio"
|
size="small"
|
>
|
<el-radio-button label="小时" />
|
<el-radio-button label="天" />
|
<el-radio-button label="月" />
|
</el-radio-group>
|
</el-form-item>
|
<el-form-item>
|
<selectHour
|
:data-type="dataType"
|
@selectHourData="selectHourData"
|
/>
|
</el-form-item>
|
<el-form-item>
|
<el-button
|
type="primary"
|
size="small"
|
@click="onSubmit"
|
>
|
查询
|
</el-button>
|
<el-button
|
type="primary"
|
size="small"
|
@click="download"
|
>
|
截图
|
</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
<div id="mapd" />
|
<div class="timeLine">
|
<div
|
:style="{ background: 'url(' + selectSensor.src + ') no-repeat' }"
|
class="buttomColorLine"
|
/>
|
<Main
|
v-if="dateTimes.length > 0&&formInline.city!==''"
|
:options="options"
|
:date-times="dateTimes"
|
:date-type="formInline.dayType"
|
@getDateFun="getDateFun"
|
/>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import dayjs from 'dayjs'
|
import _ from 'lodash'
|
import selectHour from './components/selectHour.vue'
|
import Main from './components/timeLinePlay.vue'
|
import html2canvas from 'html2canvas'
|
export default {
|
components: { selectHour, Main },
|
data () {
|
return {
|
map: null,
|
heatmap: null,
|
markerClusterer: null,
|
orgData: [],
|
orgId: 71,
|
city: '苏州',
|
formInline: {
|
city: '海城市',
|
cityCode: '210381',
|
dayType: 'hour',
|
starTime: '',
|
endTime: '',
|
dateRadio: '小时',
|
pollutant: 'PM10',
|
},
|
selectSensor: {code: 'a34002',
|
name: 'PM10',
|
maxNumber: 500,
|
src: require('@/assets/images/tl_PM10.png'),
|
gradient: {
|
'0': '#12a112',
|
'0.1': '#12a112',
|
'0.3': '#feff01',
|
'0.5': '#fd8200',
|
'0.7': '#fd0001',
|
'0.84': '#95014b',
|
'1': '#7e0226'
|
}},
|
sensorArr: [
|
{ code: 'a34002',
|
name: 'PM10',
|
maxNumber: 500,
|
src: require('@/assets/images/tl_PM10.png'),
|
gradient: {
|
'0': '#12a112',
|
'0.1': '#12a112',
|
'0.3': '#feff01',
|
'0.5': '#fd8200',
|
'0.7': '#fd0001',
|
'0.84': '#95014b',
|
'1': '#7e0226'
|
}},
|
{ code: 'a34004',
|
name: 'PM2.5',
|
maxNumber: 350,
|
src: require('@/assets/images/tl_PM2.5.png'),
|
gradient: {
|
'0': '#12a112',
|
'0.1': '#12a112',
|
'0.21': '#feff01',
|
'0.32': '#fd8200',
|
'0.42': '#fd0001',
|
'0.71': '#95014b',
|
'1': '#7e0226'
|
} },
|
{ code: 'a21026',
|
name: 'SO2',
|
maxNumber: 1000,
|
src: require('@/assets/images/tl_SO2.png'),
|
gradient: {
|
'0': '#12a112',
|
'0.05': '#12a112',
|
'0.15': '#feff01',
|
'0.47': '#fd8200',
|
'0.8': '#fd0001',
|
'0.9': '#95014b',
|
'1': '#7e0226'
|
} },
|
{ code: 'a21004',
|
name: 'NO2',
|
maxNumber: 750,
|
src: require('@/assets/images/tl_NO2.png'),
|
gradient: {
|
'0': '#12a112',
|
'0.05': '#12a112',
|
'0.1': '#feff01',
|
'0.24': '#fd8200',
|
'0.37': '#fd0001',
|
'0.75': '#95014b',
|
'1': '#7e0226'
|
}},
|
{ code: 'a21005',
|
name: 'CO',
|
maxNumber: 48,
|
src: require('@/assets/images/tl_CO.png'),
|
gradient: {
|
'0.0': '#12a112',
|
'0.04': '#12a112',
|
'0.083': '#feff01',
|
'0.29': '#fd8200',
|
'0.5': '#fd0001',
|
'0.75': '#95014b',
|
'1': '#7e0226'
|
}},
|
{ code: 'a05024',
|
name: 'O3',
|
maxNumber: 1000,
|
src: require('@/assets/images/tl_O3.png'),
|
gradient: {
|
'0': '#12a112',
|
'0.16': '#12a112',
|
'0.2': '#feff01',
|
'0.3': '#fd8200',
|
'0.4': '#fd0001',
|
'0.8': '#95014b',
|
'1': '#7e0226'
|
} },
|
{ code: 'a99054',
|
name: 'TVOC',
|
maxNumber: 4,
|
src: require('@/assets/images/tl_TVOCNew.png'),
|
gradient: {
|
'0': '#12a112',
|
'0.12': '#12a112',
|
'0.25': '#feff01',
|
'0.375': '#fd8200',
|
'0.5': '#fd0001',
|
'0.75': '#95014b',
|
'1': '#7e0226'
|
}}
|
],
|
heatMapData: [],
|
dataType: 'datetimerange',
|
options: {
|
speed: 2
|
},
|
polygon: null,
|
dateTimes: [],
|
activeItem: {},
|
markerList: []
|
}
|
},
|
watch: {
|
'formInline.dateRadio': {
|
handler: function (newVal, oldVal) {
|
if (newVal === '小时') {
|
this.dataType = 'datetimerange'
|
this.formInline.dayType = 'hour'
|
this.dateTimes = []
|
} else if (newVal === '天') {
|
this.dataType = 'daterange'
|
this.dateTimes = []
|
this.formInline.dayType = 'day'
|
} else if (newVal === '月') {
|
this.dataType = 'monthrange'
|
this.dateTimes = []
|
this.formInline.dayType = 'month'
|
}
|
},
|
deep: true
|
},
|
'formInline.city': {
|
handler: function (newVal, oldVal) {
|
console.log('newVal', newVal === '')
|
if (newVal !== '') {
|
this.init1()
|
if (!!this.formInline.starTime && !!this.formInline.endTime) {
|
this.onSubmit()
|
}
|
}
|
},
|
deep: true
|
},
|
activeItem: {
|
handler (newVal, oldVal) {
|
if (this.markerList.length > 0) {
|
console.log('2222', this.map.getAllOverlays('marker'))
|
this.map.remove(this.markerList)
|
this.markerList = []
|
// this.markerClusterer = null
|
}
|
this.getData(newVal.name)
|
},
|
deep: true
|
}
|
},
|
mounted () {
|
let dataTime = dayjs().format('YYYY-MM-DD')
|
this.getOrganizationId()
|
this.getData(`${dataTime} 00`)
|
this.$nextTick(() => {
|
this.initMap()
|
this.createHeatMap()
|
})
|
},
|
|
destroyed () {
|
if (this.map) {
|
this.map.destroy()
|
}
|
},
|
methods: {
|
download () {
|
const ref = this.$refs.content // 截图区域
|
html2canvas(ref, {
|
backgroundColor: '#e8f4ff',
|
useCORS: true // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
|
}).then((canvas) => {
|
const dataURL = canvas.toDataURL('image/png')
|
const creatDom = document.createElement('a')
|
document.body.appendChild(creatDom)
|
creatDom.href = dataURL
|
creatDom.download = '图片'
|
creatDom.click()
|
})
|
},
|
getDateFun (item) {
|
console.log(item)
|
this.activeItem = item
|
},
|
getPollutant (data) {
|
this.selectSensor = _.find(this.sensorArr, { name: data })
|
this.dateTimes = []
|
if (this.heatmap) {
|
this.map.remove(this.heatmap)
|
this.heatmap = null
|
}
|
console.log('this.heatmap', this.heatmap)
|
},
|
// 初始化地图
|
initMap () {
|
var map = new AMap.Map('mapd', {
|
resizeEnable: true,
|
zooms: [10, 10],
|
zoom: 10,
|
})
|
this.map = map
|
this.init1()
|
// let that = this
|
},
|
init1 () { // 区域遮盖
|
var that = this
|
this.map.setCity(this.formInline.city)
|
console.log('海城', this.formInline.cityCode)
|
if (that.polygon) {
|
that.map.remove(that.polygon)
|
}
|
console.log('that.polygon', that.polygon)
|
AMap.plugin('AMap.DistrictSearch', function () {
|
new AMap.DistrictSearch({
|
extensions: 'all',
|
subdistrict: 0
|
}).search(that.formInline.cityCode, function (status, result) { // 外多边形坐标数组和内多边形坐标数组
|
var outer = [
|
new AMap.LngLat(-360, 90, true),
|
new AMap.LngLat(-360, -90, true),
|
new AMap.LngLat(360, -90, true),
|
new AMap.LngLat(360, 90, true)
|
]
|
var holes = result.districtList[0].boundaries
|
var pathArray = [outer]
|
pathArray.push.apply(pathArray, holes)
|
that.polygon = new AMap.Polygon({
|
pathL: pathArray,
|
strokeColor: 'red', // 城市边界颜色
|
strokeWeight: 3,
|
fillColor: '#ccc', // 遮罩背景色黑色
|
fillOpacity: 1
|
})
|
that.polygon.setPath(pathArray)
|
that.map.add(that.polygon)
|
})
|
})
|
},
|
getData (newVal) {
|
this.$request({
|
url: '/heatMap/query',
|
method: 'get',
|
params: {
|
id: this.orgId,
|
startTime: newVal,
|
type: this.selectSensor.code,
|
form: this.formInline.dayType
|
}
|
})
|
.then(res => {
|
if (res.data !== '0') {
|
if (this.heatmap === null) {
|
this.createHeatMap()
|
}
|
this.heatMapData = []
|
this.heatMapData = res.data
|
this.heatmap.setDataSet({
|
data: this.heatMapData,
|
max: this.selectSensor.maxNumber
|
})
|
console.log('000', this.selectSensor.maxNumber)
|
console.log('1111', this.heatmap.getDataSet())
|
} else {
|
this.heatmap = null
|
}
|
})
|
.catch(err => {
|
console.log(err)
|
})
|
},
|
// 聚合点
|
setMarkers (curData) {
|
curData.forEach((item, index) => {
|
let div = document.createElement('div')
|
let bgColor = 'hsla(180, 100%, 50%, 0.7)'
|
let fontColor = '#000'
|
let borderColor = 'hsl(180, 100%, 40%)'
|
let shadowColor = 'hsl(180, 100%, 50%)'
|
div.id = 'pint' + index
|
div.style.backgroundColor = bgColor
|
let size = 40
|
div.style.width = div.style.height = size + 'px'
|
div.style.border = 'solid 1px ' + borderColor
|
div.style.borderRadius = size / 2 + 'px'
|
div.style.boxShadow = '0 0 1px ' + shadowColor
|
div.innerHTML = Math.floor(Number(item.count))
|
div.style.lineHeight = size + 'px'
|
div.style.color = fontColor
|
div.style.fontSize = '14px'
|
div.style.textAlign = 'center'
|
let marker = new AMap.Marker({
|
position: [item.lng, item.lat],
|
title: item.name,
|
extData: Math.floor(Number(item.count)),
|
anchor: 'center',
|
// 将 html 传给 content
|
content: div,
|
// 以 icon 的 [center bottom] 为原点
|
offset: new AMap.Pixel(3, 10)
|
})
|
this.markerList.push(marker)
|
})
|
this.map.add(this.markerList)
|
var count = this.markerList.length
|
// eslint-disable-next-line no-new
|
if (this.markerClusterer) {
|
this.markerClusterer.clearMarkers()
|
}
|
let that = this
|
AMap.plugin('AMap.MarkerClusterer', function () {
|
that.markerClusterer = new AMap.MarkerClusterer(that.map, that.markerList, {
|
gridSize: 100,
|
renderClusterMarker: function (context) {
|
let contNumber = 0
|
context.markers.forEach((item, index) => {
|
console.log('indexitem', index, item.getExtData())
|
contNumber += item.getExtData()
|
})
|
console.log('contNumber', contNumber)
|
let factor = Math.pow(context.count / count, 1 / 18)
|
let div = document.createElement('div')
|
let Hue = 180 - factor * 180
|
let bgColor = 'hsla(' + Hue + ',100%,50%,0.7)'
|
let fontColor = 'hsla(' + Hue + ',100%,20%,1)'
|
let borderColor = 'hsla(' + Hue + ',100%,40%,1)'
|
let shadowColor = 'hsla(' + Hue + ',100%,50%,1)'
|
div.style.backgroundColor = bgColor
|
let size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20)
|
div.style.width = div.style.height = size + 'px'
|
div.style.border = 'solid 1px ' + borderColor
|
div.style.borderRadius = size / 2 + 'px'
|
div.style.boxShadow = '0 0 1px ' + shadowColor
|
div.innerHTML = contNumber
|
div.style.lineHeight = size + 'px'
|
div.style.color = fontColor
|
div.style.fontSize = '14px'
|
div.style.textAlign = 'center'
|
context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2))
|
context.marker.setContent(div)
|
console.log('context.marker----------------', context.marker)
|
}
|
})
|
})
|
},
|
getDayListData () {
|
this.$request({
|
url: '/heatMap/queryTime',
|
method: 'get',
|
params: {
|
type: this.formInline.dayType,
|
startTime: this.formInline.starTime,
|
endTime: this.formInline.endTime,
|
}
|
})
|
.then(res => {
|
this.dateTimes = res.data
|
})
|
.catch(err => {
|
console.log(err)
|
})
|
},
|
getOrganizationId () {
|
this.$request({
|
url: '/organization/getOrganizationId',
|
method: 'get'
|
})
|
.then(res => {
|
this.orgData = res.data
|
})
|
.catch(err => {
|
console.log(err)
|
})
|
},
|
createHeatMap () {
|
let that = this
|
this.map.plugin(['AMap.Heatmap'], function () {
|
// 初始化heatmap对象
|
that.heatmap = new AMap.Heatmap(that.map, {
|
radius: 130, // 给定半径
|
opacity: [0.5, 1],
|
gradient: that.selectSensor.gradient
|
})
|
})
|
},
|
|
onSubmit () {
|
if (!!this.formInline.city && !!this.formInline.starTime && !!this.formInline.endTime) {
|
this.map.clearMap()
|
this.getDayListData()
|
this.getData(this.formInline.starTime)
|
this.init1()
|
// this.map.setZoom(12)
|
} else {
|
this.$message({
|
showClose: true,
|
duration: 2000,
|
message: '请选择区域或者时间!',
|
type: 'error'
|
})
|
}
|
},
|
regionData (id) {
|
let cityData = _.find(this.orgData, { id: id })
|
this.formInline.city = cityData.areaName
|
this.formInline.cityCode = cityData.areaCode
|
},
|
selectHourData (data) {
|
if (data) {
|
this.formInline.starTime = data[0]
|
this.formInline.endTime = data[1]
|
this.getDayListData()
|
} else {
|
this.formInline.starTime = ''
|
this.formInline.endTime = ''
|
}
|
},
|
}
|
}
|
</script>
|
|
<style scoped lang="scss">
|
.content{
|
width: 100%;
|
height: 100%;
|
position: relative;
|
.formInBox{
|
display: flex;
|
justify-content: flex-start;
|
align-items: center;
|
position: absolute;
|
padding: 5px 10px;
|
width: 100%;
|
z-index: 999;
|
background: rgba(204,204,204,0.5);
|
/deep/.el-form-item{
|
margin-bottom: 0px;
|
}
|
}
|
}
|
#mapd {
|
width: 100%;
|
height: 100%;
|
resize: both;
|
z-index: 0;
|
}
|
.timeLine{
|
position: absolute;
|
padding: 5px 10px;
|
bottom: 5px;
|
width: 100%;
|
z-index: 999;
|
.buttomColorLine{
|
height: 50px;
|
}
|
}
|
/deep/.menu-icon {
|
font-size: 20px;
|
width: 30px;
|
height: 30px;
|
background-size: cover;
|
background-repeat: no-repeat;
|
display: inline-block;
|
background-image: url('./components/img/round.png');
|
}
|
/deep/.menu-font{
|
font-size: 16px;
|
text-align: center;
|
max-width: 120px;
|
}
|
/deep/.amap-logo,/deep/.amap-copyright{
|
display: none!important;
|
}
|
</style>
|