vue3+高德地图+海量标记点+聚合点+自定义svg图片+点聚合异常报错 vg、ud

  公司开发一款大屏应用,技术栈是vue3+高德地图,要求加载百万级的标记点,开发过的童鞋都知道,设计海量级标记点开发,必定绕不开聚合点,在过程中也是换了不少方案,最终找到了解决方案,不敢称最优解,但还像是想分享出来,与各位道友共勉,如有分歧,以你为准,下面上代码:

1.申请开发者,获取秘钥,可参照这篇文章,讲的很详细,本文不水了;

高德地图API申请步骤 - 知乎 (zhihu.com)

2.在根目录的html.index文件加载高德地图相关资源


<script  src="https://webapi.amap.com/maps?v=1.4.15&key=你的key值&plugin=AMap.MarkerClusterer"></script>

<script src="https://webapi.amap.com/ui/1.1/main.js?v=1.1.1"></script>

3.创建地图组件AMap.vue

(1)模板部分

<template>

    <div id="map"></div>

</template>

(2)js部分

<script setup>

   //定义地图对象(划重点:一定、一定、一定不要用ref定义地图相关的对象,否则会报vg、ud等聚合点的错,切记!)

   let map = nullconst

   const initMap = () => {
        map = new AMap.Map('map',{
             zoom: 18, //地图放大级别,根据自身需求自行定义
             center: [108.366407,22.8177]
         })
    }

    map.setMapStyle('amap://styles/darkblue')  //地图主题颜色,可参照:  高德地图主题

    // 标记点储存对象(划重点:一定、一定、一定不要用ref定义地图相关的对象,否则会报vg、ud等聚合点的错,切记!)

    var markerList = []

    // 聚合点储存对象(划重点:一定、一定、一定不要用ref定义地图相关的对象,否则会报vg、ud等聚合点的错,切记!)

    var cluster = null

    // 生成标记点

    const initMarkers = (source = []) => {
        if(!source.length) return
        // 清除之前的标记,不然只会追加不删除没选中的点
        clearMarkers()
        for (var i = 0; i < source.length; i += 1) {
            markerList.push({
                new AMap.Marker({
                    position: source[i]['position'],
                    content: getIconType(source[i]['type'], color, size),
                    offset: new AMap.Pixel(-source[i].size / 2, -source[i].size)
                })
            })
        }
        // 标注添加点击事件
         markerList.forEach((marker, i) => {
             marker.on('click', function (e) {
                 //DOTO
                 console.log('标注添加点击事件: ', source[i])
             })
         })
         // 清除cluster聚合点实例
         cluster && cluster.setMap(null)
          var count = markerList.length
          var _renderClusterMarker = function (context) {   
                var div = document.createElement('div')   
                div.style.width = '50px'   
                div.style.height = '50px'   
                div.style.lineHeight = '50px'   
                div.style.backgroundImage = `url(/static/cluster1.png)` //自定义图标背景   
                div.style.backgroundSize = '100%'   
                div.style.backgroundRepeat = 'no-repeat'   
                div.innerHTML = context.count //聚合个数   
                div.style.color = '#FFF'   
                div.style.fontSize = '14px'   
                div.style.paddingBottom = '10px'   
                div.style.boxSizing = 'border-box'   
                div.style.textAlign = 'center'   
                var size = Math.round(     
                    30 + Math.pow(context.count / markerList.length, 1 / 5) * 20 //markers所有标点对象集合   
                )   
                context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2))   
                 context.marker.setContent(div)  }
          }
          cluster = new AMap.MarkerClusterer(map, markerList, {   
              gridSize: 50,   
              renderClusterMarker: _renderClusterMarker 
          })
    }

    /** 
      * 返回图标类型
      * @param hiddenDangerGrade  隐患级别 0:无隐患 1:一般隐患 2:严重隐患 
      * @param rectificationState 整改情况 0:未整改 1:部分整改 2:已整改
      * @param color 标记点颜色 
      * @param size 标记点尺寸
      */
    const getIconType = (type, color, size = 32) => {
         let svg = ''
         switch (type) {
               case 0:
                    svg = `<svg fill="${color}" style="width: ${scle(size)}px;height: ${scle(size)}px" t="1734006005662" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2124" width="64" height="64"><path d="M754.38 791.96V359.43c0-106.43-106.42-127.83-106.42-127.83h-29.74V125.17l29.74 0.39s7.83 0.39 7.83-15.65-7.83-14.37-7.83-14.37H376.39s-8.61 2.61-8.61 15.15 7.83 15.65 7.83 15.65h30.13V231.6c-146.35 0-136.04 129.52-136.04 129.52v430.83c0 58.7 37.83 52.96 37.83 52.96l45.39 0.26V913c0 17.36 14.87 15.22 14.87 15.22s272.35 0.15 288.28 0.15c15.93 0 15.11-15.11 15.11-15.11v-68.09h44.44c41.57 0 38.76-53.21 38.76-53.21zM587.57 231.87h-60.52v-38.09h22.7s7.57-0.13 7.57-14.61-7.17-15.26-7.17-15.26h-75.91s-7.43 0.69-7.43 14.28 7.43 15.65 7.43 15.65l22.7 0.2 0.2 37.83H436.1V126.22h151.5v105.65z" p-id="2125"></path></svg>`
                    break;
                    case 1:
                           svg = `<svg fill="${color}" style="width: ${scle(size)}px;height: ${scle(size)}px" t="1734005962340" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1967" width="64" height="64"><path d="M754.38 791.96V359.43c0-106.43-106.42-127.83-106.42-127.83h-29.74V125.17l29.74 0.39s7.83 0.39 7.83-15.65-7.83-14.37-7.83-14.37H376.39s-8.61 2.61-8.61 15.15 7.83 15.65 7.83 15.65h30.13V231.6c-146.35 0-136.04 129.52-136.04 129.52v430.83c0 58.7 37.83 52.96 37.83 52.96l45.39 0.26V913c0 17.36 14.87 15.22 14.87 15.22s272.35 0.15 288.28 0.15c15.93 0 15.11-15.11 15.11-15.11v-68.09h44.44c41.57 0 38.76-53.21 38.76-53.21zM436.07 126.22h151.5v105.65h-60.52v-38.09h22.7s7.57-0.13 7.57-14.61-7.17-15.26-7.17-15.26h-75.91s-7.43 0.69-7.43 14.28 7.43 15.65 7.43 15.65l22.7 0.2 0.2 37.83H436.1V126.22zM506.67 677c-56.54 0-102.07-44.67-102.07-100.14 0-32.76 24.72-48.17 24.33-92.84 34.54 9.63 40.82 36.97 38.47 54.31 24.75-28.49 23.57-60.86 23.57-107.85 78.93 29.29 60.46 113.24 62.82 138.68 19.64-15.8 23.57-53.92 23.57-53.92 20.79 10.4 31.4 38.89 31.4 61.63C608.74 632.33 563.21 677 506.67 677z" p-id="1968"></path></svg>`
                    break;
            })
            return svg
        }

    // 清除所有标记点
    const clearMarkers = () => { 
        for (var i = 0; i < markerList.length; i++) {   
            markerList[i].setMap(null) 
        } 
        markerList = [] 
    }
    
    onMounted(() => {
        initMarkers(markers)
    })

</script>

(3)css部分

<style>
#map {
    width: 100vw;
    height: 100vh;
}
</style>

4.标记点数据markers结构如下,这里仅是示例,可自行按需求修改;

const markers = [
    {
        id: '1',
        type: 0,
        size: 32,
        color: '#F50',
        position: [108.366407,22.8177]
    }
]

以上便是本次的分享,希望对你有帮助!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容