参考:ArcGIS API for Python - Cloning Content
企業または組織の開発環境からステージング、そして本番環境にコンテンツを移動させる最善の方法は何ですか?という質問がよくあります。このガイドでは、ある Web GIS から別の Web GIS にコンテンツを移動する方法について、可能なロードマップの 1 つを紹介します。これは、コンテンツを移動する際の基本的なソフトウェアの概念を示すためのテンプレートであり、ワークフローを他の種類のコンテンツ用に変更したり、管理者の特定のニーズに合わせて調整したりすることができます。
ContentManger の clone_items() メソッドは、ArcGIS Online、ArcGIS Enteprise、または ArcGIS Enterprise on Kubernetes などの元の組織から別の組織に、すべての用途と機能を持つ 1 つのアイテムの完全な複製を作成することを目的としています。アイテムのクローンを作成するときは、サポートされているアイテム、関連するアイテム、またはリソース アイテムとクローンされるアイテムとの関係を考慮する必要があります。
アイテムのクローンついて、基本的な用語を定義しておきましょう。クローンとは、ArcGIS Enterprise、ArcGIS Online、または ArcGIS Enterprise on Kubernetes から他のデプロイメント タイプへの、あらゆる組織間でのアイテムの転送を指します。これらのポータルのタイプについて説明するときに、これらのポータルのタイプを区別しようとして混乱しないために、デプロイメントのタイプに関係なく、コンテンツ作成元の組織を「ソース」と呼び、コンテンツのクローン先の組織を「ターゲット」と呼びます。
このドキュメントでは、ソースの管理者アカウントを使用してソース アイテムを収集し、ターゲットの管理者アカウントにクローンするワークフローを説明します。具体的には、ホスト フィーチャ レイヤーと Web マップをクローンする方法を説明します。Web マップ
は、これらのレイヤー アイテムとそのソース サービスを操作レイヤーの構成要素として利用できます。各アイテムの詳細については、ハイパーリンクをクリックしてください。
これは管理者のワークフローです。管理者アカウントを使用することで、ソース内でアイテムや依存関係にアクセスすること及び、ターゲット内でアイテムやサービスを作成するための必要な権限が保証されます。ターゲットの管理者は、ユーザー アカウントを作成し、必要に応じてアイテムの所有権やグループ メンバーシップを再割り当てすることができます。これは、ポータルが外部のアイデンティティ ストアによって管理されるユーザーを持つ場合、最も単純なワークフローになります。
冒頭に記載したように、Python API の開発者は以下のアイテム タイプを転送する用に clone_items()
メソッドを設計しました。
clone_items()
は、上記の複雑なアイテムの依存関係をクローンします。例えば、既存の Web アプリケーションをクローンする場合、Web マップと、そのマップで参照されるすべてのホスト フィーチャ レイヤーをクローンします。
clone_items()
は、マップ サービスとイメージ サービスのクローンを作成できません。これらのサービスは、構成内のホストされているサーバー以外のサーバーに公開されるため、関数がターゲット内のどこに公開するかを決定することは不可能です。その結果、これらのアイテムはコピーされますが、元のソース URL を参照し続けます。
個々のアイテムのクローンを作成し、その結果を検証する例を見てみましょう。
※このドキュメントではバージョン 2.4.0 以降を対象とした書き方で紹介します。
まず、必要なライブラリをインポートし、ソースの GIS とターゲットの GIS に接続します。
from pathlib import Path
import sys
import pandas as pd
from arcgis.gis import GIS, Item
from arcgis.env import active_gis
from arcgis.features import FeatureLayerCollection
# 2.4.0 以降では from arcgis.mapping import WebMap の代わりに以下が必要
from arcgis.map import Map
管理者としてログインするところから始めます。開発環境として ArcGIS Online を使用してテストや開発を行ってきた管理者が、本番環境となる ArcGIS Online にアイテムをクローンする場合を想定します。
source = GIS("https://www.arcgis.com", "USERNAME1")
#ID とパスワードを使用して ArcGIS Online にログイン
print(source)
target = GIS("https://www.arcgis.com", "USERNAME2")
#ここではクローン先を別のArcGIS Online アカウントとする
print(target)
まず、clone_items()
で何ができるかを簡単にデモンストレーションしてみます。管理者としてログインし、ソースのユーザーの 1 人が所有する特定のホスト フィーチャ レイヤー のアイテムを get()
で取得し、ターゲットにクローンします。クローンされたフィーチャ レイヤーの URL
を参照して、新しいアイテムを確認することができます。owner
パラメーターを指定することで、組織内の他のユーザー
にクローンを転送することもできます。
hosted_flyr = source.content.get("71af4edb22c34c92893b983d7f7b52e6")
osted_flyr
hosted_flyr.url
cloned_flyr = target.content.clone_items(items = [hosted_flyr],
folder="クローン先1"
)#ここでは owner パラメーターを使用しない
cloned_flyr[0]
cloned_flyr[0].url
clone_items()
は、クローンされたアイテムを含むリストを返すことがわかります。リストをインデックス化すると、この操作によって、ターゲット組織に、新しいホスト フィーチャ レイヤーが作成されたことがわかります。
上記では、items
パラメーター リストに 1 つのアイテムを渡す方法を示しました。次に、clone_items()
がリスト内のすべてのアイテムをクローンする方法を見てみましょう。まず、search() 関数で特定のユーザーが所有するアイテムを検索し、リストのアイテムを全て同時にターゲットにクローンします。
#複数アイテムのクローン
tester_content=source.content.advanced_search(query='tags:クローン AND owner:USERNAME1')["results"]
tester_content
cloned_items = target.content.clone_items(items=tester_content,
search_existing_items=True, #既に存在するものはクローンしない
folder="クローン先2")
cloned_items #アイテム「品川駅」は上でクローンを作成済み
clone_items()
は、items
引数に渡したリスト内のすべてのアイテムをクローンしていることがわかります。また、owner
引数を渡さないことで、clone_items()
を実行したログイン ユーザーにアイテムがクローンされます。
clone_items()
がソースからターゲットへアイテムをクローンする簡単な例をご紹介しました。次に、ホスト フィーチャ レイヤーのリストを繰り返し処理し、いくつかの追加パラメーターを使用して、それらを利用する ArcGIS コンテンツのクローンを作成します。
clone_items()
関数の非常に重要なパラメーターは、その出力に影響します :
search_existing_items
- 設定可能な値は True または False です。デフォルト値は True です。この値が True に設定されている場合の動作を説明します。クローン元アイテム
がターゲットにクローンされると、clone_items()
は、クローンされたアイテム
にすべての必須アイテム タイプ typeKeywords (アイテムに自動的に割り当てられる typeKeywords
についてはハイパーリンクを参照) に加えて、source-<source_item_id_value>
という追加の typeKeyword を割り当てます。たとえば、clone_items()
が ID d879c7d972b1d989b97d037c7a7737d6
のアイテムをソースとしてフィーチャ レイヤー アイテムをクローンする場合、ターゲットのフィーチャ レイヤー アイテムは、必須の typeKeyword
に加えて、source-d879c7d972b1d989b97d037c7a7737d6
の typeKeyword
を持つことになります。実際にクローンされる前に、clone_items()
は、そのパターンに一致する typeKeyword
を持つアイテムをターゲットから検索し、見つかった場合は、アイテムを再度クローンするのではなく、既存のターゲットアイテムを使用します。
引数を False に設定すると、指定されたアイテムと参照するアイテムは、それらが既に存在するかどうかに関係なく、ターゲットにクローンされます。
advanced_search() メソッドを使用して、Web マップのアイテムのリストを作成することができます。まず、全てのアイテムのリストを取得し、それをPandas DataFrame に変換して、Web マップ用にフィルタリングします
# ユーザーが所有するすべてのアイテムを検索
owner_items = source.content.advanced_search(query=f"owner:{source.users.me.username}",
max_items=-1)["results"]
owner_items
# Pandas DataFrame 形式のリストへ変換
owner_items_df = pd.DataFrame(owner_items)
Pandas の groupby()
を使用して、ユーザーが所有する各アイテムタイプ別のグループ オブジェクトを作成します。その後、get_group()
メソッドを使用して、すべてのWeb マップを返します。
# Web マップ形式を選択
wm_item_df = owner_items_df.groupby("type").get_group("Web Map")
wm_item_df
出力されたデータフレームのインデックスは、元のデータフレームの各 Web マップの行番号を行インデックスに使っているので、0 から始まるインデックスにリセットします。
wm_item_df.index
web_maps = wm_item_df.reset_index(drop=True)
web_maps.index
タグ検索を使ってWeb マップを取得し、それをターゲットにクローンしてみましょう :
#品川駅のみ駅タグをつけている
def check_wm(tag_list):
return "駅" in tag_list
eki_df = web_maps[web_maps.tags.apply(check_wm)]
eki_df.index
eki_df.loc[1].id
eki_wm_item = source.content.get(eki_df.loc[1].id)
eki_wm_item
Map オブジェクトを使って、Web マップ内の各レイヤーに関する情報を表示してみましょう。レイヤー名と URL に注目して見てみると、URL のパス コンポーネントの最初にレイヤーをホストしている組織が含まれていることが分かります。
wm_obj = Map(eki_wm_item)
lyr = wm_obj.content.layers[0]
lyrname = lyr.properties.name
print(lyrname)
print(lyr.url)
print(f"Host Organization id: {lyr.url.split('/')[3]}")
ソースの組織 ID を出力すると、Web マップのレイヤーがソースでホストされていることがわかります。
print(f"{source.properties.id}")
search_existing_items
パラメーターを使用することで、クローン作成時に Web マップ
で利用されるアイテムの動作を処理することができます。このパラメーターについて学んできたことを踏まえると、Web マップで利用されるアイテムの ID
が、ターゲットに既に存在する typeKeywords
のどれかと一致するかどうかを検出するために、このパラメーターを頼りにすることができます。もしこの関数がターゲットに既存のアイテムを見つけたら、新しい Web マップ
の定義に適切な値を追加します。typeKeyword
に基づいて既存のアイテムが見つからない場合、そのアイテム
をクローンします。ホストされていないアイテムの場合は、結果の Web マップ
でそれらのアイテムを再作成します。
この場合、この Web マップをクローンしたことがないので、False
に設定します。ホストされているレイヤーもターゲットにクローンするようにします。
cloned_wm = target.content.clone_items(items=[eki_wm_item],
folder="クローン先3",
search_existing_items=False)
その結果、ターゲットにどのようなアイテムがあるか見てみましょう。
cloned_wm
cloned_wm_obj = Map(cloned_wm[1])
cloned_lyr = cloned_wm_obj.content.layers[0]
cloned_lyrname = cloned_lyr.properties.name
print(cloned_lyrname)
print(cloned_lyr.url)
print(f"Host Organization id: {cloned_lyr.url.split('/')[3]}")
clone_items()
によって Web マップが正常に再作成され、操作レイヤーがクローンされ、クローンされたフィーチャ レイヤーを使用するように Web マップが構成されていることがわかります。レイヤー URL からも別の ArcGIS Online へクローンされたことが確認できます。
ArcGIS Enterprise へクローンした場合は、レイヤー URL のスキーム名とパス コンポーネントから、クローンされたレイヤーが ArcGIS Online の組織ではなく ArcGIS Enterprise の組織を使用していることがわかります。
Web マップを視覚的に比較してみましょう :
wm_obj
cloned_wm_obj
マップが同じレイヤーを含んでいるように見えることが視覚的にわかります。wm_map
ディクショナリの他の Web マップ
のソースとターゲットのペアにもこのプロセスを繰り返して、視覚的に比較することができます。
ArcGIS Dashboards のクローンの詳細については、Cloning and Troubleshooting Complex Itemsガイドを参照してください。
ArcGIS StoryMap のクローンの詳細については、Cloning and Troubleshooting Complex Itemsガイドを参照してください。
このガイドでは、ソースの Web GIS とターゲットの Web GIS の間でアイテムをクローンするための 1 つのワークフローを示しました。それぞれの GIS に管理者として接続し、個々のアイテムをクローンし、次にアイテムのセットをクローンしました。次に、Web マップ アイテムをクローンし、同時に Web マップ内のホスト フィーチャ レイヤーもクローンされ、クローンされた Web マップがターゲット組織でホストされているクローンされたフィーチャ レイヤーを読み込むように構成される方法を示した。