Google Maps API - 顯示海拔高度

除了基本的地圖使用,Google Maps API 也有提供海拔高度的服務,雖然在地形圖的檢視模式下,可以看到山脈的高低起伏,但海拔高度服務卻能查詢某個位置的高度資料,這個服務目前常見於一些導航或運動類的應用程式 ( 現在其實不少偵測高度的裝置是使用氣壓計來量測 )。

啟用 Google Maps Elevation API

要使用海拔高度服務,首先要啟用 Google Maps Elevation API,前往 Google Console,選擇和自己的 Google Maps JavaScript API 同樣的專案,進入專案後點選「啟用 API 和服務」。

Google Maps API - 顯示海拔高度

進入後搜尋 Google Maps Elevation API,搜尋到了之後就將其啟用。

Google Maps API - 顯示海拔高度

依據 Google 的限制規範,Google Maps Elevation API 的標準方案 ( 免費版 ) 每天可以有 2500 個免費 request,每個秒可以有 50 個 request,而每個 request 可以有 512 個位置,此外若使用 ElevationService,Google 也有限制不得用於 Google 地圖以外的地方,如果是開發應用程式服務,也必須標註相關使用條款與隱私權政策。

顯示地形圖

回顧 Google Maps (2) - 使用地圖與基本設定 ,只要將地圖的 mapTypeId 屬性修改為 terrain,就能在地圖上同時顯示街道與地形,接下的範例就會先把地圖變更為地形圖模式。( 其實也不見得要用地形圖,只是覺得如果偵測海拔高度,用地形圖比較應景 )

範例:Google 地圖顯示地形

var map;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {
      lat: 25.0336962,
      lng: 121.5643673
    },
    mapTypeId:'terrain' //設定為'terrain'
  });
}

Google Maps API - 顯示海拔高度

如何使用

使用海拔高度前,要先宣告 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 公尺。

範例:Google 地圖顯示某個位置的海拔高度

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);
    });
  }
}

Google Maps API - 顯示海拔高度

如果不想用瀏覽器的 console 顯示,也可以使用 Google 地圖的資訊視窗 infowindow 來顯示滑鼠點擊地點的海拔高度,下面的例子在地圖上先宣告一個 infowindow,然後在滑鼠點擊的當下,由results[0].location取的經緯度,由results[0].elevation取得海拔高度,並轉換為小數點兩位的數字,最後透過 infowindow 呈現。

範例:Google 地圖資訊視窗某個位置的海拔高度

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);
    });
  }
}

Google Maps API - 顯示海拔高度

顯示路徑上的海拔高度 ( 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 Maps API - 顯示海拔高度

如果你會使用像是 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);
    });
  });
}

Google Maps API - 顯示海拔高度

參考

有興趣瞧瞧其他新文章嗎?