チンチラのフンみたいなもの

毎日の学んだことを書いていきます

Apple・Googleそれぞれの逆ジオコーディング

逆ジオコーディングとは

ジーコーディングとは住所から経度緯度のような位置情報に変換することである。逆ジオコーディングはその逆なので、緯度経度から人間が読める住所に変換することである。AppleGoogleはそれぞれAppleマップ、Googleマップと自社が提供する地図アプリがある。そのこともあってかどちらにも位置情報のライブラリがある。そのライブラリには逆ジオコーディングをするためのメソッドがあるので、今回はそれを使っていく。

AppleGoogleの違い

Appleが提供するメソッド

func reverseGeocodeLocation(_ location: CLLocation, 
          completionHandler: @escaping CLGeocodeCompletionHandler)

Googleが提供するメソッド

func reverseGeocodeCoordinate(_ coordinate: CLLocationCoordinate2D, completionHandler handler: @escaping GMSReverseGeocodeCallback)

どちらも緯度経度をcompletionHandlerに渡してエラーがなければ住所が返ってくると言う形は変わりません。しかし、その返ってくる情報にはかなり違いがあります。実際に使いながら見てみましょう。

Apple

import CoreLocation
import Contacts
let gecoder = CLGeocoder()
gecoder.reverseGeocodeLocation(CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude), completionHandler: {(placemark, err) in
 guard let placemark = placemark?.first else { return }
    print(placemark.postalCode)   //768-0002
    print(placemark.administrativeArea) //香川県
    print(placemark.locality)   //観音寺市
    print(placemark.thoroughfare) //高屋町
    print(placemark.subLocality)   //高屋町
    print(placemark.subThoroughfare)   //2800
    print(placemark.name)   //天空の鳥居
    print(placemark.subAdministrativeArea)   //nil
    print(placemark.postalAddress)   //<CNPostalAddress: 0x281f0ba20: street=高屋町2800, subLocality=高屋町, city=観音寺市, subAdministrativeArea=, state=香川県, postalCode=768-0002, country=日本, countryCode=JP>
})

Google

import GoogleMaps
let geoCoder = GMSGeocoder()
geoCoder.reverseGeocodeCoordinate(coordinate, completionHandler: {(placemarks,err) in
    guard let placemark = placemarks?.firstResult() else { return }
    print(placemark.postalCode)   //768-0001
    print(placemark.administrativeArea)   //香川県
    print(placemark.locality)   //観音寺市
    print(placemark.subLocality)   //nil
    print(placemark.thoroughfare)   //nil
    print(placemark.lines?.first)   //日本、〒768-0001 香川県観音寺市室本町2731
})

住所の情報をもつクラスのプロパティをprint文で表示させました。print文の右側にコメントで実行結果を書きました。実行結果は私の地元である香川の観光地「天空の鳥居」をタッチした時のものです。Appleの方は簡単に県、市、町、番地と細かく分けることができるのが特徴みたいです。Googleの方は元々プロパティの数は少ないため細かく分けることはできないが、lines?.firstで非常に綺麗にフォーマットされた住所を簡単に取得できることが特徴みたいです。
それなら正直どっちでもいいじゃんとなるのですが、両者には無視できない違いがあります。まずお気づきだと思いますが、表示されている住所が違います。Appleは「〒768-0002 香川県観音寺市室本町2800」なの対し、Googleは「〒768-0001 香川県観音寺市室本町2731」です。正解はAppleの方です。GoogleMapのアプリで見ると「〒768-0002 香川県観音寺市室本町2800」となっています。どういうことなのでしょうか?またGoogleは市までしか取得できないが、Appleなら町やその場所の名前まで取得できたりする場所があります。一方でAppleGoogleの方なら番地まで表示されるのにAppleの方は表示されないという場所もあります。
色んな場所をタッチして確認して見たところ両者の情報量は、町のGoogle、山のAppleという印象です。Appleは町の中で番地まで表示できないところがちょこちょこあります。一方Googleは山の中となると市までしか取得できないことが結構あります。上の間違った住所を表示した「天空の鳥居」も山の中なのでちょっとおかしくなったのかもしれません。

まとめ

結論としては逆ジオコーディングをする際は、アプリの用途によってAppleGoogleかを選択するか、高度によって使い分けて両者のいいとこ取りをするのが良いでしょうか。この問題については私のコードや導入方法に問題がある為起きてしまっている可能性も十分にあります。何か分かる方いましたら教えて頂けると助かります。