1. 程式人生 > >簡析百度地圖點聚合功能----ClusterManager類

簡析百度地圖點聚合功能----ClusterManager類

在百度地圖提供的Demo中,已經提供了一個很簡單的點聚合的demo程式,主要用到的類就是ClusterManager<T>用來管理各個Marker的聚合,

另外就添加了一個實現了ClusterItem介面的MyItem,用來管理各個Marker的資料。

demo實在太簡單了,要實現自己的功能還是得去啃與Cluster相關的類,很累人!!

剛好最近有這方面的需求,就去啃了一把cluster相關原始碼,在這裡分享一下。

一、說明

1.點聚合的核心演算法已經由百度地圖實現了,我們只需要管理好我們的資料和圖示

2.主要有三個類需要自己實現:ClusterItem, ClusterManager, DefaultClusterRenderer

二、具體介紹

1.ClusterItem介面,這個就是地圖上一個一個獨立的標記點。準確的說我們的點MyItem必須繼承ClusterItem這個介面,

才能被ClusterManager管理。

           這個介面提供兩個方法需要實現:

/**
 * ClusterItem represents a marker on the map.
 */
public interface ClusterItem {

    /**
     * The position of this marker. This must always return the same value.
     */
    LatLng getPosition();

    BitmapDescriptor getBitmapDescriptor();
}
        一個是提供marker的位置,一個是提供marker的圖示。

         所以,我們的MyItem類必須要有座標位置的變數。

  如果,每個marker還有其他產品資料,可在MyItem中定義一個Bundle,用來儲存這個marker上的產品資料。(可以用來做點選顯示產品的功能)

2.ClusterManager類 

這個類實現了兩個與BaiduMap相關的介面:OnMapStatusChangeListener 和 OnMarkerClickListener 。

本來ClusterManager提供了ClisterItem的點選回撥介面:OnClusterItemClickListener和OnClusterClickListener,

但現在的版本還無法使用,所以只能繼續使用OnMarkerClickListener來實現marker的點選事件,但是有一點要注意,

必須要將MyItem中的資料指定給相應的marker,才能在點選marker時獲取到marker的資料,否則marker中是無資料的。

那麼,MyItem中的資料是怎麼指定給marker的呢?

別急,答案就在下面那個類裡。

我們先來看一下ClusterManager的一些必要操作,呼叫addItems()函式來新增MyItem物件,然後呼叫cluster()函式,更新資料。

3.DefaultClusterRenderer類

         把各個marker聚合和分離的操作都在這個類裡完成的,可以說這個才是真正的核心類。

上面說的將MyItem資料傳遞給marker的操作也在這個類中完成。

注意:如果自己實現了DefaultClusterRenderer則需要呼叫ClusterManager.setRenderer()函式將我們定義的Renderer傳進來。

在此類中有一個常量用來判斷幾個點才會聚合:MIN_CLUSTER_SIZE ,預設是4,我改成了1.

然後,這個類中的其他方法都不需要管,override下面四個方法就可以滿足我們的要求了。

在聚合操作之前所需要的設定,可對MarkerOptions進行一些所需要的設定。

    /**
     * Called before the marker for a ClusterItem is added to the map.
     */
    protected void onBeforeClusterItemRendered(T item, MarkerOptions markerOptions) {
    }
    /**
     * Called before the marker for a Cluster is added to the map.
     * The default implementation draws a circle with a rough count of the number of items.
     */
    protected void onBeforeClusterRendered(Cluster<T> cluster, MarkerOptions markerOptions)
在聚合操作完成之後的設定—— 可以將MyItem中的資料傳遞給Marker,以完成在點選時的資料展示。
    /**
     * Called after the marker for a Cluster has been added to the map.
     */
    protected void onClusterRendered(Cluster<T> cluster, Marker marker) {
    }

    /**
     * Called after the marker for a ClusterItem has been added to the map.
     */
    protected void onClusterItemRendered(T clusterItem, Marker marker) {
    }