官网实例请点击:Android 高德地图聚合官网

下面是一个案例:
效果图:

MainActivity


public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();private MapView mapView;private AMap aMap;/*** 地图初始化比例尺,地图比例尺*/public static float ORGZOON = 12;/*** 数据列表*/private List<DotInfo> dotList = new ArrayList<>();/*** marker数据集合*/public Map<String, Marker> markerMap = new ConcurrentHashMap<>();public static final int MARKER_NORMA = 1;public static final int MARKER_TOGE = 2;public static int markerStatus = MARKER_NORMA;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mapView = (MapView) findViewById(R.id.map);mapView.onCreate(savedInstanceState);// 此方法必须重写init();}/*** 初始化AMap对象*/private void init() {if (aMap == null) {aMap = mapView.getMap();aMap.moveCamera(CameraUpdateFactory.zoomTo(ORGZOON));}aMap.setOnCameraChangeListener(onCameraChangeListener);dotList.clear();dotList = DotInfo.initData();}/*** 设置地图移动监听*/private AMap.OnCameraChangeListener onCameraChangeListener = new AMap.OnCameraChangeListener() {@Overridepublic void onCameraChange(CameraPosition cameraPosition) {}@Overridepublic void onCameraChangeFinish(CameraPosition cameraPosition) {// 放大缩小完成后对聚合点进行重新计算updateMapMarkers();}};private synchronized void updateMapMarkers() {if (dotList != null && dotList.size() > 0) {Log.i(TAG, "地图级别:" + aMap.getCameraPosition().zoom);// 若当前地图级别小于初始化比例尺,则显示聚合网点if (aMap.getCameraPosition().zoom < 7) {markerStatus = MARKER_TOGE;updateTogMarkers();}// 显示普通markerelse {if (markerStatus == MARKER_TOGE) {markerStatus = MARKER_NORMA;updateNormalMarkers();}}System.gc();}}/*** 更新普通网点数据*/private void updateNormalMarkers() {// 判断上一次更新marker操作的操作类型,若上次显示的是聚合网点,则先清空地图,然后清空网点信息,在刷新地图markeraMap.clear();markerMap.clear();loadMarker(DotInfo.initData());}/*** 更新聚合网点*/private void updateTogMarkers() {Log.i(TAG, "开始显示聚合网点,清空地图normal marker...");aMap.clear();// 更新聚合markerMapTogetherManager.getInstance(this, aMap).onMapLoadedUpdateMarker(markerMap);// 设置marker点击事件,若是聚合网点此时点击marker则放大地图显示正常网点aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker marker) {// 初始化地图按指定的比例尺移动到定位的坐标aMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(marker.getPosition(), ORGZOON, 3, 0)), 1000, null);return true;}});}private void updateGetMarkers() {Log.e(TAG, "");aMap.clear();MapTogetherManager.getInstance(this, aMap).onMapLoadedUpdateMarker(markerMap);}/*** 初始化marker数据*/private void loadMarker(List<DotInfo> dotList) {if (dotList == null || dotList.size() == 0) {return;}for (int i = 0; i < dotList.size(); i++) {DotInfo dotInfo = dotList.get(i);MarkerOptions options = new MarkerOptions();options.anchor(0.5f, 1.0f);options.position(new LatLng(dotInfo.getDotLat(), dotInfo.getDotLon()));setIconToOptions(options);Marker marker = aMap.addMarker(options);marker.setObject(dotInfo);marker.setZIndex(ORGZOON);markerMap.put(dotInfo.getDotId(), marker);}}/*** 为marker的Options设置icon** @param options*/private void setIconToOptions(MarkerOptions options) {ImageView view = new ImageView(this);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(21, 27, 1);view.setImageResource(R.mipmap.blue_location);view.setLayoutParams(params);view.setScaleType(ImageView.ScaleType.FIT_XY);options.icon(BitmapDescriptorFactory.fromView(view));}/*** 方法必须重写*/@Overrideprotected void onResume() {super.onResume();mapView.onResume();updateNormalMarkers();}/*** 方法必须重写*/@Overrideprotected void onPause() {super.onPause();mapView.onPause();}/*** 方法必须重写*/@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);mapView.onSaveInstanceState(outState);}/*** 方法必须重写*/@Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();}}

MapTogetherManager

public class MapTogetherManager {public static final String TAG = MapTogetherManager.class.getSimpleName();private int CLUSTER_SIZE = 100;// 地图上距离小于多少个像素点,则合并private int DRAWABLE_RADIUS = 80;// 聚合网点的显示大小,drawable的radius大小private static Map<String, TogDotInfo> togDotInfoMap;// 聚合网点列表private static Map<String, Marker> togMarkerMap;// 聚合网点markerprivate Activity mContext;private AMap aMap;public static MapTogetherManager instance = null;public static MapTogetherManager getInstance(Activity mContext, AMap aMap) {if (instance == null) {instance = new MapTogetherManager(mContext, aMap);}return instance;}private MapTogetherManager(Activity mContext, AMap aMap) {this.mContext = mContext;this.aMap = aMap;togDotInfoMap = new ConcurrentHashMap<String, TogDotInfo>();togMarkerMap = new ConcurrentHashMap<String, Marker>();}// ########### 设置当地图加载完成事件 start ######################Object lockObject = new Object();/*** 更新聚合网点*/public void onMapLoadedUpdateMarker(final Map<String, Marker> markerMap) {// 清空内存聚合网点数据togDotInfoMap.clear();togMarkerMap.clear();new Thread(new Runnable() {@Overridepublic void run() {synchronized (lockObject) {Log.e(TAG, "开始循环遍历,执行网点聚合操作...");Iterator<Map.Entry<String, Marker>> iterator = markerMap.entrySet().iterator();// 循环遍历在已有的聚合基础上,对添加的单个元素进行聚合while (iterator.hasNext()) {assignSingleCluster(iterator.next().getValue());}Log.e(TAG, "开始执行将聚合网点展示在地图上...");// 将聚合的网点现在在地图上if (togDotInfoMap != null && togDotInfoMap.size() > 0) {Iterator<Map.Entry<String, TogDotInfo>> cIterator = togDotInfoMap.entrySet().iterator();while (cIterator.hasNext()) {Map.Entry<String, TogDotInfo> togMap = cIterator.next();addTogDotInfoToMap(togMap.getKey(), togMap.getValue());}}}}}).start();}/*** 在已有的聚合基础上,对添加的单个元素进行聚合*/private void assignSingleCluster(Marker marker) {DotInfo dotInfo = (DotInfo) marker.getObject();LatLng latLng = new LatLng(dotInfo.getDotLat(), dotInfo.getDotLon());Point point = aMap.getProjection().toScreenLocation(latLng);TogDotInfo togDotInfo = getCluster(point);if (togDotInfo != null) {togDotInfo.addClusterItem(marker);// 更新聚合网点个数togDotInfo.setDotCount(togDotInfo.getDotCount() + 1);} else {togDotInfo = new TogDotInfo(point, latLng);// 更新聚合网点个数togDotInfo.setDotCount(1);togDotInfo.addClusterItem(marker);togDotInfoMap.put(dotInfo.getDotId() + SystemClock.currentThreadTimeMillis(), togDotInfo);}}/*** 将聚合网点添加至地图显示* @param togDotInfo 需要更新的聚合网点对象*/private void addTogDotInfoToMap(String dotId, TogDotInfo togDotInfo) {LatLng latlng = togDotInfo.getCenterLatLng();MarkerOptions markerOptions = new MarkerOptions();markerOptions.anchor(0.5f, 0.5f).icon(getBitmapDes(togDotInfo)).position(latlng);Marker marker = aMap.addMarker(markerOptions);togMarkerMap.put(dotId, marker);}/*** 获取每个聚合点的绘制样式**/private BitmapDescriptor getBitmapDes(final TogDotInfo togDotInfo) {TextView textView = new TextView(mContext);String tile = String.valueOf(togDotInfo.getDotCount());textView.setText(tile + "");textView.setGravity(Gravity.CENTER);textView.setTextColor(Color.BLACK);textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);textView.setBackgroundDrawable(getDrawAble(togDotInfo.getDotCount()));togDotInfo.setTextView(textView);return BitmapDescriptorFactory.fromView(textView);}/*** 根据一个点获取是否可以依附的聚合点,没有则返回null* @param point* @return*/private TogDotInfo getCluster(Point point) {Iterator<Map.Entry<String, TogDotInfo>> cIterator = togDotInfoMap.entrySet().iterator();while (cIterator.hasNext()) {TogDotInfo togDotInfo = cIterator.next().getValue();Point poi = togDotInfo.getCenterPoint();double distance = getDistanceBetweenTwoPoints(point.x, point.y, poi.x, poi.y);if (distance < CLUSTER_SIZE) {return togDotInfo;}}return null;}/*** 计算地图上两个点之间的距离* @return*/private double getDistanceBetweenTwoPoints(double x1, double y1, double x2,double y2) {double distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2)* (y1 - y2));return distance;}/*** 获取聚合网点显示的Drawable* @param clusterNum* @return*/public Drawable getDrawAble(int clusterNum) {int radius = DisplayUtil.dip2px(mContext, DRAWABLE_RADIUS);// 根据不同的网点个数,显示不同的聚合网点drawable// if (clusterNum < 5) {BitmapDrawable drawable = new BitmapDrawable(drawCircle(radius,Color.argb(159, 210, 154, 6)));return drawable;/*} else if (clusterNum < 10) {BitmapDrawable drawable = new BitmapDrawable(drawCircle(radius,Color.argb(199, 217, 114, 0)));return drawable;} else {BitmapDrawable drawable = new BitmapDrawable(drawCircle(radius,Color.argb(235, 215, 66, 2)));return drawable;}*/}/*** 获取聚合网点显示的圆框* @param radius* @param color* @return*/private Bitmap drawCircle(int radius, int color) {Bitmap bitmap = Bitmap.createBitmap(radius * 2, radius * 2,Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);Paint paint = new Paint();RectF rectF = new RectF(0, 0, radius * 2, radius * 2);paint.setColor(color);canvas.drawArc(rectF, 0, 360, true, paint);return bitmap;}// ########### 设置当地图加载完成事件 end ######################
}

TogDotInfo

*** 聚合网点信息列表用于保存聚合网点信息*/
class TogDotInfo {private Point mPoint;// 中心网点private LatLng mLatLng;// 中心网点经纬度private List<Marker> mClusterItems;// 网点列表private int dotCount;// 网点个数private TextView textView;// 聚合网点显示TogDotInfo(Point point, LatLng latLng) {mPoint = point;mLatLng = latLng;mClusterItems = new ArrayList<>();}void addClusterItem(Marker clusterItem) {mClusterItems.add(clusterItem);}Point getCenterPoint() {return mPoint;}LatLng getCenterLatLng() {return mLatLng;}public int getDotCount() {return dotCount;}public void setDotCount(int dotCount) {this.dotCount = dotCount;}public List<Marker> getmClusterItems() {return mClusterItems;}public TextView getTextView() {return textView;}public void setTextView(TextView textView) {this.textView = textView;}
}

DotInfo


public class DotInfo {private String dotId;private double dotLat;private double dotLon;public String getDotId() {return dotId;}public void setDotId(String dotId) {this.dotId = dotId;}public double getDotLat() {return dotLat;}public void setDotLat(double dotLat) {this.dotLat = dotLat;}public double getDotLon() {return dotLon;}public void setDotLon(double dotLon) {this.dotLon = dotLon;}/*** 初始化数据* @return*/public static List<DotInfo> initData() {List<DotInfo> dotInfoList = new ArrayList<>();DotInfo dotInfo1 = new DotInfo();dotInfo1.setDotLat(39.976318);dotInfo1.setDotLon(116.318988);dotInfo1.setDotId("dotInfo1");dotInfoList.add(dotInfo1);DotInfo dotInfo2 = new DotInfo();dotInfo2.setDotLat(40.045813);dotInfo2.setDotLon(116.304504);dotInfo2.setDotId("dotInfo2");dotInfoList.add(dotInfo2);DotInfo dotInfo3 = new DotInfo();dotInfo3.setDotLat(39.923347);dotInfo3.setDotLon(116.507537);dotInfo3.setDotId("dotInfo3");dotInfoList.add(dotInfo3);DotInfo dotInfo4 = new DotInfo();dotInfo4.setDotLat(39.91125);dotInfo4.setDotLon(116.477378);dotInfo4.setDotId("dotInfo4");dotInfoList.add(dotInfo4);DotInfo dotInfo5 = new DotInfo();dotInfo5.setDotLat(40.041337);dotInfo5.setDotLon(116.312181);dotInfo5.setDotId("dotInfo5");dotInfoList.add(dotInfo5);DotInfo dotInfo6 = new DotInfo();dotInfo6.setDotLat(39.971879);dotInfo6.setDotLon(116.306446);dotInfo6.setDotId("dotInfo6");dotInfoList.add(dotInfo6);DotInfo dotInfo7 = new DotInfo();dotInfo7.setDotLat(40.002434);dotInfo7.setDotLon(116.463232);dotInfo7.setDotId("dotInfo7");dotInfoList.add(dotInfo7);DotInfo dotInfo8 = new DotInfo();dotInfo8.setDotLat(39.980959);dotInfo8.setDotLon(116.331772);dotInfo8.setDotId("dotInfo8");dotInfoList.add(dotInfo8);DotInfo dotInfo9 = new DotInfo();dotInfo9.setDotLat(39.925659);dotInfo9.setDotLon(116.508567);dotInfo9.setDotId("dotInfo9");dotInfoList.add(dotInfo9);DotInfo dotInfo10 = new DotInfo();dotInfo10.setDotLat(39.88543);dotInfo10.setDotLon(116.461778);dotInfo10.setDotId("dotInfo10");dotInfoList.add(dotInfo10);DotInfo dotInfo11 = new DotInfo();dotInfo11.setDotLat(39.98343);dotInfo11.setDotLon(116.311843);dotInfo11.setDotId("dotInfo11");dotInfoList.add(dotInfo11);DotInfo dotInfo12 = new DotInfo();dotInfo12.setDotLat(40.029849);dotInfo12.setDotLon(116.313302);dotInfo12.setDotId("dotInfo12");dotInfoList.add(dotInfo12);return dotInfoList;}
}

DisplayUtil

public class DisplayUtil {public static int screenWidthPx; //屏幕宽 pxpublic static int screenhightPx; //屏幕高 pxpublic static float density;//屏幕密度public static int densityDPI;//屏幕密度public static float screenWidthDip;//  dp单位public static float screenHightDip;//  dp单位public static int statusBarHight;/*** 根据手机的分辨率从 dp 的单位 转成为 px(像素)*/public static int dip2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}/*** 根据手机的分辨率从 px(像素) 的单位 转成为 dp*/public static int px2dip(Context context, float pxValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (pxValue / scale + 0.5f);}/*** 将px值转换为sp值,保证文字大小不变** @param pxValue (DisplayMetrics类中属性scaledDensity)* @return*/public static int px2sp(Context context, float pxValue) {final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (pxValue / fontScale + 0.5f);}/*** 将sp值转换为px值,保证文字大小不变** @param spValue (DisplayMetrics类中属性scaledDensity)* @return*/public static int sp2px(Context context, float spValue) {final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (spValue * fontScale + 0.5f);}
}

xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.test_map_pio.MainActivity"><com.amap.api.maps.MapView
        android:id="@+id/map"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

一些基础配置这里就不在介绍,如有什么不足,请指出。

Android 高德地图给指定坐标显示图片,以及聚合显示相关推荐

  1. Android 高德地图(带有定位和点击显示经度纬度)

    Android高德地图测试,如下: 1.Android高德地图Demo地址下载:       下载android高德地图Demo 1.2 Android定位SDK 一键下载 1.3 下载好的文件zip ...

  2. Android高德地图自定义Markers的例子

    下文为各位重点介绍关于Android高德地图自定义Markers的例子,希望这篇文章能够让各位理解到Android高德地图自定义Markers的方法. 之前的博客里说了地图的嵌入和定位,今天就说说在地 ...

  3. Android 高德地图中路线规划绘制界面线路

    Android 高德地图中路线规划绘制界面线路 下面代码是根据很多的经纬度的点,绘制出直线的线路.比较死板 /*** 绘制景区的路线*/private void setRouteInfo(List&l ...

  4. Android高德地图自定义Mark并实现聚合效果

    Android高德地图自定义Mark并实现聚合效果 起因:公司本来项目里面用到了高德地图,然后最近老板看见别人的APP里面有个聚合的这个功能,老板:"这个效果能不能实现,我也要!" ...

  5. Android 高德地图自定义线路规划选择方案之后按照方案进行导航

    Android 高德地图自定义线路规划选择方案之后按照方案进行导航 因为我这边导航需求的问题,导致我这边不能使用高德地图官方的线路规划和导航.所以我这边线路规划和导航界面都是根据高德地图那边给的api ...

  6. android高德地图自定义地图,Android实现高德地图自定义样式

    放置Android工程下的assets文件夹,在assets文件夹里面创建了一个styleMap子文件夹.将里面的文件写到sd卡中. 写出文件代码: try { // 先获取系统默认的文档存放根目录 ...

  7. Android 高德地图地铁信息查询

    Android 高德地图地铁信息查询 欢迎查看本篇文章 前言 使用 结尾 欢迎查看本篇文章 首先感谢高德技术人员协助帮助我解决疑问,本文需要您花费10分钟左右. 前言 由于想在地图上描绘地铁线突出显示 ...

  8. 解决高德地图锁屏黑屏定位不更新,高德地图绘制定位轨迹,高德定位判断定位停留点,高德地图将所有坐标绘制在可视区域内

    本文章主要介绍 高德定位锁屏黑屏定位不更新的问题. 实现流程是:程序开始阶段正常执行定位,注册监听锁屏监听,唤醒cpu监听,当锁屏 广播每2秒发起一起单次定位唤醒.源码如下: package net. ...

  9. android 高德地图SDK报 KEY鉴权失败

    android 高德地图SDK报 KEY鉴权失败. 一般在项目被转移,或项目使用的SDK被其他项目使用时,会发生这种情况! 解决办法 进入高德地图api控制台 点应用管理-我的应用-创建应用 - 根据 ...

最新文章

  1. 通用机器学习流程与问题解决架构模板
  2. delphi 执行一个外部程序,当外部程序结束后言主程序立即响应
  3. matlab 状态空间转传函,求助!!如何把多输入多输出系统的传函转换为状态空间表达式?...
  4. OpenvSwitch实现kubernetes依赖的底层网络
  5. np.copysign_带有Python示例的math.copysign()方法
  6. C++/C--二分查找之lower_bound( )和upper_bound( )【转载】
  7. Basic64 编码解码
  8. 微信小程序通用功能设计和实现
  9. excel的ADO读取ORACLE,【VBA研究】利用ADO让普通人用excel读取oracle数据库表的通用办...
  10. webgl与opengl技术资讯
  11. activiti 设置候选人_中标 | 河南移动公示无源波分复用设备集采中标候选人名单:3家厂商上榜...
  12. SQL中关于where后面不能放聚合函数(如sum等)的解决办法
  13. 忘了 忘了,以前学的矩阵知识全交给老师了,敲黑板了,矩阵乘法实例讲解
  14. C# MD5算法实现对文件校验
  15. Hadoop环境搭建
  16. php sql注入防御方法,SQL注入防御的方法有哪些
  17. 一文读懂javascript深拷贝与浅拷贝
  18. 海康萤石云 H5移动端和PC端云播放本地监控摄像头
  19. 一路编程,一路迷茫,一路醒悟,接着迷茫,再醒悟再迷茫
  20. [python]pycharm自动生成函数注释

热门文章

  1. NYOJ 427 Number Sequence
  2. 2021年德阳2中高考成绩查询,2021年德阳高中录取分数线是多少及高中排名榜
  3. 谷歌浏览器打包扩展程序(记录扩展程序根目录)
  4. 怎么添加扫描仪到计算机快捷键,Win7系统添加扫描仪快捷方式的方法
  5. Linux-无密码访问、远程拷贝、无密码登录
  6. shell语法(2)
  7. LPN(Request,Offer,Poll / Update,Establish,Cache)
  8. 次世代游戏建模技巧全解之制作高模篇
  9. (力扣)LeetCode19. 删除链表的倒数第 N 个结点(C++/C语言)
  10. 很火的《脱口秀大会》里的他们竟然都是程序员