VUE中使用高德地图(原生UI,信息窗体内部事件监听)

时间:2025-02-07 14:20:57

VUE中使用高德地图(原生UI)

先吐槽一下,本人的环境是基于vue3.0的项目,上一位参与项目的同事使用的事vue-amap,因工作需要,另外一位同事去了别的项目,所以这个万恶的项目由本人自己维护,就是再本周新增了需求,根据不用大区的用户进入到系统,显示不同的地图边界。 由也正因为于本人能力有限,未能基于vue-amap实现新增的需求,所以考虑使用原生UI功能,但因为引入原生UI与与原生UI冲突,总是报错,所以被本人放弃第三方组件方式,直接使用原生UI来进行开发。

遇到的问题(后面会详细解说)

  1. 自定义窗体问题;
  2. 窗体内部事件监听问题;
  3. 根据坐标获取Address问题;
  4. 获取省份行政区划代码问题;
  5. 行政区划添加图层展示问题;

问题内容解说前,先插入一点题外话,就是如何看API,高德地图功能很强大,据说什么样的地图都可以实现。
首先,高德地图有示例中心,有普通JS的示例,原生UI的示例,那我们要看的部分就是原生UI的示例+高德地图(WebJs API)
这里附上地址:
高德地图组件UI示例地址:/api/amap-ui/demos/amap-ui-districtexplorer/multi-load
高德地图JSAPI地址:/api/javascript-api/summary
下面针对遇到的问题开始进行详细解说,以代码为主。

本人所有功能的代码

中引入的高德地图插件(项目中是使用了vue-amap这个第三方插件的)
代码如下:

import VueAMap from 'vue-amap';
(VueAMap);
({
  key: '申请开发Web版地图的Key,再高德地图官方网站进行申请',
  plugin: ['', '', ''],
  v: '1.4.4',
  uiVersion: '1.0.11' // UI版本号
});

包含地图所有功能的vue文件

<template>
  <div class="uimap">
    <div  class="amap-box"></div>
  </div>
</template>

<script>
import vm from '@/libs/vm';
import { USER_MIXINS } from '@/libs/mixins';
import NoNet from '@/assets/images/';
import HasNet from '@/assets/images/';
import Normal from '@/assets/images/';
import Middle from '@/assets/images/';
import Interrupt from '@/assets/images/';
import Unknown from '@/assets/images/';
import { AMapManager, lazyAMapApiLoaderInstance } from 'vue-amap';
import $ from 'jquery';
import { type } from 'os';
let amapManager = new AMapManager();
const loadPromise = ();
export default {
  mixins: [USER_MIXINS],
  data() {
    let self = this;
    return {
      a_provincecode: [],
      districtExplorer: {},
      locationInfo: {},
      simpleInfoWindow: null,
      amapManager: amapManager,
      map: null,
      zoom: '',
      center: [116.50436, 39.78634],
      markers: [],
      lng: 0,
      lat: 0,
      areaName: '',
      dataCount: '' // 异常数据条数
    };
  },
  async mounted() {
     = await ();
    this.$nextTick(() => {
      let aMark = (item => {
        return ;
      }); // 覆盖默认的dom结构

      (() => {
        let _self = this;
        var _simpleInfoWindow = {};
         = new ('uimap', {
          center: ,
          resizeEnable: true
        });
        (
          [
            'misc/MarkerList',
            'overlay/SimpleMarker',
            'overlay/SimpleInfoWindow',
            'geo/DistrictExplorer'
          ],
          (MarkerList, SimpleMarker, SimpleInfoWindow, DistrictExplorer) => {
            // 创建一个实例
            _self.districtExplorer = new DistrictExplorer({
              map: _self.map
            });
            // just some colors
            var $ = .$;
            // 展示所有标记
            var markerList = new MarkerList({
              map: ,
              // 从数据中读取位置, 返回lngLat
              getPosition: function(item) {
                return ;
              },
              getInfoWindow: function(data, context, recycledInfoWindow) {
                if (recycledInfoWindow) {
                  (
                    `<strong class="infoTitle">${
                      
                    }</strong>`
                  );
                  (
                    `<p class="infoWindow">所在大区:${
                      
                    }</p>
                    <p class="infoWindow">异常数据量:${
                      
                    }</p>
                    <p class="infoWindow"><span><a class="goDetail amap-ui-infowindow-close" >详情</a></span><span class="right"><a class="close amap-ui-infowindow-close">关闭</a></span></p>`
                  );
                  return recycledInfoWindow;
                }
                return new SimpleInfoWindow({
                  infoTitle: `<strong class="infoTitle">${
                    
                  }</strong>`,
                  infoBody: `<p class="infoWindow">所在大区:${
                    
                  }</p>
                  <p class="infoWindow">异常数据量:${
                    
                  }</p><p class="infoWindow "></span><span><a class="goDetail amap-ui-infowindow-close"  >详情</a></span><span class="right"><a class="close amap-ui-infowindow-close">关闭</a></p>`,
                  offset: new (0, -37)
                });
              },
              // 构造marker用的options对象, content和title支持模板,也可以是函数,返回marker实例,或者返回options对象
              getMarker: function(data, context, recycledMarker) {
                let state = ;
                return new SimpleMarker({
                  iconStyle:
                    state === 'Interrupt'
                      ? Interrupt
                      : state === 'Middle'
                      ? Middle
                      : state === 'Unknown'
                      ? Unknown
                      : state === 'Normal'
                      ? Normal
                      : Normal,
                  // iconStyle: iconStyle,
                  containerClassNames: 'my-marker'
                });
              },
              // 需要监听的marker事件
              markerEvents: ['click', 'mouseover', 'mouseout'],
              // 需要监听的infoWindow事件
              infoWindowEvents: ['click', 'mouseover', 'mouseout'],
              selectedClassNames: 'selected',
              autoSetFitView: true
            });
            ();
            // 监听选中改变
            ('selectedChanged', function(event, info) {
               = ['_singleInfoWindow'];
              if () {
                // 详情按钮监听。。
                
                  .get$Container()
                  .on('click', '.goDetail', function(event) {
                    ();
                    _self.$('setCurrType', 4);
                    _self.routeTo();
                  });
              }
            });
            // 获取当前定位
            ('', function() {
              var geolocation = new ({
                enableHighAccuracy: true, // 是否使用高精度定位,默认:true
                timeout: 10000, // 超过10秒后停止定位,默认:5s
                buttonPosition: 'RB', // 定位按钮的停靠位置
                zoomToAccuracy: false // 定位成功后是否自动调整地图视野到定位点
              });
              _self.(geolocation);
              (function(status, result) {
                if (status == 'complete') {
                  let infoWindow = new ({
                    isCustom: true,
                    content: `<p class="self-position"><strong>${
                      
                    }</strong></p>`,
                    offset: new (0, -20)
                  });
                  (_self.map, [
                    ,
                    
                  ]);
                  // onComplete(result);
                } else {
                  _self.$(result);
                }
              });
            });
            // 获取省份编码(标记点所在的省份)
            ('', function() {
              var geocoder = new ({
                // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
                // city: '010'
              });
              _self.(item => {
                let lnglat = ;
                (lnglat, function(status, result) {
                  if (status === 'complete' && ) {
                    var address = ;
                    _self.$set(, 'adcode', );
                    _self.$set(, 'citycode', );
                    _self.$set(
                      ,
                      'proecode',
                      (0, 2) + '0000'
                    );
                    var formatAddress = ;
                    _self.a_provincecode.push();
                  } else {
                    _self.$('根据经纬度查询地址失败!');
                    return false;
                    // ('根据经纬度查询地址失败');
                  }
                });
              });
            });
            // 多区域加载

            // var adcodes = [370000, 330100, 330200, '0871'];
          }
        );
      });
    });
  },
  methods: {
    async getFactoryStatesAndAbnormalCount() {
      let { data } = await this.$(
        '/outlierquery/v1/outlier/factory/stateAndAbnormalCount',
        {
          params: {
            orgLevel: ,
            uri: 
          }
        }
      );
      if ( !== 0) return;
      if ( == 0) {
        this.$('暂无水厂数据');
        return;
      }
       = ((item, index) => {
        // 0 离线 1 在线
        const Icon =
           == '0' ? NoNet :  == '1' ? HasNet : '';
        const POSITION = (',');
        let _this = this;
        return {
          extData: item,
          position: POSITION,
          icon: Icon,
          visible: true,
          draggable: false
        };
      });

      let aLng = (item => {
        return parseFloat([0]);
      });
      let aLat = (item => {
        return parseFloat([1]);
      });
      let { maxLng, minLng, maxLat, minLat } = {
        maxLng: (...aLng),
        minLng: (...aLng),
        maxLat: (...aLat),
        minLat: (...aLat)
      };
       = [(maxLng + minLng) / 2, (maxLat + minLat) / 2];
      return { maxLng, minLng, maxLat, minLat };
    },
    routeTo(point) {
      this.$({
        name: 'abnormal_data_count',
        query: {
          factoryUri: ,
          factoryName: ,
          orgLevel: 5
        }
      });
    },
    renderAreaNode(areaNode) {
      var colors = ['#dc3912'];
      // 绘制子区域
      (areaNode, function(feature, i) {
        var fillColor = colors[i % ];
        var strokeColor = colors[ - 1 - (i % )];
        return {
          cursor: 'default',
          // bubble: true,
          // strokeColor: strokeColor, // 线颜色
          // strokeOpacity: 0, // 线透明度
          strokeWeight: 0.2 // 线宽
          // fillColor: fillColor, // 填充色
          // fillOpacity: 0.15 // 填充透明度
        };
      });

      // 绘制父区域
      (areaNode, {
        zIndex: 12,
        cursor: 'default',
        bubble: true,
        strokeColor: '#333', // 线颜色
        strokeOpacity: 1, // 线透明度
        strokeWeight: 0.2, // 线宽
        fillColor: null, // 填充色
        fillOpacity: 0.35 // 填充透明度
      });
    }
  },
  watch: {
    map: function() {
      if () {
        ([new ({ path:  })]);
      }
    },
    a_provincecode: function() {
      let _self = this;
      if (
        this.a_provincecode &&
         &&
        this.a_provincecode.length === 
      ) {
        (this.a_provincecode, function(
          error,
          areaNodes
        ) {
          if (error) {
            _self.$(error);
            return false;
          }
          // 清除已有的绘制内容
          _self.();

          for (var i = 0, len = ; i < len; i++) {
            _self.renderAreaNode(areaNodes[i]);
          }
          // 更新地图视野
          // _self.(());
        });
      }
    }
  }
};
</script>
<style lang="less">
#uimap {
  min-height: 1260px;
}
.infoTitle {
  padding: 0 10px;
  height: 32px;
  line-height: 32px;
}
.infoWindow {
  min-width: 200px;
  height: 32px;
  line-height: 32px;
  padding: 0 10px;
  .right {
    float: right;
  }
}
.self-position {
  background-color: #fff;
  padding: 10px;
  border: 1px solid #53aeef;
  position: relative;
  top: -5px;
}
</style>