来访~101715 文章~106 评论~25
2022年6月27日 作者 张临志

jeecgboot框架前端vue添加amap组件展示中国地图数据及详细信息

    1. 首先执行 npm i VUEAMAP进行amap组件安装
    2. 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', // 查询目标城市/区域的实时天气状况。
      
        ]
      })
    3. 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"/>&nbsp;水位预警:' + params.value[3] +
                          '</div>' +
                          '<div style="height: 22px;padding:10px 10px">' +
                          '<img src="/wjzBoard/p_blue.png" style="height: 13px;margin-left: 7px"/>&nbsp;排水信息:' + params.value[4] +
                          '</div>' +
                          '<div style="height: 22px;padding:10px 10px">' +
                          '<img src="/wjzBoard/p_green1.png" style="height: 13px;margin-left: 7px"/>&nbsp;发电量:' + params.value[5] +
                          '</div>' +
                          '<div style="height: 22px;padding:10px 10px">' +
                          '<img src="/wjzBoard/p_green2.png" style="height: 13px;margin-left: 7px"/>&nbsp;水质情况:' + 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>