Skip to content

各位 Google Maps JavaScript API 的玩家都應該有過 Marker 太多時,當 Maps 視角一拉遠時,全部 Marker 擠在一起的困擾吧!沒錯 OA's Marker Clustering 就是要來處理這個困擾!

oawu/OA-markerClustering

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Welcome To OA's Marker Clustering!

各位 Google Maps JavaScript API 的玩家都應該有過 Marker 太多時,當 Maps 視角一拉遠時,全部 Marker 擠在一起的困擾吧!沒錯 OA's Marker Clustering 就是要來處理這個困擾!


聲明

本作品授權採用 姓名標示-非商業性 2.0 台灣 (CC BY-NC 2.0 TW) 授權,詳見 http://creativecommons.org/licenses/by-nc/2.0/tw/


## 簡介 或許你/妳會問,市面上也有很多關於 Marker Clustering 的 Library,那又何必自己時做一套呢!?原因很簡單,因為自己做的比較能夠掌握概況,視需求去做調整,不用一大包的 code,到底怎麼跑的都摸不透,並且加以利用做出自己想要的功能!

如果試著 Google 關於 Marker Clustering 的文章都會找到 Marker Clustering 此篇,而官網上也都推崇 這套 Library,這套我也開發過,甚至改過其功能,但是最後我還是自己刻了屬於自己的 Marker Clustering 來制定當不同的 集合 Marker 時可以使用不同呈現方式!以下就是一些功能介紹、演算方法說明。


##概略方法 [OA's Marker Clustering](https://works.ioa.tw/OA-markerClustering/index.html) 主要規則就是利用 Google Maps 在不同的放大視角(以下以 zoom 代稱)時產生 **集合 Marker**,而這些 Marker 用來代表著是多數 Marker 集合。如下圖 1 是 zoom 為 16 時的狀況圖,地圖上分別有 A、B 以及 C 三個點,而圖 2 代表在 zoom 為 13 時,因為地圖視角拉遠了,所以造成 A 與 B 互相太靠近,所以必須隱藏 B 只顯示 A,所以作法如圖 3,產生一個 集合 Marker 放置在 A 的位置,並且記錄著數量為 2。

OA's Marker Clustering ▲ zoom 為 16 時的狀況圖,地圖上分別有 A、B 以及 C 三個點。

OA's Marker Clustering ▲ 地圖視角 zoom 為 13 時,因為視角拉遠所以造成 A 與 B 互相太靠近。

OA's Marker Clustering ▲ 因靠太近,故隱藏 B 只顯示 A,產生一個 集合 Marker 放置在 A 的位置,並且記錄著數量為 2。


##功能介紹 這次的 [OA's Marker Clustering](https://works.ioa.tw/OA-markerClustering/index.html) 中,我拆出兩種 Type,分別是 **moveRun**、**runAll**,其兩者在地圖上的呈現結果差不多,但方法是不一樣的。前者 moveRun 是當地圖移動完後(idle Listener),先取得地圖的範圍座標([Bounds](https://developers.google.com/maps/documentation/javascript/reference)),在塞選(filter)出地圖範圍內的座標點,再依照這些座標點去製作各個 集合 Marker。而後者的 runAll 型態則是當一開始新增玩所有點之後,立即運算出當地圖在各個 zoom 分別的 集合 Marker,當地圖 zoom 大小改變時,則可以立即得找出該 zoom 下的 集合 Marker 顯示。

Type moveRun 當地圖移動時,會重新針對範圍內做計算再合併出 集合 Marker,所以會移除舊的在上新的,整體初始速度較快,但當地圖移動時會有閃娑狀況,反之 runAll 因為開始先算出所有不同 zoom 時要顯示的結果,所以當地圖移動(平滑非放大)時,因為不用移除舊的,所以不會有閃爍狀況發生,但初始速度較慢。以下就是兩者不同 type 的 Demo。


##程式範例 因為是要配合 Google Maps JavaScript API 使用的 Library,所以就寫在 `google.maps.event.addDomListener (window, 'load', function () {});` 內較為保險。首先新增 OAMarkerClustering 物件,並且給予 Maps 物件,以及相關設定,範例如下:
// 宣告初始地圖
var maps = new google.maps.Map ($('#maps').get (0), {
  zoom: 8,
  center: new google.maps.LatLng (23.8, 120.8)
});

// 宣告 OAMarkerClustering 物件
var cluster = new OAMarkerClustering ({
  maps: maps,
  type: 'moveRun' // 分別有 moveRun、runAll
}

接著設定各個點的資訊,這邊有兩種方式提供,分別是 **google.maps.LatLng 物件陣列**、**二維坐標陣列**,其分別可以用 setLatLngs、setArrays 去做設定,範例如下:
// 四個 Demo 點
var points = [[21.899171, 120.854535], [21.905981, 120.852092], [21.922511, 120.738746]];

// 轉換成 google.maps.LatLng 物件陣列
var latLngs = points.map (function (t) {
  return new google.maps.LatLng (t[0], t[1]);
});

// 設置所有點
cluster.setLatLngs (latLngs);

// 使用 二維坐標陣列 的話可以使用 setArrays,如下:
// cluster.setArrays (points);

最後分別設定 **單點 Marker** 與 **集合 Marker** 要顯示的物件風格,單點 Marker 使用 setMarker,集合 Marker 使用 setClusteringMarker,其方式主要是利用回傳 Callback 結果來取得 google.maps.Marker 物件。

setMarker 的第一個參數代表該點的資訊,使用 setLatLngs 的話,則第一個參數就為該點 google.maps.LatLng 資訊,反之若是使用 setArrays,則第一參數就為 坐標陣列。而 setClusteringMarker 第一參數比照 setMarker 的規則,而第二參數就是此 集合 Marker 的 單點 Marker 數量!範例如下:

cluster.setClusteringMarker (function (e, count) {
  // 設置 集合 Marker 集合樣式,第一個參數為該點資訊,第二個參數為集合了多少點

  // 利用 MarkerWithLabel 來作為 集合 Marker 的顯示
  return new MarkerWithLabel ({
      map: maps,
      position: e,
      labelContent: count,
      labelAnchor: new google.maps.Point (40 / 2, 40 / 2),
      labelClass: 'clustering',
      icon: {path: 'M 0 0'},
    });
});

cluster.setMarker (function (e) {
  // 設置 單個 Marker 樣式,第一個參數為該點資訊
  
  return new google.maps.Marker ({
      map: maps,
      position: e,
    });
});

以上就是使用的流程簡介,相關程式範例可以參閱 [GitHub](https://github.com/comdan66/OA-markerClustering) 資源,亦或者直接檢視 [介紹說明頁面](https://works.ioa.tw/OA-markerClustering/about.html) 的 [JavaScript 檔](https://github.com/comdan66/OA-markerClustering/blob/master/js/about.js)。

--

About

各位 Google Maps JavaScript API 的玩家都應該有過 Marker 太多時,當 Maps 視角一拉遠時,全部 Marker 擠在一起的困擾吧!沒錯 OA's Marker Clustering 就是要來處理這個困擾!

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published