はじめに
Google Apps ScriptでGoogle MapsのGeocoding APIを使用して、場所の名前から住所と緯度経度を取得してみたいと思います。
以下の状態にすることを目指します。
※使用した場所名は山手線の駅名です。
実装内容
ジオコーディングを実施する関数
function geocode(place) {
const res = Maps.newGeocoder().setLanguage('ja').geocode(place);
if (res.results.length !== 0) {
const fullAddr = res.results[0].formatted_address;
const location = res.results[0].geometry.location;
// 「日本、〒」を削除し、郵便番号と住所を分割
const addrParts = fullAddr.replace('日本、〒', '').split(' ');
const postalCode = addrParts[0];
const address = addrParts.slice(1).join(' ');
return [postalCode, address, location];
} else {
return [null, null, { lng: null, lat: null }];
}
}
引数として場所名の文字列を受け取っています。
レスポンスで受け取る内容(res.results[0])は以下のような内容となります。
{ geometry:
{ viewport: { northeast: [Object], southwest: [Object] },
location: { lat: 35.68123620000001, lng: 139.7671248 },
location_type: 'ROOFTOP' },
plus_code:
{ compound_code: 'MQJ8+FR 日本、東京都千代田区',
global_code: '8Q7XMQJ8+FR' },
types:
[ 'establishment',
'point_of_interest',
'subway_station',
'train_station',
'transit_station' ],
formatted_address: '日本、〒100-0005 東京都千代田区丸の内1丁目9 東京駅',
partial_match: true,
place_id: 'ChIJC3Cf2PuLGGAROO00ukl8JwA',
address_components:
[ { long_name: '東京駅', short_name: '東京駅', types: [Object] },
{ long_name: '9', short_name: '9', types: [Object] },
{ types: [Object], long_name: '1丁目', short_name: '1丁目' },
{ types: [Object], short_name: '丸の内', long_name: '丸の内' },
{ long_name: '千代田区', short_name: '千代田区', types: [Object] },
{ long_name: '東京都', types: [Object], short_name: '東京都' },
{ long_name: '日本', short_name: 'JP', types: [Object] },
{ long_name: '100-0005',
short_name: '100-0005',
types: [Object] } ] }
この中geometry.locationから緯度経度を取得しています。
住所と郵便番号は、今回はformatted_addressの文字列から抽出してみました。
メイン処理
スプレッドシートから場所名を取得して先ほどの関数を実行し、スプレッドシートに結果を書き込む処理です。
function main() {
// スプレッドシートから場所名を取得
const res = Sheets.Spreadsheets.Values.batchGet(
SpreadsheetApp.getActive().getId(), // スプレッドシートID
{ ranges: ['シート1!A2:A'] } // 取得したい範囲
);
const valueRanges = res.valueRanges || [];
const places = valueRanges[0].values;
// ジオコーディングを実施
let addrs = [];
places.forEach((place, index) => {
const [postalCode, addr, location] = geocode(place);
console.log(location);
addrs.push([postalCode, addr, location.lng, location.lat]);
});
// スプレッドシートに結果を書き込む
Sheets.Spreadsheets.Values.batchUpdate(
{
valueInputOption: 'USER_ENTERED',
data: [
{
range: 'シート1!B2',
values: addrs
},
]
},
SpreadsheetApp.getActive().getId()
);
}
スプレッドシートから値を読み取る、書き込む時にはgetValuesやsetValuesを使うことも多いと思いますが、今回はSheets APIのbatchGet、batchUpdateを使用してみています。
今回くらいの件数であればさほど差は出ないですが、件数が多くなるとSheets APIを使用する方が処理速度の向上に繋がるためです。
以下の記事などを参考にしています。
GASでSheets APIを使用するためには、「サービスを追加」からSheets APIを追加してください。
これでスプレッドシートのA列に場所名を入力してmain関数を実行すると、以下のような結果が得られると思います。
まとめ
場所の名前から住所や緯度経度が取得できるのは便利ですね。今度はマップ上に可視化も試してみたいと思います。
参考