バージョン
Gemfile.lock
geocoder (1.5.2)
起きたこと
READMEを読んだ通りにやったのに、いくら住所を登録してもlatitude
とlongitude
がnullのままで登録される気配がない。
確認してみたこと
-
address
やlatitude
、longitude
のカラム名をTypoしてないか? -
latitude
とlongitude
をfloat型で定義したか? - モデルに
geocoded_by :address
とafter_validation :geocode
を記述したか? - そもそもGemをInstallした?
で上記は全部ちゃんとできていました。
原因
bin/rails c
で色々叩いてみてそれとなく原因が分かりました。
[1] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5渋谷マークシティ")
=> nil
[2] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5")
=> nil
[3] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12")
=> nil
[4] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1")
=> nil
[5] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂")
=> [35.6588903, 139.6975169]
[6] pry(main)> Geocoder.coordinates("東京都渋谷区")
=> [35.6645956, 139.6987107]
railsのアプリ上では「東京都渋谷区道玄坂1-12-5渋谷マークシティ」で登録しようとしていたのですが、そもそもその住所だと緯度と経度を取得できていないことが分かりました。
解決策
geocoder
のデフォルトのgeocoding serviceはnominatimを使用しており
このAPIの精度だと上記の結果になるようです。
これをgoogleのAPIに変更することにより精度を上げることができます。
以下の手順で使用サービスをgoogleに変更してあげましょう。
- configファイルを作成する
$ bin/rails g geocoder:config
- configの設定
config/initializers/geocoder.rb
が作成されるので編集する。
(※googleのAPI KEYを取得しておく必要があります)
Geocoder.configure(
# Geocoding options
# timeout: 3, # geocoding service timeout (secs)
lookup: :google, # name of geocoding service (symbol)
# ip_lookup: :ipinfo_io, # name of IP address geocoding service (symbol)
# language: :en, # ISO-639 language code
use_https: true, # use HTTPS for lookup requests? (if supported)
# http_proxy: nil, # HTTP proxy server (user:pass@host:port)
# https_proxy: nil, # HTTPS proxy server (user:pass@host:port)
api_key: {your google api key},
# cache: nil, # cache object (must respond to #[], #[]=, and #del)
# cache_prefix: 'geocoder:', # prefix (string) to use for all cache keys
# Exceptions that should not be rescued by default
# (if you want to implement custom error handling);
# supports SocketError and Timeout::Error
# always_raise: [],
# Calculation options
# units: :mi, # :km for kilometers or :mi for miles
# distances: :linear # :spherical or :linear
)
これで、再度コンソール上で叩くと…
[1] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5渋谷マークシティ")
=> [35.6581487, 139.6979397]
[2] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5")
=> [35.6577383, 139.6973389]
[3] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12")
=> [35.6579443, 139.6979978]
[4] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1")
=> [35.65751710000001, 139.6994338]
[5] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂")
=> [35.6581518, 139.6981574]
[6] pry(main)> Geocoder.coordinates("東京都渋谷区")
=> [35.6619707, 139.703795]
となり、しっかり緯度と経度が取得できていることが分かります。