LoginSignup
18
12

More than 3 years have passed since last update.

【GoogleMaps APIを使わずに!!】GASで住所から各種情報を取得するTips

Last updated at Posted at 2018-07-25

背景

住所が入力されたシートから、郵便番号を生成してほしいという依頼をうける。
Googleが出しているGeocoding APIを使わないといけないかなぁと調べていると・・・Classあるじゃん!!となる。

本題

Class Geocoder

公式ドキュメントにあるように、Urlfetch使ってGeocoding API叩くなど不要!!

注意

使いすぎると課金対象・・・な気がします。
ちゃんと調べてないですが。
1日100件とかなら動きます。(一応、私はsleep挟んで使ってます。1秒間のリクエスト上限もあったはず。)

サンプル

A1セルに入っている住所をGeocoder Classを使って情報を取得します。

image.png

コード

function sample_geocoder () {
  const address = SpreadsheetApp.getActiveSheet().getRange(1,1).getValue();
  var
    geocoder = Maps.newGeocoder(), // Creates a new Geocoder object.
    geocoder = geocoder.setLanguage('ja'),  // Use Japanese
    response = geocoder.geocode(address).results[0]
    json = JSON.stringify(response); // ets the approximate geographic points for a given address.
  Logger.log(json);
}// function sample_geocoder

結果

出てきたデータを適当にフォーマッターにかけました。
JSONで帰ってくるので、あとは[Geocoding API]の仕様にあわせて必要なデータを取得しにいくだけです!

geocode.json
{
    "plus_code": {
        "compound_code": "JPM5+45 日本、東京都目黒区",
        "global_code": "8Q7XJPM5+45"
    },
    "types": [
        "street_address"
    ],
    "geometry": {
        "location": {
            "lng": 139.7079097,
            "lat": 35.63275660000001
        },
        "location_type": "ROOFTOP",
        "viewport": {
            "southwest": {
                "lat": 35.63140761970851,
                "lng": 139.7065607197085
            },
            "northeast": {
                "lng": 139.7092586802915,
                "lat": 35.63410558029151
            }
        }
    },
    "address_components": [
        {
            "types": [
                "premise"
            ],
            "short_name": "3",
            "long_name": "3"
        },
        {
            "long_name": "9",
            "short_name": "9",
            "types": [
                "political",
                "sublocality",
                "sublocality_level_4"
            ]
        },
        {
            "types": [
                "political",
                "sublocality",
                "sublocality_level_3"
            ],
            "long_name": "3丁目",
            "short_name": "3丁目"
        },
        {
            "types": [
                "political",
                "sublocality",
                "sublocality_level_2"
            ],
            "long_name": "目黒",
            "short_name": "目黒"
        },
        {
            "long_name": "目黒区",
            "short_name": "目黒区",
            "types": [
                "locality",
                "political"
            ]
        },
        {
            "short_name": "東京都",
            "long_name": "東京都",
            "types": [
                "administrative_area_level_1",
                "political"
            ]
        },
        {
            "types": [
                "country",
                "political"
            ],
            "short_name": "JP",
            "long_name": "日本"
        },
        {
            "types": [
                "postal_code"
            ],
            "long_name": "153-0063",
            "short_name": "153-0063"
        }
    ],
    "formatted_address": "日本、〒153-0063 東京都目黒区目黒3丁目9−3",
    "place_id": "ChIJQ2DzCiOLGGAR3-c813QEVuY"
}

緯度,・経度を取得

response > geometry > viewport
と遡っていけばいい。

コード

sample_geocoder.js
function sample_geocoder () {
  const address = SpreadsheetApp.getActiveSheet().getRange(1,1).getValue();
  var
    geocoder = Maps.newGeocoder() // Creates a new Geocoder object.
    , geocoder = geocoder.setLanguage('ja') // Use Japanese
    , response = geocoder.geocode(address).results[0]; // ets the approximate geographic points for a given address.
  Logger.log(response.geometry.location.lat + " : " + response.geometry.location.lng);
}// function sample_geocoder

結果

緯度 : 経度 の形式で取得。
35.6590249 : 139.703473

郵便番号

response > address_components > types has "postal_code"

コード

配列ぐるぐる探す方法。
もう少しいい方法はないものか?

sample_geocoder.js
function sample_geocoder () {
  const address = SpreadsheetApp.getActiveSheet().getRange(1,1).getValue();
  var
    geocoder = Maps.newGeocoder() // Creates a new Geocoder object.
    , geocoder = geocoder.setLanguage('ja') // Use Japanese
    , response = geocoder.geocode(address).results[0] // ets the approximate geographic points for a given address.
    , components = response.address_components // get address_components object
  ;
  components.forEach(function ( value ) {
    if ( value.types.indexOf('postal_code') > -1 ) {
      Logger.log(value.long_name);
      return;
    }// if
  });// forEach
}// function sample_geocoder

結果

150-0002

住所

typesの中にも複数入っている。辛い。

コード

超絶ブサイクですが。
function get_data_by_type() の中身がforEachではなく、for文になっているのは、うまいこと途中抜けできなかったからです。
(勉強不足感)

sample.js
function get_data_by_type ( components, key_type ) {
  for ( var i = 0; i < components.length; ++i ) {
    var value = components[i];    
    if ( value.types.indexOf( key_type ) > -1 ) {
      return value.long_name;
    }// if
  }// for_i
}// function get_data_by_type

function sample_geocoder () {
  const address = SpreadsheetApp.getActiveSheet().getRange(1,1).getValue();
  var
    geocoder = Maps.newGeocoder() // Creates a new Geocoder object.
    , geocoder = geocoder.setLanguage('ja') // Use Japanese
    , response = geocoder.geocode(address).results[0] // ets the approximate geographic points for a given address.
    , components = response.address_components // get address_components object
  ;
  var
    res 
     = [ 
         get_data_by_type( components, 'postal_code' )
         , get_data_by_type( components, 'country' )
         , get_data_by_type( components, 'administrative_area_level_1' )
         , get_data_by_type( components, 'locality' )
         , get_data_by_type( components, 'sublocality_level_2' )
         , get_data_by_type( components, 'sublocality_level_3' )
         , get_data_by_type( components, 'sublocality_level_4' )
       ].join(' ')
  ;
  Logger.log( res );
}// function sample_geocoder

結果

150-0002 日本 東京都 渋谷区 渋谷 2丁目 21

18
12
2

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
18
12