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 控制台中,按一下專案下拉式選單,然後選取要用於本程式碼研究室的專案。
- 在 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 地圖平台服務 (例如 Places)。
如果您先前使用過 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 Loader,請按照下列步驟操作:
- 開啟
/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 載入器會傳回 Promise,API 載入完成並可供使用時,Promise 就會解析。加入下列存根,載入 API 並處理 Promise:loader.load().then(() => { console.log('Maps JS API loaded'); });
如果一切順利,您應該會在瀏覽器控制台中看到 console.log
陳述式。使用 Chrome 時,可以依序點選「查看」->「開發人員」->「Javascript 控制台」,存取這個額外視窗。
總結來說,您現在已從程式碼動態載入 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.load().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 }; }
- 取得
div
,地圖應注入至 DOM 中。
顯示地圖前,您必須先告知 Maps JavaScript API 要在網頁的哪個位置顯示地圖。如果您快速查看index.html
,會發現已有類似這樣的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 Promise 處理常式呼叫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);
}
完成後,您應該會在 Google 地圖上看到所選樣式!
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
,可自動為您完成所有作業。您可以在 GitHub 上查看 MarkerClustererPlus 的來源。
- 匯入
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 Promise 處理常式呼叫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 地圖平台,請參閱下列連結: