android 高德聚合实现

针对项目需求,本文档介绍了如何实现自定义的高德地图聚合功能,以解决官方Demo存在的不便,如需修改ClusterOverlay以实现个性化Marker绘制逻辑和无法批量动态管理数据的问题。文中详细描述了聚合逻辑,并提供了实现效果的展示,以及简化版的计算过程,未单独开启线程进行计算。
摘要由CSDN通过智能技术生成

最近的项目需求中需要做聚合功能,研究了一下官方demo,发现官方Demo有以下两个用起来不太方便的点:

  1. 需要修改ClusterOverlay才能实现自己的Marker绘制逻辑。(仅聚合簇的绘制开放了接口)。
  2. 不能批量的动态添加和移除数据,如果要做这个功能的话,还是要修改官方的ClusterOverlay实现。

为了解决这两个问题,自己实现了一个聚合工具类。主要逻辑和官方demo的逻辑差不多。

大概的聚合逻辑如下:

  1. 定义聚合簇的结构,它由锚点和吸附于它的一系列点组成,锚点本身也对应着一个有具体数据的标记物。锚点一定范围内的点被吸附到这个聚合簇。
  2. 如果当前不存在任何聚合簇,则被循环到的第一个点作为第一个聚合簇的锚点。
  3. 如果已经存在聚合簇,则对于其他点,在需要聚合的缩放级别下,判断它是否位于聚合簇锚点的范围阈值(单位为m)内。这个范围阈值等于clusterPXSize*map.scalePerPixel,如果它位于这个范围,则其依附于该聚合簇。
  4. 对于聚合完成后,依然没有依附于任何聚合簇的孤立点,不将其绘制为聚合簇的标记物形式,而是直接绘制为未聚合状态下的标记物形式。

这个逻辑还是挺简单的,官方demo也是这样实现的。除此之外,官方demo加入了聚合物的BitmapDescriptor缓存和开线程计算等优化步骤。
我自己写的就没有单开线程进行计算了。
实现效果如下:
在这里插入图片描述
如上图,图片中的蓝色标记物是无法被聚合的孤立点,黑色标记物是聚合簇。
代码如下:

@file:Suppress("unused")

package com.bian.cluster

import android.content.Context
import android.graphics.Color
import android.util.LruCache
import android.util.TypedValue
import android.view.Gravity
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.TextView
import com.amap.api.maps.AMap
import com.amap.api.maps.AMapUtils.calculateLineDistance
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.amap.api.maps.model.animation.AlphaAnimation
import com.amap.api.maps.model.animation.Animation
import com.bian.cluster.CustomClusterOverlay.ClusterModel

/**
 * author fhbianling
 * date 2020/6/11 17:26
 * 类描述:高德聚合工具类
 * 聚合逻辑:
 *      1.如果当前不存在任何聚合锚点,则被循环到的第一个点作为聚合锚点
 *      2.如果已经存在聚合簇,则对于其他点,在任意map的zoom情况下,判断它是否位于聚合簇锚点的范围阈值(单位为m)内。
 *      这个范围阈值等于clusterPXSize*map.scalePerPixel,如果它位于这个范围,则其依附于该聚合簇
 *      3.对于聚合完成后,依然没有依附于任何聚合簇的孤立点,不将其绘制为聚合簇的标记物形式,而是直接绘制为未聚合状态下的标记物形式
 *
 * [ClusterModel]聚合锚点
 * [CustomClusterOverlay.clusterRender] 聚合簇标记物渲染器
 * [CustomClusterOverlay.markerRender] 未聚合状态下标记物的渲染器
 * [CustomClusterOverlay.clusterPXSize]聚合判断的屏幕像素范围
 * [CustomClusterOverlay.clusterDisappearZoom]当map.zoom大于或等于该值时,不再进行聚合
 */
class CustomClusterOverlay<T : CustomClusterOverlay.Model>(
    private val map: AMap,
    private val clusterPXSize: Int,
    private val context: Context,
    private val zMarkerIndex: Float,
    private val zClusterIndex: Float,
    private var markerRender: MarkerRender<T>? = null,
    private var clusterRender: ClusterRender? = null,
    private var clusterDisappearZoom: Int = CLUSTER_DISAPPEAR_ZOOM
) {
    private val data = mutableListOf<T>()
    private val showingMarkers = mutableMapOf<T, Marker>()
    private val clusterMarkers = mutableMapOf<ClusterModel<T>, Marker>()
    private val defaultMarkerRender by lazy { DefaultMarkerRender<T>() }
    private val defaultClusterRender by laz
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值