Leaflet+Echarts实现GIS地图动态播放以及使用Echarts对点位数据详情进行展示

≯℡__Kan透↙ 提交于 2019-12-01 20:46:49

是的,你没看错…我还在发烧中,昨天在众多人的围殴当中我顽强的活了下来。请允许我最后作死一波,因为我知道漂亮的小姐姐个帅气的小哥哥一定都不会和我一般见识的…

效果图大致长得这个德行

小凳子,上代码

<template>
    <div style="width: 100%;height: 100%;">
    </div>
</template>

<script>
    import 'leaflet/dist/leaflet.css'
    import L from 'leaflet'
    import Monitor from './../../../data/request/hbmis/monitor/data'
    import moment from 'moment'
    import Echarts from 'echarts'
    import Aqi from '../../../data/request/hbmis/aqi/aqi'
    import WebGis from '../../../data/request/hbmis/monitor/webgis'

    import geoJson from '../overview/data/130000'
    import GeoCity from '../../../../static/js/city'
    import GeoCounty from '../../../../static/js/county'

    export default {
        props: {
            options: {
                type: Object,
                default() {
                    return {}
                }
            },
            point: {
                type: Object,
                default() {
                    return {}
                }
            },
            isPoint: {
                type: Boolean,
                default: true
            },
            isBasic: {
                type: Boolean,
                default: false
            },
            mapType: {
                type: String,
                default: 'city'
            },
            type: {
                type: String,
                default: 'hour'
            }
        },
        data() {
            return {
                map: null,
                layerGroup: null,
                layerGroupArr: [],
                layerControl: null,
                markerGroup: null,
                circle: null,
                center: [38.920469, 117.110617],
                geoJsonData: null,
                // 当前图层
                curBasic: null,
                curName: null,
                curCity: null,
                curCounty: null,
                curRound: null,
                curLayer: null,
                curPoint: null,
                curZoom: 7,
                // 查询参数
                params: {
                    dataType: 2,
                    starttime: '',
                    endtime: '',
                    ptids: ''
                },
                currentData: {},
                // 柱状图对象
                myCharts: null,
                // 趋势图配置项
                chartOptions: {
                    tooltip: {
                        trigger: 'axis'
                    },
                    grid: {
                        left: '1%',
                        right: '4%',
                        bottom: '1%',
                        top: '4%',
                        containLabel: true
                    },
                    xAxis: [
                        {
                            type: 'category',
                            data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
                            splitLine: {
                                show: false
                            },
                            axisTick: {
                                alignWithLabel: true
                            }
                        }
                    ],
                    yAxis: [
                        {
                            type: 'value',
                            splitLine: {
                                show: false
                            },
                            splitArea: {
                                show: true,
                            },
                        }
                    ],
                    series: [
                        {
                            name: 'AQI',
                            type: 'bar',
                            itemStyle: {
                                normal: {
                                    color: (d) => {
                                        return this.format_cur_color(d.data)
                                    }
                                }
                            },
                            data: [32.6, 25.9, 39.0, 26.4, 28.7, 70.7, 75.6, 82.2, 48.7, 58.8, 16.0, 32.3],
                        }
                    ]
                }
            }
        },
        watch: {
            options() {
                this.loadData(this.options)
                this.load_point(this.point)
                if (this.isBasic) {
                    if (this.mapType == 'city') {
                        this.load_city()
                    }
                    if (this.mapType == 'county') {
                        this.load_county()
                    }
                } else {
                    if (this.curCity instanceof Object) {
                        this.curCity.remove()
                    }
                    if (this.curCounty instanceof Object) {
                        this.curCounty.remove()
                    }
                }
            },
            point() {
                // this.load_point(this.point)
            },
            isPoint() {
                if (this.isPoint) {
                    this.load_point(this.point)
                } else {
                    if (this.curPoint instanceof Object) {
                        this.curPoint.remove()
                    }
                }
            },
            isBasic() {
                if (!this.isBasic) {
                    this.load_basic()
                    this.load_name()
                    if (this.curCity instanceof Object) {
                        this.curCity.remove()
                    }
                    if (this.curCounty instanceof Object) {
                        this.curCounty.remove()
                    }
                } else {
                    if (this.curBasic instanceof Object) {
                        this.curBasic.remove()
                    }
                    if (this.curName instanceof Object) {
                        this.curName.remove()
                    }
                    if (this.mapType == 'city') {
                        this.load_city()
                    }
                    if (this.mapType == 'county') {
                        this.load_county()
                    }

                }
            },
            mapType() {
                if (this.curCity instanceof Object) {
                    this.curCity.remove()
                }
                if (this.curCounty instanceof Object) {
                    this.curCounty.remove()
                }
                if (this.mapType == 'city') {
                    this.load_city()
                }
                if (this.mapType == 'county') {
                    this.load_county()
                }
            },
            type() {
                if (this.type == 'hour') {
                    this.params.dataType = 2
                }
                if (this.type == 'day') {
                    this.params.dataType = 3
                }
                if (this.type == 'month') {
                    this.params.dataType = 5
                }
                if (this.type == 'year') {
                    this.params.dataType = 8
                }
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            // 加载底图
            load_basic() {
                if (!this.map || this.options == '') return
                if (this.curBasic && this.curBasic instanceof Object) {
                    this.curBasic.remove()
                    this.map.removeLayer(this.curBasic)
                    this.curBasic = null
                }
                this.curBasic = L.tileLayer('http://t{s}.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}', {
                    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
                }).addTo(this.map)
            },
            // 加载城市名称
            load_name() {
                if (!this.map || this.options == '') return
                if (this.curName && this.curName instanceof Object) {
                    this.curName.remove()
                    this.map.removeLayer(this.curName)
                    this.curName = null
                }
                this.curName = L.tileLayer('http://t{s}.tianditu.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}', {
                    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                    zIndex: 201
                }).addTo(this.map)
            },
            // 加载城市GEOJSON数据
            load_city() {
                if (!this.map || this.options == '') return
                if (this.curCity && this.curCity instanceof Object) {
                    this.curCity.remove()
                    this.map.removeLayer(this.curCity)
                    this.curCity = null
                }
                this.curCity = L.geoJSON(GeoCity, {
                    style(feature) {
                        return {
                            color: 'gray',
                            fill: false,
                            fillOpacity: 0,
                            weight: 1
                        }
                    }
                }).addTo(this.map);
            },
            // 加载区县GEOJSON数据
            load_county() {
                if (!this.map || this.options == '') return
                if (this.curCounty && this.curCounty instanceof Object) {
                    this.curCounty.remove()
                    this.map.removeLayer(this.curCounty)
                    this.curCounty = null
                }
                this.curCounty = L.geoJSON(GeoCounty, {
                    style() {
                        return {
                            color: 'gray',
                            fill: false,
                            fillOpacity: 0,
                            weight: 1
                        }
                    },
                }).addTo(this.map);
            },
            // 加载省市边界数据
            load_round(data) {
                if (this.curRound && this.curRound instanceof Object) {
                    this.curRound.remove()
                    this.map.removeLayer(this.curRound)
                    this.curRound = null
                }
                this.curRound = L.geoJSON(data, {
                    style() {
                        return {
                            color: 'gray',
                            fill: false,
                            weight: 2,
                            fillOpacity: 0
                        }
                    },
                }).addTo(this.map);
            },
            // 加载插值数据
            loadData(data) {
                if (!this.map || this.options == '') return
                if (this.curLayer && this.curLayer instanceof Object) {
                    this.curLayer.remove()
                    this.map.removeLayer(this.curLayer)
                    this.curLayer = null
                }
                this.curLayer = L.geoJSON(data, {
                    style(feature) {
                        let lvalue = feature.properties.lvalue,
                            color = '#EFEFEF'
                        if (lvalue >= 0 && lvalue < 51) {
                            color = 'rgba(0, 288, 0, 1)'
                        } else if (lvalue >= 51 && lvalue < 101) {
                            color = 'rgba(255, 255, 0, 1)'
                        } else if (lvalue >= 101 && lvalue < 151) {
                            color = 'rgba(255, 126, 0, 1)'
                        } else if (lvalue >= 151 && lvalue < 201) {
                            color = 'rgba(255, 0, 0, 1)'
                        } else if (lvalue >= 201 && lvalue < 301) {
                            color = 'rgba(153, 0, 76, 1)'
                        } else if (lvalue >= 301 && lvalue <= 500) {
                            color = 'rgba(126, 0, 35, 1)'
                        }
                        return {
                            color: 'blue',
                            fillColor: color,
                            weight: 1,
                            opacity: 0,
                            fillOpacity: 0.8
                        }
                    }
                }).addTo(this.map)
            },
            // 加载站点
            load_point(data) {
                let _this = this
                if (!this.map || this.options == '' || !this.isPoint) return
                if (this.curPoint && this.curPoint instanceof Object) {
                    this.curPoint.remove()
                    this.map.removeLayer(this.curPoint)
                    this.curPoint = null
                }
                this.curPoint = L.geoJSON(data, {
                    pointToLayer(geoJsonPoint, latlng) {
                        let cvalue = geoJsonPoint.properties.value
                        let curMark = _this.icon_create(cvalue, latlng, _this.curZoom)

                        let mValue = geoJsonPoint.properties

                        curMark.on('click', function () {
                            // curMark.openPopup()
                            _this.params.ptids = mValue.ptid
                            _this.params.starttime = mValue.datatime
                            _this.params.endtime = mValue.datatime
                            _this.get_dataList(function () {
                                let randomId = Math.floor(Math.random() * 1000)
                                let phtml = _this.popup_create(_this.currentData, randomId, _this.params.dataType)
                                console.log(randomId, 0)
                                curMark.bindPopup(phtml).openPopup()

                                _this.get_pointer_trend(randomId)
                            })

                        })

                        return curMark
                    }
                }).addTo(this.map)
            },
            init() {
                let _this = this
                let normal1 = L.tileLayer('http://t{s}.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}', {
                    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
                })
                let normal2 = L.tileLayer('http://t{s}.tianditu.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}', {
                    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
                })
                let normal = [
                    // L.layerGroup([normal1]),
                    // L.layerGroup([normal2])
                ]
                this.map = L.map(_this.$el, {
                    center: _this.center,
                    zoom: 7,
                    minZoom: 6,
                    maxZoom: 12,
                    layers: normal,
                })

                // 事件绑定
                this.map_event()

                this.load_basic()
                this.load_name()
            },
            // 监听地图缩放
            map_event() {
                this.map.on('zoom ', (val) => {
                    console.log(val.target._zoom)
                    this.curZoom = val.target._zoom
                    this.load_point(this.point)
                })
                this.map.on('move', () => {
                    this.$emit('move')
                })
            },
            // icon生成器
            icon_create(value, latlng, zoom) {
                let myMark = ''
                let myIcon = ''
                let iconStr = 'level-0'

                if (value >= 0 && value < 51) {
                    iconStr = 'level-1'
                } else if (value >= 51 && value < 101) {
                    iconStr = 'level-2'
                } else if (value >= 101 && value < 151) {
                    iconStr = 'level-3'
                } else if (value >= 151 && value < 201) {
                    iconStr = 'level-4'
                } else if (value >= 201 && value < 301) {
                    iconStr = 'level-5'
                } else if (value >= 301 && value <= 500) {
                    iconStr = 'level-6'
                }
                if (zoom > 8) {
                    myIcon = L.divIcon({
                        html: `<div class="leaflet-icon-custom leaflet-icon-big leaflet-icon-${iconStr}">${value}</div>`,
                        bgPos: [0, 0],
                        className: 'leaflet-icon-custom-reset'
                    })
                    myMark = L.marker(latlng, {
                        icon: myIcon,
                        iconSize: [24, 24]
                    })
                } else {
                    myIcon = L.divIcon({
                        html: `<div class="leaflet-icon-custom leaflet-icon-small leaflet-icon-${iconStr}"></div>`,
                        bgPos: [0, 0],
                        className: 'leaflet-icon-custom-reset'
                    })
                    myMark = L.marker(latlng, {
                        icon: myIcon,
                        iconSize: [8, 8]
                    })
                }
                return myMark
            },
            // popup生成器
            popup_create(value, id, type) {
                let popupStr = ''
                popupStr = `
                    <div class="leaflet-popup-custom">
                        <p class="leaflet-popup-title">
                            <span>站点详情</span>
                        </p>
                        <div class="leaflet-popup-con">
                            <div class="leaflet-popup-abcon">
                                <div class="leaflet-row">
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-name">${value.ptname}</p>
                                    </div>  
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt" style="background:${this.format_cur_color(value.aqi)}">AQI</p>
                                        <p class="leaflet-popup-value">${value.aqi}</p>
                                    </div>  
                                </div>
                                <div class="leaflet-row">
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt" style="background:${this.format_cur_color(value.iaqi_448A)}">PM2.5</p>
                                        <p class="leaflet-popup-value">${value.iaqi_448A}</p>
                                    </div>
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt" style="background:${this.format_cur_color(value.iaqi_4486)}">PM10</p>
                                        <p class="leaflet-popup-value">${value.iaqi_4486}</p>
                                    </div>
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt" style="background:${this.format_cur_color(value.iaqi_4402)}">SO2</p>
                                        <p class="leaflet-popup-value">${value.iaqi_4402}</p>
                                    </div>
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt" style="background:${this.format_cur_color(value.iaqi_4467)}">NO2</p>
                                        <p class="leaflet-popup-value">${value.iaqi_4467}</p>
                                    </div>
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt" style="background:${this.format_cur_color(value.iaqi_4404)}">CO</p>
                                        <p class="leaflet-popup-value">${value.iaqi_4404}</p>
                                    </div>
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt" style="background:${this.format_cur_color(type == 2 ? value.iaqi_4471 : value.iaqi_4D71)}">O3</p>
                                        <p class="leaflet-popup-value">${type == 2 ? value.iaqi_4471 : value.iaqi_4D71}</p>
                                    </div>
                                </div>
                                <div class="leaflet-row">
                                    <div class="leaflet-col-1">
                                        <p class="leaflet-popup-txt">${type == 2 ? '近24小时趋势图' : '近一阶段趋势图'}</p>
                                        <div class="leaflet-popup-chart" id="leaflet-popup-chart-${id}"></div>
                                    </div>  
                                </div>
                            </div>
                        </div>
                        <p class="leaflet-popup-time"><small>更新于:${moment(value.datatime).format('YYYY/MM/DD HH:00')}</small></p>
                    </div>
                `
                return popupStr
            },
            // 获取当前站点小时数据
            get_dataList(fn) {
                let _this = this;
                (async () => {
                    try {
                        let result = await Aqi.station_source_search(this.params)
                        if (result.content && result.content[0]) {
                            this.currentData = result.content[0]
                        }
                        console.log(this.currentData)
                        fn && fn()
                    } catch (error) {
                        let msg = error.message || '数据获取失败'
                        this.$message.error(msg)
                    }
                })()
            },
            // 格式化污染等级样式
            format_cur_color(lvalue) {
                let color = '#EFEFEF'
                if (lvalue >= 0 && lvalue < 51) {
                    color = 'rgba(0, 288, 0, 1)'
                } else if (lvalue >= 51 && lvalue < 101) {
                    color = 'rgba(255, 255, 0, 1)'
                } else if (lvalue >= 101 && lvalue < 151) {
                    color = 'rgba(255, 126, 0, 1)'
                } else if (lvalue >= 151 && lvalue < 201) {
                    color = 'rgba(255, 0, 0, 1)'
                } else if (lvalue >= 201 && lvalue < 301) {
                    color = 'rgba(153, 0, 76, 1)'
                } else if (lvalue >= 301 && lvalue <= 500) {
                    color = 'rgba(126, 0, 35, 1)'
                }
                return color
            },
            // 初始化图表
            init_bar_chart(id) {
                if (this.myCharts && this.myCharts.dispose) {
                    this.myCharts.dispose()
                    this.myCharts = null
                }
                let targetDom = document.getElementById(`leaflet-popup-chart-${id}`)

                this.myCharts = Echarts.init(targetDom)
                this.myCharts.setOption(this.chartOptions)
            },
            // 获取站点趋势图数据
            async get_pointer_trend(id) {

                let _this = this
                let trendParams = {}
                let timeStr = ''

                if (_this.params.dataType == 2) {
                    trendParams.starttime = moment(_this.params.starttime).subtract(24, 'h').format('YYYY-MM-DD HH:00:00')
                    timeStr = 'HH:00'
                } else if (_this.params.dataType == 3) {
                    trendParams.starttime = moment(_this.params.starttime).subtract(30, 'd').format('YYYY-MM-DD HH:00:00')
                    timeStr = 'MM/DD'
                } else if (_this.params.dataType == 5) {
                    trendParams.starttime = moment(_this.params.starttime).subtract(12, 'M').format('YYYY-MM-DD HH:00:00')
                    timeStr = 'YYYY/MM'
                } else if (_this.params.dataType == 8) {
                    trendParams.starttime = moment(_this.params.starttime).subtract(3, 'Y').format('YYYY-MM-DD HH:00:00')
                    timeStr = 'YYYY'
                }
                trendParams.endtime = _this.params.endtime
                trendParams.dataType = _this.params.dataType
                trendParams.ptids = _this.params.ptids

                    try {
                        let result = await WebGis.get_gisdata_trend(trendParams)
                        _this.chartOptions.series[0].data = result.data.series[0].data
                        _this.chartOptions.xAxis[0].data = result.data.xAxis.map((m) => {
                            return moment(m).format(timeStr)
                        })
                        _this.init_bar_chart(id)
                    } catch (error) {
                        let msg = error.message || '数据获取失败'
                        this.$message.error(msg)
                    }
            },
        }
    }
</script>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!