Google Maps API v3 實用技巧 (二) Markers

[anti-both]

在 自 己 的 網 站 建 立 好 一 幅 Google Maps 之 後 ,當 然 要 在 地 圖 上 面 畫 點 東 西 。絕 大 多 數 人 第 一 樣 會 做 的 就 是 在 地 圖 上 加 上 markers,用 以 標 示 或 者 突 出 某 些 地 點 。

要 在 Google Maps 上 建 立 marker 很 簡 單 ,新 增 一 個 marker 物 件 ,並 且 把 它 的 map 參 數 指 定 為 你 的 Google Maps 就 可 以 了 。

1
2
3
4
5
6
7
8
...
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
...
var marker = new google.maps.Marker({
   position: new google.maps.LatLng(22.40,114.34),
   map: map,
});
...

要 改 變 那 個 marker 的 圖 示 ,你 就 要 加 入 icon 參 數 。最 簡 單 的 icon 參 數 就 是 你 自 己 的 圖 檔 的 url。如 果 像 筆 者 一 樣 ,不 是 繪 圖 高 手 ,那 亦 可 以 使 用 http://www.google.com/mapfiles/ 裡 面 的 圖 示 。除 了 Google 自 己 的 圖 示 ,筆 者 也 很 喜 歡 使 用 http://mapicons.nicolasmollet.com/ 的 圖 檔 。

1
2
3
4
5
6
7
...
var marker = new google.maps.Marker({
   position: new google.maps.LatLng(22.40,114.34),
   map: map,
   icon: 'http://www.google.com/mapfiles/ms/micons/campground.png'
});
...

使 用 圖 檔 之 外 ,筆 者 更 喜 歡 是 使 用 Symbol 來 做 圖 示 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
var marker = new google.maps.Marker({
   position: location,
   map: map,
   icon: {
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#FFFFFF',
      fillOpacity: 1,
      strokeColor: '#00FF00',
      strokeWeight: 3,
      scale: 6
   }
});
...

雖 然 Google Maps 只 內 建 了 兩 種 Symbols ( 圓 圈 和 箭 頭 ),但 只 要 使 用 不 同 的 參 數 ,其 實 這 兩 種 Symbols 的 外 觀 已 經 可 以 變 化 多 端 。當 然 ,你 也 可 以 自 己 設 定 path 參 數 來 建 立 不 同 形 狀 的 Symbol,那 樣 就 更 能 切 合 自 己 的 需 要 。

筆 者 喜 歡 使 用 的 Symbol 的 原 因 是 在 marker 的 mouseover / mouseout 之 類 的 情 況 之 下 想 改 變 marker 的 顏 色 會 變 得 十 分 容 易 ,只 要 改 變 fillColor 或 者 strokeColor 就 可 以 ,不 需 要 另 外 去 製 作 不 同 顏 色 的 圖 檔 。

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
34
...
var marker = new google.maps.Marker({
   position: location,
   map: map,
   title: title,
   icon: {
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#FFFFFF',
      fillOpacity: 1,
      strokeColor: '#00FF00',
      strokeWeight: 3,
      scale: 6
   }
});
google.maps.event.addListener(marker, 'mouseover', function(e) {
   this.setIcon({
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#FFFFFF',
      fillOpacity: 1,
      strokeColor: '#FF0000',
      strokeWeight: 3,
      scale: 6
   });
});
google.maps.event.addListener(marker, 'mouseout', function(e) {
   this.setIcon({
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#FFFFFF',
      fillOpacity: 1,
      strokeColor: '#00FF00',
      strokeWeight: 3,
      scale: 6
   });
});...

我 們 也 可 以 用 setInterval 方 法 去 改 變 marker,加 入 一 點 點 動 態 的 效 果 。下 例 就 可 以 做 到 一 種 blinking 的 效 果 。

1
2
3
4
5
6
7
8
9
...
setInterval(function() {
   if (marker.getVisible()) {
      marker.setVisible(false);
   } else {
      marker.setVisible(true);
   }
}, 1000);
...

運 用 上 面 各 個 範 例 中 程 式 碼 ,就 可 以 製 成 下 圖 的 例 子 ,裡 面 幾 個 marker 全 都 是 用 Google Maps 內 建 的 SymbolPath 中 的 Circle 做 出 來 的 。大 家 不 妨 試 試 用 mouse 去 移 動 它 們 ,因 為 它 們 都 是 可 以 移 動 的 啊 ( draggable: true )。

有 了 marker,我 們 又 怎 麼 會 不 加 入 InfoWindow 呢 ?Marker 的 InfoWindow 通 常 就 是 在 Marker 的 click event 來 打 開 的 。InfoWindow 沒 什 麼 好 說 的 ,唯 一 就 是 有 時 候 在 某 些 browser 打 開 InfoWindow 時 會 有 scrollbar。如 果 想 避 免 這 種 情 況 ,我 們 可 以 在 content 外 面 包 上 一 個 div,並 且 把 該 div 的 overflow 設 為 hidden。

把 上 面 的 所 有 東 西 加 在 一 起 ,我 們 的 addMarker function 就 會 像 下 面 這 樣 。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
...
var Markers = [];
...
function addMarker(map, location, title, content) {
   var marker = new google.maps.Marker({
      position: location,
      map: map,
      title: title,
      icon: {
         path: google.maps.SymbolPath.CIRCLE,
         fillColor: '#FFFFFF',
         fillOpacity: 1,
         strokeColor: '#FFFF00',
         strokeWeight: 3,
         scale: 6
      }
   });
   google.maps.event.addListener(marker, 'mouseover', function(e) {
      this.setIcon({
         path: google.maps.SymbolPath.CIRCLE,
         fillColor: '#FFFFFF',
         fillOpacity: 1,
         strokeColor: '#FF0000',
         strokeWeight: 3,
         scale: 6
      });
      this.setZIndex(1000);
   });
   google.maps.event.addListener(marker, 'mouseout', function(e) {
      this.setIcon({
         path: google.maps.SymbolPath.CIRCLE,
         fillColor: '#FFFFFF',
         fillOpacity: 1,
         strokeColor: '#FFFF00',
         strokeWeight: 3,
         scale: 6
      });
      this.setZIndex(1);
   });
   var infowindow = new google.maps.InfoWindow({
      content: '<div style = "overflow: hidden;" >' + content + '</div>',
      maxWidth: 350
   });
   google.maps.event.addListener(marker, 'click', function() {
      infowindow.open(map, marker);
   });
   Markers.push(marker);
}
...

當 然 ,你 喜 歡 的 話 可 以 更 詳 細 地 設 定 你 的 custom function,例 如 加 入 marker 的 顏 色 ,mouse over 的 顏 色 等 等 。

如 同 上 面 的 例 子 ,如 果 地 圖 上 有 多 於 一 個 marker,我 們 就 可 以 用 一 個 array ( Markers=[] ) 來 儲 存 所 有 marker,每 建 立 一 個 新 的 marker 就 把 它 加 入 array 裡 面 ( Markers.push() )。這 樣 子 可 以 方 便 管 理 ,例 如 可 以 一 次 過 刪 除 。

1
2
3
4
5
6
7
8
9
10
...
var Markers = [];
...
function deleteAllMarkers() {
   for (var i = 0; i < Markers.length; i++) {
      Markers[i].setMap(null);
   }
   Markers = [];
}
...

如 果 地 圖 上 有 好 幾 組 不 同 類 的 marker,當 然 也 可 以 用 幾 個 不 同 的 array 來 儲 存 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
var hillTops = [];
var Camps = [];
...
function addHillTop() {
   ...
   var marker = new google.maps.Marker({
      ...
   });
   ...
   hillTops.push(marker);
}
...
function addCamp() {
   ...
   var marker = new google.maps.Marker({
      ...
   });
   ...
   Camps.push(marker);
}
...

當 地 圖 上 有 很 多 自 訂 的 圖 示 之 後 ,為 免 讀 者 混 淆 ,我 們 也 可 以 在 Google Maps 中 加 入 圖 例 。要 加 入 圖 例 ,其 實 就 跟 加 入 一 個 Custom control 一 樣 。我 們 先 建 立 一 個 「圖 例 div」,然 後 把 它 當 成 是 一 個 custom control 加 入 Google Maps 裡 面 。

1
2
3
4
5
6
7
8
9
10
11
...
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
...
var legend = document.createElement('div');
legend.style.backgroundColor='rgba(255,255,255,0.7)';
legend.style.padding='4px';
legend.style.fontSize = '14px';
legend.innerHTML = 'your own legend html...';

map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(legend);
...

上 圖 中 就 分 別 有 兩 種 marker,每 個 marker 都 有 自 己 的 infoWindow,並 且 在 右 下 角 加 入 了 圖 例 。我 亦 把 markers 分 開 了 兩 個 array 來 獨 立 管 理 ,兩 組 可 以 獨 立 設 定 為 顯 不 顯 示 。大 家 只 按 一 下 圖 例 上 面 的 兩 個 checkbox 就 可 以 了 。

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

This entry was posted in Computer & Network and tagged , , , , , , , , . Bookmark the permalink.

17 Responses to Google Maps API v3 實用技巧 (二) Markers

  1. 藍藍路 says:

    謝謝你紀錄了這些QQ

  2. 請教~ says:

    可以請教您 現在上面已經用了兩個圖片在地圖上
    那如何在圖片上還能顯示資料 (與資料庫連接的資料)
    例如在圖片上還能顯示第1個營地 第2個營地 這樣

    • C.T. Leung says:

      你問的「圖片」應該是 marker 吧?下次問問題的時間要注意好一些專有名稱,不然別人會看不明白的。

      如果只用 google 的 api ,marker 有文字的屬性就只有,1. title ( 只在 mouse over 時顯示 ) 和 2. label ( 只能顯示一個字母 ),而兩者都明顯不合你用。

      不過,其實 google map 亦有一些第三方的 extended libraries 可以令你輕鬆完成工作的。
      http://googlemaps.github.io/libraries.html

      裡面其中的 maplabel 和 richmarker 都可以達到你想要的效果,而 richmarker 可能更適合你一些。不過我建議你兩者都試試看。

  3. hhashoww says:

    請問最後一個例子在地圖右下角加上了圖例的選項
    該怎麼實現呢 ??
    在對應的 marker 使用 visible 選項嗎 ?

  4. Lan says:

    您好,我想請教您有關javascript Google map API的問題~
    我現在已經知道如何匯入一個地圖並使用infowindow,
    但我現在有一份excel清單,裡面有各筆資料的經緯度,
    請問如何將這份excel匯入,使得最後呈現出來的地圖有這份清單各個經緯度的marker及內容呢?謝謝~~

  5. Becky says:

    你好,很感謝你寫了這些文章。真的非常受用QQ
    想請教,如果是Marker 要變成一段HTML程式碼 呢?
    我想要達到的目標是:把自訂字塞到裡,然後標注在座標上

  6. Tommy says:

    可以請教您要如何在infowindow顯示超連結嗎?
    麻煩您了!

    • C.T. Leung says:

      好奇怪的問題啊…..

      我在文中教大家用一個 div element 做 infowindow 的 content,那你在 div 裡面加一個 ( 或幾個 ) A tag 不就得了?

      我懷疑你問的不是這個吧??

      • Tommy says:

        我後來解決了,真的是個蠢問題XD
        可以在請問您要如何在顯示第二個infowindow的同時關閉第一個infowindow嗎?
        我試了很多網路上的方法都失敗了

        • C.T. Leung says:

          好奇怪的問題啊… ( 第二次 XDDDD )

          infowindow.close() 你肯定知道的吧,怎麼能夠不會用?而且還「試了很多網路上的方法都失敗了」?我非常好奇,就 google 了一下 ( how to close infowindow ),然後第一個 result 就解說得很清楚了,真的好奇怪喔。

          然後我仔細的想了一下,你大概是找不到「第一個」 infowindow 的 reference 吧?在 comment 裡面打程式碼比較困難,我就另開了一文解說這個事情,希望你遇到的就是這個問題。

          Google Maps API v3 實用技巧 (四) References to Objects

          • Tommy says:

            謝謝您的幫忙,因為我的程式設計基礎不好,所以這個問題對我來說真的很難,非常感謝您讓我的問題可以順利解決!
            (之前唯一學過的程式設計是距今兩年多,高一的C++,段考平均15分,而且滿分超過100,現在會跟您請教程式設計的問題我也很意外😂)

Leave a Reply

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