GeoPandasのジオコーディングのプロバイダー(Gecoder)を指定してみた
こんにちは、CX事業本部 IoT事業部の若槻です。
GeoPandasは、pandasで使われているデータ形式であるDataFrameを、地理空間データの操作をできるように拡張したライブラリです。
このGeoPandasではジオコーディング(地名やランドマーク名から緯度/経度への変換)の機能もあるのですが、その際に使用されるプロバイダーは任意のものを指定することが可能です。
今回は、GeoPandasでジオコーディングのプロバイダー(Gecoder)を指定する方法を確認してみました。
やってみる
環境
$ python3 Python 3.10.6 (main, Aug 11 2022, 13:36:31) [Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import geopandas >>> geopandas.__version__ '0.11.1' >>> import geopy >>> geopy.__version__ '2.2.0'
GeoPandasやGeopyの詳しい導入方法は前回のエントリ(M1 Macの場合)または公式ドキュメントをご覧ください。
使用可能なGeocoder一覧の確認
geopy.geocoders.SERVICE_TO_GEOCODER
で使用可能なGeocoder名とクラスの対応一覧を確認できます。
>>> geopy.geocoders.SERVICE_TO_GEOCODER {'algolia': <class 'geopy.geocoders.algolia.AlgoliaPlaces'>, 'arcgis': <class 'geopy.geocoders.arcgis.ArcGIS'>, 'azure': <class 'geopy.geocoders.azure.AzureMaps'>, 'baidu': <class 'geopy.geocoders.baidu.Baidu'>, 'baiduv3': <class 'geopy.geocoders.baidu.BaiduV3'>, 'banfrance': <class 'geopy.geocoders.banfrance.BANFrance'>, 'bing': <class 'geopy.geocoders.bing.Bing'>, 'databc': <class 'geopy.geocoders.databc.DataBC'>, 'geocodeearth': <class 'geopy.geocoders.geocodeearth.GeocodeEarth'>, 'geocodio': <class 'geopy.geocoders.geocodio.Geocodio'>, 'geonames': <class 'geopy.geocoders.geonames.GeoNames'>, 'google': <class 'geopy.geocoders.google.GoogleV3'>, 'googlev3': <class 'geopy.geocoders.google.GoogleV3'>, 'geolake': <class 'geopy.geocoders.geolake.Geolake'>, 'here': <class 'geopy.geocoders.here.Here'>, 'herev7': <class 'geopy.geocoders.here.HereV7'>, 'ignfrance': <class 'geopy.geocoders.ignfrance.IGNFrance'>, 'mapbox': <class 'geopy.geocoders.mapbox.MapBox'>, 'mapquest': <class 'geopy.geocoders.mapquest.MapQuest'>, 'maptiler': <class 'geopy.geocoders.maptiler.MapTiler'>, 'nominatim': <class 'geopy.geocoders.nominatim.Nominatim'>, 'opencage': <class 'geopy.geocoders.opencage.OpenCage'>, 'openmapquest': <class 'geopy.geocoders.openmapquest.OpenMapQuest'>, 'pickpoint': <class 'geopy.geocoders.pickpoint.PickPoint'>, 'pelias': <class 'geopy.geocoders.pelias.Pelias'>, 'photon': <class 'geopy.geocoders.photon.Photon'>, 'liveaddress': <class 'geopy.geocoders.smartystreets.LiveAddress'>, 'tomtom': <class 'geopy.geocoders.tomtom.TomTom'>, 'what3words': <class 'geopy.geocoders.what3words.What3Words'>, 'what3wordsv3': <class 'geopy.geocoders.what3words.What3WordsV3'>, 'yandex': <class 'geopy.geocoders.yandex.Yandex'>}
分かりやすく並べてみます。標準で31種類も使えるんですね。(ただしgoogle
とgooglev3
は同じクラスを指しているなど重複はあります。)
>>> geocoders = geopy.geocoders.SERVICE_TO_GEOCODER.keys() >>> for mykey in geocoders: print(mykey) ... algolia arcgis azure baidu baiduv3 banfrance bing databc geocodeearth geocodio geonames google googlev3 geolake here herev7 ignfrance mapbox mapquest maptiler nominatim opencage openmapquest pickpoint pelias photon liveaddress tomtom what3words what3wordsv3 yandex >>> len(geocoders) 31
ジオコーディングしてみる
それでは各種Geocoderを使ってジオコーディングを試してみます。
構文は下記のようになります。
geopandas.tools.geocode(strings, provider=None, **kwargs)
ちなみに第2引数のprovider
の指定は、前節で確認したGeocoder名もしくはクラスの直接指定のいずれでも可能です。例えばAlgoliaなら次の2通りが可能です。お好きな方をどうぞ。
>>> geopandas.tools.geocode("東京都", "algolia") >>> geopandas.tools.geocode("東京都", geopy.geocoders.algolia.AlgoliaPlaces)
指定なし(Photon)
Geocoderが未指定の場合、既定ではPhotonが使われます。PhotonはOpenStreetMap上での検索APIを提供します。
検索対象の地名やランドマークをいくつか試してみます。
>>> geocoder = None >>> geopandas.tools.geocode("東京都", geocoder) geometry address 0 POINT (135.53399 34.69673) 京橋, Higashi Nodamachi, 534-0025, Higashi Nodam... >>> geopandas.tools.geocode("東京都千代田区", geocoder) geometry address 0 GEOMETRYCOLLECTION EMPTY None >>> geopandas.tools.geocode("東京都千代田区九段南1-2-1", geocoder) geometry address 0 GEOMETRYCOLLECTION EMPTY None >>> geopandas.tools.geocode("東京タワー", geocoder) geometry address 0 POINT (139.74893 35.70054) タワー飯田橋通り, 102-0072, 東京都, 日本 >>> geopandas.tools.geocode("Tokyo, Japan", geocoder) geometry address 0 POINT (139.75945 35.68284) 東京都, 日本 >>> geopandas.tools.geocode("Chiyoda-Ku, Tokyo, Japan", geocoder) geometry address 0 POINT (139.76124 35.68450) パレスホテル東京, 1-1-1 Marunouchi, Chiyoda-ku, Tokyo,...
Photonでは日本の地名や住所だと日本語の場合は上手くジオコーディングが行われず、英語だと行われるようです。(なぜパレスホテル東京
なのかは謎ですが)東京タワー
のジオコーディングも場所がずれています。
指定した場合(Algolia)
次にGeocoderを指定した場合の例としてAlgoliaを試してみます。Algoliaは検索エンジン機能が有名ですが、ジオコーディング機能も提供しているんですね。
前節と同じ検索対象で試してみます。
>>> geocoder = geopy.geocoders.algolia.AlgoliaPlaces >>> geopandas.tools.geocode("東京都", geocoder) geometry address 0 POINT (139.75900 35.68280) 東京都 >>> geopandas.tools.geocode("東京都千代田区", geocoder) geometry address 0 GEOMETRYCOLLECTION EMPTY None >>> geopandas.tools.geocode("東京都千代田区九段南1-2-1", geocoder) geometry address 0 GEOMETRYCOLLECTION EMPTY None >>> geopandas.tools.geocode("東京タワー", geocoder) geometry address 0 POINT (139.74500 35.65860) 東京タワー >>> geopandas.tools.geocode("Tokyo, Japan", geocoder) geometry address 0 POINT (139.77700 35.62940) Tokyo Trick Art Museum >>> geopandas.tools.geocode("Chiyoda-Ku, Tokyo, Japan", geocoder) geometry address 0 GEOMETRYCOLLECTION EMPTY None
Algoliaは日本の地名や住所は日本語および英語のいずれでもジオコーディングが行われないようです。しかしランドマーク東京タワー
は上手くできています。
アクセスキーが必要なものもある
ちなみに一部のGeocoderはAPIを叩くためのアクセスキーを指定しないと使えません。Geocoderのサービス側で事前に取得しておく必要があります。
いくつか試してみたところ次のGeocoderでアクセスキーが必要でした。
- azure
- bing
- googlev3
- here
- herev7
- mapbox
- what3words
- what3wordsv3
これらのGeocoderでアクセスキー未指定の場合は次のようにエラーとなります。
>>> geopandas.tools.geocode("東京タワー", geopy.geocoders.bing.Bing) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/opt/homebrew/lib/python3.10/site-packages/geopandas/tools/geocoding.py", line 67, in geocode return _query(strings, True, provider, throttle_time, **kwargs) File "/opt/homebrew/lib/python3.10/site-packages/geopandas/tools/geocoding.py", line 136, in _query coder = provider(**kwargs) TypeError: Bing.__init__() missing 1 required positional argument: 'api_key'
おわりに
GeoPandasでジオコーディングのプロバイダー(Gecoder)を指定する方法を確認してみました。
フリーで使えるサービスのGecoderだと日本に対応していない場合も多いようで、AzureやGoogleを有償利用するなどした方が良さそうです。what3words(ある地点を3つのワードで指定できる)は気になるので次回以降試してみたいです。
以上