MENU

沿線・駅名リストからその駅の所在地(都道府県、市区町村)をGASで取得する

※非エンジニアがchatGPTに聞きながら作成したGASですので、プロ目線では至らないところがあるかと思いますが自身のメモ代わりに残します。

A列に沿線名(JR〇〇線、地下鉄△△線)、B列に駅名が入っているリスト
→それぞれの駅が存在する都道府県と市区町村を取得してcsv形式で出力したい。

目次

1. スプレッドシートの準備

駅名CSVをGoogleスプレッドシートにアップロード。以下画像のように整形する。

C列とD列に値が自動で入るイメージ。

2. Google Maps APIキーを取得

  1. Google Cloud Console にアクセスする
  2. プロジェクト作成(例:駅住所取得)
  3. 左メニュー → 「APIとサービス」→ 「ライブラリ」
  4. Geocoding API を有効にする
  5. 「認証情報」からAPIキーを作成・コピー

Geocoding APIとは?
住所や地名を経度・緯度などの地理座標に変換してくれる。
住所はJSON形式(構造化されたオブジェクト)で返され、住所情報は、results[].address_components[] という配列の中に格納されている。

無料枠のAPIリクエスト数制限は4万回/月
1件の住所(駅名)=1回のリクエストになるので、4万件までは使用可能。

address_components の中身

{
  "results": [
    {
      "address_components": [
        {
          "long_name": "東京都",
          "short_name": "東京都",
          "types": ["administrative_area_level_1", "political"]
        },
        {
          "long_name": "渋谷区",
          "short_name": "渋谷区",
          "types": ["locality", "political"]
        },
        {
          "long_name": "神南一丁目",
          "short_name": "神南1",
          "types": ["sublocality_level_1", "sublocality", "political"]
        }
      ],
      "formatted_address": "日本、〒150-0041 東京都渋谷区神南1丁目",
      ...
    }
  ],
  "status": "OK"
}
プロパティ内容
long_name住所のフル表記(例:「東京都」)
short_name略称(例:「東京」や「神南1」など)
types(配列)その成分が何を意味するかを表すタグ

よく出てくる types 一覧

typesの値意味
country日本
administrative_area_level_1都道府県東京都
administrative_area_level_2郡や政令指定都市の区北葛飾郡、横浜市
locality市区横浜市、渋谷区
ward東京23区などの「区」世田谷区
sublocality町名・丁目など神南一丁目
route通り名明治通り
premise建物名渋谷ヒカリエ
postal_code郵便番号150-0041

3. Google Apps Scriptを設定

  1. スプレッドシート上部メニュー「拡張機能」→Apps Scriptを開く
  2. 以下のコードを貼り付けて、Geocoding APIキーを設定して保存する
  3. スクリプトを実行すると、自動でスプレッドシートC列、D列に値が格納される。
const API_KEY = '★ここにAPIキーを貼る★';
const MAX_ROWS = 50;//一度に処理する駅の最大数。時間制限対策で「何件まで」に制限//

function geocodeStations() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();//現在開いてるスプレッドシートの「アクティブなシート」を取得//
  const data = sheet.getDataRange().getValues();//シート上のすべてのデータ(2次元配列)を取得。1行=1駅、1列目から順に「路線名/駅名/都道府県/市区町村」。//
  let processed = 0;

  for (let i = 1; i < data.length; i++) {// 1行目(ヘッダー)を飛ばして、2行目(i=1)からデータを繰り返し処理//
    if (processed >= MAX_ROWS) break;//一度に処理する件数がMAX_ROWSを超えたら強制終了(時間制限回避のため)//

    const stationName = data[i][1];//B列=駅名を取得//
    const prefectureCell = data[i][2];//C列=すでに入力された都道府県(空なら未処理)//
    const cityCell = data[i][3];//D列=すでに入力された市区町村。//

    if (!stationName || (prefectureCell && cityCell)) continue;//駅名が空 or 都道府県・市区町村がすでに入力済みなら処理スキップ。//

    const address = stationName + '駅';//検索精度を上げるため、駅名に「駅」を足して検索用の住所文字列を作る。//

    try {
      const response = UrlFetchApp.fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&language=ja&key=${API_KEY}`);//Google Maps Geocoding API に住所を送って、住所データを取得。//
      const json = JSON.parse(response.getContentText());

      if (json.status === 'OK') {
        const components = json.results[0].address_components;//結果の中の「住所の構成要素(都道府県、市区町村、丁目など)」の配列を取得。//
        let prefecture = '';//最終的に取得する都道府県と市区町村を入れる変数。//
        let city = '';

        components.forEach(component => {//住所要素(都道府県、市区町村、丁目…など)を順番に処理。//
          const types = component.types;//各住所要素が「何を意味するのか(都道府県?市?区?)」を表すタグを取得。//

          if (types.includes('administrative_area_level_1')) prefecture = component.long_name;// 都道府県の要素が見つかれば、そこから都道府県名を取得。//

          if (
            types.includes('locality') ||
            types.includes('ward') ||
            types.includes('administrative_area_level_2')
          ) {//市区町村に該当するものだけ抽出。//
            if (!city) city = component.long_name;
          }
        });

        sheet.getRange(i + 1, 3).setValue(prefecture);
        sheet.getRange(i + 1, 4).setValue(city || '市区町村不明');
        processed++;
        Utilities.sleep(300);
      } else {
        sheet.getRange(i + 1, 3).setValue('取得失敗');//APIのstatusが"OK"でなければ「取得失敗」と記録。//
        sheet.getRange(i + 1, 4).setValue(json.status);
      }
    } catch (error) {
      sheet.getRange(i + 1, 3).setValue('エラー');//ネットエラーやAPI障害が起きたら、内容をそのままD列に書き出す。//
      sheet.getRange(i + 1, 4).setValue(error.message);
    }
  }

  Logger.log(`${processed} 件処理しました`);
}

なぜ駅名から住所が返されるのか?

  • Googleが「品川駅」という駅名を知っている(ランドマーク扱いとしてGoogle Mapsに大量に登録されている)
    • →緯度経度のデータを保持
  • 経度緯度に紐づいた住所も知っている
    • →その結果がJSONで返される

※同名駅(例:田町駅は東京にも大阪にもある)などは曖昧になることもあるので、「◯◯駅+路線名」や「都道府県名を補足」すると精度UP

この記事をシェアする
  • URLをコピーしました!
目次