vue-实现高德地图-省级行政区地块显示+悬浮显示+标签显示+省市级切换

2 篇文章 0 订阅

在这里插入图片描述

<template>
  <div>
    <div id="container" />
    <div @click="showFn">显示</div>
    <div @click="removeFn">移除</div>
  </div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader'
import chinaData from './provincialData/中华人民共和国.json'
export default {
  data() {
    return {
      map: null,
      infoWindow: null,
      markers: [],
      provincPolygonList: []
    }
  },
  async mounted() {
    await this.initMap()
    // 初始完地图后,开始绘制
    await this.setUpPlotsFn(chinaData)
  },
  methods: {
    /** 1. 初始化地图 **/
    initMap() {
      return new Promise((resolve) => {
        window._AMapSecurityConfig = {
          securityJsCode: '你的安全密钥' // 自2021年12月02日升级后, key与安全密钥必须一起使用, 否则可能会出现一些API无法使用,如 DistrictSearch
        }
        AMapLoader.load({
          key: '你的安全密钥key', // 首次调用 load 时必填
          version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
          plugins: [
            'AMap.DistrictSearch', // 配置行政区查询服务
            'AMap.GeoJSON' // 配置行政区查询服务
          ] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        })
          .then((AMap) => {
            this.map = new AMap.Map('container', {
              center: [116.30946, 39.937629],
              zoom: 3
            })
            this.map.on('complete', () => {
              resolve()
            })
          })
          .catch((e) => {
            console.log(e)
          })
      })
    },

    // 设置地块
    setUpPlotsFn(featuresObj) {
      const { features } = featuresObj
      features.forEach((item) => {
        this.addGeoJsonFn(item)
      })
      this.map.add(this.provincPolygonList)
      this.map.add(this.markers)
      // 地图自适应
      this.map.setFitView()
    },
    // GeoJson数据进行解析
    addGeoJsonFn(feature) {
      const geoJSON = {
        type: 'FeatureCollection',
        features: [feature]
      }
      this.map.plugin('AMap.Geocoder', () => {
        const polygon = new window.AMap.GeoJSON({
          geoJSON: geoJSON,
          getPolygon: function(geojson, lnglats) {
            // 将解析出来的面 进行绘制
            return new window.AMap.Polygon({
              path: lnglats,
              fillOpacity: 0.4,
              fillColor: '#80d8ff',
              strokeColor: '#08B2BD',
              strokeWeight: 1,
              map: this.map
            })
          }
        })
        const { name, centroid } = feature.properties
        console.log('🚀 ~ file: MapConnentNewLast.vue:89 ~ this.map.plugin ~  feature.properties:', feature.properties)
        polygon.on('mouseover', (e) => {
          // 鼠标移入更改样式
          polygon.setOptions({
            fillOpacity: 0.7,
            fillColor: '#08B2BD'
          })
          const info = []
          info.push(
            `<div style="font-size: 12px; background-color: #fff;padding: 10px; border-radius: 10px;"><div style="font-weight: 700;">${name}</div>`
          )
          info.push(
            '<div style="display: flex; justify-content: space-between;align-items: center;padding: 4px 0;"><span style="color:#666;padding-right: 10px;">聚合资源总量</span> <span style="font-weight: 700;">100MW</span></div>'
          )
          info.push(
            '<div style="display: flex; justify-content: space-between;align-items: center;padding: 4px 0;"><span style="color:#666;">充电站</span> <span style="font-weight: 700;">100座</span></div>'
          )
          info.push(
            '<div style="display: flex;justify-content: space-between;align-items: center;padding: 4px 0;"><span style="color:#666;">换电站</span> <span style="font-weight: 700;">100座</span></div>'
          )
          info.push(
            '<div style="display: flex;justify-content: space-between;align-items: center;padding: 4px 0;"><span style="color:#666;">光伏</span> <span style="font-weight: 700;">100MW</span></div>'
          )
          info.push(
            '<div style="display: flex; justify-content: space-between;align-items: center;padding: 4px 0;"><span style="color:#666;">储能</span> <span style="font-weight: 700;">100MWH</span></div></div>'
          )
          this.infoWindow = new window.AMap.InfoWindow({
            isCustom: true, // 使用自定义窗体
            content: info.join(''),
            offset: new window.AMap.Pixel(0, -30)
          })
          // 获取点击的位置信息
          const lnglat = e.lnglat
          // 在点击的位置上显示信息窗体
          this.infoWindow.open(this.map, lnglat)
        })

        polygon.on('mouseout', () => {
          // 鼠标移出恢复样式
          this.infoWindow.close()
          polygon.setOptions({
            fillOpacity: 0.5,
            fillColor: '#80d8ff'
          })
        })

        this.provincPolygonList.push(polygon)

        const center = this.$turf.centroid(geoJSON).geometry.coordinates
        console.log('🚀 ~ file: MapConnentNewLast.vue:138 ~ this.map.plugin ~ center:', center)
        if (name) {
          this.addMarkerList(centroid || center, name)
        }
      })
    },

    addMarkerList(center, item) {
      const markersContent = []
      markersContent.push(`<div style="display: flex;align-items: center;font-size: 10px;border-radius: 4px;">`)
      markersContent.push(
        `<span style="color:#666;background-color: #fff;min-width: 40px;height: 20px;display: flex;align-items: center;justify-content:center">${item}</span>`
      )
      markersContent.push(
        `<span style="color:#fff;background-color: #3AD6C4;min-width: 40px;height: 20px;display: flex;align-items: center;justify-content:center">3213</span>`
      )
      markersContent.push(`</div>`)
      const marker = new window.AMap.Marker({
        position: center, // 标注点位置
        content: markersContent.join(''),
        map: this.map // 将标注点添加到地图上
      })
      this.markers.push(marker)
    },
    // 隐藏
    removeFn() {
      if (this.markers) {
        this.markers.forEach((item) => item.hide())
        this.provincPolygonList.forEach((item) => item.hide(item))
      }
    },
    // 隐藏
    showFn() {
      if (this.markers) {
        this.markers.forEach((item) => item.show())
        this.provincPolygonList.forEach((item) => item.show(item))
      }
    }
  }
}
</script>

<style scoped lang="scss">
#container {
  width: 100%;
  height: 53vh;
}

.infoWindow {
  display: flex;
  flex-direction: column;
  font-size: 10px;

  .title {
    color: #000;
  }

  .info_item {
    display: flex;
    justify-content: space-between;
    align-items: center;

    &:first-child {
      span {
        color: #444;

      }
    }
  }
}

.amap-info-content {
  border-radius: 10px;
}</style>

遇到的问题:

获取地块数据的链接 https://datav.aliyun.com/portal/school/atlas/area_selector
在这里插入图片描述

1. 获取到的地块数据不符合全省的各个地块范围

解决方法:构造多边形的地块数据,能够符合地块显示的格式
获取的文件格式
在这里插入图片描述

    /**
     * GeoJson数据进行解析
     * @param {*} feature 地块
     * @returns {*} polygonObj 解析的地块
     * @returns {*} markerObj 解析的标记
     */
    addGeoJsonFn(feature) {
      const geoJSON = {
        type: 'FeatureCollection',
        features: [feature]
      }
    

2. 自定义标记masker样式修改

*解决方法:需要加 /deep/ 才能生效

    // 添加标识
    addMarkerList(center, name, infoObj, level) {
      const markersContent = [
        `<div class='markers_connent'>`,
        `<span class='markers_connent_left' >${name}</span>`,
        `<span class='${level === 'city' ? 'markers_connent_right_city' : 'markers_connent_right'}'>666</span>`,
        `</div>`
      ]
      const marker = new window.AMap.Marker({
        position: center, // 标注点位置
        content: markersContent.join(''),
        map: this.map // 将标注点添加到地图上
      })
      return marker
    },
/deep/ .markers_connent {
  display: flex;
  align-items: center;
  font-size: 10px;
  border-radius: 4px;

  .markers_connent_left {
    color: #666;
    background-color: #fff;
    min-width: 40px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

3. 高德地图切换路由后失效

*解决方法:在加载前,将map置空,异步加载绘制方法,离开页面,销毁掉

  async mounted() {
    console.log('加载中')
    this.map = null
    await this.initMap()
      // 初始完地图后,开始绘制
    setTimeout(() => {
      this.setProvinceParcelFn(chinaData.features)
    }, 1000)
  },
  beforeDestroy() { // 离开页面,销毁掉
    this.map && this.map.destroy()
  },
  

4. 市级图层-需要构造二维数组,优化请求

*解决方法:根据数组中相同的provinceCode来实现是否需要重新加载地块图层
在这里插入图片描述

5. 聚合标注图层

*解决方法: 使用高德的覆盖物组 new window.AMap.OverlayGroup() 优化多个marker

       const provinceMarkers = new window.AMap.OverlayGroup(this.provinceMarkers)

6. 重复添加覆盖物组无法有效清除

*解决方法: this.map.clearMap() 只能使用这个进行全部清除

  • 待优化事项
  • 地块图层是否可以设置图层id来实现显示隐藏
  • 是否能实现聚合效果
  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue高德地图区域绑定信息窗是指在Vue组件中使用高德地图API实现区域与信息窗口的绑定功能。 首先,我们需要安装并引入高德地图JavaScript API库。可以使用npm安装或者通过CDN引入。然后,在Vue组件的mounted钩子函数中初始化地图实例。 接着,我们可以通过高德地图提供的API创建区域、信息窗口,并将它们绑定在一起。首先,使用AMap.Polygon对象创建一个区域,并设置区域的坐标点。然后,使用AMap.InfoWindow对象创建一个信息窗口,并设置其内容及位置。 接下来,在Vue组件的data属性中,定义一个变量来保存区域和信息窗口的实例。然后,在初始化地图实例时,将该变量与地图实例绑定,以便在其他方法中使用。 然后,在Vue组件的methods属性中,定义一个方法来显示信息窗口。在该方法中,通过调用信息窗口实例的open方法,将信息窗口显示在指定的位置。 最后,在区域的点击事件中,调用显示信息窗口的方法,以实现点击区域时弹出相应的信息窗口。 总结起来,使用Vue高德地图区域绑定信息窗的步骤包括初始化地图实例、创建区域和信息窗口、定义变量保存实例、编写显示信息窗口的方法、设置区域的点击事件来触发显示信息窗口的方法。通过这些步骤,我们可以实现Vue组件中使用高德地图API来绑定区域和信息窗口的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值