一、原來 Google Maps API 有每個月的免費額度
之前聽到 Google Maps API 要錢,就一直沒想碰這塊,最近朋友在問,回頭去看了一下定價後,才發現官網上面寫每個月有 200 美金的免費額度。
照免費的額度表上看,因為這篇會用到的是「Maps JavaScript API」,是屬於「Dynamic Maps」這個,每個月可以載入 28,000 次,超過才開始計價。
28,000 次耶,一般頁面正常使用,那個流量都可以放個廣告了吧。覺得自己平常在玩的小頁面不會到這個量,就想來學一下。
這篇筆記主要想寫的,是文件上從「Get an API Key」,一直看到「Interacting with the Map」這邊的學習記錄,一邊看一邊實作。
因為想要記下的是以後會常用到的功能,所以想看所有 Google Maps API 的話,可以直接看官方文件。
本篇參考、使用資源如下:
- 官網 Maps Javascript API 文件
- JS framework:Vue.js
- CSS framework:Bootstrap4
- icon:Eva Icons
二、申請 Google Maps API Key
API Key 要從 Google Cloud Platform(GCP) 的後台申請。
這邊新開一個專案來用,填寫完專案名稱後按確認,GCP 就會執行開新專案的動作。
建立完後,點選剛新增的專案,就會列出跟 map 相關的一堆 API:
這邊用的是 Maps Javascript API,點進去後再點啟用,GCP 就可以看到了:
確認完要用的 API 是啟用狀態後,接著生成一組 API Key,以及對這組 API Key 設定限制,防止有人看到你的 API Key 後,拿去偷用。
直接點啟用 API 那邊的項目,再點憑證,或是直接進入 GCP 憑證頁面 後,就會看見要申請的區塊:
點選 API 金鑰,會出現一個金鑰的 Key,把值 copy 下來,之後頁面在引用 JavaScript 時,就是這樣:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"> </script>
GCP 很貼心的提醒要為金鑰增加限制,點選「限制金鑰」後,會看見 4 種限制方式:
要用哪一種就看各人了。
官方文件連結:Get an API Key
三、開始使用 Maps Javascript API
新增一個 HTML 的頁面,引用 Map JS:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
這邊因為有用 Vue.js,所以會把後面的「callback=initMap」刪掉,改成 window load 完後再執行 initMap()
。
以下寫的 code,很偷懶的直接用 ES6,如果要支援度高一點的話,請自行編譯成 ES5
初始化地圖(initMap)的 function,做 2 件事:
- 建立地圖,設定地圖中心點
- 放置標記(marker)
HTML 如下(CSS framework:Bootstrap4):
<div id="app" class="container"> <div class="row"> <div class="col"> <div id="map" class="embed-responsive embed-responsive-16by9"></div> </div> </div> </div>
JavaScript 如下:
開啟頁面後,就會看到如下:
對,看起來就跟一般我們在用 Google Map 差不多,畢竟只用了基本功能,想有些不一樣就要再加一些 code。
四、放置多個標記
要放多個標記前,當然可以直接在頁面上加一個陣列,然後資料全寫在裡面。
但 Google 文件上在這部份用了比較好的做法,就是把資料收集在一個檔案上,然後 GET 進來。
之所以會寫這點,是因為他的檔案不是常見的 xxx.json,而是 xxx.geojson。
看了文件後才知道有 geojson 這格式,維基百科 上寫是拿來記錄地理訊息的 JSON。
參考 Google文件的範例,把幾個點的位置存成了 map.geojson,如下:
geometry
裡的經緯度必填。
properties
,看示範時很像是可以填自己客製的東西,就拿來填名稱跟地址,之後在 info windows 時會用到。
有了各地點的檔案後,就是用回圈把每個地點設成 marker,JS 如下:
開啟頁面後,看到如下:
對,看上去也跟用 My Map 的功能一樣,沒什麼厲害的。畢竟這也只是在基本的地圖上,多放了幾個標記而已。
接下來再加上可以用的參數,看上去就會不一樣了。
五、標記(Marker)客製化
對網頁上要放 Google Map 來說,最會被企畫問到的問題就是:「標記的圖案可以改嗎?」、「標記可以改成公司的 logo 嗎?」
Google Maps API 有提供修改標記的參數,主要有 2 個可以用:
- 用 Google 預設的 4 種圖案
- 直接讀一個圖檔
Google 預設的 4 種圖案
使用的方式很簡單,在 JS 裡,marker 的部份改成以下:
var marker = new google.maps.Marker({ position: latLng, icon: { path: google.maps.SymbolPath.CIRCLE, scale: 10 }, map: map });
icon.path,有 4 種可用,顯示出來的樣式如 Google 提供的圖表:
直接讀一個圖檔
直接讀一個圖檔,是更能達成企畫需求的方式,code 如下:
var marker = new google.maps.Marker({ position: latLng, icon: '圖檔的絕對路徑.png', map: map });
code 很簡單,icon 的值直接寫入圖檔路徑就行。
這邊直接在 Eva Icons 上抓一張圖來用,code 如下:
marker 的另外 2 個參數
「標記」除了自定 icon,還有另外 2 個參數可以用:
- 可否拖拉
- 動態效果
可否拖拉的參數是「draggable」,動態效果是「animation」:
let marker = new google.maps.Marker({ position: latLng, map: this.map, animation: google.maps.Animation.DROP, // DROP掉下來、BOUNCE一直彈跳 draggable: false // true、false可否拖拉 });
這一階段會看到的結果如下:
六、Info Windows
在標記上,還有一個很特別的功能,是要用 API 才會有的,就是 Info Windows,資訊小視窗,樣式如下:
官方文件中,info windows 有專門的一頁在介紹,這邊就直接製作一個範例出來。(info Windows官方文件)
在用回圈寫入 marker 時,就要把 info Windows 加進去,並監聽 click 事件。
這邊的範例再特別寫入一個,由外面的按鈕讓 marker 上的 info windows 被打開,而不是一定要點到 marker 才會打開。
HTML 用 v-for 為每個地點加入一個按鈕,並加上 @click 事件:
<button type="button" class="btn btn-outline-secondary" v-for="f in features" @click="openInfoWindows(f.properties.id)" > {{ f.properties.name }} </button>
JavaScript 部份如下:
看到的頁面截圖如下:
七、客製化地圖樣式
API 除了可以做出客製標記(marker)、info windows 外,還可以做一個直接用 Google Map 做不到的事,就是客製化地圖樣式。
這邊直接參考文件的示範,寫一個 night mode 的地圖,跟隱藏商家的地圖。
night mode 地圖
在一開始建立地圖,也就是以下這段的時候:
this.map = new google.maps.Map(document.getElementById('map'), { center: location, zoom: 16, mapTypeId: 'terrain', styles: [ /* ... */ ] // 這邊可加入客製style });
就可以加入一個「styles」的參數,把想要的樣式給加進去了。當然,加的規則必須照著文件上的寫。(Start Styling your Map官方文件)
這邊寫一個可以用 toggle 按鈕,切換日間/夜間地圖的範例:
以下是頁面截圖:
2 個重要的連結
這邊附上 2 個重要連結:
1 每一個 feature、element 的說明:
https://developers.google.com/maps/documentation/javascript/style-reference?hl=zh-tw#style-features
2 styles 生成器:
https://mapstyle.withgoogle.com/
有了以上這 2 個連結,想用一些自訂的模式就比較容易了。
隱藏地圖上其他商家
以下附上隱藏商家的 Demo,主要是覺得會有企畫提出「地圖上東西太多太干擾了想隱藏掉」、「地圖上出現其他同業了啦要刪掉」這種需求。
其實會了上面的 night mode 以後,隱藏商家就容易了,設定的 styles 比夜間模式還少,styles 上改成以下就行:
hideStyle: [{ featureType: 'poi.business', stylers: [{ visibility: 'off' }] }]
頁面的截圖如下:
拿掉商家後,地圖一整個乾淨很多。
八、隱藏地圖上UI
Google Map上有一些預設的 UI,如下圖紅框:
Google Map API 有提供參數去隱藏 / 顯示它們,如下:
- zoomControl: boolean
- mapTypeControl: boolean
- scaleControl: boolean
- streetViewControl: boolean
- rotateControl: boolean
- fullscreenControl: boolean
要使用時,只要在建立地圖上加上這些參數就行了,例如:
this.map = new google.maps.Map(document.getElementById('map'), { center: location, zoom: 16, mapTypeId: 'terrain', mapTypeControl: false });
九、本篇原始檔下載
Google Maps API 的官方文件有好幾頁,有很多東西可以玩,這篇是看到現在的第一階段筆記,記錄一下覺得以後會遇到的需求。
上面的原始碼整理在 GitHub 上了,歡迎使用:
https://github.com/letswritetw/letswrite-google-map-api-1
請問 如果我只想顯示 道路名稱 其餘商家等等資訊都不要時
該怎樣編寫呢?
方便請在解答一下
謝謝
參考他的設定值:
https://developers.google.com/maps/documentation/javascript/style-reference#style-features
所以可以這樣寫:
結果會是這樣:
您好:
想請問一下如果多點包含其他國家的話會怎麼顯示呢??
目前看您的範例都是以同一縣市或同一區做示範~
方便的話再幫我解答一下,感謝~