PythonのGeopyライブラリを使って住所のジオコードを取得する方法

スポンサーリンク

地球上のすべての地点は、緯度と経度の値で表すことができる。

Wikipediaによると、”ジオコーディングとは、郵便物の住所の記述を地球表面の位置(数値座標による空間表現)に変換する計算処理 “だそうです。

簡単にまとめると、テキストの住所を地球表面上の対応する緯度・経度に表現する処理をジオコーディングと呼んでいます。

今回は、PythonのGeoPyライブラリを使って、住所のジオコードを取得します。

スポンサーリンク

GeoPy

GeoPyはジオコーディングサービスではなく、いくつかの有名なジオコーディングWebサービスのための単なるPythonクライアントです。

それはアドレスのジオコードを見つけるために、サードパーティのジオコーダと他のデータソースを使用します。

下の図は、GeoPyの機能に関するいくつかのアイデアを示しています。

#Importing the Nominatim geocoder class
from geopy.geocoders import Nominatim
 
#address we need to geocode
loc = 'Taj Mahal, Agra, Uttar Pradesh 282001'
 
#making an instance of Nominatim class
geolocator = Nominatim(user_agent="my_request")
 
#applying geocode method to get the location
location = geolocator.geocode(loc)
 
#printing address and coordinates
print(location.address)
print((location.latitude, location.longitude))

上の図に見られるように、ジオコーディングは多くの異なるサービスによって提供されています。

これらのサービスはAPIを提供し、GeoPyライブラリはこれらのAPIの実装を一つのパッケージで提供します。

geopyが実装するジオコーディングサービスプロバイダの完全なリストは、このドキュメントを参照することができます

考慮すべきいくつかの重要なポイントがあります。

  • ジオコーディングサービスは有料または無料なので、サービスを選択する前に、利用規約、クォータ、価格、ジオデータベースなどに目を通しておいてください。
  • ジオコーディングサービスは有料または無料です。

GeoPyが何をするかという高レベルのアイデアは十分なので、次はそれを使って住所のジオコードを取得する方法を見てみましょう。

ジオコーディングサービス

ジオコーディングサービスはたくさんありますが、私はGeocodeAPIがとても気に入りました。

住所から緯度経度を取得するエンドポイントや、逆ジオコーディングのエンドポイントが複数用意されています。

先進的な機能としては、住所のオートコンプリートAPIがある。

部分的な住所から完全な住所を返すこともできる。

また、1日あたり10,000リクエストまで無料で利用できるので、アプリケーションの構築を始めたばかりの方にもおすすめだ。

詳しくは、価格ページで確認できる。

GeoPyを使ったジオコーディング

各ジオロケーションサービス(Nominatimなど)は、サービスのAPIにリンクしている geopy.geocoders に独自のクラスを持っています。

Geocodersには少なくとも geocode メソッドがあり、与えられた文字列(ジオコーディングしたい住所)から座標を検索することができます

このクラスには reverse メソッドの実装もあり、これは geocode メソッドと逆の動作をします。

ここでは、地表のある点の座標を提供する必要があり、このメソッドは提供された緯度と経度に関連する住所を返す。

1. 住所のジオコードを検索する

この記事では、Nominatimのジオコーディングサービスを使用します。

#Importing the required modules
import pandas as pd
from geopy.geocoders import Nominatim
from geopy.extra.rate_limiter import RateLimiter
 
#Creating a dataframe with address of locations we want to reterive
locat = ['Coorg, Karnataka' , 'Khajjiar, Himachal Pradesh',
         'Chail, Himachal Pradesh' , 'Pithoragarh, Uttarakhand','Munnar, Kerala']
df = pd.DataFrame({'add': locat})
 
#Creating an instance of Nominatim Class
geolocator = Nominatim(user_agent="my_request")
 
#applying the rate limiter wrapper
geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1)
 
#Applying the method to pandas DataFrame
df['location'] = df['add'].apply(geocode)
df['Lat'] = df['location'].apply(lambda x: x.latitude if x else None)
df['Lon'] = df['location'].apply(lambda x: x.longitude if x else None)
 
df
Output:
Taj Mahal, Taj Mahal Internal Path, Taj Ganj, Agra, Uttar Pradesh, 282001, India
(27.1750123, 78.04209683661315)

上のコードを使って、インドのアグラにあるタージマハルの座標を求めました。

Nominatimのクラスには geocode メソッドがあり、住所の文字列を受け取って、サービスプロバイダのデータベースからその座標を返します。

ジオコードメソッドを使用して返されるオブジェクトは、完全な住所を返す address メソッドと、その住所の緯度と経度を取得する latitudelonditude メソッドを持っています。

Nominatim geocoder クラスは入力引数として user_agent を受け取り、 geocoder API にリクエストを送るためのヘッダとして動作します。

2. GeoPy と Pandas Dataframe を使う

RateLimiter` クラスは geocoder クラスのラッパーとして動作し、多くのリクエストを処理する必要がある場合に、サーバへのリクエスト時間を遅延させることができます。

ジオコーディングサービスプロバイダーへのリクエスト数を考慮しながら、複数のリクエストを行わないとエラーになります。

では、インドの美しい自然スポットの住所を持つpandasのデータフレームにこれを適用してみましょう。

Geopy Api
Geopy
DataFrame With Coordinates
DataFrame With Coordinates


RateLimiterクラスはgeocoderクラスオブジェクトとmin_delay_seconds` を入力引数として必要とします。

このメソッドは指定した時間遅延でジオコーディングサービスのサーバーにリクエストをします。

文字列の位置が見つからない場合は自動的に None を返します。

Pandasの.applyメソッドを使用すると、データフレーム上の指定したカラムにラッパーを適用することができます

まとめ

この記事では、ジオコーディングとは何か、そしてpythonのGeoPyライブラリがジオコーディングサービスAPIの簡単な実装をどのように提供しているかを学びました。

また、緯度と経度の座標を得るためにテキストフォーマットの住所をジオコーディングし、住所のカラムを持つpandas DataFrameにこのメソッドを適用しました。

タイトルとURLをコピーしました