百度地图之标注聚会

俗话说站在巨人的肩膀上将事半功倍,在写android的百度地图标注物聚合时,我在网上也进行了大量的查询,发现标注物聚合的算法很早就有人写了,不过他们是js或者是Google地图c#版的。借鉴他们的想法,我写了android的这版代码与大家一起分享。

一、牛人们的想法

下面是我参考的有关的博客,下面将一一列举

1.MarkerCluster之百度地图版  http://hi.baidu.com/liongg/item/d8adece188fbfb11585dd89f

2.Marker Cluster面面观 http://hi.baidu.com/liongg/item/a380cc95bd70c2bdcd80e581

3.GoogleMap标注物聚合解决办法 http://www.svennerberg.com/2009/01/handling-large-amounts-of-markers-in-google-maps/

4.百度地图官网上已经有JS版的标注物聚合实例与原文件,建议看百度地图上的代码,规范且函数注释明确。

百度地图javascript开源库:  http://developer.baidu.com/map/library.htm

二、我的思路

1.下面以一个流程图来表述我的想法。

2.下面贴出代码

<span style="font-family:KaiTi_GB2312;"><span style="font-size:18px;">//cluster聚合器类  
package com.zhl.map;  
 
import java.util.ArrayList;  
import java.util.List;  
 
import android.graphics.Bitmap;  
import android.graphics.Point;  
import android.graphics.drawable.BitmapDrawable;  
import android.util.Log;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.widget.TextView;  
import baidumapsdk.demo.R;  
 
 
import com.baidu.mapapi.cloud.Bounds;  
import com.baidu.mapapi.map.MapView;  
import com.baidu.mapapi.map.OverlayItem;  
import com.baidu.mapapi.utils.DistanceUtil;  
import com.baidu.platform.comapi.basestruct.GeoPoint;  
import com.zhl.activity.MarkerClusterActivity;  
import com.zhl.util.MapUtils;  
 
public class Cluster{  
 
    private MarkerClusterActivity mMarkCluster;  
    private MapView mMapView;  
    private int mMinClusterSize;  
    private Boolean isAverageCenter;  
    private int mGridSize;  
    private double mDistance;  
 
    private List<ClusterMarker> mMarkers;  
 
 
    public Cluster(MarkerClusterActivity markCluster,MapView mapView  
            ,int minClusterSize,Boolean isAverageCenter  
            ,int mGridSize,double mDistance) {  
 this.mMarkCluster = markCluster;  
 this.mMapView = mapView;  
 this.mMinClusterSize = minClusterSize;  
 this.isAverageCenter = isAverageCenter;  
 this.mGridSize = mGridSize;  
 this.mDistance = mDistance;  
 mMarkers = new ArrayList<ClusterMarker>();  
    }  
 
    public List<OverlayItem> createCluster(List<OverlayItem> markerList){  
        this.mMarkers.clear();  
        List<OverlayItem> itemList = new ArrayList<OverlayItem>();  
        for(int i=0;i<markerList.size();i++){  
            addCluster(markerList.get(i));  
        }  
        for(int i=0;i<mMarkers.size();i++){  
            ClusterMarker cm = mMarkers.get(i);  
            setClusterDrawable(cm);  
            OverlayItem oi = new OverlayItem(cm.getmCenter(),cm.getTitle(),cm.getSnippet());  
            oi.setMarker(cm.getMarker());  
            itemList.add(oi);  
        }  
        return itemList;  
    }  
 
    private void addCluster(OverlayItem marker){  
        GeoPoint markGeo = marker.getPoint();  
        if(mMarkers.size()==0){  
            ClusterMarker clusterMarker = new ClusterMarker(marker.getPoint(), marker.getTitle(), marker.getSnippet());  
            clusterMarker.setMarker(marker.getMarker());  
            clusterMarker.AddMarker(marker, isAverageCenter);  
            Bounds bound = new Bounds(markGeo.getLatitudeE6(),markGeo.getLongitudeE6(),markGeo.getLatitudeE6(),markGeo.getLongitudeE6());  
 bound = MapUtils.getExtendedBounds(mMapView, bound, mGridSize);  
            clusterMarker.setmGridBounds(bound);  
            mMarkers.add(clusterMarker);  
        }else{  
            ClusterMarker clusterContain = null;  
            double distance = mDistance;  
            for(int i=0;i<mMarkers.size();i++){  
                ClusterMarker clusterMarker = mMarkers.get(i);  
                GeoPoint center = clusterMarker.getmCenter();  
                double d = DistanceUtil.getDistance(center, marker.getPoint());  
                if(d<distance){  
 distance = d;  
 clusterContain = clusterMarker;  
                }  
            }  
            if(clusterContain == null||!isMarkersInCluster(markGeo, clusterContain.getmGridBounds())){  
                ClusterMarker clusterMarker = new ClusterMarker(marker.getPoint(), marker.getTitle(), marker.getSnippet());  
                clusterMarker.AddMarker(marker, isAverageCenter);  
 
                clusterMarker.AddMarker(marker, isAverageCenter);  
                Bounds bound = new Bounds(markGeo.getLatitudeE6(),markGeo.getLongitudeE6(),markGeo.getLatitudeE6(),markGeo.getLongitudeE6());               bound = MapUtils.getExtendedBounds(mMapView, bound, mGridSize);  
                clusterMarker.setmGridBounds(bound);  
 
                mMarkers.add(clusterMarker);  
            }else{  
                clusterContain.AddMarker(marker, isAverageCenter);  
            }  
 
        }  
    }  
 
    private void setClusterDrawable(ClusterMarker clusterMarker){  
        View drawableView = LayoutInflater.from(mMarkCluster).inflate(  
                R.layout.drawable_mark, null);  
        TextView text = (TextView) drawableView.findViewById(R.id.drawble_mark);  
        int markNum = clusterMarker.getmMarkers().size();  
        if(markNum>=2){  
            text.setText(markNum+"");  
            if(markNum<11){  
                text.setBackgroundResource(R.drawable.m0);  
            }else if(markNum>10&&markNum<21){  
                text.setBackgroundResource(R.drawable.m1);  
            }else if(markNum>20&&markNum<31){  
                text.setBackgroundResource(R.drawable.m2);  
            }else if(markNum>30&&markNum<41){  
                text.setBackgroundResource(R.drawable.m3);  
            }else{  
                text.setBackgroundResource(R.drawable.m4);  
            }  
            Bitmap bitmap = MapUtils.convertViewToBitmap(drawableView);  
            clusterMarker.setMarker(new BitmapDrawable(bitmap));  
        }else{  
 
        }  
    }  
 
    private Boolean isMarkersInCluster(GeoPoint markerGeo,Bounds bound){  
        if(markerGeo.getLatitudeE6()>bound.leftBottom.getLatitudeE6()  
                &&markerGeo.getLatitudeE6()<bound.rightTop.getLatitudeE6()  
                &&markerGeo.getLongitudeE6()>bound.rightTop.getLongitudeE6()  
                &&markerGeo.getLongitudeE6()<bound.leftBottom.getLongitudeE6()){  
            return true;  
        }  
        return false;  
 
    }  
}</span></span> 

3.工程demo代码下载,地图标注物聚合.zip

4.下面是程序的实例图片

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码生

Swift2转Swift3

接触swift 已经有一年多的时间了,由最初的OC代码转为 swift 代码,然后从 swift 2.3 转为 swift 3。每次的转换都感觉是将项目整个的翻...

1715
来自专栏Java爬坑系列

【JAVA零基础入门系列】Day12 Java类的简单应用

  俗话说的好,实践出真知,所以除了理论知识掌握扎实以外,更重要的是要多加操练,这样才能掌握核心科技。   今天我们就用刚学会的类来实践一下,目标便是完成上一篇...

2259
来自专栏潇涧技术专栏

Android Heroes Reading Notes

最近有幸认识了很多国内安卓开发的大神,每每想到这里都感觉自己总算是找到了组织,步入了正轨。(^o^) 前段时间购入了几位大牛们写的书,这些书都是好评如潮啊,哈哈...

1002
来自专栏崔庆才的专栏

使用requests+正则表达式爬取猫眼电影排行

本节中,我们利用requests库和正则表达式来抓取猫眼电影TOP100的相关内容。requests比urllib使用更加方便,而且目前我们还没有系统学习HTM...

7667
来自专栏熊二哥

UML快速入门

UML(Unified Modeling Language)统一建模语言的概念已经出现了近20年,虽然并不是所有的概念都非常有实践意义,但常见的用例图、类图、序...

2649
来自专栏牛客网

蚂蚁金服暑期实习生一面总结

6892
来自专栏听Allen瞎扯淡

玩花招的PowerMock

当我们面对一个遗留系统时,常见的问题是没有测试。正如Michael Feathers在Working Effectively with Legacy Code一...

1182
来自专栏CDA数据分析师

三行Python代码,让数据预处理速度提高2到6倍

Python 是机器学习领域内的首选编程语言,它易于使用,也有很多出色的库来帮助你更快处理数据。但当我们面临大量数据时,一些问题就会显现……

1954
来自专栏牛客网

百度、今日头条、新东方、滴滴社招安卓面经一、百度二、新东方(是新东方教育,不是新东方厨师呀,新东方厨师的广告跟挖掘机一样,打得非常响亮)三、头条四、滴滴

1754
来自专栏恰童鞋骚年

设计模式的征途—7.适配器(Adapter)模式

在现实生活中,我们的笔记本电脑的工作电压大多数都是20V,而我国的家庭用电是220V,如何让20V的笔记本电脑能够工作在220V的电压下工作?答案:引入一个电源...

1343

扫码关注云+社区

领取腾讯云代金券