高德地圖Marker實現聚合效果

最近接到一個新的需求,要在高德地圖實現marker點的聚合,想實現的功能是能夠按縮放比例或者按省市區級別實現聚合。
翻了一下高德API,發現示例里面只有【 AMap.MarkerClusterer】 插件實現的點聚合。【 AMap.MarkerClusterer】的點聚合通過一些簡單的算法通過網格的像素大小來實現聚合,當然也可以通過maxZoom的設置來設置最大的聚合級別,大于該級別就不進行相應的聚合(要理解到位:聚合級別越小,同屏下展示的地圖越大)。這并不是我們想要的效果。

下面貼2個圖理解下maxZoom的配置:


縮放級別為4時的地圖
縮放級別為7時的地圖

下面貼上我的代碼,看看我是如何實現的,有問題大家及時交流:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="chrome=1">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <style type="text/css">
      body,html,#container{height: 100%;margin: 0px;font:12px Arial;}
      .circle{border-radius: 50%;border: solid 1px silver;width: 50px;height: 50px;padding: 3px;text-align: center;line-height: 25px;max-width: 50px;color:#fff;}
      .showtitle{background:#393;width:150px;height:30px;line-height:30px;color:#fff;border-radius:5px;padding-left:5px;}
      .showtitle i{font-size:16px;}
      .showcontent{background:#62ab00;width:300px;font-size:12px;margin-left:-80px;border-radius:5px;color:#fff;position:absolute;display:none;bottom:30px;z-index:99;}
      .showcontent .p{line-height:30px;padding-left:10px;margin-top:-0px;}
      .showcontent i.triangle_i{color:#62ab00;font-size:25px;display:block;width:100%;background:#fff;text-align:center;height:25px;}
      .showcontent i.close_i{position: absolute;right: 5px;top:5px;font-size:25px;z-index:99999;}
    </style>
    <link rel="stylesheet" >
    <link rel="stylesheet" />
    <script src="http://www.w3school.com.cn/jquery/jquery.js"></script>
    <title>高德地圖Marker實現聚合效果</title>
  </head>
  <body>
   <div id="container" tabindex="0"></div>
   <div id="tip">可以縮放地圖,得到縮放級別哦!<br><span id="info"></span></div>
   <script src="./marker.js"></script>
   <script src="https://webapi.amap.com/maps?v=1.4.1&key=de46cac2667f7b246a14192b88ba619d"></script>
   <script type="text/javascript">
       $(function(){
            //彈出框關閉
            $('.showtitle').live('click',function(){
                $(this).prev('.showcontent').toggle();
            })
            $('.close_i').live('click',function(){
                $(this).parent().hide();
            })
        })
        //初始化地圖容器
        var map = new AMap.Map('container', {
            resizeEnable: true,
                zoom: 5,
                zooms:[4,18],
                center: [106.49, 34.60]
        });
       
       //設置地圖比例尺
       AMap.plugin(['AMap.Scale'],
            function(){
                map.addControl(new AMap.Scale());
        });
       
       //添加監聽時間,當前縮放級別
        AMap.event.addListener(map,'zoomend',function(){
            document.getElementById('info').innerHTML = '當前縮放級別:' + map.getZoom();
        });
       
        var markersTwo;
        var markersThree;
        var createMarker = function(data,hide) {
            var div = document.createElement('div');
            div.className = 'circle';
            var r = Math.floor(data.count / 1024);
            div.style.backgroundColor = hide ?'#393':'#09f';
            var htmlData='<div>'+data.name+'</div><div>'+data.count+'</div>';
            div.innerHTML = htmlData;
            
            var marker = new AMap.Marker({
                content: div,
                title:data.name,
                position: data.center.split(','),
                offset: new AMap.Pixel(-24, 5),
                zIndex: data.count,
            });
            marker.subMarkers = [];
            if(data.name==='山東省'||data.name==='河南省'||data.name==='濟南市'||data.name==='天橋區'){
                marker.setLabel({content:'&larr;請點擊',offset:new AMap.Pixel(45,0)})
                map.setCenter(marker.getPosition());
            }
            if(!hide){
                marker.setMap(map)
            }
             if(data.subDistricts&&data.subDistricts.length){
                for(var i = 0 ; i<data.subDistricts.length;i+=1){
                    marker.subMarkers.push(createMarker(data.subDistricts[i],true));
                }
            } 
            return marker;
        }
        
        
        
        var _onZoomEnd = function(e) {  
            console.log('監聽地圖縮放')
            if (map.getZoom() < 7) {//全國下的省份
                for (var i = 0; i < markers.length; i += 1) {
                    map.remove(markers[i].subMarkers);
                }
                map.add(markers);
            }else if((map.getZoom() < 9) && (map.getZoom() > 7)){//省份下的市
                for (var i = 0; i < markersTwo.length; i += 1) {
                    map.remove(markersTwo[i].subMarkers);
                }
                map.add(markersTwo);
            }else if(map.getZoom() < 14 && map.getZoom() > 9){//市下面的區或縣
                for (var i = 0; i < markersThree.length; i += 1) {
                    map.remove(markersThree[i].subMarkers);
                }
                map.add(markersThree);
            }
        }
        var _onClick = function(e) {
            console.log(e)
            if(e.target.subMarkers.length){
            
                map.add(e.target.subMarkers);
                map.setFitView(e.target.subMarkers);
                markersTwo=e.target.subMarkers;
                
                var subMarkersTwo=e.target.subMarkers;
                for (var j = 0; j < subMarkersTwo.length; j += 1) {
                    AMap.event.addListener(subMarkersTwo[j], 'click', _onClickTwo);
                    AMap.event.addListener(subMarkersTwo[j], 'mouseover', _onMouseoverTwo);
                    AMap.event.addListener(subMarkersTwo[j], 'mouseout', _onMouseoutTwo);
                } 
                map.remove(markers)
            }
        }
        
        var _onMouseover = function(e) {
            var div = e.target.getContent();
            div.style.backgroundColor = '#393';
            e.target.setContent(div);
        }
        var _onMouseout = function(e) {
            var div = e.target.getContent();
            div.style.backgroundColor = '#09f';
            e.target.setContent(div);
        }
        
        
        var _onClickTwo = function(e) {
            
            if(e.target.subMarkers.length){
            
                map.add(e.target.subMarkers);
                map.setFitView(e.target.subMarkers);
                map.setZoom(11);
                markersThree=e.target.subMarkers;
                var subMarkersThree=e.target.subMarkers;
                for (var j = 0; j < subMarkersThree.length; j += 1) {

                    AMap.event.addListener(subMarkersThree[j], 'click', _onClickThree);
                    AMap.event.addListener(subMarkersThree[j], 'mouseover', _onMouseoverThree);
                    AMap.event.addListener(subMarkersThree[j], 'mouseout', _onMouseoutThree);
                    
                }
                
                map.remove(markersTwo)
                
            }
            
        }
        
        var _onMouseoverTwo = function(e) {
            var div = e.target.getContent();
            div.style.backgroundColor = '#09f';
            e.target.setContent(div);
        }
        
        
        var _onMouseoutTwo = function(e) {
            var div = e.target.getContent();
            div.style.backgroundColor = '#393';
            e.target.setContent(div);
        }
        
        var _onClickThree = function(e) {
            
            if(e.target.subMarkers.length){
                map.add(e.target.subMarkers);
                map.setFitView(e.target.subMarkers);
                var subMarkersFour=e.target.subMarkers;
                for (var j = 0; j < subMarkersFour.length; j += 1) {
                    var title = e.target.subMarkers[j].getTitle();
                    var html='<div class="showcontent"><div class="p">公司名稱:'+title+'</div><div class="p">聯系方式:'+title+'</div><i class="fa triangle_i">&#xf0d7</i><i class="fa close_i">&#xf057</i></div><div class="showtitle"><i  class="fa">&#xf1ba</i>&nbsp;&nbsp;'+title+'</div>';
                    e.target.subMarkers[j].setContent(html);
                }
                map.remove(markersThree)
            }
            
        }
        
        var _onMouseoverThree = function(e) {
            var div = e.target.getContent();
            div.style.backgroundColor = '#09f';
            e.target.setContent(div);
        }
        var _onMouseoutThree = function(e) {
            var div = e.target.getContent();
            div.style.backgroundColor = '#393';
            e.target.setContent(div);
        }
        
        var markers = []; //province見Demo引用的JS文件
        for (var i = 0; i < provinces.length; i += 1) {
            var marker = createMarker(provinces[i]);
            markers.push(marker);
            AMap.event.addListener(marker, 'click', _onClick);
            AMap.event.addListener(marker, 'mouseover', _onMouseover);
            AMap.event.addListener(marker, 'mouseout', _onMouseout);
        }
        map.setFitView();
        AMap.event.addListener(map, 'zoomend', _onZoomEnd);     
    </script>
    <script type="text/javascript" src="https://webapi.amap.com/demos/js/liteToolbar.js"></script>
  </body>
</html>

到這里其實還有一個很重要的一步,就是從后臺拿數據,類似于這樣的數據,即可實現不同的級別下展示該級別下的marker:

var provinces = [ {
    "id": "15",
    "name": "山東省",
    "center": "117.000923,36.675807",
    "count": 12500,
    "subDistricts": [{
        "id":370100,
        "name": "濟南市",
        "center": "117.000923,36.675807",
        "count": 10000,
        "subDistricts": [
            {
                "name": "歷下區",
                "center": "117.0768,36.66661",
                "count": 10000
            },
            {
                "name": "市中區",
                "center": "116.99741,36.65101",
                "count": 10000
            },
            {
                "name": "槐蔭區",
                "center": "116.90075,36.65136",
                "count": 10000
            },
            {
                "name": "天橋區",
                "center": "116.98749,36.67801",
                "count": 10000,
                "subDistricts": [
                    {
                        "name": "濟南長途客運中心",
                        "center": "116.984658,36.677631",
                        "count": 10000
                    },
                    {
                        "name": "山東交通學院東區",
                        "center": "116.964788,36.68152",
                        "count": 10000
                    },
                    {
                        "name": "西苑小區(中區)",
                        "center": "116.966677,36.687509",
                        "count": 10000
                    },
                    {
                        "name": "金牛建材",
                        "center": "116.97659,36.694391",
                        "count": 10000
                    },
                    {
                        "name": "濟南師范小學",
                        "center": "116.990752,36.694804",
                        "count": 10000
                    },
                ]
            },
            {
                "name": "歷城區",
                "center": "117.06509,36.67995",
                "count": 10000
            },
            {
                "name": "長清區",
                "center": "116.75192,36.55352",
                "count": 10000
            },
            {
                "name": "平陰縣",
                "center": "116.45587,36.28955",
                "count": 10000
            },
            {
                "name": "濟陽縣",
                "center": "117.17327,36.97845",
                "count": 10000
            },
            {
                "name": "商河縣",
                "center": "117.15722,37.31119",
                "count": 10000
            },
            {
                "name": "章丘市",
                "center": "117.53677,36.71392",
                "count": 10000
            },
        ]
    }];
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,224評論 6 529
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,916評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,014評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,466評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,245評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,795評論 1 320
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,869評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,010評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,524評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,487評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,634評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,173評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,884評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,282評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,541評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,236評論 3 388
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,623評論 2 370

推薦閱讀更多精彩內容

  • 第三章 幼稚傲嬌的向陽先生 在橙子小姐的心里,咱們的向陽先生是個什么樣的人呢?那還用問嗎?當然是成熟穩重、溫柔...
    南橘愛北枳閱讀 356評論 0 21
  • 今天又不自覺的發脾氣了,無法自控,又一次成為了情緒的奴隸。其實道理我都懂,就是在現實生活中,怎么就那么難實現呢?唉...
    bu離bu棄閱讀 651評論 0 0
  • 許是生長在北方的緣故,對水總是有著難以割舍的渴求,去年九月和老公一起來到水鄉蘇州。從無錫下飛機,開車去蘇州的路上隨...
    文藝囡閱讀 382評論 0 0
  • 記不清何時開始聽你的歌 記不清何時開始喜歡你的歌 那時你是情歌的天后 而我喜歡上你卻是在你離開以后 開始把你的歌當...
    利君理療閱讀 205評論 0 0
  • Nice to meet u!
    Skye0601閱讀 185評論 0 0