Google Maps API v3 實用技巧 (三) Polylines

除 了 Marker 之 外 ,最 多 人 會 在 Google Maps 上 繪 畫 的 應 該 就 是 「路 徑 」了 。要 在 Google Map 上 繪 畫 路 線 ,我 們 便 要 用 到 Polyline。Google Map 上 的 Polyline,其 實 就 是 由 很 多 個 點 組 成 的 。Google Map 會 用 直 線 來 連 起 每 一 個 點 ,所 以 即 使 是 彎 彎 曲 曲 的 路 線 ,放 到 最 大 之 後 ,仍 然 是 一 條 一 條 直 線 來 的 。

我 們 要 製 作 一 條 Polyline,第 一 樣 其 實 唔 學 Google Map Api,而 係 要 準 備 好 Polyline 上 的 所 有 點 ,亦 即 是 endpoints。Google Map 上 的 點 ,當 然 是 由 經 緯 度 組 成 的 ,所 以 我 們 要 準 備 好 一 個 經 緯 度 的 Array。

1
2
3
4
5
6
7
8
var coordinates = [
   {lat: 22.3719, lng: 114.37314 },
   {lat: 22.37191, lng: 114.37314 },
   ...
   ...
   {lat: 22.42163, lng: 114.33234 },
   {lat: 22.42154, lng: 114.33232 }
];

大 家 不 要 以 為 這 是 一 個 很 簡 單 的 事 ,就 像 上 圖 中 小 小 的 「麥 理 浩 徑 第 二 段 」,就 包 含 了 1,127 個 點 。係 ,你 無 聽 錯 ,係 一 千 一 百 二 十 七 個 點 。要 在 Google Map 上 畫 一 條 路 徑 ,是 比 在 Google Map 上 畫 一 個 Marker 要 花 心 機 許 多 許 多 的 。如 果 你 覺 得 要 處 理 大 量 的 數 據 唔 係 你 杯 茶 ,咁 你 應 該 就 此 打 住 ,唔 好 浪 費 光 陰 再 睇 落 去 。

能 夠 被 Google Map Api 讀 取 的 「點 」群 組 ,可 以 有 兩 種 格 式 。一 就 係 上 面 這 種 最 普 通 的 經 緯 度 Array。而 另 一 種 ,就 是 Google Map Api 裡 面 的  MVCArray。MVCArray 也 是 Array,不 過 裡 面 的 成 員 都 必 須 要 是 Google Map Api 的 LatLng。

我 們 看 看 如 何 把 上 面 的 經 緯 度 Array 轉 變 成 MVCArray。

1
2
3
4
5
var pathOne = new google.maps.MVCArray();
for (var i = 0; i & lt; coordinates.length; i++) {
   var point = new google.maps.LatLng(coordinates[i]["lat"], coordinates[i]["lng"]);
   pathOne.push(point);
}

使 用 MVCArray 的 好 處 是 , 當 你 在 Google Map 建 立 好 了 Polyline 之 後 ,只 要 你 修 改 那 個 MVCArray,該 條 polyline 就 會 隨 著 MVCArray 而 自 動 更 新 。有 了 MVCArray,我 們 就 可 以 建 立 我 們 的 第 一 條 Polyline 了 。

1
2
3
4
5
6
7
8
9
10
11
...
var map = new google.maps.Map(document.getElementById("map"), myOptions);
...
polyOne = new google.maps.Polyline({
   map: map,
   path: pathOne,
   strokeColor: '#00FF00',
   strokeOpacity: 0.5,
   strokeWeight: 4
});
...

就 係 咁 簡 單 ,你 的 第 一 條 路 徑 就 畫 左 出 來 。上 面 的 map 參 數 好 明 顯 就 係 你 的 Google Map,而 path 參 數 就 是 MVCArray 或 者 經 緯 度 Array。另 外 幾 個 stroke 參 數 ,就 會 影 響 Polyline 的 外 觀 。

不 過 現 在 的 路 徑 會 有 點 無 頭 無 尾 ,所 以 我 都 會 喜 歡 在 路 徑 的 開 頭 和 結 尾 ,都 加 上 一 個 marker,令 路 徑 美 觀 一 點 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
var markers = [];

var marker = new google.maps.Marker({
   position: new google.maps.LatLng(22.3719, 114.37314),
   map: map,
   title: '起 點 ',
   icon: {
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#FFFFFF',
      fillOpacity: 1,
      strokeColor: '#00FF00',
      strokeWeight: 3,
      scale: 6
   }
});
markers.push(marker);

var marker = new google.maps.Marker({
   position: new google.maps.LatLng(22.42154, 114.33232),
   map: map,
   title: '終 點 ',
   icon: {
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#FFFFFF',
      fillOpacity: 1,
      strokeColor: '#00FF00',
      strokeWeight: 3,
      scale: 6
   }
});
markers.push(marker);
...

起 點 的 座 標 ,就 是 經 緯 度 Array 第 一 點 的 座 標 。而 終 點 的 座 標 ,自 然 就 是 最 後 一 點 的 座 標 。我 習 慣 用 markers Array 來 裝 著 所 有 marker,以 方 便 以 後 管 理 和 刪 除 。而 如 果 你 的 地 圖 上 有 很 多 條 Polyline,當 然 亦 可 以 用 一 個 Array 來 裝 著 它 們 ,以 方 便 之 後 的 管 理 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
function deleteLine() {
   polyOne.setMap(null);
   for (var i = 0; i & lt; Markers.length; i++) {
      markers[i].setMap(null);
   }
}
...
function hideLine() {
   polyOne.setVisible(false);
   for (var i = 0; i & lt; Markers.length; i++) {
      markers[i].setVisible(false);
   }
}
...

如 果 想 清 除 或 者 隱 藏 Polyline,可 以 用 setMap(null) 又 或 者 setVisible(false)。別 忘 記 也 要 清 除 或 隱 藏 之 前 加 的 起 點 和 終 點 markers。

在 地 圖 上 顯 示 Polyline,有 一 樣 野 比 顯 示 Marker 煩 既 ,就 係 Polyline 唔 單 單 係 一 個 點 ,佢 會 有 一 個 範 圍 。如 果 只 是 要 顯 示 一 個 marker,我 們 有 marker 的 座 標 ,我 們 只 要 用 setCenter 或 者 panTo 方 法 就 可 以 了 ,完 全 唔 需 要 理 Zoom。要 顯 示 Polyline,除 了 要 有 一 個 中 心 點 座 標 ,還 要 設 定 好 Zoom,如 果 唔 係 ,條 Polyline 就 有 機 會 在 Google Map 顯 示 的 範 圍 以 外 了 。

其 實 Google Map Api 亦 有 提 供 比 較 簡 單 的 方 法 ,就 是 fitBounds 和 panToBounds。Bounds 是 什 麼 呢 ?Bounds 的 正 式 名 稱 是 LatLngBounds。它 其 實 就 是 一 個 長 方 形 的 範 圍 ,簡 單 說 其 實 就 是 一 個 長 方 形 四 隻 角 的 座 標 。但 其 實 要 齊 四 隻 角 的 座 標 是 多 餘 的 ,所 以 我 們 建 立 一 個 LatLngBounds 的 時 候 只 需 要 提 供 東 北 角 和 西 南 角 兩 個 座 標 就 夠 。

其 實 很 多 Google Map Api 的 物 件 都 有 getBounds 方 法 ,令 我 們 可 以 簡 易 快 捷 地 找 出 那 個 物 件 的 範 圍 。但 偏 偏 Polyline 就 是 沒 有 這 個 方 法 。但 係 唔 緊 要 ,我 們 可 以 自 己 建 立 。

1
2
3
4
5
6
7
8
9
...
google.maps.Polyline.prototype.getBounds = function() {
   var bounds = new google.maps.LatLngBounds();
   this.getPath().forEach(function(e) {
      bounds.extend(e);
   });
   return bounds;
}
...

補 回 Polyline 的 getBounds 方 法 之 後 ,要 在 地 圖 上 完 整 顯 示 Polyline 就 簡 單 得 多 了 。

1
2
3
4
...
var bounds = polyOne.getBounds();
map.fitBounds(bounds);
...

很 簡 單 的 ,我 們 就 學 懂 了 怎 樣 在 Google Map 上 畫 Polyline。不 過 如 果 每 條 Polyline 都 上 千 個 點 的 ,一 般 都 比 較 少 在 Javascript 裡 用 Array 儲 存 路 徑 。這 麼 長 的 路 徑 ,通 常 都 會 儲 存 在 database,例 如 用 Ajax 取 得 所 有 點 ,然 後 才 display 在 Google Map 上 。

最 後 ,給 完 全 找 不 到 座 標 的 朋 友 提 供 一 個 小 工 具 ,令 你 可 以 在 Google 地 圖 上 任 意 選 取 一 點 ,而 獲 得 該 點 的 座 標 。

https://www.latlong.net/

ctleung張 先 生 ,男 性 ,肖 龍 。
職 業 :I.T. Consultant
簡 介 :不 好 好 讀 書 ;七 尺 差 五 寸 ,手 長 過 膝 ,雙 耳 垂 肩 ;性 寬 和 ,寡 言 語 ,喜 怒 不 形 於 色 。據 說 少 時 曾 斬 白 蛇 於 鳳 凰 山 下 ……
This entry was posted in Computer & Network and tagged , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *