Google Maps API - 顯示海拔高度
除了基本的地圖使用,Google Maps API 也有提供海拔高度的服務,雖然在地形圖的檢視模式下,可以看到山脈的高低起伏,但海拔高度服務卻能查詢某個位置的高度資料,這個服務目前常見於一些導航或運動類的應用程式 ( 現在其實不少偵測高度的裝置是使用氣壓計來量測 )。
啟用 Google Maps Elevation API
要使用海拔高度服務,首先要啟用 Google Maps Elevation API,前往 Google Console,選擇和自己的 Google Maps JavaScript API 同樣的專案,進入專案後點選「啟用 API 和服務」。
![]()
進入後搜尋 Google Maps Elevation API,搜尋到了之後就將其啟用。
![]()
依據 Google 的限制規範,Google Maps Elevation API 的標準方案 ( 免費版 ) 每天可以有 2500 個免費 request,每個秒可以有 50 個 request,而每個 request 可以有 512 個位置,此外若使用 ElevationService,Google 也有限制不得用於 Google 地圖以外的地方,如果是開發應用程式服務,也必須標註相關使用條款與隱私權政策。
顯示地形圖
回顧 Google Maps (2) - 使用地圖與基本設定 ,只要將地圖的 mapTypeId 屬性修改為 terrain,就能在地圖上同時顯示街道與地形,接下的範例就會先把地圖變更為地形圖模式。( 其實也不見得要用地形圖,只是覺得如果偵測海拔高度,用地形圖比較應景 )
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: {
lat: 25.0336962,
lng: 121.5643673
},
mapTypeId:'terrain' //設定為'terrain'
});
}
![]()
如何使用
使用海拔高度前,要先宣告 ElevationService,宣告的方法很簡單,一行程式碼就搞定。
var elevator = new google.maps.ElevationService;
宣告後,就能使用 callback 的方法,這裡有兩種方法可以使用:
- getElevationForLocations():位置高度要求,指定一個或多個位置然後回傳對應高度。
- getElevationAlongPath():路徑高度要求,指定一段路徑上的樣本數,回傳對應高度。
再來就看看回傳的內容,包含一組 ElevationStatus 物件和 ElevationResult 物件,ElevationStatus 表示呼叫高度服務後的狀態,總共有五種代碼狀態,基本上只要是 OK 就表示呼叫成功。
- OK:指出服務要求成功
- INVALID_REQUEST:指出服務要求的格式錯誤
- OVER_QUERY_LIMIT:指出要求者已超過配額
- REQUEST_DENIED:指出服務沒有完成要求,原因可能是因為參數無效
- UNKNOWN_ERROR:指出不明錯誤
呼叫成功後,callback 內的函式變數 results 就包含 ElevationResult 物件,ElevationResult 有三個元素,這也是到時候結果要顯示的內容。
- location:正在計算高度資料的地點,回傳經緯度。
- elevation:該位置的海拔高度 ( 以公尺為單位 )。
- resolution:以內插計算高度的兩個資料點之間的最大距離 ( 以公尺為單位,如果解析度為未知,則不會有此屬性 )。
顯示位置上的海拔高度 ( getElevationForLocations() )
getElevationForLocations() 的用法:
getElevationForLocations({
locations[]: LatLng
},callback(results, status));
下面這段程式碼,首先使用addListener監聽 map 的滑鼠點擊事件,在點擊的當下,取得滑鼠的經緯度,接著把經緯度拋給 ElevationService,透過 getElevationForLocations() 獲得該經緯度的海拔高度,並顯示在瀏覽器的 console 裏頭,以下方的例子,當我點擊「松山文創園區」,就能看到它的海拔高度約為 11.186 公尺。
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: {
lat: 25.0336962,
lng: 121.5643673
},
mapTypeId: 'terrain'
});
var elevator = new google.maps.ElevationService;
map.addListener('click', function(event) {
displayLocationElevation(event.latLng, elevator);
});
function displayLocationElevation(location, elevator) {
elevator.getElevationForLocations({
'locations': [location]
}, function(results, status) {
console.log(results, status);
});
}
}
![]()
如果不想用瀏覽器的 console 顯示,也可以使用 Google 地圖的資訊視窗 infowindow 來顯示滑鼠點擊地點的海拔高度,下面的例子在地圖上先宣告一個 infowindow,然後在滑鼠點擊的當下,由results[0].location取的經緯度,由results[0].elevation取得海拔高度,並轉換為小數點兩位的數字,最後透過 infowindow 呈現。
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: {
lat: 25.0336962,
lng: 121.5643673
},
mapTypeId: 'terrain'
});
var elevator = new google.maps.ElevationService;
var infowindow = new google.maps.InfoWindow();
map.addListener('click', function(event) {
displayLocationElevation(event.latLng, elevator);
});
function displayLocationElevation(location, elevator) {
elevator.getElevationForLocations({
'locations': [location]
}, function(results, status) {
var coordinate = {
lat: results[0].location.lat(),
lng: results[0].location.lng()
};
var elevation = Math.round(results[0].elevation * 100) / 100;
infowindow.setPosition(coordinate);
infowindow.setContent('<h2>海拔:' + elevation + ' 公尺</h2>');
infowindow.open(map);
});
}
}
![]()
顯示路徑上的海拔高度 ( getElevationAlongPath() )
getElevationAlongPath() 的用法:
getElevationAlongPath({
path[]: LatLng,
samples: Number
},callback(results, status));
getElevationAlongPath() 顧名思義就是沿著一個形狀的海拔高度,所以要先在地圖上繪製一段折線 ( 參考 Google Maps (9) - 繪製折線 ( Polyline ) ),並定義取樣的數量,應該就可以在瀏覽器的 console 裡看到折線中每個取樣點的海拔高度,以下面的例子來說,我在龍山寺到指南宮之間繪製一條直線,中間取樣 100 個點,透過 console 就能看到中間的高度變化。
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {
lat: 25.0336962,
lng: 121.5643673
},
mapTypeId: 'terrain'
});
var elevator = new google.maps.ElevationService;
var polylinePathPoints = [{
lat: 25.037113,
lng: 121.499916
}, {
lat: 24.979854,
lng: 121.587109
}];
var polylinePath = new google.maps.Polyline({
map: map,
path: polylinePathPoints,
strokeColor: '#ff0000',
strokeOpacity: 0.8,
strokeWeight: 10
});
displayPathElevation(polylinePathPoints,elevator);
function displayPathElevation(path, elevator) {
elevator.getElevationAlongPath({
'path': path,
'samples': 100
}, function(results, status){
console.log(results, status)
});
}
}
![]()
如果你會使用像是 Google Charts 之類的工具來繪製折線圖,你就可以把這些數值傳出來畫圖,看來彷彿就是這條線上的地形頗面圖,操作方式也很容易,只需要改寫剛剛執行的流程,把繪製折線圖的函式加進去即可。
範例:繪製路徑海拔折線圖
function displayPathElevation(path, elevator) {
elevator.getElevationAlongPath({
'path': path,
'samples': 100
}, function(results, status) {
// 將 results 轉換為 Google 折線圖的資料格式
var arr = [];
arr.push(['number','elevation']);
for (let i = 0; i < results.length; i++) {
arr.push([i, results[i].elevation]);
}
// Google Chart 繪製折線圖函式
google.charts.load('current', {
'packages': ['corechart']
});
google.charts.setOnLoadCallback(function() {
var data = google.visualization.arrayToDataTable(arr);
var chart = new google.visualization.LineChart(document.getElementById('draw-chart'));
var options = {
legend: {
position: 'bottom'
}
};
chart.draw(data, options);
});
});
}
![]()