「さわって覚える ArcGIS API for Python」シリーズブログは、 ArcGIS API for Python のガイドやサンプル、API リファレンスなどのリソースを最大限ご活用いただく第一歩として、ガイドの中で紹介されている主要なモジュールを中心に、実際にさわって覚えていただくようなノートブックと共にシリーズとして紹介していく予定です。
前回の記事では、フィーチャ レイヤーへのアクセス方法やフィーチャの編集についてご紹介しました。第 3 回目となる今回は、場所検索、ジオコーディング編として、「geocode() メソッドの理解」のノートブックをもとに、主要な処理を解説していきます。紹介したノートブックは GitHub にも公開しますので、ご参照ください。
ArcGIS API for Python の環境構築がまだお済みでない方は、開発リソース集のインストールガイドにインストール方法を掲載しておりますので、ご参照ください。
本記事では以下の内容でジオコーディングについてご紹介します。
geocode() メソッドを使用したジオコーディング
ジオコーディングとは、住所、地名、目標物、郵便番号などが示す場所に対して座標を付与することです。
geocoding モジュールの geocode() メソッドは、住所や地名等を含む文字列を指定することでジオコーディングすることができるメソッドです。ここからは geocode() メソッドが持つさまざまなパラメーターを使用したジオコーディングについてご紹介していきます。
ArcGIS Online を利用している場合、デフォルトでは ArcGIS World Geocoding Service がジオコーダーとして利用されます。以降では ArcGIS World Geocoding Service の利用を前提として話を進めます。なお、以下のコードを実行すると現在利用しているジオコーダーの URL を把握することができます。
from arcgis.gis import GIS
from arcgis.geocoding import get_geocoders
gis = GIS("ポータルの URL", "ユーザー名", "パスワード")
get_geocoders(gis)
address パラメーターを使用したジオコーディング
geocode() メソッドの address パラメーターではジオコーディングする住所や地名、郵便番号、または POI を含む文字列を指定することができます。
以下のコードでは geocode() メソッドに住所を入力しマップ ウィジェットにジオコーディング結果を表示します。
まずは、ジオコーディング結果を表示するマップ ウィジェットを表示します。
# インポート
from arcgis.geocoding import geocode
from arcgis.gis import GIS
# 地図の表示
gis = GIS("ポータルの URL", "ユーザー名", "パスワード")
map = gis.map("東京都千代田区平河町")
map
続いて geocode() メソッドで “東京都千代田区平河町2-7-1” の住所を指定しジオコーディングを行います。
# geocode() メソッドでジオコーディング
single_line_address = "東京都千代田区平河町2-7-1"
esrij = geocode(single_line_address)[0]
esrij['location'].update({"spatialReference" : {"wkid" : 4326}})
ジオコーディングの結果は辞書 (dictionary) 型で返却され以下のキーを持っています。
最後にジオコーディング結果の location キーに含まれる XY の情報を使用してマップ ウィジェットに表示します。
以下のコードではポップアップを設定して draw() メソッドの引数にジオコーディング結果の location (esrij['location']) を設定し、マップ ウィジェットに描画しています。また、ここではシンボルを見やすいように調整しています。
# ポップアップを追加しマップ ウィジェットに描画
popup = {"title" : "ESRIジャパン株式会社",
"content" : esrij['address']}
# シンボルを設定
symbol = {"color":[0,0,128,128],
"size":18,
"type":"esriSMS",
"style":"esriSMSCircle",
"outline":{"color":[0,0,128,255],
"width":1,
"type":"esriSLS",
"style":"esriSLSSolid"}}
map.draw(esrij['location'], popup, symbol=symbol)
マップ ウィジェットを確認するとジオコーディングの結果が表示されます。表示されたポイントをクリックしてポップアップも確認してみましょう。
ArcGIS API for Python バージョン 2.4.0 以降をお使いの方は、下記のコードでジオコーディング結果をマップに表示することができます。
from arcgis.map.popups import PopupInfo
from arcgis.map.symbols import SimpleMarkerSymbolEsriSMS
# ポップアップを追加しマップ ウィジェットに描画
popup = PopupInfo(**{
"title" : "ESRIジャパン株式会社",
"description" : esrij['address']
})
symbol = SimpleMarkerSymbolEsriSMS(**{
"color":[0,0,128,128],
"size":18,
"type":"esriSMS",
"style":"esriSMSCircle",
"outline":{"color":[0,0,128,255],
"width":1,
"type":"esriSLS",
"style":"esriSLSSolid"}})
map.content.draw(esrij['location'], popup, symbol=symbol)
search_extent パラメーターを使用したジオコーディング
search_extent パラメーターでは、座標の組み合わせを指定し、検索範囲を特定の地域に限定することができます。このパラメーターを使用することで、例えば現在のマップのエクステント内にある場所や住所を検索する際に活用することができます。
以下の例では、東京都千代田区平河町のジオコーディング結果のエクステント内にある病院を検索しています。
まず、東京都千代田区平河町でジオコーディングを行いマップ ウィジェットを表示します
result = geocode("東京都千代田区平河町")[0]
map = gis.map(result['address'])
map
先ほどご紹介したようジオコーディング結果の辞書 (dictionary) にはエクステントの情報 (result[‘extent’]) が含まれています。
以下のコードでは、ジオコーディング結果から取得したエクステント (result[‘extent’]) をgeocode() メソッドのsearch_extent パラメーターに指定して検索範囲を東京都千代田区平河町のジオコーディング結果のエクステント内に絞り込んでいます。
# 平河町周辺の病院をジオコーディング
# ArcGIS World Geocoding Service を用いて郵便局、病院など不特定のPOIを検索する際は英単語で行うことをおすすめします。
# 平河町周辺の病院をジオコーディング
hospitals = geocode("hospital", search_extent = result['extent'])
# マップ ウィジェットに描画
for hospital in hospitals:
map.draw(hospital['location'], symbol = symbol)
ArcGIS API for Python バージョン 2.4.0 以降をお使いの方は下記のコードで実行できます。
hospitals = geocode("hospital", search_extent = result['extent'])
# マップ ウィジェットに描画
for hospital in hospitals:
hospital['location'].update({"spatialReference" : {"wkid" : 4326}})
map.content.draw(hospital['location'], symbol = symbol)
location パラメーターを使用したジオコーディング
本記事執筆時点では、ArcGIS API for Python の API リファレンスの location パラメーターの説明では、 distance パラメーターと併せて用いるものとして説明されていますが、ラッピングしている ArcGIS REST API のドキュメントでは distance パラメーターは既に廃止されており、パラメーターを渡しても認識されない旨が記載されています。
location パラメーターは指定した位置からの近さに基づいてジオコーディングの候補をソートするために用います。location location パラメーターを使うことで指定した座標から近い場所にある候補ほど上位に表示されるようになります。そのため、例えばモバイル アプリケーションで GPS で取得したユーザーの位置から近い場所や、現在表示しているマップの中心地に近い場所などを優先的に検索したい場合などに便利です。
location パラメーターは、XY 座標で表現するか、JSON ポイント オブジェクトとして表現することができます。XY で表現する場合、空間参照は WGS 84 でなければなりません。そうでない場合は、座標の空間参照は、JSON オブジェクトで定義することができます。JSON での定義についてはこちらをご参照ください。
以下の例では東京都千代田区平河町2-7-1 をジオコーディングし、その座標を location に指定して郵便局を検索しています。
# 中心となる地点をジオコーディング
esrij = geocode("東京都千代田区平河町2-7-1")[0]
esrij['location']
location パラメーター上記のジオコーディング結果の XY 座標 (esrij['location'])を指定し、郵便局を検索します。
post_offices = geocode("post office", location=esrij['location'])
for post_office in post_offices:
print(post_office["attributes"]["LongLabel"])
比較のために location パラメーターを指定せずに実行してみましょう。この場合、東京都千代田区平河町2-7-1 の座標からの近さは表示順に影響を与えなくなります。そのため、海外の郵便局が上位に表示されます。
post_offices = geocode("post office")
for post_office in post_offices:
print(post_office["attributes"]["LongLabel"])
今回は、geocode () メソッドを使ったジオコーディングについてご紹介しました。geocode () メソッドは他にも返却される結果の件数を制御する max_location や、結果を FeatureSet として返却するかどうかを指定する as_featureset パラメーターなどが提供されており、それぞれを組み合わせたりすることで検索結果の絞り込みや活用の幅を広げることができます。ご紹介したもの以外のジオコーディングの方法については「geocode() メソッドの理解」や「ジオコーディング結果のフィルタリング」のノートブックの他、「Understanding the geocode() function」や「Filtering your geocoding results」等のガイドもご参照ください。また、ArcGIS API for Python を使用する際は冒頭でご紹介したガイドやサンプル、API リファレンスなどのリソースと併せて、本シリーズブログもご活用ください。
次回は「ネットワーク解析編」としましてルート検索についてご紹介する予定です。