9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GAS で Google Maps API を利用して目的地までの所要時間を取得する

Posted at
  • ある地点から 目的地までの所要時間を Google Apps Script でまとめて取得しました

TL;DR

  • Maps.newDirectionFinder() で Google Maps Directions API を利用した経路検索ができます
    • origin (出発地), destination (目的地), mode (移動手段) をパラメータに指定します
  • 所要時間は directions.routes[0].legs[0].duration で取得できます
const origin = 'XXXXX' // 出発地の名称を記入してください

const directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(dest)
  .setMode(Maps.DirectionFinder.Mode.DRIVING)
  .getDirections()

const duration = directions.routes[0].legs[0].duration

目次

  • はじめに
  • 大まかな流れ
  • スクリプト実行前のスプレッドシート (例)
  • 実装
    • スプレッドシートから値を取得する
    • 目的地までの所要時間を取得する
    • スプレッドシートに 所要時間 (テキスト, 数値) を記入する
  • 全体のコード
  • スクリプト実行後のスプレッドシート (例)
  • おわりに
  • 補足
  • 参考

はじめに

  • 今回は Standalone ではなく Container-bound Script として GAS を作成します
    • 紐付くスプレッドシートに対する 読み/書き を行います
  • 読み/書き の権限を与えるため appsscript.json (manifest file) に以下を追記します
{
  ...
  "oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets.currentonly"
  ],
  ...
}

大まかな流れ

  • スプレッドシートにあらかじめ 目的地の名称を記入しておきます
  • GAS を実行して 目的地までのそれぞれの所要時間 を スプレッドシートに記入します
  • スプレッドシート側で 所要時間の少ない順にソートできるようにします

スクリプト実行前のスプレッドシート (例)

destination duration.text duration.value
ららぽーと富士見    
コクーンシティ    
浦和PARCO    
ららぽーと新三郷    
イオンレイクタウン    

実装

スプレッドシートから値を取得する

  • getDataRange() でデータが存在する範囲を取得します
// slice(1) to skip the header
const rows = SpreadsheetApp.getActiveSheet().getDataRange().getValues().slice(1)

// row[0] is the column of destinations
return rows.map(function (row) { return row[0] })

目的地までの所要時間を取得する

  • Maps.newDirectionFinder() を利用します
  • 今回は 車での経路取得をしました
const directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(dest)
  .setMode(Maps.DirectionFinder.Mode.DRIVING)
  .getDirections()
  • のちにソートするために 所要時間の秒数表記の値 duration.value も取得しておきます
"duration" : {
  "text" : "51 mins",
  "value" : 3062
}
  • のちにスプレッドシートに書き込むために object を 配列に変換しておきます
const duration = directions.routes[0].legs[0].duration

// Object.values() doesn't exist in Google Apps Script
return Object.keys(duration).map(function (key) { return duration[key] })

スプレッドシートに 所要時間 (テキスト, 数値) を記入する

  • getRange(row, column, numRows, numColumns) で durations を書き込むシートの範囲を取得します
  • range.setValues で二次元配列の durations をシートに記入します
// slice(1) to skip the header
const rows = SpreadsheetApp.getActiveSheet().getDataRange().getValues().slice(1)

// NOTE: getRange(row, column, numRows, numColumns)
const range = SpreadsheetApp.getActiveSheet().getRange(2, 2, rows.length, 2)

range.setValues(durations)

全体のコード

// Goal:
//   Find the closest store
//
// Usage:
//   Run the code on the Script Editor manually
//
// Summary:
//   Return duration.text and duration.value to the spreadsheet
//   Sort by duration.value on the spreadsheet
//
// Description:
//   1. Obtain destinations from the spreadsheet
//   2. Call calcDuration(dest) for each destinations
//   3. Calculate a duration
//   4. Update the duration.text and duration.value on the spreadsheet

function getDuration() {
  const destinations = readDestinations()

  const durations = destinations.map(function (dest) {
    return calcDuration(dest)
  })

  writeDurations(durations)
}

function readDestinations() {
  const rows = getTargetedRows()

  // row[0] is the column of destinations
  return rows.map(function (row) { return row[0] })
}

function writeDurations(durations) {
  const rows = getTargetedRows()

  // NOTE: getRange(row, column, numRows, numColumns)
  const range = SpreadsheetApp.getActiveSheet().getRange(2, 2, rows.length, 2)
  
  range.setValues(durations)
}

// Return duration.text and duration.value in a multi-dimensional array
function calcDuration(dest) {
  // Hard-coding the value of `origin`
  const origin = 'XXXXX' // 出発地の名称を記入してください

  const directions = Maps.newDirectionFinder()
    .setOrigin(origin)
    .setDestination(dest)
    .setMode(Maps.DirectionFinder.Mode.DRIVING)
    .getDirections()

  const duration = directions.routes[0].legs[0].duration

  // Object.values() doesn't exist in Google Apps Script
  return Object.keys(duration).map(function (key) { return duration[key] })
}

function getTargetedRows() {
  // slice(1) to skip the header
  return SpreadsheetApp.getActiveSheet().getDataRange().getValues().slice(1)
}

スクリプト実行後 スプレッドシート (例)

destination duration.text duration.value
ららぽーと富士見 35 mins 2102
コクーンシティ 51 mins 3039
浦和PARCO 52 mins 3094
ららぽーと新三郷 1 hour 2 mins 3708
イオンレイクタウン 1 hour 5 mins 3875

おわりに

  • 私は埼玉に土地勘がなく 商業施設の名称を見ても出発地からの距離感がわからなかったのですが GAS を使うことで 近くの店舗を見つけることができました
  • まだ試したことはないのですが 次回は Google Charts を利用して Map にプロットできると良さそうですね

補足

  • スプレッドシートの 読み/書き に getDataRange() を利用したのですが あまりスマートなやり方とは思えません...
  • より良い方法をご教授いただけると幸いです :bow:

スプレッドシートから目的地の名称を取得

const rows = SpreadsheetApp.getActiveSheet().getDataRange().getValues().slice(1)

// column A
return rows.map(function (row) { return row[0] })

所要時間を記入するシートの範囲を取得する

const rows = SpreadsheetApp.getActiveSheet().getDataRange().getValues().slice(1)

// column B, C
const range = SpreadsheetApp.getActiveSheet().getRange(2, 2, rows.length, 2)

参考

9
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?