最新データのマッピング

サンゴの生存は藻類に依存しています。海洋温度が高すぎるか低すぎると、藻類が減少し、サンゴが白化し、死滅率が高くなります。NOAA Coral Reef Watch プログラムは、サンゴの白化リスクに関するグローバル データを提供しています。このデータは頻繁に更新されます。

このレッスンでは、ArcGIS Pro と Python を使用し、最新のサンゴの白化データを JSON ファイルとして取得します。次に、データに基づいて 2 つのフィーチャクラスを作成し、これらのシンボルを変更して公開します。後のレッスンでは、フィード ルーチンを作成し、新しいデータが利用できるようになった際に、これらのレイヤーとサービスが自動的に更新されるようにします。

ArcPy および ArcGIS API for Python のインポート

最初に、ArcGIS Pro で新しいプロジェクトを作成し、ベースマップを変更します。次に、Python を使用して ArcPy と ArcGIS API for Python をインポートします。

ArcPy は Python サイト パッケージです。これにより、Python を使用してジオプロセシング ツールやその他の ArcGIS 関数を実行できます。ArcGIS API for Python は、Python が GIS タスクを実行できるようにする Python ライブラリです。後で、このライブラリを使用して ArcGIS Online または ArcGIS Enterprise に接続します。

  1. ArcGIS Pro を起動します。サイン インを求められたら、ライセンスが割り当てられた ArcGIS アカウントを使用して (あるいは指定ユーザー アカウントを使用して ArcGIS Enterprise ポータルに) サイン インします。
    備考:

    ArcGIS Pro がない場合、ArcGIS の無料トライアルにサイン アップできます。Enterprise アカウントにサイン インする場合は、ArcGIS Pro が自分の組織のポータルを使用するように構成されていることを確認します。

  2. [空のテンプレート][マップ] をクリックします。

    マップ テンプレート

  3. [新しいプロジェクトの作成] ウィンドウの [名前] に「Coral Bleaching」と入力します。[OK] をクリックします。

    ArcGIS Pro で空のマップ プロジェクトが開きます。組織の設定に応じて、デフォルトの範囲は異なる場合があります。まず、ベースマップをデータを強調するものに変更します。

  4. リボンの [マップ] タブをクリックします。[レイヤー] グループで、[ベースマップ] をクリックして、[キャンバス (ライト グレー)] を選択します。

    [キャンバス (ライト グレー)] ベースマップ オプション

    ベースマップがマップと [コンテンツ] ウィンドウに追加されます。ベースマップには、地名を含む参照レイヤーも含まれています。この参照レイヤーは不要なため、オフにします。

  5. [コンテンツ] ウィンドウで、[World Light Gray Reference] レイヤーをオフにします。

    [コンテンツ] ウィンドウで [World Light Gray Reference] レイヤーをオフ

    次に、[Python] ウィンドウを開きます。

    ArcGIS Pro には、Anaconda ディストリビューションを通じて Python 3 が付属しています。Anaconda ディストリビューションには、データ サイエンス アプリケーションで使用される多くの一般的な Python モジュールが含まれています。

  6. リボンの [解析] タブをクリックします。[ジオプロセシング] グループで、[Python] をクリックします。

    [解析] タブの [Python] ボタン

    [Python] ウィンドウが表示されます。このウィンドウには、Python プロンプトとトランスクリプトの 2 つのパートが含まれています。Python プロンプトは、Python コードを入力する場所です。トランスクリプトには、入力した Python コードの記録が表示されます。

    まず、Python コードの簡単な行を実行して、基本的な Python 構文を習熟します。

    ヒント:

    必要に応じて、[Python] ウィンドウを再配置したり、サイズ変更したりできます。タイトル バーをドラッグしてウィンドウを再配置し、ウィンドウのエッジをドラッグしてサイズを変更します。ArcGIS Pro の複数のエリアにドッキングすることもできます。

  7. Python プロンプト ([Enter Python code here] と表示されている場所) をクリックし、「print('Hello World!')」と入力して Enter キーを押します。

    print 関数を含むトランスクリプト

    print() 関数を実行すると、トランスクリプトは括弧付きのテキストを表示します。今回の場合、print() は関数であり、'Hello World!' は引数 (関数の変数または入力) です。

    多くの Python 関数は、関数の名前を入力し、括弧内に引数を設定することで実行できます。引数を必要としない関数もあれば、複数の引数 (カンマ区切り) を必要とする関数もあります。

    関数はトランスクリプトで値を返します。一方、ステートメントは値を返すことなくプロセスを実行します。モジュール (ArcPy など) をインポートするには、関数の代わりにステートメントを使用します。最初に、sys モジュールをインポートします。このモジュールは、システムに固有な複数の関数を提供します。

  8. Python プロンプトに「import sys」と入力して、Enter キーを押します。

    sys モジュールがインポートされます。次に、version 属性を使用して Python のバージョンを表示します。属性は、Python オブジェクトのプロパティ (関数、変数、または定数) です。属性はドットを使用して Python オブジェクトに追加できます。

  9. sys.version」と入力し、Enter キーを押します。

    import sys および sys.version 行を含むトランスクリプト

    今回の場合、sys 関数はオブジェクトであり、version はその属性です。

    トランスクリプトは、Python のバージョンに関する情報を返します。この画像例では バージョンは 3.6.6 ですが、 ArcGIS Pro のバージョンによって異なる場合があります。

    ArcPy では、Python プロンプトを使用して ArcGIS ジオプロセシング ツールを実行できます。次に、sys モジュールをインポートした際と同じ方法で arcpy モジュールをインポートします。

  10. Python プロンプトに「import arcpy」と入力して、Enter キーを押します。

    arcpy モジュールがインポートされます。

  11. help(arcpy)」と入力し、Enter キーを押します。

    import arcpy および help(arcpy) 行を含むトランスクリプト

    help() 関数は、指定された引数 (arcpy) に関する情報を提供します。今回の場合、大量の情報が追加されています。Python ウィンドウのサイズを変更して、すべてを確認できます。

    次に、arcgis モジュールを使用して ArcGIS API for Python をインポートします。

  12. Python プロンプトに「import arcgis」と入力して、Enter キーを押します。

    ArcGIS API for Python がインポートされます。

    備考:

    arcgis モジュールのインポート中に [ModuleNotFoundError] メッセージが表示された場合、ArcGIS API for PythonArcGIS Pro インスタンスにインストールされていない可能性があります。インポートするには、[プロジェクト] タブをクリックした後、[Python] タブをクリックします。[パッケージの追加] をクリックして、「arcgis」を検索します。検索結果のリストで [arcgis] パッケージをクリックして、[インストール] をクリックします。「インストールと設定」ガイドでは、ArcGIS API for Python のインストール方法を詳細に説明しています。

  13. help(arcgis)」と入力し、Enter キーを押します。

    import arcgis および help(arcgis) 行を含むトランスクリプト

    arcgis モジュールに関する情報が表示されます。

ファイルのダウンロード

次に、NOAA Coral Reef Watch プログラムから JSON 形式の空間データをダウンロードします。このデータには、サンゴの白化リスクに関する最新の情報が含まれています。

データは、Coral Reef Watch の Webサイトでホストされています。データの取得には、複数の関数を使用します。これらの関数を使用するには、最初に適切なモジュールをインポートする必要があります。

  1. Python プロンプトで、次の行を実行します。
    import os, tempfile

    os および tempfile モジュールがインポートされます。urllib モジュールの request サブモジュールもインポートします。

  2. 次の行を実行します。
    from urllib import request

    request サブモジュールには、データの取得に使用する urlretrieve 関数が含まれています。urlretrieve 関数には、オンライン ファイルの URL (url) と、コンピューター上の保存先 (filename) の 2 つの変数が必要です。

    Python の変数は、等号 (=) を使用して定義および割り当てを行います。filename 変数を定義するには、os.path.join() 関数を実行して、一時ディレクトリ (temp_dir) を目的のファイル名に結合します。一時ディレクトリを定義するには、tempfile.mkdtemp() 関数を実行します。

    備考:

    filename 変数には、コンピューター上の場所を指す任意のパスを指定できます。ただし、ファイルは一時ディレクトリに保存することをお勧めします。ファイル パス内のフォルダーの区切りに使用される文字に関係なく、すべてのオペレーティング システムで動作する os.path.join() 関数が使用されます。

  3. 次の行を実行します (行をコピーして貼り付け、全行を一度に実行します)。
    url = 'https://coralreefwatch.noaa.gov/vs/vs_polygons.json'
    temp_dir = tempfile.mkdtemp()
    filename = os.path.join(temp_dir, 'latest_data.json')
    response = request.urlretrieve(url, filename)

    これらの行によって、必要な変数がすべて定義されます。取得した JSON ファイルのパスを確認するには、filename を引数に設定して print 関数を実行します。

  4. 次の行を実行します。
    print(filename)

    最新データへのパスを含むトランスクリプト

    この画像例の最後の行は、取得した latest_data.json ファイルへのパスです (パスは異なります)。ファイル名をコピーし、コンピューターのファイル エクスプローラー (Windows エクスプローラーなど) に貼り付けて、ファイルを開くことができます。ファイルは任意のテキスト エディターで開くことができます。

    次に、データを JSON 形式で表す data_raw 変数を作成します。コード行で JSON データを参照する際は、常にこの変数を使用します。変数を作成するには、json モジュールをインポートして json.load() 関数を実行できるようにしておく必要があります。また、ファイルを開くための json_file という名前の中間変数を作成する必要もあります。

  5. 次の行を実行します。
    import json
    json_file = open(filename)
    data_raw = json.load(json_file)

    トランスクリプトには何も表示されませんが、json_file 変数 (今回使用する JSON ファイル) が開かれ、data_raw 変数がロードされます。

    備考:

    json_file 変数は、json_file.close() コマンドが実行されるまで開いたままになります。with ステートメントを使用して、ファイルを開くこともできます。この場合、コード ブロックが閉じられた後にファイルが自動的に閉じられます。次のコード行は、json_file 変数を with ステートメントで開く方法を表しています。

    with open(filename) as json_file:
        data_raw = json.load(json_file)    # Do something with the 'data_raw' variable
    # Do something else outside the 'with' section. The json_file variable is now closed.

    シャープ記号 (#) で始まる行はコメントです。コードに影響を与えることなく、ユーザーに情報を提供します。

ファイルからのレイヤーの作成

ダウンロードしたデータの視覚化 (および Python を使用して空間データを操作する方法の習熟) を行うには、JSON ファイルに基づいて 2 つのフィーチャクラスを作成します。

最初に、フィーチャクラスを含むファイル ジオデータベースを新規作成します。このファイルにはポイント フィーチャとポリゴン フィーチャのデータが含まれているため、フィーチャ タイプごとに 1 つずつ、計 2 つの JSON ファイルに分割します。次に、JSON ファイルごとにフィーチャクラスを作成し、ジオデータベースに保存します。

urlretrieve 関数と同様、ジオデータベース (arcpy.management.CreateFileGDB) を作成する関数にはパスと名前が必要です。また、arcpy.env.workspace 関数を実行し、ジオデータベースをデフォルト ワークスペースとして設定します。

  1. コンピューターのドライブ C 上に、「Temp」という名前のフォルダーを作成します。
  2. Python プロンプトで、次の行を実行します。
    arcpy.management.CreateFileGDB(r'C:\Temp', 'Live.gdb')
    arcpy.env.workspace = os.path.join(r'C:\Temp', 'Live.gdb')

    Live ジオデータベースは Temp フォルダーに作成されます (フォルダーを開いて確認できます)。次に、ポイント フィーチャ (ステーション) に使用する辞書と、ポリゴン フィーチャ (NOAA によって決定された対象エリア) に使用する辞書の 2 つの辞書を作成します。

    Python の辞書は、インデックスが付けられた順不同のアイテムのコレクションです。作成する辞書には、GeoJSON ファイル形式で必要な 2 つのエレメントが含まれています。type エレメントは、data_raw 変数 (今回使用する JSON) のジオメトリ タイプを参照します。features エレメントには、フィーチャが一覧表示されます。この時点では、括弧のペアで表されているとおり、リストは空です。

  3. 次の行を実行します。
    data_stations = dict(type=data_raw['type'], features=[])
    data_areas = dict(type=data_raw['type'], features=[])

    辞書を作成する行を含むトランスクリプト

    辞書が作成されます。次に、フィーチャ ジオメトリ タイプに応じて、data_raw 変数内のフィーチャを data_stations または data_areas ライブラリに読み込みます。

    最初に、for ループを作成します。for ループは、リスト内の各アイテムに対して関数またはステートメントを実行します。data_raw 変数内のすべてのフィーチャをループするループを作成します。条件 if ステートメントを作成することで、各フィーチャのジオメトリ タイプを決定します。次に、append() メソッドを使用して、特定のジオメトリ タイプのフィーチャを適切なライブラリのフィーチャ リストに追加します。

  4. 次の行を実行します。
    for feat in data_raw['features']:
        if feat['geometry']['type'] == 'Point':
            data_stations['features'].append(feat)
        else: # elif feat['geometry']['type'] in ['MultiPolygon', 'Polygon']:        
            data_areas['features'].append(feat)
    注意:

    Python Software Foundation では、タブの代わりにスペースを使用してコード行をインデントすることを推奨しています。コードが正しく実行されなくなるため、インデントにタブとスペースを混在させないでください。

    JSON データに表示されている各フィーチャのジオメトリ タイプがポイントの場合、そのフィーチャは data_stations ライブラリに追加されます。ジオメトリ タイプがポリゴンまたはマルチポリゴンの場合、フィーチャは data_areas ライブラリに追加されます。

    data_stations['features'] リストを使用して len() 関数を実行し、リストに読み込まれたフィーチャの数を確認します。

  5. 次の行を実行します。
    len(data_stations['features'])

    ステーション数をカウントする len() 関数を表示するトランスクリプト

    この行は 213 という数字を返します。これは、ポイント フィーチャが 213 個あることを示しています。JSON 内のポリゴン フィーチャは、NOAA によって決定された対象地域に対応しています。このエリアは定期的に変更されるため、ステーションほど簡単には検証できません。

    代わりに、リストの 10 番目のフィーチャの名前と座標にアクセスします。Python では、リストは 1 ではなく 0 から始まるため、10 番目のフィーチャはフィーチャ 9 です。

  6. 次の行を実行します。
    data_areas['features'][9]['properties']['name']

    トランスクリプトは、10 番目のフィーチャの名前を返します。

  7. 次の行を実行します。
    data_areas['features'][9]['geometry']['coordinates']

    トランスクリプトは、ポリゴンの各頂点に対応する長い座標リストを返します。

    備考:

    このデータは定期的に更新されるため、結果が画像例と異なる場合があります。

    Beagle Gulf フィーチャの名前と座標を示すトランスクリプト

    次に、元の JSON を保存した場所 (temp_dir) と同じ一時ディレクトリに、辞書を JSON ファイルとして保存します。os.path.join() 関数を実行して、新しい JSON ごとにファイル パスを作成します。次に、with ステートメントを作成し、json.dump() 関数を使用して辞書を JSON ファイルとして保存します。

  8. 次の行を実行します (コメントは任意です)。
    # Filenames of temp json files 
    stations_json_path = os.path.join(temp_dir, 'points.json')
    areas_json_path = os.path.join(temp_dir, 'polygons.json')
    # Save dictionaries into json files
    with open(stations_json_path, 'w') as point_json_file:
        json.dump(data_stations, point_json_file, indent=4)
    with open(areas_json_path, 'w') as poly_json_file:
        json.dump(data_areas, poly_json_file, indent=4)

    各パスで print() 関数を実行し、ファイルが正しく保存されたことを確認します。

  9. 次の行を実行します。
    print(stations_json_path)
  10. 次の行を実行します。
    print(areas_json_path)
    備考:

    ファイル パスは、画像例に示されているものとは異なります。

    各 JSON ファイルに print() 関数を使用したトランスクリプト

    各パスは Temp フォルダーを示しています。ファイル名は、os.path.join() 関数を実行した際に指定した points.json および polygons.json です。必要に応じて各パスをコピーし、任意のテキスト エディターでファイルを開くことができます。

    JSON ファイルを作成したので、arcpy.conversion.JSONToFeatures() 関数を実行してフィーチャクラスに変換します。この関数には、JSON ファイルへのパスと、作成するフィーチャクラスの名前が必要です。

  11. 次の行を実行します。
    # Convert JSON files to features
    arcpy.conversion.JSONToFeatures(stations_json_path, 'alert_stations') 
    arcpy.conversion.JSONToFeatures(areas_json_path, 'alert_areas')

    フィーチャクラスは、以前にLive ジオデータベースとして指定したデフォルト ワークスペースに保存されます。2 つのレイヤー (alert_stations および alert_areas) がマップに追加されます。

    ステーションとエリアを示すマップ

シンボルの変更

Python を使用してレイヤー シンボルを更新することもできます。この作業はフィード ルーチンの作成には不要ですが、視覚効果が高くわかりやすい方法でデータを表示することをお勧めします。また、シンボルの変更用に作成したコードは、後でシンボルを変更する際にすばやく調整できます。

記録された熱ストレスに応じた 0 ~ 4のアラート レベルに基づき、レイヤーをシンボル表示します。低いアラート レベルは青色になり、高いアラート レベルは赤色になります。レイヤーにはアラート レベル用のテキスト フィールドが含まれていますが、等級シンボルを設定するには、フィールドが数値である必要があります。

最初に、arcpy.management.AddField 関数を使用してアラート レベル用の新しい数値フィールドを作成します。この関数の引数には、まずフィールドの追加先となるレイヤーを指定し、続いてフィールドの名前、データ タイプ、フィールド エイリアスを指定します。その他の設定も指定できますが、フィールドに必要な引数は上記のみです。

  1. Python プロンプトで、次の行を実行します。
    # Add alert_level field
    arcpy.management.AddField('alert_stations', 'alert_level', 'SHORT', field_alias='Alert Level')
    arcpy.management.AddField('alert_areas', 'alert_level', 'SHORT', field_alias='Alert Level')

    alert_stations レイヤーと alert_areas レイヤーの両方に alert_level フィールドが追加されます。両方のフィールドには、Short integer データ タイプ (数値データ タイプ) と Alert Level のエイリアスがあります。

    次に、arcpy.management.CalculateField 関数を使用して新しいフィールドを計算します。この関数の引数には、レイヤー名とフィールド名のほか、フィールドを計算する式も必要です。式では int() 関数を使用して、alert テキスト フィールドの値を整数に変換します。

  2. 次の行を実行します。
    # Calculate alert_level field
    arcpy.management.CalculateField('alert_stations', 'alert_level', "int(!alert!)")
    arcpy.management.CalculateField('alert_areas', 'alert_level', "int(!alert!)")

    フィールドが計算されます。

    ヒント:

    フィールドが正しく計算されたことを確認するには、[alert_stations] または [alert_areas] レイヤーを右クリックして、[属性テーブル] を選択します。テーブルの最後までスクロールし、0 ~ 4 の値を含む Alert Level フィールドが追加されたことを確認します。

    次に、新しいフィールドに基づいて、alert_stations レイヤーのシンボルを変更します。最初に、現在のプロジェクト (p) およびマップ (m) を表す変数を作成します。alert_stations レイヤー (points_lyr) とそのシンボル (points_sym) の変数も作成します。

  3. 次の行を実行します。
    # Symbology
    p = arcpy.mp.ArcGISProject("CURRENT")
    m = p.listMaps('Map')[0]
    # Points
    points_lyr = m.listLayers('alert_*')[0]
    points_sym = points_lyr.symbology

    次に、レンダラーを更新します。現時点で、シンボルは SimpleRenderer タイプ (単一シンボル) でレンダリングされています。フィールドに基づいてフィーチャを異なる方法でシンボル表示するには、レンダラーを GraduatedSymbolsRenderer (等級シンボル) に変更します。

    また、alert_level フィールドを分類フィールドとして使用し、データを 4 つのクラス (0 ~ 1、1 ~ 2、2 ~ 3、3 ~ 4) に分類するようにレンダラーを設定します。各クラスに対して、アラート レベルが高くなるごとにサイズも大きくなり、色が青色から赤色に変化するよう、サイズと色を設定します。

  4. 次の行を実行します。
    # Always change to the GraduatedSymbolsRenderer from the SimpleRenderer
    if points_sym.renderer.type != 'SimpleRenderer':
        points_sym.updateRenderer('SimpleRenderer')
    points_sym.updateRenderer('GraduatedSymbolsRenderer')
    points_sym.renderer.classificationField = 'alert_level'
    points_sym.renderer.breakCount = 4
    points_labels = ['0 - 1', '> 1 - 2', '> 2 - 3', '> 3 - 4']
    points_upperBounds = [1, 2, 3, 4]
    points_sizes = [6, 16.50, 27, 37.50] 
    layers_colors = [{'RGB': [5, 113, 176, 40]}, {'RGB': [146, 197, 222, 50]},
                       {'RGB': [244, 165, 130, 50]}, {'RGB': [202, 0, 32, 30]}]

    次に、for ループを作成し、指定したサイズと色を各クラスに適用します。クラスは 1 ~ 4 の数値リストの中に含まれています。i (整数の場合) をプレースホルダー変数として使用し、番号付きのクラスを表します。

  5. 次の行を実行します。
    for i in range(4):
        item = points_sym.renderer.classBreaks[i]
        item.symbol.applySymbolFromGallery('Circle', 1)
        item.label = points_labels[i]
        item.upperBound = points_upperBounds[i]
        item.symbol.size = points_sizes[i]
        item.symbol.color = layers_colors[i]

    このループは、指定した範囲 (4) のすべての整数分繰り返されます。最初の整数には、以前に作成したリストの最初のラベル、上限、サイズ、および色が使用されます。2 番目の整数には、リストのそれぞれ 2 つ目の値が使用され、以降の整数も同様に処理されます。

    最後に、これまでに実行した行に基づいて、レイヤーのシンボルを更新する行を実行します。

  6. 次の行を実行します。
    # Update
    points_lyr.symbology = points_sym

    シンボルが更新されます。(ソース データが更新されている場合、マップはこの画像例とは異なる場合があります)。

    ポイント シンボルが更新されたマップ

    同様のコードを使用して、alert_areas レイヤーのシンボルを変更します。最初に、レイヤー (polygons_lyr) とそのシンボル (polygons_sym) の変数を作成します。

  7. 次の行を実行します。
    # Polygons
    polygons_lyr = m.listLayers('alert_*')[1]
    polygons_sym = polygons_lyr.symbology

    次に、レンダラーを更新し、ポイント レイヤー用に作成したクラスと一致する 4 つのクラスを作成します。

  8. 次の行を実行します。
    # Always change to the GraduatedSymbolsRenderer from the SimpleRenderer
    if polygons_sym.renderer.type != 'SimpleRenderer':
        polygons_sym.updateRenderer('SimpleRenderer') 
    polygons_sym.updateRenderer('GraduatedColorsRenderer')
    polygons_sym.renderer.classificationField = 'alert_level'
    polygons_sym.renderer.breakCount = 4
    polygons_labels = ['0 - 1', '> 1 - 2', '> 2 - 3', '> 3 - 4']
    polygons_upperBounds = [1, 2, 3, 4]
    layers_colors = [{'RGB': [5, 113, 176, 40]}, {'RGB': [146, 197, 222, 50]},
                       {'RGB': [244, 165, 130, 50]}, {'RGB': [202, 0, 32, 30]}]

    最後に、ループを作成して、各クラスのラベル、サイズ、および色を変更し、レイヤー シンボルを更新します。

  9. 次の行を実行します。
    for i in range(4):
        item = polygons_sym.renderer.classBreaks[i]
        item.label = polygons_labels[i]
        item.upperBound = polygons_upperBounds[i]
        item.symbol.color = layers_colors[i]
    # Update
    polygons_lyr.symbology = polygons_sym

    シンボルが更新されます。(このレイヤーがはっきり見えるようにするには、表示を拡大する必要があるかもしれません)。

    ポリゴン シンボルが更新されたマップ

  10. プロジェクトを保存します。

レイヤーの公開

次に、ArcGIS Online または ArcGIS Enterprise ポータルにレイヤーを公開します。

  1. ArcGIS Online アカウント (または名前付きユーザー アカウントを使用する ArcGIS Enterprise ポータル) にサイン インしていることを確認します。
    備考:

    サイン インしている場合は、アカウントの名前が ArcGIS Pro の右上隅に表示されます。

  2. リボンの [共有] タブをクリックします。[共有] グループで、[Web レイヤー] をクリックします。

    [共有] グループの [Web レイヤー] ボタン

  3. [Web レイヤーとして共有] ウィンドウで、次のパラメーターを設定します。
    • [名前] に「Coral Reef Watch」と入力します。
    • [サマリー] に「NOAA's latest data for risk of coral bleaching」と入力します。
    • [タグ] に「NOAA」、「Coral Bleaching」、および「Alert Levels」と入力し、各タグの間で Enter キーを押します。
    • [レイヤー タイプ][フィーチャ] が選択されていることを確認します。

    [アイテムの詳細] および [レイヤー タイプ] パラメーター

  4. [分析] をクリックします。

    レイヤーを解析し、公開を妨げるエラーが存在しないことを確認します。解析ではエラーは返されませんが、フィーチャ テンプレートとデータ ソースに関連する複数の警告が返されています。この演習では、これらの警告を無視できます。

  5. [公開] をクリックします。

    ツールが実行されます。ウィンドウの下部に、Web レイヤーが公開されたことを確認するメッセージが表示されます。

  6. プロジェクトを保存します。

    次に、レイヤーを Web マップに追加し、レイヤーが正常に公開されたことを確認します。

  7. ArcGIS の組織アカウント または ArcGIS Enterprise ポータルにサイン インします。
  8. リボンの [コンテンツ] をクリックします。

    リボンの [コンテンツ] オプション

    2 つの新しいアイテム (Coral Reef Watch フィーチャ レイヤーおよびサービス定義) が [コンテンツ] ページに追加されました。

  9. [Coral Reef Watch] フィーチャ レイヤーのオプション ボタン (横方向の 3 つのドット) をクリックし、[マップ ビューアーで開く] を選択します。

    [マップ ビューアーで開く] オプション

    Web マップが開き、作成したレイヤーが表示されます。

このレッスンでは、Python を使用して、Coral Reef Watch プログラムから最新のデータを取得し、2 つのフィーチャクラスに変換して、シンボル表示しました。次に、レイヤーをフィーチャ サービスとして公開しました。次のレッスンでは、最新の Coral Reef Watch データが利用できるようになった際に、自動的にデータをダウンロードするフィード ルーチンを作成します。


フィード ルーチンの作成

前のレッスンでは、NOAA の Coral Reef Watch プログラムから最新のデータを取得、マッピング、および公開しました。このデータは、決められたある瞬間のサンゴの白化情報を示していますが、データは頻繁に更新されます。NOAA がデータを更新するたびにマップを迅速に更新するにはどうすればよいでしょうか?

このレッスンでは、フィード ルーチンを作成します。フィード ルーチンは、コンテンツを自動的にダウンロードおよび処理し、データセットを公開します。フィード ルーチンには、前のレッスンで使用した Python ワークフローが含まれます。

スタンドアロン スクリプトの作成

前のレッスンのように ArcGIS Pro でスクリプトを実行するのではなく、1 つのコマンドで保存および実行できるようなスタンドアロン スクリプトをテキスト エディターで作成します。このスクリプトにはフィード ルーチンが含まれ、Aggregated Live Feed (ALF) 手法のガイドラインに準拠しています。

ALF 手法は、運用環境でのライブ フィード ルーチンの展開に使用されるガイドライン、ツール、および関数セットです。これらのツールを使用することで、最小限の管理作業でルーチンの配置を自動化できます。ALF 手法では、ライブ フィード ルーチンのステップをカプセル化し、コンポーネントを追加することで一般的なワークフローを改善します。これらのコンポーネントにより、実行したすべてのステップをログに記録し、ファイルを効率的に解凍して、処理が失敗すると自動的に電子メールが送信する機能が追加されます。

備考:

ALF 手法の詳細を確認するには、Aggregated Live Feed コミュニティ グループに参加してください。また、「Aggregated Live Feed Methodologies」ドキュメントをダウンロードして確認することもできます。

  1. プレーン テキスト エディターで新しいファイルを開きます。
    備考:

    プレーン テキスト エディターを保有していない場合、Notepad++ を無料でダウンロードできます。PyCharmPyScripterSpyder などの Python IDE (統合開発環境) を使用することもできます。このレッスンの画像例では、Notepad++ を使用します。

    最初に、ファイルを Python スクリプト ファイルとして保存します。Notepad++ を含む一部のテキスト エディターでは、使用されているコーディング言語に応じて構文がハイライト表示され、コードを記述する際に役立ちます。

  2. リボンの [ファイル] をクリックして [保存] または [名前を付けて保存] を選択します。ファイルを「coral_reef_exercise.py」として、選択した場所に保存します。
    備考:

    ファイルを Python ファイル (*.py) として保存するプロセスは、使用しているプログラムによって異なる場合があります。

    前のレッスンで最新のデータをマッピングした際、最初に sys モジュールをインポートしました。このため、フィード ルーチンの先頭にインポートを行うステートメントを追加します。

  3. テキスト エディターで、「import sys」行を作成します。

    また、引数 url (データの URL) および workGDB (以前作成したファイル ジオデータベースのパス) を必要とする feedRoutine という名前の新しい関数も定義します。後で、データを取得およびマッピングするステップを実行する関数を定義しますが、ここでは、これらのステップの代わりにプレースホルダー値 pass を使用します。

    また、「__name__ = "__main__"」ステートメントを追加し、スクリプトをスタンドアロン ルーチン (コマンド プロンプトでの実行など) として実行できるようにします。この場合、スタンドアロン スクリプトは、コマンド プロンプトから sys.argv[1:] ステートメントを介して url および workGDB 引数を渡すことにより、feedRoutine 関数を実行します。

  4. Enter キーを 2 回押します。3 行目から始める次の行をコピーして貼り付けます。
    def feedRoutine (url, workGDB):
        pass
    if __name__ == "__main__":
    	[url, workGDB] = sys.argv[1:]
    	feedRoutine (url, workGDB)
    備考:

    インデントは、スクリプトを正しく実行するために重要です。スクリプト内のインデントは必ず維持してください。不要なインデントを追加しないでください。

    冒頭のステートメントを含むフィード ルーチン

    ワークフロー中に他の複数のモジュールをインポートしました。モジュールごとに import ステートメントを再度実行するのではなく、同じ関数で必要なすべてのモジュールをスクリプトでインポートします。

  5. 1 行目 (import sys) を変更して、「import sys, arcpy, os, tempfile, json」と記述します。Enter キーを押して、2 行目に「from urllib import request」行を作成します。

    完全な行の記述は次のとおりです。

    import sys, arcpy, os, tempfile, json
    from urllib import request

    すべてのモジュールを含むフィード ルーチン

    次に、pass プレースホルダーを、データの取得とレイヤーの作成に必要なステップに置き換えます。最初に、デフォルト ジオデータベース (arpy.env.workspace) として workGDB を定義し、arcpy.management.CreateFileGDB 関数を使用してジオデータベースを作成します。

  6. 5 行目 (pass) を次の行に置き換えます。
    # workGDB and default workspace
        arcpy.env.workspace = workGDB 
        arcpy.management.CreateFileGDB(os.path.dirname(workGDB), os.path.basename(workGDB))
    備考:

    次の画像に示すように、ウィンドウのサイズによっては、長い行の一部が折り返される場合があります。

    デフォルト ジオデータベースが定義されたフィード ルーチン

    次に、配置ロジック関数のプレースホルダー コードを追加します。この関数はすぐには必要ありませんが、後のレッスンで使用するため、スクリプトに場所を追加しておくことをお勧めします。また、前のレッスンのコードのプレースホルダーも追加します。

  7. 7 行目の後で、Enter キーを 2 回押して、インデントを削除します。9 行目以降に、次の行 (インデントを含む) をコピーして貼り付けます。
    ### Placeholder for retrieving and mapping data ###
        # Deployment Logic
        deployLogic()
        # Return
        return True
    def deployLogic():
        pass

    配置ロジックのプレースホルダーを含むフィード ルーチン

    備考:

    インデントには、タブではなくスペースを使用することが重要です。

    次に、データの取得およびマッピングを行うプレースホルダーを、前のレッスンで実行したコードに置き換えます。

    このコードには、シンボルを変更するコードは含まれません。レイヤーのシンボルは ArcGIS Pro プロジェクトと Web マップの両方ですでに保存されているため、シンボルを再度変更する必要はありません (alert_level フィールドは既存のシンボルに必要なため、これらのフィールドの追加および計算を行うコードは維持されます)。

    また、このコードには、実行中の行を通知するステートメントを含む、複数の print() 関数が含まれます。

  8. 9 行目 (### Placeholder for retrieving and mapping data ###) を次の行に置き換えます。
    # Download and split json file
        print("Downloading data...")
        temp_dir = tempfile.mkdtemp()
        filename = os.path.join(temp_dir, 'latest_data.json')
        response = request.urlretrieve(url, filename)
        with open(filename) as json_file:
            data_raw = json.load(json_file)
            data_stations = dict(type=data_raw['type'], features=[])
            data_areas = dict(type=data_raw['type'], features=[])
        for feat in data_raw['features']:
            if feat['geometry']['type'] == 'Point':
                data_stations['features'].append(feat)
            else:
                data_areas['features'].append(feat)
        # Filenames of temp json files
        stations_json_path = os.path.join(temp_dir, 'points.json')
        areas_json_path = os.path.join(temp_dir, 'polygons.json')
        # Save dictionaries into json files
        with open(stations_json_path, 'w') as point_json_file:
            json.dump(data_stations, point_json_file, indent=4)
        with open(areas_json_path, 'w') as poly_json_file:
            json.dump(data_areas, poly_json_file, indent=4)
        # Convert json files to features
        print("Creating feature classes...")
        arcpy.conversion.JSONToFeatures(stations_json_path, 'alert_stations') 
        arcpy.conversion.JSONToFeatures(areas_json_path, 'alert_areas')
        # Add 'alert_level ' field
        arcpy.management.AddField('alert_stations', 'alert_level', 'SHORT', field_alias='Alert Level')
        arcpy.management.AddField('alert_areas', 'alert_level', 'SHORT', field_alias='Alert Level')
        # Calculate 'alert_level ' field
        arcpy.management.CalculateField('alert_stations', 'alert_level', "int(!alert!)")
        arcpy.management.CalculateField('alert_areas', 'alert_level', "int(!alert!)")

    次に、スクリプトの他の部分に 3 つの print() 関数を追加します。これらの関数には、スクリプトの完了をユーザーに通知する関数も含まれています。

  9. 5 行目 (# workGDB and default workspace) の後に、Enter キーを押します。6 行目で、既存のインデントを削除し、次の行を作成します。
    print("Creating workGDB...")

    workGDB ブロックに print() 関数を追加したフィード ルーチン

  10. 43 行目 (# Deployment Logic) の後に、Enter キーを押します。44 行目で、既存のインデントを削除し、次の行を作成します。
    print("Deploying...")
  11. 47 行目 (# Return) の後に、Enter キーを押します。48 行目で、既存のインデントを削除し、次の行を作成します。
    print("Done!")

    スクリプトを作成した方法によっては、タブのインデントが残っている可能性があります。

  12. スクリプト全体をチェックして、すべてのインデントがタブではなくスペースになっていることを確認してください。
    ヒント:

    Notepad++ を使用している場合、タブをスペースに自動的に変換できます。リボンの [Edit] をクリックし、[Blank Operations] をポイントして [TAB to Space] を選択します。

  13. スクリプトを保存します。
    備考:

    スクリプトが正しく作成されたことを確認する場合は、サンプル スクリプトと比較できます。

    次に、スクリプトのテストを行います。

  14. Windows の [スタート] メニューを開きます。[Python コマンド プロンプト] を検索し、開きます。

    最初に、coral_reef_exercise.py ファイルを保存したディレクトリを参照します。

    備考:

    サンプル画像の場合、coral_reef_exercise.py ファイルは [ドキュメント] フォルダー (C:\Users\Documents) に保存されています。Windows エクスプローラーなどのファイル ブラウザーでファイルを参照し、ブラウザーの上部にあるパスをコピーすることで、ファイルのパスを取得できます。

  15. [Python コマンド プロンプト] で「cd」と入力し、Space キーを押します。Python ファイルを保存したディレクトリにルートを貼り付けます。パスにスペースが含まれる場合は、パスを引用符で囲みます。

    ディレクトリを変更するコマンドを含む [Python コマンド プロンプト]

  16. Enter キーを押します。

    ディレクトリが変更されます。次に、スクリプトを実行します。python コマンドを使用して、ファイル名、サンゴ礁データを含む Web サイトの URL、ジオデータベースのパスと名前を入力します。

  17. 次のコマンドを実行します:

    python coral_reef_exercise.py https://coralreefwatch.noaa.gov/vs/vs_polygons.json C:\Temp\Work.gdb

    コマンドの実行が完了するまで、数秒かかります。実行すると、print() 関数によって進行状況が更新されます。

    スタンドアロン スクリプトを含む [Python コマンド プロンプト]

    Work ジオデータベースのレイヤーは、最新のデータで更新されます (このデータは前のレッスンで使用したデータと同じ可能性があります)。この時点では、スクリプトによって、ArcGIS Pro プロジェクトのマップまたは Web マップのいずれかに表示されるレイヤーが更新されることはありません。後で、deployLogic() 関数を使用して更新する機能を追加します。

高度なスクリプト機能の追加

スクリプトは正常に機能していますが、さらに改善することもできます。最初に、ジオデータベースが存在しない場合にのみジオデータベースを作成するよう、スクリプトを調整します。

arcpy.Exists 関数を使用して if ステートメントを作成し、ワークスペースが存在するかどうかを確認します。この場合、新しいフィーチャクラスによって置き換えられるよう、alert_ から始まる既存のフィーチャクラスを削除します。両方の alert レイヤーは文字列 alert_* で表すことができます。アスタリスクには任意のテキストが代入されます。

  1. 必要に応じて、テキスト エディターで coral_reef_exercise スクリプトを開きます。
  2. 5 ~ 8 行目 (デフォルト ワークスペースを作成している行) を次の行に置き換えます。
    # Create workGDB and default workspace
        print("Starting workGDB...")
        arcpy.env.workspace = workGDB
        if arcpy.Exists(arcpy.env.workspace):
            for feat in arcpy.ListFeatureClasses ("alert_*"):   
                arcpy.management.Delete(feat)
        else:
            arcpy.management.CreateFileGDB(os.path.dirname(workGDB), os.path.basename(workGDB))

    既存の workGDB の存在を確認する高度なスクリプト

    インターネット アクセスのないコンピューターでスクリプトを実行すると、オンライン JSON ファイルのダウンロードに失敗します。この一般的なエラーをキャッチするには、URL が利用できないことをユーザーに通知する標準的な例外 URLError を発生させます。

  3. 18 行目 (response = request.urlretrieve(url, filename)) を次の行に置き換えます。
    try:
            response = request.urlretrieve(url, filename)
        except URLError:
            raise Exception("{0} not available. Check internet connection or url address".format(url))

    URLError を発生させる高度なスクリプト

    次に、実行中のステップをログ ファイルに記録します。コマンド プロンプトでスクリプトの各部分に関するメッセージをすでに出力しているため、各 print() 関数の後に logging.info() 関数を追加します。この関数は、スクリプトでエラーが発生した場合のデバッグに役立つメッセージをログに記録します。ログに記録されるメッセージには、メッセージがログに記録された日時が含まれます。

    最初に、スクリプトを変更して logging モジュールと datetime モジュールをインポートします。以前に使用した URLError 例外もインポートします。

  4. 1 ~ 2 行目 (import 行) を次の行に置き換えます。
    import sys, os, tempfile, json, logging, arcpy
    import datetime as dt
    from urllib import request
    from urllib.error import URLError

    次に、logging.basicConfig() 関数を使用して、メッセージを記録するログ ファイルを構成します。日時の表示方法を定義する log_format 変数も設定します。

  5. 6 行目 (def feedRoutine) の後に、次の行を追加します。
    # Log file
        logging.basicConfig(filename="coral_reef_exercise.log", level=logging.INFO)
        log_format = "%Y-%m-%d %H:%M:%S"

    ログを構成する高度なスクリプト

    次に、ログにメッセージを追加する logging.info() 関数を追加します。これらの関数では、dt.datetime.now() 関数で日時を記録し、以前に作成した log_format 変数を使用して日時を書式設定します。すべての print() 関数の後に、これらの関数を追加します。

  6. 11 行目 (print("Starting workGDB...")) の後に、次の行を追加します。
    logging.info("Starting workGDB... {0}".format(dt.datetime.now().strftime(log_format)))
  7. 21 行目 (print("Downloading data...")) の後に、次の行を追加します。
    logging.info("Downloading data... {0}".format(dt.datetime.now().strftime(log_format)))
  8. 47 行目 (print("Creating feature classes...")) の後に、次の行を追加します。
    logging.info("Creating feature classes... {0}".format(dt.datetime.now().strftime(log_format)))
  9. 59 行目 (print("Deploying...")) の後に、次の行を追加します。
    logging.info("Deploying... {0}".format(dt.datetime.now().strftime(log_format)))
  10. 64 行目 (print("Done!")) の後に、次の行を追加します。
    logging.info("Done! {0}".format(dt.datetime.now().strftime(log_format)))

    また、logging.exception() 関数を使用して URLError 例外をログに記録します。

  11. 27 行目 (except URLError) の後に、次の行を追加します。
    logging.exception("Failed on: request.urlretrieve(url, filename) {0}".format(
                              dt.datetime.now().strftime(log_format)))

    最後に、logging.shutdown() 関数を使用し、スクリプトの最後でログ ファイルを閉じます。

  12. 63 行目の終わりで Enter キーを 2 回押して、新しい行のインデントを削除します。65 行目に、次の行を追加します。
    # Close Log File
        logging.shutdown()

    ログ ファイルを閉じる高度なスクリプト

  13. スクリプトにタブのインデントが含まれていないことを確認してください。スクリプトを保存します。
    備考:

    スクリプトが正しく作成されたことを確認する場合は、サンプル スクリプトと比較できます。

このレッスンでは、コマンド プロンプトを使用してスタンドアロン スクリプトとして実行できるフィード ルーチンを作成しました。また、いくつかの高度な機能も追加しました。次のレッスンでは、フィード ルーチンを調整して、ArcGIS Pro プロジェクトのローカル フィーチャクラスを更新します。


ローカル フィーチャクラスの更新

前のレッスンでは、フィード ルーチンを作成しました。このフィード ルーチンを実行すると、最新の NOAA のサンゴ白化データがダウンロードされ、ポイント データに使用するフィーチャクラスと、ポリゴン データに使用するフィーチャクラスの 2 つのフィーチャクラスが作成されます。これらのフィーチャクラスは、Work ジオデータベースにあります。ただし、スクリプトは、Live ジオデータベースに含まれる ArcGIS Pro プロジェクトのレイヤーを更新しません。

このレッスンでは、ArcGIS Pro プロジェクトの alert_stations レイヤーと alert_areas レイヤーを自動的に更新するよう、フィード ルーチンを調整します。

配置論理関数の定義

フィード ルーチンには、deployLogic() という名前の配置論理関数のプレースホルダー スクリプトが含まれています。ALF 手法の配置論理プロセスは、インターネットから取得した最新の情報 (今回の場合、Work ジオデータベース内に存在) を収集し、ライブ データ (Live ジオデータベースにあるフィーチャクラス) を上書きします。

  1. Coral_reef_exercise_local.py という名前の coral_reef_exercise.py スクリプトのコピーを作成します。コピーをテキスト エディターまたは Python IDE で開きます。

    次に、shutil モジュールがインポートされるようにスクリプトを変更します。このモジュールには、配置論理関数の定義に必要な複数の高度なファイル操作機能が含まれています。

  2. coral_reef_exercise_local.py スクリプトの 1 行目で、「shutil」をモジュールのリストに追加します。

    shutil モジュールを使用したインポート機能

    次に、3 番目の引数を、liveGDB という名前のフィード ルーチンに追加します。これは、プロジェクト内のレイヤーが配置されているLive ジオデータベースを表します。

  3. 6 行目で、「liveGDB」を feedRoutine 引数のリストに追加します。

    liveGDB 引数を使用したフィード ルーチン

    また、スクリプトの末尾にある sys.argv[1:] コマンドにこの引数を追加します。このようにして、ユーザーはコマンド プロンプトでスクリプトを実行する際、Live ジオデータベースのパスと名前を指定できます。

  4. 77 行目で、括弧付きリストに「liveGDB」を追加します。78 行目で、「liveGDB」を feedRoutine 引数のリストに追加します。

    追加の liveGDB 引数を使用したフィード ルーチン

    deployLogic() 関数には 2 つの引数 (workGDBliveGDB) が必要なため、これらの引数を関数が定義および呼び出される場所に追加します。

  5. 63 行目および 73 行目で、deployLogic() を「deployLogic(workGDB, liveGDB)」に置き換えます。

    deployLogic() 引数を使用したフィード ルーチン

    次に、deployLogic() 関数を定義します。for ループを使用して workGDB 引数内のすべてのエレメントをコピーし、これらのエレメントを使用して liveGDB 引数内のエレメントを置き換えます。os.walk() 関数を使用してファイルを一覧表示し、shutil.copy2() 関数を使用してファイルをコピーおよび置換します。ALF 手法に従って、スクリプトで *.lock ファイルを無視することもできます。

  6. 74 行目で、pass (プレースホルダー) を次の行に置き換えます。
    for root, dirs, files in os.walk(workGDB, topdown=False):
    	    files = [f for f in files if '.lock' not in f]
    	    for f in files:
    	        shutil.copy2(os.path.join(workGDB, f), os.path.join(liveGDB, f))

    deployLogic() 関数を定義するスクリプト

    備考:

    このフィード ルーチンは、ArcGIS Pro プロジェクトのフィーチャクラスを自動的に置き換えますが、一定の予防措置が必要です。新しいフィーチャクラスは、以前のデータ構造と一貫している必要があります。欠落しているフィールドや異なる名前により、マップ プロジェクトを破壊してしまう可能性があります。

  7. スクリプトにタブのインデントが含まれていないことを確認します。スクリプトを保存します。
    備考:

    スクリプトが正しく作成されたことを確認する場合は、サンプル スクリプトと比較できます。

スタンドアロン スクリプトの実行

次に、調整したフィード ルーチンを実行し、ArcGIS Pro プロジェクトを更新します。

プロジェクトで最新のデータをマッピングした後、NOAA はデータを更新していない可能性があります。この時点でスクリプトを実行した場合、おそらくデータの変更を確認できません。スクリプトが正しく機能することをテストするには、Learn ArcGIS がホストする履歴ファイルを使用してデータを更新します。

  1. 必要に応じて、ArcGIS Pro[Coral Bleaching] プロジェクトを開きます。
  2. 必要に応じて、Python コマンド プロンプトを開き、cd コマンドを使用して、coral_reef_exercise_local.py ファイルが保存されているディレクトリを参照します。
  3. コマンド プロンプトで、次のコマンドを実行します。

    python coral_reef_exercise_local.py https://downloads.esri.com/LearnArcGIS/update-real-time-data-with-python/vs_polygons.json C:\Temp\Work.gdb C:\Temp\Live.gdb

    コマンドが実行されます。

    コマンドが実行された Python コマンド プロンプト

    備考:

    NOAA Coral Reef Watch プログラムでデータが更新されたら、履歴ファイルの URL (https://downloads.esri.com/LearnArcGIS/update-real-time-data-with-python/vs_polygons.json) を NOAA のデータのURL (https://coralreefwatch.noaa.gov/vs/vs_polygons.json) に置き換えることができます。

    プロンプトにはコマンドが正常に実行された旨が表示されますが、ArcGIS Pro のマップは変更されていません。ArcGIS Pro を再起動してマップ表示を更新し、変更内容を視覚化します。

  4. ArcGIS Pro を閉じます (プロンプトが表示されたら保存します)。[Coral Bleaching] プロジェクトを再度開きます。

    ArcGIS Pro の再起動により、マップ表示も更新された可能性があります。更新されなかった場合は、手動で表示を更新できます。

  5. 必要に応じて、[マップ] ビューの右下隅にある [更新] ボタンをクリックします。

    [更新] ボタン

    マップが更新され、履歴データが表示されます (2019 年 2 月 19 日以降)。

    履歴データを使用したマップ

    属性データが更新されたことを確認することもできます。

  6. マップ上で、任意のステーションまたはエリア フィーチャをクリックします。

    フィーチャのポップアップを開きます。[date] フィールドには、履歴データの日付である [2019-02-19] が表示されます。

    過去の日付を含むポップアップ

  7. ポップアップを閉じます。

このレッスンでは、フィード ルーチンを作成および実行し、ローカル データセットを更新しました。マップを履歴データで更新することによりフィード ルーチンをテストしましたが、Python コマンドで使用されている URL を置き換えることで、NOAA の最新データに同じプロセスを適用できます。次のレッスンでは、同様のフィード ルーチンを作成および実行し、オンライン フィーチャ サービスを更新します。


オンライン フィーチャ サービスの更新

前のレッスンでは、フィード ルーチンを作成および実行して、ArcGIS Pro プロジェクトのローカル フィーチャクラスを更新しました。このレッスンでは、同様のプロセスでフィード ルーチンを作成および実行し、Web マップ内のオンライン フィーチャ サービスを更新します。

サービス定義および ID の取得

ローカル フィーチャクラスを更新する際、ライブ ジオデータベースを新しいデータのコピー先として使用しました。オンライン フィーチャ サービスはジオデータベースに格納されないため、ArcGIS API for Python を使用したフィーチャ サービスを検索および置換するには、サービス定義ファイルおよびアイテム ID が必要になります。

最初のレッスンでは、最新のデータを使用してフィーチャ サービスを公開しました。このフィーチャ サービスを更新のターゲットに使用します。最初に、フィーチャ サービスのサービス定義ファイルをダウンロードします。

  1. 必要に応じて、ArcGIS 組織のアカウント または ArcGIS Enterprise ポータルにサイン インします。
  2. [コンテンツ] ページに移動し、[Coral Reef Watch] フィーチャ レイヤーとサービス定義ファイルが配置されているフォルダーにアクセスします。
    備考:

    サービス定義ファイルは、レイヤーの公開時に作成されています。このファイルを使用してフィーチャ サービスを更新するため、フィーチャ サービスが更新されると、公開後にフィーチャ サービスに加えられた変更内容 (メタデータやシンボルの変更など) は失われます。フィーチャ サービスを含む Web マップまたはアプリも影響を受けます。

    フィーチャ サービスへの変更内容が失われないようにするには、ビュー レイヤーの作成をお勧めします。フィーチャ レイヤーを使用するマップまたは Web アプリでは、フィーチャ サービスではなくビュー レイヤーを指定でき、フィーチャ サービスの更新時にもビュー レイヤーへの変更内容は保持されます。ビュー レイヤーを作成するには、フィーチャ レイヤーの詳細ページを開き、[ビュー レイヤーを作成] をクリックします。詳細については、ドキュメント ページをご参照ください。

  3. [Coral Reef Watch] サービス定義ファイルのオプション ボタン (3 つのドット) をクリックし、[ダウンロード] を選択します。

    サービス定義ファイルのダウンロード

    サービス定義ファイル (*.sd) がコンピューターにダウンロードされます。

  4. サービス定義ファイルをドライブ C 上の [Temp] フォルダーにコピーします。

    次に、レイヤーのアイテム ID をコピーします。

  5. [Coral Reef Watch] フィーチャ レイヤーのオプション ボタンをクリックし、[アイテム詳細の表示] を選択します。

    フィーチャ レイヤーの詳細ページが開きます。ID は URL に記載されています。

  6. 詳細ページの URL で、id= より後ろの文字と数字から構成される文字列をコピーします (画像例では 2dcf249f5cd54a609d51acba6e0ba029)。
    備考:

    フィーチャ レイヤーのアイテム ID は異なります。

    フィーチャ レイヤーのアイテム ID

  7. 空のテキスト ファイルなど、簡単にアクセスできる場所に ID を貼り付けます。

配置論理関数の定義

次に、元のフィード ルーチンのコピーをもう 1 つ作成します。次に、オンライン フィーチャ サービスを Work ジオデータベースからダウンロードしたデータに置き換えるスクリプトを使用して、deployLogic() 関数を定義します。

  1. 元の coral_reef_exercise.py スクリプト「coral_reef_exercise_online.py」のコピーを作成します。コピーをテキスト エディターまたは Python IDE で開きます。

    作成するスクリプトには、fnmatchshutilsubprocessarcgis モジュールのほか、GIS サブモジュールが必要です。

  2. coral_reef_exercise_online.py スクリプトの 1 行目で、「fnmatch」、「shutil」、「subprocess」、および「arcgis」をモジュールのリストに追加します。Enter キーを押して、2 行目に「from arcgis.gis import GIS」行を追加します。

    完全な行の記述は次のとおりです。

    import sys, os, tempfile, json, logging, arcpy, fnmatch, shutil, subprocess, arcgis
    from arcgis.gis import GIS

    モジュールおよびサブモジュールをインポートする行を含むフィード ルーチン

    ローカル フィーチャクラスを更新する配置論理関数を定義した際、フィード ルーチン liveGDB に引数を追加しました。この引数を使用して、スクリプトの実行時に必要なジオデータベースのパスを指定できます。このフィード ルーチンに、フィーチャ サービスのアイテム ID、サービス定義ファイル、およびサービス名のパラメーターを追加します。

  3. 7 行目で、引数「itemid」、「original_sd_file」、および「service_name」を feedRoutine 引数のリストに追加します。

    完全な行の記述は次のとおりです。

    def feedRoutine (url, workGDB, itemid, original_sd_file, service_name):

    feedRoutine 関数に追加された引数

    また、スクリプトの末尾にある sys.argv[1:] コマンドにこれらのパラメーターを追加します。

  4. 78 行目および 79 行目で、引数「itemid」、「original_sd_file」、および「service_name」を両方の引数リストに追加します。

    完全な行の記述は次のとおりです。

    [url, workGDB, itemid, original_sd_file, service_name] = sys.argv[1:]
        feedRoutine (url, workGDB, itemid, original_sd_file, service_name)

    sys.argv[1:] コマンドに追加された引数

    また、これらの引数 (および workGDB 引数) を、コマンドが定義および呼び出される deployLogic() 関数に追加します。

  5. 64 行目および 74 行目で、deployLogic() を「deployLogic(workGDB, itemid, original_sd_file, service_name)」に置き換えます。

    コマンドが定義および呼び出される deployLogic 関数の引数

    次に、deployLogic() 関数を定義します。この関数では、複数のタスクが実行されます。最初に、gis.content.get() 関数を使用して、ArcGIS Online または ArcGIS Enterprise ポータルからフィーチャ サービス アイテム (「itemid」引数で表される) を取得します。

    GIS() 関数で定義された gis 変数も作成します。この関数の引数には、組織のポータルの URL (ArcGIS Online の場合は「https://arcgis.com」)、アカウント ユーザー名、およびアカウント パスワードが含まれます。

  6. 75 行目で、プレースホルダー スクリプト (pass) を次の行に置き換えます。
    # Get item from ArcGIS Online
        gis = GIS(url='https://arcgis.com', username='your_username', password='your_password')
        item = gis.content.get(itemid)
        sd_file_name = os.path.basename(original_sd_file)
        if sd_file_name != item.related_items("Service2Data")[0].name:
            raise Exception('Erroneous itemid, service name, or original sd file'.format(itemid))
    備考:

    ArcGIS Online アカウントを使用している場合、url パラメーターはオプションです。

  7. 76 行目で、username および password パラメーターを ArcGIS アカウントのユーザー名とパスワードに置き換えます。アカウントが ArcGIS Enterprise ポータル用である場合は、url パラメーターをポータルの URL に置き換えます。
    注意:

    このスクリプトにはパスワードが含まれているため、他のユーザーと共有する場合は注意してください。認証情報の保護に役立つ高度なスクリプト機能もあります。

    次に、deployLogic() 関数でサービス定義ファイル (original_sd_file) のコンテンツを解凍します。この解凍は、多くの Windows コンピューターにデフォルトで付属している 7-Zip を使用して実行されます。7-Zip を使用してファイルを解凍するスクリプトを追加する前に、コンピューターに 7-Zip が存在することを確認し、Windows の Path 環境変数に追加します。この環境変数に追加することで、スクリプトを使用してプログラムを呼び出すことができます。

  8. 必要に応じて、お使いのコンピューターに適したバージョンの 7-Zip をダウンロードしてインストールします。

    環境変数の編集プロセスは、オペレーティング システムによって異なりますが、通常は [環境変数] ウィンドウから実行できます。

  9. コンピューター上で、[コントロール パネル] を開きます。[システムとセキュリティ][システム][システムの詳細設定] の順にクリックします。[システム プロパティ] ウィンドウで、[環境変数] をクリックします。(正確なパスは、オペレーティング システムによって異なる場合があります)。
  10. [環境変数] ウィンドウの [システム変数] で、[Path] 変数を選択して [編集] をクリックします。

    オペレーティング システムに応じて、[環境変数名の編集] ウィンドウまたは [システム変数の編集] ウィンドウが開きます。新しい変数を追加するプロセスは、ウィンドウごとに異なります。

  11. [環境変数名の編集] ウィンドウが開いたら、[新規] をクリックし、新しい変数として「C:\Program Files\7-Zip」を追加します。[システム変数の編集] ウィンドウが開いたら、[変数] 値パラメーターの末尾までスクロールし、「;C:\Program Files\7-Zip」を末尾に貼り付けます (既存のテキストを削除しないようにしてください)。
  12. [OK] をクリックします。[環境変数] ウィンドウで [OK] をクリックします。

    次に、スクリプトを作成します。このスクリプトには、[Path] 環境変数で 7-Zip が見つからない場合に発生するエラー メッセージが含まれます。

  13. coral_reef_exercise_online.py スクリプトの 80 行目の後に、次の行を追加します。
    # Unpack original_sd_file using 7-zip
        path_7z = fnmatch.filter(os.environ['path'].split(';'), '*7-Zip')
        temp_dir = tempfile.mkdtemp()
        if len(path_7z):
            exe_7z = os.path.join(path_7z[0], '7z.exe')
            call_unzip = '{0} x {1} -o{2}'.format(exe_7z, original_sd_file, temp_dir)
        else:
            raise Exception('7-Zip could not be found in the PATH environment variable')
        subprocess.call(call_unzip)

    スクリプトはフィーチャ サービスを取得し、サービス定義ファイルを解凍した後、そのデータを Work.gdb にダウンロードされたデータに置き換えます。Live.gdb を、新しいサービス定義ファイルに圧縮できる中間フォルダーとして使用します。

    スクリプトは shutil.rmtree() 関数を使用して Live.gdb を削除し、os.mkdir() 関数を使用して再度作成することで、ジオデータベース内の既存のコンテンツを削除します。

  14. 89 行目の後に、次の行を追加します。
    # Replace Live.gdb content
        liveGDB = os.path.join(temp_dir, 'p20', 'live.gdb')
        shutil.rmtree(liveGDB)
        os.mkdir(liveGDB)
        for root, dirs, files in os.walk(workGDB):
            files = [f for f in files if '.lock' not in f]
            for f in files:
                shutil.copy2(os.path.join(workGDB, f), os.path.join(liveGDB, f))

    次に、スクリプトは Live.gdb を updated_sd という名前の新しいサービス定義ファイルに圧縮します。

  15. 97 行目の後に、次の行を追加します。
    # Zip file
        os.chdir(temp_dir)
        updated_sd = os.path.join(temp_dir, sd_file_name)
        call_zip = '{0} a {1} -m1=LZMA'.format(exe_7z, updated_sd)
        subprocess.call(call_zip)

    最後に、スクリプトはアイテムの manager メソッド (arcgis.features.FeatureLayerCollection.fromitem(item).manager) を使用して、フィーチャサービスを新しいデータで上書きします。

  16. 102 行目の後に、次の行を追加します。
    # Replace file
        manager = arcgis.features.FeatureLayerCollection.fromitem(item).manager
        status = manager.overwrite(updated_sd)
        # Return
        return True
  17. スクリプトにタブのインデントが含まれていないことを確認します。スクリプトを保存します。
    備考:

    スクリプトが正しく作成されたことを確認する場合は、サンプル スクリプトと比較できます。

スタンドアロン スクリプトの実行

次に、Python コマンド プロンプトでフィード ルーチンを実行し、Coral Reef Watch オンライン フィーチャ サービスを更新します。前のレッスンと同様に、この演習では履歴データを使用してフィーチャ サービスを更新します。

  1. 必要に応じて、ArcGIS Online または ArcGIS Enterprise ポータルのマップ ビューアーで [Coral Reef Watch] フィーチャ レイヤーを開きます。
  2. 必要に応じて、Python コマンド プロンプトを開き、cd コマンドを使用して、coral_reef_exercise_local.py ファイルが保存されているディレクトリを参照します。
    備考:

    Path 環境変数に 7-Zip を追加した場合、Python コマンド プロンプトの再起動が必要になる場合があります。

  3. 次のコマンドを貼り付けます (ただし、まだ実行しないでください)。

    python coral_reef_exercise_online.py https://downloads.esri.com/LearnArcGIS/update-real-time-data-with-python/vs_polygons.json C:\Temp\Work.gdb

    コマンドを実行する前に、必要な残りの引数 (アイテム Id、元のサービス定義ファイル、およびサービス名) を追加します。

  4. コマンドの末尾で Space キーを押して、フィーチャ サービスのアイテム ID を貼り付けます。
    備考:

    アイテム ID は、フィーチャ サービスの URL に含まれている、文字と数字から構成された文字列です (例: 2dcf249f5cd54a609d51acba6e0ba029)。

    以前に元のサービス定義ファイルをダウンロードし、Temp フォルダーにコピーしました。サービス名は Coral_Reef_Watch です。

  5. Space キーを押して、「C:\Temp\Coral_Reef_Watch.sd Coral_Reef_Watch」を貼り付けます。

    完成したコマンドは、次のコマンドと同様の形式になります (ただし、アイテム ID は異なります)。

    python coral_reef_exercise_online.py https://downloads.esri.com/LearnArcGIS/update-real-time-data-with-python/vs_polygons.json C:\Temp\Work.gdb 2dcf249f5cd54a609d51acba6e0ba029 C:\Temp\Coral_Reef_Watch.sd Coral_Reef_Watch

    Python コマンド プロンプトのコマンド例

  6. コマンドを実行します。

    コマンドが実行されます。コマンド プロンプトは、7-Zip と抽出中のデータに関する大量の情報を返します。コマンドが終了すると、コマンド プロンプトは Done 行を返します。

    Done を返すコマンド プロンプト

    次に、Web マップの変更内容を視覚化します。

  7. ブラウザーの [更新] または [再読み込み] ボタンを使用して、Web マップを更新します。

    マップが 2019 年 2 月 19 日のデータで更新されます。

    2019 年 2 月 19 日のデータを含む最終的なマップ

  8. ステーションまたはエリアをクリックして、ポップアップを開きます。

    [Date] フィールドに [2019-02-19] と表示され、データが正しく更新されたことを確認します。

    ポップアップの [Date] フィールド

  9. ポップアップを閉じます。保存せずに Web マップを閉じます (必要に応じて Web マップを保存することもできます)。

このレッスンでは、ローカル レイヤーと Web レイヤーを最新の NOAA データで自動的に更新するフィード ルーチンを作成しました。このレッスンでは、基本的な Python トピックと高度な Python トピックも紹介し、ALF 手法を使用してフィード ルーチンを作成および実装しました。このレッスンでは、履歴データを使用してレイヤーを更新しましたが、NOAA データの URL を使用して同じスクリプトを実行できます。

このスクリプトを頻繁に実行することで、レイヤーを最新の状態に保つことができます。Windows でタスクを設定することにより、指定した間隔でスクリプトを自動的に実行し、リアルタイム データで配置できるようにすることができます。

その他のレッスンについては、「Learn ArcGIS Lesson ギャラリー」をご参照ください。