1. 事前準備
本程式碼研究室將說明 Google 地圖平台網頁版的一切必要設定。從設定到載入 Maps JavaScript API、顯示第一個地圖、使用標記和標記叢集、在地圖上繪製,以及處理使用者互動等操作,您都會學到所有基本知識。
建構項目
在這個程式碼研究室中,您將建構簡單的網頁應用程式:
- 載入 Maps JavaScript API
- 顯示以澳洲雪梨為中心的地圖
- 顯示雪梨熱門景點的自訂標記
- 實作標記叢集
- 啟用使用者最近的標記,並在使用者點擊標記時在地圖上繪製圓形
課程內容
- 開始使用 Google 地圖平台
- 從 JavaScript 程式碼動態載入 Maps JavaScript API
- 載入地圖
- 使用標記、自訂標記和標記叢集
- 使用 Maps JavaScript API 事件系統為使用者提供互動功能
- 動態控管地圖
- 在地圖上繪圖
2. 必要條件
您必須熟悉以下物品,才能完成此程式碼研究室。如果您熟悉 Google 地圖平台的使用方式,請直接跳到程式碼研究室!
必要的 Google 地圖平台產品
在本程式碼研究室中,您會使用下列 Google 地圖平台產品:
- Maps JavaScript API
- MarkerClustererPlus 開放原始碼標記叢集資料庫
這個程式碼研究室的其他規定
要完成此程式碼研究室,您需要下列帳戶、服務和工具:
- 已啟用帳單功能的 Google Cloud Platform 帳戶
- 已啟用 Maps JavaScript API 的 Google 地圖平台 API 金鑰
- JavaScript、HTML 和 CSS 的基本知識
- 您電腦上安裝的 Node.js
- 您選擇的文字編輯器或 IDE
開始使用 Google 地圖平台
如果您未曾使用過 Google 地圖平台,請按照開始使用 Google 地圖平台指南或觀看 Google 地圖平台入門指南完成下列步驟:
- 建立帳單帳戶。
- 建立專案。
- 啟用 Google 地圖平台的 API 和 SDK (如上一節所示)。
- 產生 API 金鑰。
3. 進行設定
設定 Google 地圖平台
如果您還沒有 Google Cloud Platform 帳戶和已啟用計費功能的專案,請參閱開始使用 Google 地圖平台指南,建立帳單帳戶和專案。
- 在 Cloud Console 中按一下專案下拉式選單,然後選取您要用於這個程式碼研究室的專案。
- 在 Google Cloud Marketplace 中啟用此程式碼研究室所需的 Google 地圖平台 API 和 SDK。詳細步驟請參閱這部影片或這份文件。
- 在 Cloud Console 的「憑證」頁面中產生 API 金鑰。你可以按照這部影片或這份說明文件中的步驟進行。傳送至 Google 地圖平台的所有要求都需要 API 金鑰。
Node.js 設定
如果您尚未安裝,請前往 https://nodejs.org/,在您的電腦下載並安裝 Node.js 執行階段。
Node.js 隨附 npm 套件管理員,您必須為這個程式碼研究室安裝依附元件。
專案入門範本設定
開始進行這個程式碼研究室之前,請按照下列步驟下載入門專案範本以及完整的解決方案程式碼:
- 前往 https://github.com/googlecodelabs/maps-platform-101-js 下載或建立此程式碼研究室的 GitHub 存放區。
入門專案位於 /starter
目錄中,其中包含完成程式碼研究室所需的基本檔案結構。您所需的一切都位於/starter/src
目錄中。2. 下載入門專案後,請在 /starter
目錄中執行 npm install
。這會安裝 package.json
中列出的所有必要依附元件。3. 安裝依附元件後,請在目錄中執行 npm start
。
設定完成之後,您可以使用 Webpack-dev-server,這個程式會編譯及執行您寫入的程式碼。webpack-dev-server 也會在您變更程式碼時,在瀏覽器中自動重新載入應用程式。
如要查看完整的解決方案程式碼,請在 /solution
目錄中完成上述設定步驟。
4. 載入 Maps JavaScript API
開始之前,請務必按照設定說明中的步驟操作。全部完成了嗎?好了,該來使用 Google 地圖平台建立您的第一個網路應用程式了!
使用 Google 地圖平台網頁版的宗旨是 Maps JavaScript API。此 API 提供 JavaScript 介面,以使用 Google 地圖平台的所有功能,包括地圖、標記、繪圖工具和其他 Google 地圖平台服務 (例如「地點」)。
如果您過去有使用 Maps JavaScript API 的經驗,您或許會熟悉將 script
標記插入 HTML 檔案來載入,如下所示:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
雖然載入 API 仍是完全有效的方法,但現代化的 JavaScript 依附元件通常會以動態方式包含在程式碼中。為了從程式碼中完成 script
標記的對等項目,您將使用 @googlemaps/js-api-loader 模組。JS API 載入器已納入專案的 package.json
檔案的依附元件,因此您先前執行的 npm install
已安裝此檔案。
如要使用 JS API 載入器,請執行下列步驟:
- 開啟
/src/app.js
。這個檔案是您在此程式碼研究室的所有工作。 - 從 @googlemaps/js-api-loader 匯入
Loader
類別。
將以下內容新增至app.js
頂端:import { Loader } from '@googlemaps/js-api-loader';
- 建立
apiOptions
物件。
Loader
類別需要一個 JSON 物件,以指定載入 Maps JavaScript API 的多種選項,包括 Google Maps Platform API 金鑰、您要載入的 API 版本,以及您要載入的 Maps JS API 提供的任何其他程式庫。關於本程式碼研究室,您只要將下列指令附加至app.js
,即可指定 API 金鑰:const apiOptions = { apiKey: "YOUR API KEY" }
- 建立
Loader
的執行個體,並傳送給您的apiOptions
。const loader = new Loader(apiOptions);
- 載入 Maps JS API。
如要載入 API,請在Loader
執行個體上呼叫load()
。JS API 載入器會傳回一個承諾,待 API 載入後即可開始使用。加入以下 stub 以載入 API 並處理承諾:loader.load().then(() => { console.log('Maps JS API loaded'); });
如果一切都成功,你會在瀏覽器控制台中看到 console.log
陳述式:
我們來複習一下,您現已從程式碼中動態載入 Maps JavaScript API,並定義可在 Maps JavaScript API 載入後執行的回呼函式。
您的 app.js
檔案應如下所示:
import { Loader } from '@googlemaps/js-api-loader';
const apiOptions = {
apiKey: "YOUR API KEY"
}
const loader = new Loader(apiOptions);
loader.then(() => {
console.log('Maps JS API Loaded');
});
Maps JavaScript API 已載入完成,您將在下一個步驟中載入地圖。
5. 顯示地圖
是時候顯示您的首張地圖了!
Maps JavaScript API 最常用的部分是 google.maps.Map
,這個類別讓我們能夠建立及操控地圖執行個體。請查看「displayMap()
」這項新功能,看看如何達成這個目標。
- 定義地圖設定。
Maps JavaScript API 支援多種不同的地圖設定,但只需要加入兩項設定即可:center
:設定地圖的中心緯度和經度。zoom
:設定地圖的初始縮放等級。
function displayMap() { const mapOptions = { center: { lat: -33.860664, lng: 151.208138 }, zoom: 14 }; }
- 取得將地圖插入 DOM 的
div
。
您必須先告訴 Maps JavaScript API 要顯示地圖的位置,才能顯示地圖。當您快速瀏覽index.html
時,發現div
已經是如下所示的
:<div id="map"></div>
如要指出 Maps JavaScript API 是您要將地圖插入的位置,請使用<div id="map"></div>
document.getElementById
以取得其 DOM 參照:const mapDiv = document.getElementById('map');
- 建立
google.maps.Map
的執行個體。
若要要求 Maps JavaScript API 建立可顯示的新地圖,請建立google.maps.Map
的執行個體,然後傳入mapDiv
和mapOptions
。您還可以從這個函式傳回Map
執行個體,以便之後使用更多功能:const map = new google.maps.Map(mapDiv, mapOptions); return map;
- 顯示地圖!
定義建立地圖執行個體的所有邏輯後,只要從 JS API 承諾處理常式中呼叫displayMap()
,系統就會在 Maps JavaScript API 載入後呼叫該函式:loader.then(() => { console.log('Maps JS API loaded'); const map = displayMap(); });
您的瀏覽器現在應該會顯示美麗的雪梨地圖:
總而言之,在這個步驟中,您已定義地圖的顯示選項、建立新的地圖執行個體,並插入 DOM。
displayMap()
函式看起來應該會像這樣:
function displayMap() {
const mapOptions = {
center: { lat: -33.860664, lng: 151.208138 },
zoom: 14
};
const mapDiv = document.getElementById('map');
const map = new google.maps.Map(mapDiv, mapOptions);
return map;
}
6. 雲端式地圖樣式設定 (選用)
您可以使用雲端式地圖樣式設定功能自訂地圖樣式。
建立地圖 ID
如果您尚未建立具有相關地圖樣式的地圖 ID,請參閱地圖 ID 指南,完成以下步驟:
- 建立地圖 ID。
- 將地圖 ID 與地圖樣式建立關聯。
在應用程式中加入地圖 ID
如要使用您建立的地圖 ID,請修改 app.js
檔案中的 displayMap
函式,並將 mapOptions
物件的 mapId
屬性傳送至您的地圖 ID。
app.js
function displayMap() {
const mapOptions = {
center: { lat: -33.860664, lng: 151.208138 },
zoom: 14,
mapId: 'YOUR_MAP_ID'
};
const mapDiv = document.getElementById('map');
return new google.maps.Map(mapDiv, mapOptions);
}
完成此操作後,即可在地圖上查看您選取的樣式!
7. 在地圖上加入標記
開發人員使用 Maps JavaScript API 執行許多操作,但將標記放上地圖絕對是最受歡迎的功能。您可以透過標記在地圖上顯示特定點,這是處理使用者互動的常見 UI 元素。如果您之前已經使用過 Google 地圖,那麼您應該很熟悉預設標記,如下所示:
在這個步驟中,您將使用 google.maps.Marker
在地圖上放置標記。
- 為您的標記位置定義物件。
首先,請建立新的addMarkers()
函式,並宣告locations
物件,其中包含針對雪梨熱門觀光景點的下列經緯度座標。
另外請注意,您必須將Map
例項傳送至函式。稍後在建立標記執行個體時使用。function addMarkers(map) { const locations = { operaHouse: { lat: -33.8567844, lng: 151.213108 }, tarongaZoo: { lat: -33.8472767, lng: 151.2188164 }, manlyBeach: { lat: -33.8209738, lng: 151.2563253 }, hyderPark: { lat: -33.8690081, lng: 151.2052393 }, theRocks: { lat: -33.8587568, lng: 151.2058246 }, circularQuay: { lat: -33.858761, lng: 151.2055688 }, harbourBridge: { lat: -33.852228, lng: 151.2038374 }, kingsCross: { lat: -33.8737375, lng: 151.222569 }, botanicGardens: { lat: -33.864167, lng: 151.216387 }, museumOfSydney: { lat: -33.8636005, lng: 151.2092542 }, maritimeMuseum: { lat: -33.869395, lng: 151.198648 }, kingStreetWharf: { lat: -33.8665445, lng: 151.1989808 }, aquarium: { lat: -33.869627, lng: 151.202146 }, darlingHarbour: { lat: -33.87488, lng: 151.1987113 }, barangaroo: { lat: - 33.8605523, lng: 151.1972205 } } }
- 為您想顯示的每個標記建立
google.maps.Marker
例項。
如要建立標記,請使用下列程式碼,以使用for...in
迴圈疊代locations
物件,建立一組標記顯示方式選項,並為各個位置建立google.maps.Marker
的執行個體。
請注意markerOptions
的icon
屬性。還記得先前的地圖預設圖釘嗎?您知道嗎?好極了!
icon
屬性可讓您為要當做自訂標記的圖片檔案提供路徑。如果您是使用我們的專案範本來啟動此程式碼研究室,則/src/images
中已包含一張圖片。
請注意,您必須將標記例項儲存在陣列中,並從函式傳回這些執行個體,以便日後使用。const markers = []; for (const location in locations) { const markerOptions = { map: map, position: locations[location], icon: './img/custom_pin.png' } const marker = new google.maps.Marker(markerOptions); markers.push(marker); } return markers;
- 顯示標記。
每次建立新的google.maps.Marker
執行個體時,Maps JavaScript API 都會自動建立並顯示標記,因此您只需要更新 JS API 承諾處理常式,即可呼叫addMarkers()
並傳遞Map
例項:loader.then(() => { console.log('Maps JS API loaded'); const map = displayMap(); const markers = addMarkers(map); });
系統現在應該會在地圖上顯示自訂標記:
我們來複習一下,在這個步驟中,您定義了一組標記位置,並建立了 google.maps.Marker
的執行個體,其中包含每個位置的自訂標記圖示。
addMarkers()
函式看起來應該會像這樣:
function addMarkers(map) {
const locations = {
operaHouse: { lat: -33.8567844, lng: 151.213108 },
tarongaZoo: { lat: -33.8472767, lng: 151.2188164 },
manlyBeach: { lat: -33.8209738, lng: 151.2563253 },
hyderPark: { lat: -33.8690081, lng: 151.2052393 },
theRocks: { lat: -33.8587568, lng: 151.2058246 },
circularQuay: { lat: -33.858761, lng: 151.2055688 },
harbourBridge: { lat: -33.852228, lng: 151.2038374 },
kingsCross: { lat: -33.8737375, lng: 151.222569 },
botanicGardens: { lat: -33.864167, lng: 151.216387 },
museumOfSydney: { lat: -33.8636005, lng: 151.2092542 },
maritimeMuseum: { lat: -33.869395, lng: 151.198648 },
kingStreetWharf: { lat: -33.8665445, lng: 151.1989808 },
aquarium: { lat: -33.869627, lng: 151.202146 },
darlingHarbour: { lat: -33.87488, lng: 151.1987113 },
barangaroo: { lat: - 33.8605523, lng: 151.1972205 }
}
const markers = [];
for (const location in locations) {
const markerOptions = {
map: map,
position: locations[location],
icon: './img/custom_pin.png'
}
const marker = new google.maps.Marker(markerOptions);
markers.push(marker);
}
return markers;
}
在下一個步驟中,您將瞭解如何使用標記叢集改善標記使用者體驗。
8. 啟用標記叢集
如果您使用的標記或標記彼此相鄰,您可能會碰到問題重疊或標記過於擁擠,導致使用者體驗不佳。例如,在最後一個步驟中建立標記後,您可能注意到以下情況:
這時,標記叢集就能派上用場。標記叢集是另一項常見的實作功能,可將鄰近標記分組為單一縮放等級,並依據縮放等級調整內容,如下所示:
標記叢集演算法會將地圖可見區域分成一個網格,然後在同一個儲存格中對叢集圖示進行分組。別擔心,Google 地圖平台小組建立了一套名為 MarkerClustererPlus
的實用開放原始碼程式庫,可自動執行所有工作,因此您不必擔心上述問題。您可以查看 MarkerClustererPluson GitHub 的來源。
- 匯入
MarkerCluster
。
在這個程式碼研究室的範本專案中,MarkerClustererPlus
公用程式庫已包含在package.json
檔案中所宣告的依附元件中,因此您已在這個程式碼研究室開始時執行npm install
。
如要匯入程式庫,請將以下內容新增至app.js
檔案的頂端:import MarkerClusterer from '@google/markerclustererplus';
- 建立新的
MarkerClusterer
執行個體。
如要建立標記叢集,您必須執行下列兩項操作:提供您想用於標記叢集的圖示,以及建立新的MarkerClusterer
例項。
首先,宣告一個物件,指定要使用的圖示路徑。在範本專案中,./img/m
已經儲存了一組映像檔。請注意,圖片檔案名稱的先後順序相同,例如:m1.png
、m2.png
、m3.png
等。
當您在標記叢集選項的選項中設定imagePath
屬性時,只需提供路徑和檔案前置字元,標記叢集工具就會自動使用含有該前置字串的所有檔案,並在結尾加上一個數字。
接著,建立新的MarkerClusterer
執行個體,並將Map
的執行個體傳送至要顯示標記叢集的執行個體,以及Marker
的叢集叢集。function clusterMarkers(map, markers) { const clustererOptions = { imagePath: './img/m' } const markerCluster = new MarkerClusterer(map, markers, clustererOptions); }
- 顯示標記叢集。
從 JS API 承諾處理常式中呼叫clusterMarkers()
。透過函式呼叫建立MarkerClusterer
執行個體時,標記叢集會自動新增至地圖。loader.then(() => { console.log('Maps JS API loaded'); const map = displayMap(); const markers = addMarkers(map); clusterMarkers(map, markers); });
系統現在應該會在地圖上顯示數個標記叢集。
請注意,放大或縮小標記時,MarkerClustererPlus 會自動為您重新調整叢集大小並調整大小。您也可以按一下任一標記叢集圖示來放大及檢視該叢集中的所有標記。
我們來複習一下,在這個步驟中,您已匯入開放原始碼 MarkerClustererPlus
公用程式庫,並利用該程式庫建立 MarkerClusterer
的執行個體,該叢集會自動將您在前一個步驟建立的標記分群。
clusterMarkers()
函式看起來應該會像這樣:
function clusterMarkers(map, markers) {
const clustererOptions = { imagePath: './img/m' }
const markerCluster = new MarkerClusterer(map, markers, clustererOptions);
}
接下來,您將瞭解如何處理使用者互動。
9. 新增使用者互動
現在您擁有一張很棒的地圖,可顯示雪梨一些熱門的旅遊景點。在這個步驟中,您會使用 Maps JavaScript API 的事件系統,額外處理使用者互動作業,以進一步改善使用者的使用者體驗。
Maps JavaScript API 提供全方位的事件系統,該系統使用 JavaScript 事件處理常式,方便您處理程式碼中的各種使用者互動。舉例來說,您可以建立事件監聽器來觸發程式碼的執行行為,例如使用者點選地圖和標記、平移地圖檢視、縮放及執行其他動作。
在此步驟中,您會新增一個點擊接聽器至您的標記,然後透過程式進行平移,將標記放在地圖中央。
- 在標記上設定點擊接聽器。
Maps JavaScript API 中支援事件系統的所有物件都會導入一組標準函式,以便處理使用者互動 (例如addListener
、removeListener
等)。
如要在每個標記中加入點擊事件監聽器,請反覆處理markers
陣列並呼叫標記例項上的addListener
,為click
事件附加事件監聽器:function addPanToMarker(map, markers) { markers.map(marker => { marker.addListener('click', event => { }); }); }
- 點選滑鼠並捲動到標記上。
每次使用者點擊或輕觸標記時,就會觸發click
事件,並以 JSON 物件的形式傳回事件,其中包含所點擊 UI 元素的相關資訊。如要改善使用者的地圖體驗,您可以處理click
事件並使用其LatLng
物件,取得所點擊標記的緯度和經度。
完成此操作後,只要將該函式傳送至Map
執行個體的panTo()
內建函式,即可在事件處理常式的回呼函式中加入下列指令,讓地圖平穩出現在點擊的標記中:const location = { lat: event.latLng.lat(), lng: event.latLng.lng() }; map.panTo(location);
- 指派點擊接聽器。
從 JS API 承諾處理常式中呼叫addPanToMarker()
,並傳送地圖和標記來執行程式碼,並指派點擊事件監聽器。loader.then(() => { console.log('Maps JS API loaded'); const map = displayMap(); const markers = addMarkers(map); clusterMarkers(map, markers); addPanToMarker(map, markers); });
現在請開啟瀏覽器,然後按一下您的標記。當使用者按一下標記時,地圖應該會自動平移至較新。
我們來複習一下,您利用 Maps JavaScript API 的事件系統,為點擊的所有標記指派點擊接聽器,從已觸發的點擊事件中擷取標記緯度和經度,然後在每次點選標記時,使用該標記來更新地圖。
addPanToMarker()
函式看起來應該會像這樣:
function addPanToMarker(map, markers) {
markers = markers.map(marker => {
marker.addListener('click', event => {
const location = { lat: event.latLng.lat(), lng: event.latLng.lng() };
map.panTo(location);
});
});
return markers;
}
只剩一個步驟!接下來,您會使用 Maps JavaScript API 的繪圖功能,進一步改善使用者的使用者體驗。
10. 在地圖上繪圖
到目前為止,您已建立雪梨地圖,其中顯示熱門觀光景點的標記,並處理使用者互動。在本程式碼研究室的最後一個步驟中,您將使用 Maps JavaScript API 的繪圖功能,為地圖體驗加入額外的實用功能。
假設這張地圖將由想要探索雪梨市的使用者使用。有用就是在使用者點擊標記時,以視覺化方式呈現標記周圍的半徑範圍。讓使用者只要按一下滑鼠,就能輕易得知其他目的地的距離。
Maps JavaScript API 包含一組可在地圖上繪製形狀的函式,例如方形、多邊形、線條和圓形。接下來,您必須按一下圓圈,在使用者點擊後顯示標記周圍 800 公尺 (約半英里) 的半徑範圍。
- 畫出
google.maps.Circle
社交圈。
Maps JavaScript API 的繪圖功能提供多種選項,讓您在地圖上查看繪圖物件的顯示方式。如要顯示圓環半徑,請宣告一組圓環 (例如顏色、筆劃粗細),其中圓形應設為中心點及其半徑,然後建立新的google.maps.Circle
例項來建立新的圓形:function drawCircle(map, location) { const circleOptions = { strokeColor: '#FF0000', strokeOpacity: 0.8, strokeWeight: 1, map: map, center: location, radius: 800 } const circle = new google.maps.Circle(circleOptions); return circle; }
- 按住標記即可繪製圓圈。
如要在使用者點擊標記時畫圓圈,您只需呼叫您在addPanToMarker()
的點擊接聽器回呼中寫入的drawCircle()
函式,然後傳送該標記的地圖和位置即可。
請注意,您所新增的條件陳述式如何呼叫circle.setMap(null)
。當使用者按一下其他標記時,這會從地圖中移除之前轉譯的圓圈,因此使用者瀏覽網頁時,不會 看到被覆蓋的圓圈。addPanToMarker()
函式看起來應該會像這樣:function addPanToMarker(map, markers) { let circle; markers.map(marker => { marker.addListener('click', event => { const location = { lat: event.latLng.lat(), lng: event.latLng.lng() }; map.panTo(location); if (circle) { circle.setMap(null); } circle = drawCircle(map, location); }); }); }
大功告成!前往瀏覽器,然後按一下其中一個標記。您應該會看到周圍的圓形半徑:
11. 恭喜
您已成功使用 Google 地圖平台建立第一個網路應用程式,包括載入 Maps JavaScript API、載入地圖、使用標記、在地圖上控制和繪圖,以及新增使用者互動。
如要查看完成的程式碼,請查看 /solutions
目錄中已完成的專案。
後續步驟
本程式碼研究室將說明 Maps JavaScript API 的基本功能。接著,請嘗試在地圖中新增下列部分功能:
- 變更地圖類型,以顯示衛星、混合和地形地圖。
- 啟用本地化功能,以不同語言載入地圖。
- 自訂其他使用者互動,例如縮放和地圖控制項。
- 新增資訊視窗即可在顯示標記時顯示相關資訊。
- 查看 Maps JavaScript API 的其他程式庫,以啟用「地點」、「繪圖」和「視覺化」等其他功能。
若要繼續探索更多使用 Google 地圖平台網頁版的方法,請參考下列連結: