高德地图Marker实现聚合效果

作者: LiLi原上草 | 来源:发表于2018-06-26 10:49 被阅读18次
    最近接到一个新的需求,要在高德地图实现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" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css">
        <link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css"/>
        <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
                },
            ]
        }];
    

    相关文章

      网友评论

        本文标题:高德地图Marker实现聚合效果

        本文链接:https://www.haomeiwen.com/subject/hbspyftx.html