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]
    }
]

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容