はじめに
「さわって覚える ArcGIS API for Python」シリーズブログは、ArcGIS API for Python のガイド、サンプル、API リファレンスなどのリソースを最大限ご活用いただく第一歩として、ガイドの中で紹介されている主要なモジュールを中心に、実際にさわって覚えていただくようなノートブックと共に、シリーズとして紹介しています。
前回の記事では、ネットワーク解析を前編、後編に分けてご紹介しました。第 5 回目は、マッピング、可視化編として、「マップ ウィジェットの使用」と「スマートマッピング」のノートブックをもとに主要な処理を解説していきます。紹介したノートブックは GitHub にも公開していますので、ご参照ください。
ArcGIS API for Python の環境構築がまだお済みでない方は、開発リソース集のインストールガイドにインストール方法を掲載しておりますので、ご参照ください。
本記事では以下の内容でマップ ウィジェットを使用したマップやレイヤーの操作方法、可視化手法としてスマートマッピングについてご紹介します。
注意:本記事は ArcGIS API for Python バージョン 2.3.x までで動作します。モジュールの変更に伴い一部機能は変更または廃止されています。バージョン 2.4.0 以降をお使いの方は What's New in 2.4.0 をご参照の上メソッドなどを置き換えてご活用ください。
1. マップ ウィジェットの使用
1-1. マップのプロパティを設定
1-2. マップに対してのレイヤーの操作
・レイヤーの追加
・レイヤーの一覧を確認
・レイヤーの削除
1-3. グラフィック
・描画
・削除
2. Webマップの保存
3. スマートマッピング
1. マップ ウィジェットの使用
GIS オブジェクトには、地理的な位置の表示や GIS コンテンツの可視化、および分析結果の表示のためのマップ ウィジェットが含まれています。マップ ウィジェットを使用するには、GIS オブジェクトの map() メソッドを使用します。gis.map() を変数に設定し、その変数を呼び出すことでノートブックにマップ ウィジェットを表示させることができます。
以下の例では、map() メソッドのコンストラクタとして、日本と指定し、日本を中心とした範囲でマップ ウィジェットを作成しています。そのほかにもコンストラクタに設定できる引数として以下の内容があります。
引数 |
説明 |
location |
Optional string:マップを中央に配置する場所の住所、または、緯度経度を指定 |
mode |
Optional string:マップモードを '2D' または '3D' で指定、デフォルトは '2D' です。 |
注意:マップ ウィジェットは Jupyter Notebook 内のみサポートされています。
# インポート
import arcgis
from arcgis.gis import GIS
# GIS オブジェクトを作成します。
gis = GIS("ポータルの URL", "ユーザー名", "パスワード")
# マップ ウィジェットの作成
map1 = gis.map('日本') # コンストラクタに地名を指定します。
# マップの範囲を初期化して表示
map1
1-1. マップのプロパティを設定
マップ ウィジェットには、ズームレベルやマップの中心、回転、ベースマップなど設定するためのプロパティが提供されています。以下ではズームレベルやマップの中心、ベースマップのプロパティを使用する例をご紹介します。
① ズームレベル
# ズームレベルの確認
map1.zoom
zoom プロパティに値を指定すると、設定したズームレベルに応じてマップ ウィジェットが更新されます。
# ウィジェットの更新 (zoom プロパティにズームレベルを指定)
map1.zoom = 10
② 地図の中心
center プロパティは、現在表示している地図の中心座標を取得することができます。
map2 = gis.map() # デフォルトのパラメーターでマップオブジェクトを作成します。
map2
# 地図の中心座標を確認
map2.center
center プロパティに緯度と経度を指定することで、指定した座標を中心にマップ ウィジェットが更新されます。ズームレベルを 15 に指定して確認すると東京駅が中心になっていることが分かります。
map2.center = [35.681236, 139.767125] # ここでは、地図の中心を東京駅に指定しています。
map2.zoom = 15
③ ベースマップ
basemap プロパティは、現在使用しているベースマップを把握したり、新しいベースマップに更新したりできます。
マップ ウィジェットに含まれているベースマップのリストを確認するには、basemaps プロパティを呼び出します。
map3 = gis.map() # デフォルトのパラメーターでマップオブジェクトを作成します。
map3.basemaps
ベースマップを変更するには、basemap プロパティに変更させたい目的のベースマップを指定します。例えば、以下のように 'dark-gray-vector' を指定することでベクター ベースマップに変更することができます。
map3.basemap = 'dark-gray-vector'
map3
ArcGIS API for Python 2.4.0 でマップウィジェットが更新されたため、2.4.0 以降では下記のコードでベースマップのリストの表示やベースマップを変更することができます。
バージョン 2.4.0 以降の場合
## ベースマップ一覧の表示
map3 = gis.map() # デフォルトのパラメーターでマップオブジェクトを作成します。
map3.basemap.basemaps
## ベースマップの変更
map3.basemap.basemap = 'dark-gray-vector'
1-2. マップに対してのレイヤー操作
マップ ウィジェットに対してレイヤーを追加してレンダリングしたり、追加したレイヤーを削除したりできます。以下では、マップ ウィジェットに対してレイヤーを操作する方法についてご紹介します。
レイヤーの追加
レイヤーの追加は、add_layer() メソッド※を使用します。add_layer() メソッドの引数に Item オブジェクト、またはレイヤー オブジェクトを指定することによりレイヤーをマップ ウィジェットに追加することができます。
※ ArcGIS API for Python 2.4.0 で add_layer() メソッドは add() メソッドに更新されました。
詳細は What's New in 2.4.0 をご参照ください。
はじめにレイヤーを追加するためにマップ ウィジェットを作成します。
# Web マップとしてウィジェットを保存するため、ログインします。
gis = GIS("https://www.arcgis.com", "ユーザー名", "パスワード")
usa_map = gis.map('USA')
usa_map
① Item オブジェクトによるレイヤーの追加
Item オブジェクトは、ContentManager の get() メソッドにアイテム ID を指定することで取得すことができます。
## Item オブジェクトを取得
world_timezones_item = gis.content.get('312cebfea2624e108e234220b04460b8')
## Item オブジェクトを add_layer() メソッドに指定
usa_map.add_layer(world_timezones_item)
usa_map
バージョン 2.4.0 以降の場合
## Item オブジェクトを取得
world_timezones_item = gis.content.get('312cebfea2624e108e234220b04460b8')
## Item オブジェクトを add() メソッドに指定
usa_map.content.add(world_timezones_item)
② レイヤー オブジェクトによるレイヤーの追加
マップには、FeatureLayer (フィーチャ レイヤー)、FeatureCollection (フィーチャ コレクション)、ImageryLayer (イメージ レイヤー)、MapImageLayer (マップイメージ レイヤー) などのさまざまなレイヤーオブジェクトを追加することができます。
FeatureLayer (フィーチャ レイヤー) の具体的な使用方法については、さわって覚える ArcGIS API for Python:フィーチャ データ編 もご参照ください。
ここでは、FeatureLayer (フィーチャ レイヤー) を使用した例をご紹介します。先ほどと同様に Item オブジェクトを取得し、Item オブジェクトの layers プロパティにアクセスして、FeatureLayer (フィーチャ レイヤー)を取得します。
# Item オブジェクトを取得
world_countries_item = gis.content.get('ac80670eb213440ea5899bbf92a04998')
# layers プロパティで、フィーチャ サービスで利用可能な1番目のレイヤーを取得します。
world_countries_layer = world_countries_item.layers[0]
world_countries_layer
取得したレイヤー オブジェクトの world_countries_layer を add_layer() メソッドに指定することで、マップに追加することができます。add_layer() メソッドを呼び出すときに、レンダラーの指定に options パラメーターの dictionary (辞書) を設定することができます。以下の例では、レイヤーの透過度 (opacity) を設定しています。opacity の値の範囲は 0 から 1 で、0 は完全に透過、1 は完全に不透明になります。
# レイヤーの追加
usa_map.add_layer(world_countries_layer, options={'opacity':0.4})
usa_map
バージョン 2.4.0 以降の場合
# レイヤーの追加
usa_map.content.add(world_countries_layer, options={'opacity':0.4})
レイヤーの一覧を確認
layers プロパティを呼び出すことで、マップに追加されたレイヤーの一覧表を表示することができます。
# レイヤーの一覧を確認
usa_map.layers
バージョン 2.4.0 以降の場合
# レイヤーの一覧を確認
usa_map.content.layers
レイヤーの削除
レイヤーを削除するには、remove_layers() メソッド※を使用します。remove_layers() メソッドの layers プロパティに削除したいレイヤーのリストを指定します。削除できる有効なレイヤーのリストを取得するには、「レイヤーの一覧を確認」で、ご紹介した layers プロパティを使用します。
以下の例では、world_countries_layer レイヤーを削除する方法を示しています。レイヤーの削除に成功した場合は、True が返ってきます。
usa_map.remove_layers(layers=[world_countries_layer])
すべてのレイヤーを削除するには、remove_layers() メソッドの layers プロパティにレイヤーリストを指定しないで呼び出すことで削除できます。
※ バージョン 2.4.0 以降の場合、特定のレイヤーの削除は remove() メソッド、すべてのレイヤーの削除は remove_all() メソッドを使用します。
## 特定のレイヤーを削除
usa_map.content.remove(index)
## すべてのレイヤーを削除
usa_map.content.remove_all()
1-3. グラフィック
draw() メソッド※を使用することで、マップ上にグラフィックを描画したり、スケッチしたりすることができます。
※グラフィックの描画はバージョン 2.3.x までの機能です。2.4.0 以降は廃止されました。
描画
描画は、矩形、楕円、矢印などいくつかの図形を使用して描画することができます。
draw() メソッドに 'rectangle' を指定することで、マップに矩形を描画することができます。draw() メソッドを呼び出したあとに、マップ上でマウスの右クリックを押下することで、矩形を描画させることができます。
usa_map.draw('rectangle')
draw() メソッドに circle を指定することで、マップに円を描画することができます。同様にdraw() メソッドを呼び出したあとに、マップ上でマウスの右クリックを押下することで、円を描画させることができます。
usa_map.draw('circle')
その他、マップ上でスケッチがサポートされている図形のリストは、draw の API リファレンスをご参照ください。
削除
削除は、clear_graphics() メソッドを呼び出すことで、マップに描画されたグラフィックをすべて削除することができます。
clear_graphics() メソッドを呼び出し、マップに描画されたグラフィックをすべて削除します。
usa_map.clear_graphics()
2. Web マップの保存
Python API バージョン 1.3 から、マップ ウィジェットを Web マップとして保存することができます。
この処理は、ベースマップ、スマートマッピング、ポップアップ、範囲、カスタム シンボル、グラフィックなど、追加された全てのレイヤーや設定を Web マップとして保存します。
マップを保存するには、save() メソッドを使用します。このメソッドは Web マップの Item オブジェクトを新規に作成します。以下のように save() メソッドの item_properties、thumbnail、folder パラメーターを指定しています。
item_properties には、アイテムのタイトルやスニペット、タグなどを指定できます。thumbnail は、サムネイル画像のパスやURL、folder はアイテムを配置するフォルダの名前になります。item_properties の詳細については、save() メソッドをご参照ください。
webmap_properties = {'title':'USA time zones and capitols',
'snippet': 'Jupyter notebook widget saved as a web map',
'tags':['automation', 'python']}
webmap_item=usa_map.save(webmap_properties, thumbnail='./webmap_thumbnail.png', folder='webmaps')
webmap_item
Web マップは、Notebook で使用したり、各 ArcGIS が提供しているアプリ等で使用することができます。また、Python API で使用する Web マップの使用方法については、working with web maps and scenes をご参照ください。
3. スマートマッピング
スマート マッピングは、ArcGIS Online および Portal for ArcGIS (10.3.1 以降) に組み込まれた新しい機能で、美しいマップを簡単に作成することができます。スマート マッピングを使用すると、データを素早く分析し、デフォルトを設定 (シンボルの大きさや、色、表示縮尺、分類の閾値などが自動で設定) して、簡単にイラストマップを作成することができます。
このエキサイティングな機能の詳細については、ヘルプページとこのブログ記事をご覧ください。ここには、データのスタイルを変更する様々な方法についての 詳細なヘルプがあります。
① ラインの可視化
最初の例では、streets レイヤーを使用して直線的な特徴を可視化する方法をご紹介します。マップに Item オブジェクトを追加すると、マップ ウィジェットはアイテムのデフォルトのシンボルを使用してレンダリングします。スマートマッピングを使えば、これをカスタマイズすることができます。以下の例では、ClassSizeRenderer を使用して、ライン フィーチャの太さを変化させて値の違いを強調しています。
はじめにマップ ウィジェットを作成します。
from arcgis.gis import *
gis = GIS()
map1 = gis.map('USA',3)
次に USA Freeway System by esri_dm というタイトルの項目を検索して、マップに追加します。
search_result = gis.content.search('title:USA Freeway system AND owner:esri_dm',
item_type = 'Feature Layer')
search_result
検索した Item オブジェクトの search_result を変数 freeway_item に設定し、add_layer() メソッドに freeway_item を指定してレイヤーを追加します。
freeway_item = search_result[0]
map1.add_layer(freeway_item)
map1
バージョン 2.4.0 の場合
freeway_item = search_result[0]
map1.content.add(freeway_item)
map1
高速道路 (freeway) レイヤーはシンプルなシンボルを使用しています。次にフィーチャ レイヤーの利用可能なフィールドの1つで可視化してみましょう。そのためには、まずアイテムのレイヤーを FeatureLayer オブジェクトとして取得します。オブジェクトの FeatureLayer から、URL と利用可能なフィールドを見つけることができます。
# サービスで利用可能な1番目のレイヤーを使用します.
freeway_feature_layer = freeway_item.layers[0]
# レイヤーの URL とフィールド名を表示します.
print(freeway_feature_layer.url)
for field in freeway_feature_layer.properties['fields']:
print(field['name'])
map1.add_layer(freeway_feature_layer, {"renderer":"ClassedSizeRenderer", "field_name": "DIST_MILES"})
# 2.4.0 以降
map1.content.add(freeway_feature_layer, {"renderer":"ClassedSizeRenderer", "field_name": "DIST_MILES"})
ここでは DIST_MILES フィールドを使用して、レンダラーには、ClassedSizeRenderer を指定します。また、地図の範囲を変えて、違いをより分かりやすくしましょう。
# 地図の範囲をロサンゼルスに変更する
map1.center = [34, -118]
map1.zoom = 10
map1
このように、長い距離の高速道路は太い線で、短い距離の高速道路は細い線で表現しています。
② ポリゴンの可視化
エリアまたはポリゴン フィーチャは、値の違いを表すために様々な色で表示されます。 以下の例は、ClassedColorRenderer を使用して、ワシントン州の人口の違いを可視化する方法をご紹介しています。
前のサンプルで見たように、スマートマッピングの機能を使用することで、レンダラーのタイプと使用するフィールドを指定するだけでマップを作成でき、あとはベースマップに基づいて適切なカラースキーム (配色)を特定したり、カラーランプの最小値と最大値を指定したりします。
また、定義式 (definition_expression) を使ってレイヤーから表示されるフィーチャを制限する方法や、ベースマップが見えるようにレイヤーを透過度で表現する方法もご紹介していきます。
マップ ウィジェットを作成します。
map2 = gis.map('Seattle, WA', 6)
map2
ポリゴンの可視化に利用するフィーチャ レイヤーは、米国の人口統計データを使用して、マップに追加します。
add_layer() の option 引数として、
map2.add_layer(
{
"type":"FeatureLayer",
"url":"//sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/2",
"definition_expression" : "STATE_NAME='Washington'",
"renderer":"ClassedColorRenderer",
"field_name":"POP2007",
"opacity":0.7
}
)
ワシントン州を群別に人口で色分けして表示しています。
おわりに
最終回ではマッピング、可視化編ということで、マップ ウィジェットの使用方法からスマートマッピングによる可視化方法までの基本的な内容をご紹介しました。基本ではなく、マップ ウィジェットの高度な使用を考えている方は、ガイドの advanced-map-widget-usage をご参照ください。こちらには、3D フィーチャ レイヤーの表示、コールバック関数を使用した非同期な処理によるマップ ウィジェットの作成などをご紹介しています。
また、スマートマッピングでは自動的にクラス分類して表示しましたが、独自にクラスの分類を設定したい場合や、数値によってシンボルサイズを変更して表示したいなどがあるかと思います。そちらに関しては、ガイドの advanced-cartography-part1 や advanced-cartography-part2 を併せてご参照ください。
本シリーズは今回で最終回ですが、ArcGIS API for Python を使用する際は冒頭でご紹介したガイドやサンプル、API リファレンスなどのリソースと併せて、これまでご紹介した本シリーズブログもご活用ください。
関連リンク