Web前端On the Road(成为大牛)H5技术栈Web 前端开发

高德地图Marker实现聚合效果

2018-06-26  本文已影响18人  LiLi原上草
最近接到一个新的需求,要在高德地图实现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
            },
        ]
    }];
上一篇下一篇

猜你喜欢

热点阅读