Vue.jsでGeocoder APIを使ってみた (vue2-geocoder)


はじめに

Vue.jsでGeocoder APIを呼び出し緯度/経度を取得してみた。

Geocoder APIとは

住所を地理座標(緯度/経度)に変換できるAPIです。
参照 : https://developers.google.com/maps/documentation/geocoding/overview

使用ライブラリと詳細

  • 使用ライブラリ : @pderas/vue2-geocoder
    使用理由 : vue2のgeocoding用プラグインでよく使われている。
    参照 : https://github.com/PDERAS/vue2-geocoder#readme

  • query時に設定できるパラメータの説明
    (address_line_1) : 住所での検索時使用するパラメータ
    (address_line_2) : こちらも住所での検索時使用するパラメータですが、(address_line_1)だけで検索できます。
    (city) : 都市の名前などで検索したいときのパラメータ
    (state): 国をアメリカなどの州を持つ国にした場合の、州検索時に使用するパラメータ
    (zip_code) : 郵便番号で検索したいときのパラメータ  
    (country) : 検索対象になる国の名前を絞り込むためのパラメータ[今回は日本に限定]上記パラメータを利用し、入力した際に緯度/経度を絞り込みます。

Geocoder API Request / Response

handleSetCity.ts

  private async handleSetCity() {
    let lat = 0
    let lon = 0

    const addressObj = {
      address_line_1: '東京都庁',
      address_line_2: '',
      city: '',
      state: '',
      zip_code:'',
      country: '日本'
    }

    (Vue as any).$geocoder.send(addressObj, (response: any) => {
      if (response.results) {
        lat = response.results[0].geometry.location.lat
        lon = response.results[0].geometry.location.lng
      }
    })
  }
  • Response
[
    {
        "address_components": [
            {
                "long_name": "45階",
                "short_name": "45階",
                "types": [
                    "subpremise"
                ]
            },
            {
                "long_name": "第一本庁舎",
                "short_name": "第一本庁舎",
                "types": [
                    "establishment",
                    "point_of_interest"
                ]
            },
            {
                "long_name": "東京都庁",
                "short_name": "東京都庁",
                "types": [
                    "premise"
                ]
            },
            {
                "long_name": "1",
                "short_name": "1",
                "types": [
                    "premise"
                ]
            },
            {
                "long_name": "8",
                "short_name": "8",
                "types": [
                    "political",
                    "sublocality",
                    "sublocality_level_4"
                ]
            },
            {
                "long_name": "2丁目",
                "short_name": "2丁目",
                "types": [
                    "political",
                    "sublocality",
                    "sublocality_level_3"
                ]
            },
            {
                "long_name": "西新宿",
                "short_name": "西新宿",
                "types": [
                    "political",
                    "sublocality",
                    "sublocality_level_2"
                ]
            },
            {
                "long_name": "新宿区",
                "short_name": "新宿区",
                "types": [
                    "locality",
                    "political"
                ]
            },
            {
                "long_name": "東京都",
                "short_name": "東京都",
                "types": [
                    "administrative_area_level_1",
                    "political"
                ]
            },
            {
                "long_name": "日本",
                "short_name": "JP",
                "types": [
                    "country",
                    "political"
                ]
            },
            {
                "long_name": "163-8001",
                "short_name": "163-8001",
                "types": [
                    "postal_code"
                ]
            }
        ],
        "formatted_address": "日本、〒163-8001 東京都新宿区西新宿2丁目8−1 東京都庁 45階 第一本庁舎",
        "geometry": {
            "location": {
                "lat": 35.6898531,
                "lng": 139.6917321
            },
            "location_type": "ROOFTOP",
            "viewport": {
                "northeast": {
                    "lat": 35.6912020802915,
                    "lng": 139.6930810802915
                },
                "southwest": {
                    "lat": 35.6885041197085,
                    "lng": 139.6903831197085
                }
            }
        },
        "place_id": "ChIJnctryNSMGGARLv4MknPFseU",
        "plus_code": {
            "compound_code": "MMQR+WM 日本、東京都新宿区",
            "global_code": "8Q7XMMQR+WM"
        },
        "types": [
            "establishment",
            "point_of_interest",
            "tourist_attraction"
        ]
    }
]

ただ、実際に緯度/経度を取得する場合に使用するのは、Responseのgeometry.locationの中身になります。

"geometry": {
  "location": {
    "lat": 35.6898531,
    "lng": 139.6917321
  },
・
・
・

Geocoder APIのエラーハンドリング

Geocoder APIを使用した時のエラーハンドリングには、Geocoder APIに標準で返ってくる[エラーメッセージ]を使用すると良さげです。

  • statusがOK以外のステータスコードを返す場合、Geocodingレスポンスオブジェクト内にerror_messageフィールドがある可能性があります。 このフィールドには、特定のステータスコードの背後にある理由に関する詳細情報が含まれています。
    参照 : https://developers.google.com/maps/documentation/geocoding/overview#StatusCodes

vue2-geocoderを使用した時のエラー検証結果

  • 検索が引っかからない場合
    response : {"results":[],"status":"ZERO_RESULTS"}

  • API_KEYを無効にした場合
    response : {"error_message":"This API project is not authorized to use this API.","results":[],"status":"REQUEST_DENIED"}

Geocoder APIの回数制限

GCP上でAPIごとに(Geocodingのみを)回数制限を設定することできます。