2022年6月27日
jeecgboot框架前端vue添加amap组件展示中国地图数据及详细信息
-
- 首先执行 npm i VUEAMAP进行amap组件安装
- src根目录下的main.js文件添加
Vue.use(VueAMap); VueAMap.initAMapApiLoader({ // 高德key key: '99b5478354df37c00ea14301e334c40a', // 自己到官网申请,我随便写的 // 插件集合 (插件按需引入) plugin: [ 'AMap.Geocoder', 'AMap.Autocomplete', // 输入提示插件 'AMap.PlaceSearch', // POI搜索插件 'AMap.Scale', // 右下角缩略图插件 比例尺 'AMap.OverView', // 地图鹰眼插件 'AMap.ToolBar', // 地图工具条 'AMap.MapType', // 类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制 'AMap.PolyEditor', // 编辑 折线多,边形 'AMap.CircleEditor', // 圆形编辑器插件 'AMap.Geolocation', // 定位控件,用来获取和展示用户主机所在的经纬度位置 'AMap.CitySearch', // 定位控件,地图初始化加载定位到当前城市 'AMap.Weather', // 查询目标城市/区域的实时天气状况。 ] })
- demo如下
<template> <div :bordered="false" style="padding: 0px;"> <a-row style="height: 61%;padding-bottom: calc(100vh*10/1080);padding-top:calc(100vh*15/1080)"> <div class="back" ref="mapBack" v-if="mapBackShow" @click="mapBackClick">返 回</div> <div ref="centerChart11" style="height: 100%;width: 100%"/> </a-row> <a-row class="bg_4" style="height: 33%;margin-left:calc(100vw*-42/1920)"> <a-col :span="8"> <a-row style="color:#FFFFFF;padding-left: calc(100vw*39/1920);padding-top: calc(100vh*25/1080);font-size: calc(100vh*20/1080);"> <span>水位实时监控分析</span> </a-row> <a-row> <a-col :span="24" style="padding-top: calc(100vh*60/1080);"> <v-echarts ref="waterLevelChart" :option="waterLevelOption" style="height:100%;"/> </a-col> </a-row> </a-col> </a-row> </div> </template> <script> import '@/assets/less/TableExpand.less' import JSuperQuery from '@/components/jeecg/JSuperQuery.vue' import vEcharts from '@/components/v-echarts' import 'echarts/lib/component/polar' import {graphic} from 'echarts/lib/export' import VueSeamlessScroll from 'vue-seamless-scroll'; import {randomNumber, randomUUID} from '@/utils/util' import { getAction, getFileAccessHttpUrl, postAction } from '@api/manage' import Vue from 'vue'; import echarts from 'echarts'; import main from '../../map/main' import {filterMultiDictText, initDictOptions} from '@/components/dict/JDictSelectUtil' export default { name: '', components: { JSuperQuery, vEcharts, 'vue-seamless-scroll': VueSeamlessScroll,echarts }, data() { return { description: '', screenTitle: '', mapBackShow: false, geoJson: {}, citySimpleList:[], projDataList: [], areaEquipNumList: [], cityCode:100000, map:[], } }, created() { this.$nextTick(() => { this.getMonth(); this.getDays(); that.t = setTimeout(that.time(), 1000); this.loadData(); if(this.t2){ clearInterval(this.t2); } this.t2=setInterval(()=>{ this.loadData(); },1000*60) }) }, computed: { optionSingleHeightTime() { return { singleHeight: 32, waitTime: 2000 } }, importExcelUrl: function () { return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`; }, }, methods: { loadData() { getAction('/btBoardSetting/btBoardSetting/getData',{}).then(res=>{ // 该处为调用后端接口,请自行修改 this.map = res.map this.loadMap() }) }, mapBackClick() { if (this.parentInfo.length == 1) { return } this.parentInfo.pop() this.adCode = this.splitAdCode(this.parentInfo[this.parentInfo.length - 1].code) this.mapLevelCode = this.parentInfo[this.parentInfo.length - 1].level this.cityCode = this.parentInfo[this.parentInfo.length - 1].code this.mapInit(this.parentInfo[this.parentInfo.length - 1].code) this.loadData() if (this.parentInfo.length == 1) { this.mapBackShow = false } }, /****map代码 Start****/ loadMap() { this.geoJson = {}, this.parentInfo = [{ cityName: '全国', code: 100000 }] this.mapInit(100000) }, async mapInit(adcode) { await this.getGeoJson(adcode).then(data => { console.log('adcode:',adcode) for (let i = 0; i < data.features.length; i++) { for (let j = 0; j < this.citySimpleList.length; j++) { if(data.features[i].properties.name == this.citySimpleList[j].title){ data.features[i].properties.name = this.citySimpleList[j].value } } } this.geoJson = data this.getMapData() }) }, //这里我封装了下,直接可以拿过来用 getGeoJson(adcode, childAdcode) { return new Promise((resolve, reject) => { function insideFun(adcode, childAdcode) { AMapUI.loadUI(['geo/DistrictExplorer'], DistrictExplorer => { let districtExplorer = new DistrictExplorer() districtExplorer.loadAreaNode(adcode, function (error, areaNode) { if (error) { reject(error) return } let Json = areaNode.getSubFeatures() if (Json.length === 0) { let parent = areaNode._data.geoData.parent.properties.acroutes insideFun(parent[parent.length - 1], adcode) return } if (childAdcode) { Json = Json.filter(item => { return item.properties.adcode == childAdcode }) } let mapJson = { features: Json } resolve(mapJson) }) }) } insideFun(adcode, childAdcode) }) }, async getMapData() { let that = this let mapData = []; let sum = 0; let equipOnlineNumSum = 0; that.pointData = []; let geoJsonfeatures = that.geoJson.features // 点击地图后会加载下一层数据,但是北京等直辖市下一层是区县,不是城市,所以根据获取到的下一层数据的第一个的level判断当前需要请求的数据时项目个数还是项目详情 this.mapLevelCode = geoJsonfeatures && geoJsonfeatures.length > 0 ? geoJsonfeatures[0].properties.level : ''; console.log('this.adCode:',this.adCode,'this.mapLevelCode:',this.mapLevelCode,'this.mapLevel:',this.mapLevel,'this.equipType:',this.selectEquipType,'this.transformerType:',this.selectTransformerType) if (this.isLoadRandom) { let projInfoList = this.areaEquipNumList if (geoJsonfeatures && geoJsonfeatures.length > 0) { //geoJsonfeatures开始 for (let i = 0; i < geoJsonfeatures.length; i++) { let item = geoJsonfeatures[i] for (let p = 0; p < that.map.length; p++) { console.log(item.properties.name) if (that.map[p].province == item.properties.name) { let name = that.map[p].name; let water_level_warn = that.map[p].water_level_warn; let drainage = that.map[p].drainage; let power_generation = that.map[p].power_generation; let water_quality = that.map[p].water_quality; mapData.push({ name: item.properties.name, value: [name,water_level_warn,drainage,power_generation,water_quality], cityCode: item.properties.adcode, level: item.properties.level }) that.pointData.push({ name: item.properties.name, value: [item.properties.center[0], item.properties.center[1], name,water_level_warn,drainage,power_generation,water_quality], cityCode: item.properties.adcode, level: item.properties.level // 散点图为了控制数据的变化,新增属性random,每隔三秒,random+1 }) } } } } //geoJsonfeatures结束 } if(!this.isLoadRandom){ this.sbzlVal = sum; this.sbzxVal = equipOnlineNumSum; } mapData = mapData.sort(function (a, b) { return b.value - a.value }) that.initEchartMap(mapData, sum, that.pointData) }, //渲染echarts initEchartMap(mapData, sum) { /*if(!mapData || mapData.length==0){ return; }*/ let that = this; let min = 0; let max = 100; if (mapData && mapData.length > 0) { min = mapData[mapData.length - 1].value max = mapData[0].value if (mapData.length === 1) { min = 0; } } //这里做个切换,全国的时候才显示南海诸岛 只有当注册的名字为china的时候才会显示南海诸岛 echarts.registerMap(this.parentInfo.length === 1 ? 'china' : 'map', this.geoJson); let viewText = '设备监控信息'; function addImage(url, params, api, realData) { return { type: 'image', style: { image: url, x: api.coord([ realData[params.dataIndex].lng, realData[params.dataIndex] .lat ])[0], y: api.coord([ realData[params.dataIndex].lng, realData[params.dataIndex].lat ])[1], width: 20, height: 19 } } } this.mapOption = { baseOption: { tooltip: { trigger: 'axis', enterable: true, axisPointer: { type: 'shadow' } }, grid: { left: '5%', top: '12%' // bottom: '0%', // width: '20%' }, geo: { map: this.parentInfo.length === 1 ? 'china' : 'map', // zoom: 1.1, zoom: this.parentInfo.length === 1 ? 1.7 : 1.1, roam: true, // top:'30%', top: this.parentInfo.length === 1 ? '30%' : '10%', tooltip: { trigger: 'item', enterable: true, }, label: { normal: { show: true, color: '#ffffff', //省份标签字体颜色 formatter: p => { switch (p.name) { case '内蒙古自治区': p.name = '内蒙古' break case '西藏自治区': p.name = '西藏' break case '新疆维吾尔自治区': p.name = '新疆' break case '宁夏回族自治区': p.name = '宁夏' break case '广西壮族自治区': p.name = '广西' break case '香港特别行政区': p.name = '香港' break case '澳门特别行政区': p.name = '澳门' break } return p.name } }, }, itemStyle: { normal: { areaColor: { x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: '#0A4FC5' // 0% 处的颜色 }, { offset: 1, color: '#08316E' // 100% 处的颜色 }] }, borderColor: '#1CA1E4', borderWidth: 2 }, emphasis: { areaColor: '#8dd7fc', borderWidth: 1.6, shadowBlur: 25 } } }, series: [ { // name: timeTitle[currentIndex] + '年销售额度', type: 'map', geoIndex: 0, map: this.parentInfo.length === 1 ? 'china' : 'map', roam: true, zoom: 1.4, layoutCenter: ['60%', '50%'], //地图位置 layoutSize: '100%', symbol: 'image://data:images/icon01.png', symbolSize: 20, tooltip: { show:false, position: function (point, params, dom, rect, size) { return [point[0] + 10, point[1] + 10]; }, formatter: function (params) { let val = params.value; if (params.name == '南海诸岛') return if (window.isNaN(val)) { return; } }, backgroundColor: 'none', borderRadius: 3, textStyle: { color: '#f7fafb', width: 50, height: 20, }, }, label: { normal: { show: false }, emphasis: { show: false } }, data: mapData, renderItem: function (params, api) {//具体实现自定义图标的方法 if (that.pointData[params.dataIndex].num > 0 && dataTemp[params.dataIndex].num <= 50) { return addImage('img/index2/jcd_1.png', params, api, dataTemp) } else if (dataTemp[params.dataIndex].num > 50 && dataTemp[params.dataIndex].num <= 100) { return addImage('img/index2/jcd_2.png', params, api, dataTemp) } else if (dataTemp[params.dataIndex].num > 100 && dataTemp[params.dataIndex].num <= 150) { return addImage('img/index2/jcd_3.png', params, api, dataTemp) } else if (dataTemp[params.dataIndex].num > 150 && dataTemp[params.dataIndex].num <= 200) { return addImage('img/index2/jcd_4.png', params, api, dataTemp) } else if (dataTemp[params.dataIndex].num > 200 && dataTemp[params.dataIndex].num <= 250) { return addImage('img/index2/jcd_5.png', params, api, dataTemp) } else { return addImage('img/index2/jcd_6.png', params, api, dataTemp) } } }, { name: '散点', type: 'effectScatter', coordinateSystem: 'geo', rippleEffect: { brushType: 'stroke' }, itemStyle: { normal: { color: '#4DBC44', shadowBlur: 10, shadowColor: '#333' } }, label: { show: true, formatter: function (params) { let val = params.value; if (params.name == '南海诸岛') return if (window.isNaN(val)) { val = 0; } return params.data.value[2]; }, }, data: this.pointData, symbolSize: function (val) { let value = 0; if (val && val.length == 3) { value = val[2] } if (value == max) { return 30 } return 20 }, showEffectOn: 'render', //加载完毕显示特效 z: 1, tooltip: { position: 'top', enterable: true, formatter: function (params) { let val = params.value; if (params.name == '南海诸岛') return if (window.isNaN(val)) { val = 0; } let str = '<div style=" height: calc(100vh*204/1080);width: calc(100vw*240/1920);background: url(/wjzBoard/bj_tk2.png) no-repeat; background-size: 100% 100%;padding:5px;">' + '<div style=" height: 28px;font-size: 12px;font-weight: bolder;text-align: left;padding-top:calc(100vh*15/1080);">' + ' <div style="font-size: 12px;color: #00F6FF;margin-left: 20px;display: inline-block;' + ' max-width: 100%; white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">' + params.value[2] + '</div>' + '</div>' + '<div style="height: 22px;padding:10px 10px;color:#FF8A00 ">' + '<img src="/wjzBoard/p_orange.png" style="height: 13px;margin-left: 7px"/> 水位预警:' + params.value[3] + '</div>' + '<div style="height: 22px;padding:10px 10px">' + '<img src="/wjzBoard/p_blue.png" style="height: 13px;margin-left: 7px"/> 排水信息:' + params.value[4] + '</div>' + '<div style="height: 22px;padding:10px 10px">' + '<img src="/wjzBoard/p_green1.png" style="height: 13px;margin-left: 7px"/> 发电量:' + params.value[5] + '</div>' + '<div style="height: 22px;padding:10px 10px">' + '<img src="/wjzBoard/p_green2.png" style="height: 13px;margin-left: 7px"/> 水质情况:' + params.value[6] + '</div>' + '</div>'; return str; }, backgroundColor: 'none', borderRadius: 3, textStyle: { color: '#f7fafb', width: 50, height: 20, }, }, }, ] } } this.centerChart11Ref = echarts.init(this.$refs.centerChart11) this.centerChart11Ref.setOption(this.mapOption, true) //点击前解绑,防止点击事件触发多次 this.centerChart11Ref.off('click') // if (this.mapLevel != 3) { // this.centerChart11Ref.on('click', this.echartsMapClick) // } this.centerChart11Ref.on('click', this.echartsMapClick) this.openTooltip(); }, //map点击事件 echartsMapClick(params) { if (!params.data) { return } else { this.mapBackShow = true console.log('最后一级11:',params.data) //如果当前是最后一级,那就直接return if (this.parentInfo[this.parentInfo.length - 1].code == params.data.cityCode) { if(params.data.pId) this.openProjRemoteView(params.data.name) return } let data = params.data this.parentInfo.push({ cityName: data.name, code: data.cityCode }) this.adCode = this.splitAdCode(data.cityCode) this.cityCode = data.cityCode this.mapInit(data.cityCode) this.loadData() } }, openProjRemoteView(projectName) { if (projectName) { let routeUrl = this.$router.resolve({ path: '/blank/EquipRealTimeDataList', query: { projectName: projectName } }) window.open(routeUrl.href, '_blank') } }, // 将adCode进行截取,分三部分,xxyyzz,每部分是00的需要去掉 splitAdCode(adCode) { let value = adCode + '' if (value == '100000') { this.mapLevel = 0 return null } let level = 0 if (value && value.length == 6) { level = 3 let str3 = value.substr(4, 2) if (str3 == '00') { level = 2 value = value.substr(0, 4) let str2 = value.substr(2, 2) if (str2 == '00') { level = 1 value = value.substr(0, 2) } } } this.mapLevel = level return value }, getCitySimple(){ initDictOptions(escape(`city_simple,status = 1`)).then((res) => { if (res.success) { this.citySimpleList = res.result; console.log('this.citySimpleList:',this.citySimpleList) } }); }, openTooltip(){ // 动态显示tootip let that = this; let loopIndex = 0 //播放所在下标 if (that.center11ChartLoop) { clearInterval(that.center11ChartLoop) } that.center11ChartLoop = setInterval(function () { //使得tootip每隔三秒自动显示 that.centerChart11Ref.dispatchAction({ type: 'showTip', seriesIndex: 1, dataIndex: loopIndex }) loopIndex++ if (loopIndex > that.mapOption.baseOption.series[1].data.length) { loopIndex = 0 } }, 5000) }, } } </script> <style scoped> @import '~@assets/less/common.less'; </style>