チュートリアル: arcpy.mapping を使用した高度な Web マップの印刷/エクスポート

複雑性: 上級 データ要件: ソフトウェアと共にインストール済み

下の図に、これから作成する ArcGIS Web API アプリケーションのサンプルを示します。この Web アプリケーションでは、エンド ユーザは以下を実行できます。

Web アプリケーション

出力 PDF のサンプルを下に示します。Web アプリケーションのコンテンツ ウィンドウ凡例でレイヤがオフにされており、それがこの出力に反映されています。

出力 PDF

[Export Map] ボタンに実装されているコードでは、ArcGIS Web API の [Print Task] を使用しています。これは、ArcGIS 10.1 for Desktop および ArcGIS 10.1 for Server 以降で使用可能です。このチュートリアルでは、[Print Task] に追加パラメータ(たとえば、出力 PDF ファイルにジオリファレンス情報をエクスポートするかどうかなど)を渡す方法についても示します。[Print Task] に追加パラメータを渡す機能は、Web アプリケーションから任意の数の追加パラメータを取得できるようになるため、役立ちます。[Print Task] が使用するジオプロセシング サービスとして公開される、Python スクリプトも作成します。この Python スクリプトは、arcpy.mapping モジュールの ConvertWebMapToMapDocument 関数を使用して、完全な状態の Web マップをテンプレート マップ ドキュメントに挿入します。ユーザが選択できる複数のテンプレートに段階分けします。各テンプレートには、マップ サービス内の選択可能なすべてのレイヤと同等のベクタが含まれます。テンプレートには、凡例、ダイナミック テキストなどの、他のエレメントも含めることができます。また、arcpy.mapping モジュールは、サービス レイヤを識別し、それらをローカル データを指すレイヤと交換する機能、および、さまざまな形式(たとえば、PDF)にエクスポートする機能を提供します。

このチュートリアルを実行するには、arcpy.mapping モジュール、ArcGIS Web APIArcGIS for Desktop、および ArcGIS for Server について把握する必要があります。このチュートリアルには、すべての ArcGIS Web API のサンプル コードが含まれています。次の Web アプリケーションのヘルプ トピックを読み、印刷についても熟知する必要があります。

Web アプリケーションでの印刷Web マップの高度な印刷

このチュートリアルは、ArcGIS for Desktop のインストール ディレクトリ(通常は、C:\Program Files (x86)\ArcGIS\Desktop10.2 にあります)の MapTemplates フォルダと TemplateData フォルダを使用します。このチュートリアルは、マップ テンプレートとテンプレート データが存在し、それらが変更されていないことを前提にしています。そうでない場合、ArcGIS for Desktop の再インストールが必要になる可能性があります。

チュートリアル データのコピー

ArcGIS for Desktop のインストール ディレクトリ内のマップ テンプレートのいくつかを、新しいフォルダにコピーします。それらは、最終的に、Web アプリケーションで段階的マップ テンプレートとして使用されます。

これを実行する前に、フォルダ構造が存在し、そこで ArcGIS for Server が、Web アプリケーションで使用されるテンプレート マップ ドキュメントとテンプレート データを参照できることを確認する必要があります。このチュートリアルは、ArcGIS for Server に登録されたフォルダがあることを前提にしています。ArcGIS for Server へのデータ登録の詳細については、以下をご参照ください。

ヒントヒント:

ConvertWebMapToMapDocument 関数でテンプレート マップ ドキュメントを使用する場合、ArcGIS for Server に登録されたデータを使用することをお勧めします。登録されたデータを使用しない場合、テンプレート マップ ドキュメントとデータがパッケージ化されてサーバにコピーされます。パッケージ化の際に、データが ConvertWebMapToMapDocument で認識できないフォルダ構造に移動され、そのフォルダ構造への相対パスを使用して再作成される場合があります。詳細については、ConvertWebMapToMapDocument のヘルプ トピックをご参照ください。

手順:
  1. 新しい空の ArcMap セッションを開きます。
  2. カタログ ウィンドウで、登録済みフォルダに移動します。登録済みフォルダ内に、「USA」という名前で新しいフォルダを作成します。
  3. カタログ ウィンドウで、ArcGIS for Desktop のインストール ディレクトリにある MapTemplates フォルダに移動します。このフォルダは、通常、C:\Program Files (x86)\ArcGIS\Desktop10.2\MapTemplates にあります。さらに、その下の Traditional Layouts\USA フォルダに移動します。
  4. カタログ ウィンドウで、CentralUSA.mxd、ConterminousUSA.mxd、NortheasternUSA.mxd、NorthwesternUSA.mxd、SouthernUSA.mxd、および SouthwesternUSA.mxd の各ファイルをコピーし、前述の手順で作成した USA フォルダに貼り付けます。
    MapTemplates フォルダ
  5. カタログ ウィンドウで、ArcGIS for Desktop のインストール ディレクトリにある TemplateData フォルダに移動します。このフォルダは、通常、C:\Program Files (x86)\ArcGIS\Desktop10.2\TemplateData にあります。
  6. カタログ ウィンドウで、TemplateData.gdb をコピーし、前述の手順で作成した USA フォルダに貼り付けます。
    TemplateData フォルダ
  7. 登録済みフォルダには、次のような内容が表示されます。
    登録済みフォルダ
    注意注意:

    上のスクリーン キャプチャでは、登録済みフォルダの名前は、MyDataStore です。登録済みフォルダには、任意の名前を付けることができます。

Web アプリケーションでテンプレートとして使用するマップ ドキュメントの準備

ConvertWebMapToMapDocument でテンプレートとして使用するために、マップ ドキュメントを準備する必要があります。

現在、登録済みフォルダにあるマップ ドキュメントを、同じく登録済みフォルダ内にある TemplateData.gdb に再作成する必要があります。これは、ArcMap ユーザ インタフェースを使用して、または Python スクリプトを使用して実行できます。ここでは、後者の方法を使用します。

注意注意:

登録済みフォルダ内に独自のマップ ドキュメント テンプレートを一から作成する場合、下記の手順は不要です。

手順:
  1. ArcdMap で Python ウィンドウを開きます。
  2. 以下のスクリプトをコピーして Python ウィンドウに貼り付けます。
  3. import arcpy, os
    
    # The path to the registered folder where the template MXDs reside
    folderPath = "C:/MyDataStore/USA"
    
    # The location of TemplateData.gdb within the registered folder
    newPath = "C:/MyDataStore/USA/TemplateData.gdb"
    
    # Loop through all MXDs in the specified folder and change the layer's data source to the new path
    for filename in os.listdir(folderPath):
        fullpath = os.path.join(folderPath, filename)
        if os.path.isfile(fullpath):
            basename, extension = os.path.splitext(fullpath)
            if extension.lower() == ".mxd":
                mxd = arcpy.mapping.MapDocument(fullpath)
                mxd.findAndReplaceWorkspacePaths(arcpy.mapping.ListLayers(mxd)[1].workspacePath, newPath)
                mxd.save()
    print "done"
    
  4. Python ウィンドウ で、folderPath 変数の値を、テンプレート MXD が存在する登録済みフォルダへのパスに変更します。パスでは、必ずスラッシュ(/)を使用してください。
  5. Python ウィンドウ で、newPath 変数の値を、登録済みフォルダ内の TemplateData.gdb の場所に変更します。パスでは、必ずスラッシュ(/)を使用してください。
  6. スクリプトは次のようになります。
  7. カーソルを、最後の行の右に置きます。Enter キーを 2 回押してスクリプトを実行します。スクリプトの実行が終わるのを待ちます。

これで、マップ ドキュメントを Web アプリケーションでテンプレートとして使用する準備が整いました。

Web アプリケーションで使用するマップ サービスの作成

マップ ドキュメントを準備し、Web アプリケーションで使用するマップ サービスとして公開する必要があります。ここでは、登録済みフォルダ内の ConterminousUSA.mxd をマップ サービスとして使用します。これをサーバで公開するには、公開のための次の準備を行う必要があります。

手順:
  1. ArcMap で ConterminousUSA.mxd を開きます。
  2. デフォルトでは、マップはレイアウト ビューに表示されます。ArcMap のメインメニューで、[ビュー] [データ ビュー] の順に選択してデータ ビューに切り替えます。
  3. ここで、このマップ ドキュメントのマップ アノテーション グループをオフにします。このマップには、マップ グラフィックスが含まれています。マップ グラフィックスによって、読み込んだドキュメントのメモリ容量が増え、パフォーマンスが低下します。このような悪影響があるため、マップ グラフィックスはマップ サービスでサポートされていません。
    1. コンテンツ ウィンドウ内のデータ フレームの名前を右クリックして [プロパティ] をクリックし、[Conterminous United States] データ フレームのプロパティを開きます。
    2. [アノテーション グループ] タブをクリックします。
    3. [<デフォルト>] グループをオフにします。[アノテーション グループ] タブは次のようになります。
      [アノテーション グループ] タブ
    4. [データ フレーム プロパティ] ダイアログ ボックスの [OK] をクリックします。
  4. このマップは、ベースマップ レイヤ を使用します。ベースマップ レイヤは、ArcGIS for Server では公開されません。グループを解除することによって、レイヤをベースマップ レイヤから移動します。
    1. コンテンツ ウィンドウでベースマップ レイヤを右クリックし、[グループ解除] をクリックします。
    注意注意:

    独自のマップ ドキュメント テンプレートを一から作成する場合、またはマップ グラフィックスおよびベースマップ レイヤのいずれも含まない既存のマップ ドキュメント テンプレートを使用する場合、以降の手順は不要です。

    これで、マップをサーバで公開する準備が整いました。公開プロセスに慣れていない場合は、「サービスの公開方法」を確認してください。

  5. [ファイル] → [共有] → [サービス] の順にクリックします。
  6. [サービスを公開] をクリックします。
  7. [次へ] をクリックします。
  8. ArcGIS for Server コンピュータへの公開接続または管理接続を選択します。
  9. [次へ] をクリックします。
  10. USA」という名前で新しいフォルダを作成します。
  11. [続行] をクリックします。
  12. [サービス エディタ] ダイアログ ボックスの右上隅にある [公開] をクリックします。

これで、Web アプリケーションで使用するマップ サービスが作成されました。

Python スクリプトの作成

カスタム ジオプロセシング サービスとして使用する Python スクリプトを作成します。

カスタム ジオプロセシング サービスの Python スクリプトは、ConvertWebMapToMapDocument 関数を実行します。この関数は、印刷またはエクスポートする Web マップ(JSON 形式)をマップ ドキュメントに変換します。次に、arcpy.mapping スクリプトは、出力マップ ドキュメント内のすべてのレイヤについてループし、JSON Web マップ内のサービス レイヤに対応するベクタ レイヤを除くすべてのレイヤを削除します。次に、arcpy.mapping スクリプトは、凡例に含まれるすべてのレイヤについてループし、JSON Web マップの凡例に含まれるサービス レイヤに対応するベクタ レイヤを除き、凡例のすべてのレイヤを削除します。このスクリプトは、カスタム印刷タスクから追加パラメータも読み取ります。この場合の追加パラメータは、ジオリファレンス情報を出力 PDF ファイルにエクスポートするかどうかの指定です。その後、マップ ドキュメントを、選択した形式(たとえば、PDF)でエクスポートできます。

手順:
  1. 任意のPython IDEArcGIS for Desktop に付属する IDLE など)を開きます。
  2. 以下のコードをコピーして新しい Python スクリプトに貼り付けます。
  3. import arcpy
    import os
    import uuid
    
    # The template location in the registered folder (as UNC path)
    templatePath = '//MyComputerName/MyDataStore/USA'
    
    # Input WebMap json
    Web_Map_as_JSON = arcpy.GetParameterAsText(0)
    
    # Format for output
    Format = arcpy.GetParameterAsText(1)
    if Format == '#' or not Format:
        Format = "PDF" 
    
    # Input Layout template
    Layout_Template = arcpy.GetParameterAsText(2)
    if Layout_Template == '#' or not Layout_Template:
        Layout_Template = "NorthwesternUSA" 
        
    # Extra parameter - georef_info
    Georef_info = arcpy.GetParameterAsText(3)
    if Georef_info == '#' or not Georef_info:
        Georef_info = "False"
    
    # Convert Georef_info string to boolean
    if Georef_info.lower() == 'false': 
        Georef_info_bol = False
    elif Georef_info.lower() == 'true': 
        Georef_info_bol = True
    
    # Get the requested map document
    templateMxd = os.path.join(templatePath, Layout_Template + '.mxd')
    
    # Convert the WebMap to a map document
    result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd)
    mxd = result.mapDocument
    
    # Reference the data frame that contains the webmap
    # Note: ConvertWebMapToMapDocument renames the active dataframe in the template_mxd to "Webmap"
    df = arcpy.mapping.ListDataFrames(mxd, 'Webmap')[0]
    
    # Get a list of all service layer names in the map
    serviceLayersNames = [slyr.name for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df) 
                          if slyr.isServiceLayer and slyr.visible and not slyr.isGroupLayer]
    
    # Create a list of all possible vector layer names in the map that could have a 
    # corresponding service layer
    vectorLayersNames = [vlyr.name for vlyr in arcpy.mapping.ListLayers(mxd, data_frame=df) 
                         if not vlyr.isServiceLayer and not vlyr.isGroupLayer]
    
    # Get a list of all vector layers that don't have a corresponding service layer
    removeLayerNameList = [vlyrName for vlyrName in vectorLayersNames 
                           if vlyrName not in serviceLayersNames]
    
    # Remove all vector layers that don't have a corresponding service layer
    for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
        if not lyr.isGroupLayer \
        and not lyr.isServiceLayer \
        and lyr.name in removeLayerNameList \
        and lyr.name in vectorLayersNames:
            arcpy.mapping.RemoveLayer(df, lyr)
                    
    # Reference the legend in the map document
    legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT")[0]
    
    # Get a list of service layers that are on in the legend because the incoming 
    # JSON can specify which service layers/sublayers are on/off in the legend
    legendServiceLayerNames = [lslyr.name for lslyr in legend.listLegendItemLayers() 
                               if lslyr.isServiceLayer and not lslyr.isGroupLayer]
    
    # Remove vector layers from the legend where the corresponding service layer 
    # is also off in the legend
    for lvlyr in legend.listLegendItemLayers():
        if not lvlyr.isServiceLayer \
        and lvlyr.name not in legendServiceLayerNames \
        and not lvlyr.isGroupLayer \
        and lvlyr.name in vectorLayersNames:
            legend.removeItem(lvlyr)
    
    # Remove all service layers
    # This will leave only vector layers that had corresponding service layers
    for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
        if slyr.isServiceLayer:
            arcpy.mapping.RemoveLayer(df, slyr)
            
    # ConvertWebMapToMapDocument renames the active dataframe in the template_mxd to "Webmap".
    # Lets rename it to something more meaningful.
    df.name = Layout_Template
    
    # Use the uuid module to generate a GUID as part of the output name
    # This will ensure a unique output name
    output = 'WebMap_{}.{}'.format(str(uuid.uuid1()), Format)
    Output_File = os.path.join(arcpy.env.scratchFolder, output)
    
    # Export the WebMap
    if Format.lower() == 'pdf':
        arcpy.mapping.ExportToPDF(mxd, Output_File, georef_info=Georef_info_bol) 
    elif Format.lower() == 'png':
        arcpy.mapping.ExportToPNG(mxd, Output_File)
    
    # Set the output parameter to be the output file of the server job
    arcpy.SetParameterAsText(4, Output_File)
    
    # Clean up - delete the map document reference
    filePath = mxd.filePath
    del mxd, result
    os.remove(filePath)
    
  4. templatePath 変数の値を、テンプレート マップ ドキュメントが含まれる登録済みフォルダ内のフォルダへの UNC パスに変更します。
  5. 注意注意:

    ArcGIS for ServerArcGIS for Desktop、および登録済みフォルダがすべて同じコンピュータ上にある場合、登録済みフォルダへの UNC パスは不要です。代わりに、絶対パスを使用できます。

  6. Python スクリプトを保存します。スクリプトには、「AdvancedHighQualityPrinting.py」という名前を付けます。そのスクリプトを、登録済みフォルダ内の「WebApp」という名前のフォルダに保存します。

これで、Python スクリプトをツールボックスに追加する準備が整いました。

ツールボックスの作成

手順:
  1. ArcMap のカタログ ウィンドウで、登録済みフォルダ内の WebApp フォルダに移動します。
  2. WebApp フォルダを右クリックして、[新規作成] → [ツールボックス] の順にクリックします。ツールボックスに、「AdvancedHighQualityPrinting」という名前を付けます。
  3. [AdvancedHighQualityPrinting] ツールボックスを右クリックして、[アイテム説明] をクリックします。
  4. [アイテム説明] ダイアログ ボックスで、任意のテキストを使用して[タグ] アイテムと [サマリ] アイテムに入力します。必要に応じて、他のアイテム説明も入力します。
  5. [保存] をクリックして [アイテム説明] ダイアログ ボックスを終了します。

Python スクリプト ツールの作成

次に、AdvancedHighQualityPrinting.py スクリプトを [AdvancedHighQualityPrinting] ツールボックスに追加します。

手順:
  1. カタログ ウィンドウで [AdvancedHighQualityPrinting] ツールボックスを右クリックし、[追加] [スクリプト] の順にクリックします。
  2. [スクリプトの追加] ダイアログ ボックスで、[名前][ラベル] の両方に「AdvancedHighQualityPrinting」と入力します。
  3. [次へ] をクリックします。
  4. スクリプト ファイルを選択するため、登録済みフォルダ内の WebApp フォルダに移動して、AdvancedHighQualityPrinting.py を選択します。
  5. [スクリプトの追加] ダイアログ ボックスで [次へ] をクリックします。
  6. 5 つのパラメータをスクリプト ツールに追加する必要があります。
    1. 1 つ目のパラメータは、Web_Map_as_JSON です。このパラメータには、Web アプリケーションに表示されている、エクスポートするマップの状態を表す JSON 表現を入力します。プロパティの値を、次のスクリーン キャプチャの値に合わせてください。
      Web_Map_as_JSON パラメータ
    2. 2 つ目のパラメータは、Format です。印刷用に生成されるマップ イメージの形式を指定します。プロパティの値を、次のスクリーン キャプチャの値に合わせてください。
      Format パラメータ
    3. 3 つ目のパラメータは、Layout_Template です。使用するテンプレート マップ ドキュメントを指定します。プロパティの値を、次のスクリーン キャプチャの値に合わせてください。
      Layout_Template パラメータ
    4. 4 つ目のパラメータは、Georef_info です。座標系情報の出力 PDF ファイルへのエクスポートを有効にする、文字列で表すブール値です。プロパティの値を、次のスクリーン キャプチャの値に合わせてください。
      Georef_info パラメータ
    5. 5 つ目のパラメータは、Output_File です。作成する出力ファイルを指定します。プロパティの値を、次のスクリーン キャプチャの値に合わせてください。
      Output_File パラメータ

      注意注意:

      Web_Map_as_JSON、Format, Layout_Template、および Output_File の各パラメータ名は、ArcGIS Web API の [Print Task] のツール シグネチャに一致するように、示されたとおりに正確に記述する必要があります。パラメータの詳細については、「Web マップのエクスポート」をご参照ください。Georef_info パラメータは、[Print Task] に渡される追加パラメータです。そのため、このパラメータに適用する命名規則はありません。

    6. [スクリプトの追加] ダイアログ ボックスで [完了] をクリックします。
  7. [AdvancedHighQualityPrinting] スクリプト ツールを右クリックして、[アイテム説明] をクリックします。
  8. [アイテム説明] ダイアログ ボックスで、任意のテキストを使用して [タグ] アイテムと [サマリ] アイテムに入力します。[アイテム説明] ダイアログ ボックスの [構文] セクションにある、5 つのパラメータに対応する [ダイアログの説明] にもすべて入力します。必要に応じて、他のアイテム説明も入力します。

ツールの実行

ツールを正常に実行して、ArcGIS for Server で公開できる結果を [結果] ウィンドウに作成する必要があります。ここでは、ConvertWebMapToMapDocument を使用するテスト スクリプトを使用して、重要な問題について説明します。このスクリプトをローカルで実行するには、有効な JSON Web マップが必要です。しかし、ArcGIS Web API は、スクリプトが公開されて初めて、Web アプリケーションで JSON Web マップを提供します。これを回避するために、ConvertWebMapToMapDocument のヘルプ トピックにあるテスト用の JSON を使用できます。さらに、Web アプリケーションから取得する JSON と同じになるように、ツールが期待するエレメントを含めて、テスト用の JSON を変更できます。このチュートリアルでは、Web アプリケーションのユーザは、マップのサービス レイヤのオン/オフを調整し、さらに、凡例のレイヤのオン/オフも調整します。したがって、次のようなテスト用の JSON Web マップ記述を使用する必要があります。

{
    "operationalLayers": [
        {
            "url": "http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer",
            "title": "MyDynamicService",
            "opacity": 1,
            "id": "MyDynamicService",
            "visibility": true,
            "visibleLayers": [
                0,
                2,
                3,
                4,
                5,
                6,
                7
            ]
        }
    ],
    "mapOptions": {
        "extent": {
            "xmin": -2200000,
            "ymin": 500000,
            "xmax": -1300000,
            "ymax": 1300000,
            "spatialReference": {
                "wkid": 102008
            }
        },
        "scale": 5000000,
        "rotation": 0
    },
    "layoutOptions": {
        "copyrightText": "",
        "authorText": "",
        "legendOptions": {
            "operationalLayers": [
                {
                    "id": "MyDynamicService",
                    "subLayerIds": [
                        0,
                        2,
                        5
                    ]
                }
            ]
        }
    }
}

ここで、visibleLayers エレメントにレイヤ 1 が含まれていないことに注意してください。つまり、マップ サービスのレイヤ 1 は出力されません。また、legendOptionssubLayerIDs にも注意してください。凡例のレイヤは、02、および 5 のみが表示されます。これは、Web アプリケーションから返される JSON と同じです。詳細については、「JSON Web マップの仕様」をご参照ください。

スクリプト ツールを実行するときに、JSON の記述がコピーされて、Web_Map_as_JSON 入力パラメータに貼り付けられます。ただし、記述が有効な入力になるには、改行を削除する必要があります。改行を削除した JSON の記述を次に示します。

{"operationalLayers":[{"url":"http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer","title":"MyDynamicService","opacity":1,"id":"MyDynamicService","visibility":true,"visibleLayers":[0,2,3,4,5,6,7]}],"mapOptions":{"extent":{"xmin":-2200000,"ymin":500000,"xmax":-1300000,"ymax":1300000,"spatialReference":{"wkid":102008}},"scale":5000000,"rotation":0},"layoutOptions":{"copyrightText":"","authorText":"","legendOptions":{"operationalLayers":[{"id":"MyDynamicService","subLayerIds":[0,2,5]}]}}}

サーバ名(上記の MyServer:6080)を、使用している ArcGIS for Server サーバの名前に変更する必要もあります。

ヒントヒント:

公開する目的の場合、ArcGIS Web API が Web アプリケーションで JSON Web マップを提供することになるため、Web_Map_as_JSON 入力パラメータを空白のままにすることを選択できます。空白の入力によってエラーが発生しない方法で Python スクリプトが記述されている場合に限り、Web_Map_as_JSON 入力パラメータを空白のままにすることができます。たとえば、スクリプトが Web マップ レイヤを名前で検索しない場合です。スクリプトがエラーによってサーバ上で失敗した場合、それをローカルで修正してから、サーバで再公開する必要があります。したがって、有効な JSON Web マップ記述または JSON Web マップ内のすべてのエレメントを含むデバッグ用のマップ ドキュメントを使用してテストすることによって、スクリプトがローカルで動作することを確認してから公開することをお勧めします。このチュートリアルでは、有効な JSON のコードが提供されます。

手順:
  1. カタログ ウィンドウで [AdvancedHighQualityPrinting] スクリプト ツールを右クリックし、[開く] をクリックします。
  2. Web_Map_as_JSON パラメータに入力するため、改行を削除した JSON の記述を前述の 1 行のコードブロックからコピーして、Web_Map_as_JSON パラメータに貼り付けます。使用しているサーバの名前に一致するように、サーバ名を変更することを忘れないようにしてください。[AdvancedHighQualityPrinting] スクリプト ツール ダイアログ ボックスは、次のようになります。
    [AdvancedHighQualityPrinting] スクリプト ツール ダイアログ ボックス
  3. その他のパラメータはすべてデフォルトのままにし、[OK] をクリックします。
  4. [結果] ウィンドウを開きます
  5. 出力 PDF を参照するために、下でハイライト表示されている [Output_File] をダブルクリックします。
    [結果] ダイアログ ボックス

    これによって、PDF が表示されます。JSON Web マップで指定したように、PDF において、マップ のレイヤ 1 はオフになり、凡例の レイヤは 02、および 5 のみが表示されるはずです。

結果の公開

これで、結果をジオプロセシング サービスとして公開する準備が整いました。ジオプロセシング サービスの公開に慣れていない場合は、以下をご参照ください。

手順:
  1. [結果] ウィンドウで、[AdvancedHighQualityPrinting] の結果を右クリックし、[共有] → [ジオプロセシング サービス] の順にクリックします。
  2. [サービスを公開] をクリックします。
  3. [次へ] をクリックします。
  4. ArcGIS for Server コンピュータへの公開接続または管理接続を選択します。
  5. [次へ] をクリックします。
  6. USA という名前の既存のフォルダを使用します。
  7. [続行] をクリックします。
  8. [サービス エディタ] ダイアログ ボックスの右上隅にある [公開] をクリックします。
  9. スクリプト ツールが正常に公開されたら、ArcGIS for Server への GIS サーバ接続を使用して、ArcMap で ジオプロセシング サービスをテストすることをお勧めします。[ジオプロセシング結果] ウィンドウで、ジオプロセシング サービスの結果を参照できます。

これで、ジオプロセシング サービスを ArcGIS Web API で使用する準備が整いました。

Web アプリケーションの作成に使用する ArcGIS Web API の選択

ArcGIS Web API には、GIS 機能に類似した機能が用意されています。ユーザは、好みに合わせて開発プラットフォームを選択することができます。各 API からは、必要なリソースが提供されます。API リファレンスに目を通してください。入門として役に立ち、何が実行できるかを示す動作サンプルをご参照ください。また、フォーラム、ブログ、コード ギャラリーなどを通じて、他のユーザと情報交換することをお勧めします。各 API を使用した Web アプリケーションの構築の概要説明については、このチュートリアルの対象外です。それについては、API のドキュメントをご参照ください。詳細については、次のトピックをご参照ください。

各 ArcGIS Web API には、[Print Task] があります。[Print Task] には、作成済みのカスタム ジオプロセシング サービスを参照する、URL プロパティがあります。[Print Task] の詳細については、ArcGIS Web API のドキュメントをご参照ください。

以降のセクションでは、ArcGIS Web API のサンプル コードを使用します。これらを組み込んで、独自の Web アプリケーションを構築できます。

ArcGIS API for Silverlight のサンプル コード

ArcGIS API for Silverlight を使用している場合、下のサンプル コードを使用して独自の Web アプリケーションを構築できます。

下に示す ArcGIS API for Silverlight のサンプル コードでは、URL を前述の手順で作成したマップ サービスとジオプロセシング サービスに変更して、使用しているサーバ名に一致するようにしています。それらは、次の行で参照されています。

Url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"
printTask = new PrintTask("http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting");

XAML コード:

<UserControl x:Class="TestSilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:esri="http://schemas.esri.com/arcgis/client/2009">

    <Grid x:Name="LayoutRoot" Background="White">

        <esri:Map x:Name="MyMap" Extent="-2260000,-1500000,2250000,1220000">
            <esri:Map.Layers>
                <esri:ArcGISDynamicMapServiceLayer ID="MyDynamicService" 
                    Url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"
                    Initialized="ArcGISDynamicMapServiceLayer_Initialized"/>
            </esri:Map.Layers>
        </esri:Map>

        <StackPanel Orientation="Vertical" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Top" >
            <Border x:Name="PrintPanel" CornerRadius="10" BorderBrush="Gray" BorderThickness="1" Background="White" HorizontalAlignment="Left" 
                    VerticalAlignment="Top" Margin="15" Padding="10">
                <Border.Effect>
                    <DropShadowEffect/>
                </Border.Effect>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="LayoutTemplates" Grid.Row="0" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="LayoutTemplates" ItemsSource="{Binding LayoutTemplates}" Grid.Row="0" Grid.Column="1" Width="100" Margin="2"/>
                    <TextBlock Text="Formats" Grid.Row="1" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="Formats" Grid.Row="1" ItemsSource="{Binding Formats}"  Grid.Column="1" Width="100" Margin="2"/>
                    <TextBlock Text="Georef info?" Grid.Row="2" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="Georef_info" Grid.Row="2" Grid.Column="1" Width="100" Margin="2">
                        <ComboBoxItem Content="True"></ComboBoxItem>
                        <ComboBoxItem Content="False"></ComboBoxItem>
                    </ComboBox>
                    <Button x:Name="Print" Content="Export Map" Click="ExportMap_Click" 
                            Grid.Row="3" Grid.Column="0" Margin="2"/>

                </Grid>
            </Border>
        </StackPanel>

        <StackPanel Orientation="Vertical" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Center" >
            <Border Background="#99919191" BorderThickness="1" CornerRadius="5"
                HorizontalAlignment="Right" VerticalAlignment="Top"
                Margin="20,20,20,30" Padding="10" BorderBrush="Black">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="15" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="Table of Contents" Foreground="White" Grid.Row="0" >
                    <TextBlock.Effect>
                        <DropShadowEffect ShadowDepth="1" />
                    </TextBlock.Effect>
                    </TextBlock>
                    <ListBox Name="TOCListBox" Margin="0,5,0,0" ItemsSource="{Binding ElementName=MyMap, Path=Layers.[MyDynamicService].Layers}" 
                         Grid.Row="1">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <CheckBox Margin="2"
                                  Name="MyDynamicService"
                                  Content="{Binding Name}" 
                                  IsChecked="{Binding DefaultVisibility}" 
                                  Tag="{Binding ID}"
                                  ClickMode="Press" 
                                  Click="CheckBox_Click" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </Grid>
            </Border>
        </StackPanel>

        <StackPanel Orientation="Vertical" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Bottom" >
            <Border Background="#99919191" BorderThickness="1" CornerRadius="5"
                HorizontalAlignment="Right" VerticalAlignment="Top"
                Margin="20,20,20,30" Padding="10" BorderBrush="Black">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="18" />
                        <ColumnDefinition Width="62" />
                        <ColumnDefinition Width="6" />
                        <ColumnDefinition Width="56" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="15" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="Include in Legend" Foreground="White" Grid.ColumnSpan="4">
                    <TextBlock.Effect>
                        <DropShadowEffect ShadowDepth="1" />
                    </TextBlock.Effect>
                    </TextBlock>
                    <ListBox Name="LegendListBox" Margin="0,5,0,0" Grid.Row="1" Grid.ColumnSpan="4">
                        <ListBoxItem>
                            <CheckBox x:Name="CapitalCities" Content="Capital Cities" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="InterstateHighways" Content="Interstate Highways" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="Rivers" Content="Rivers" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="Lakes" Content="Lakes" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="StateBoundaries" Content="State Boundaries" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                    </ListBox>
                </Grid>
            </Border>
        </StackPanel>

    </Grid>


</UserControl>

背後にある C# のコード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client.Printing;
using ESRI.ArcGIS.Client.Tasks;

namespace TestSilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        PrintTask printTask;
        public MainPage()
        {
            InitializeComponent();
            printTask = new PrintTask("http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting");
            printTask.DisableClientCaching = true;
            printTask.JobCompleted += new EventHandler<PrintJobEventArgs>(printTask_JobCompleted);
            printTask.GetServiceInfoCompleted += new EventHandler<ServiceInfoEventArgs>(printTask_GetServiceInfoCompleted);
            printTask.GetServiceInfoAsync();
        }

        void printTask_GetServiceInfoCompleted(object sender, ServiceInfoEventArgs e)
        {
            PrintPanel.DataContext = e.ServiceInfo;
        }


        void printTask_JobCompleted(object sender, PrintJobEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.PrintResult != null)
                    System.Windows.Browser.HtmlPage.Window.Navigate(e.PrintResult.Url, "_blank");
            }
        }

        private void ExportMap_Click(object sender, RoutedEventArgs e)
        {

            if (printTask == null || printTask.IsBusy) return;
            ComboBoxItem typeItem = (ComboBoxItem)Georef_info.SelectedItem;
            string value = typeItem.Content.ToString();
            var gpExtraInput = new List<GPParameter>();
            gpExtraInput.Add(new GPString("Georef_info", value));

            // Specify the LayoutOptions to provide marginalia in the output map.
            ESRI.ArcGIS.Client.Printing.LayoutOptions myLayoutOptions = new ESRI.ArcGIS.Client.Printing.LayoutOptions();
            // Define the LegendOptions. This will show specified Layers in the printed map's legend area.
            ESRI.ArcGIS.Client.Printing.LegendOptions myLegendOptions = new ESRI.ArcGIS.Client.Printing.LegendOptions();

            // Define a List<LegendInfo> objects to put in the LegendOptions.
            List<ESRI.ArcGIS.Client.Printing.LegendInfo> myLegendInfos = new List<ESRI.ArcGIS.Client.Printing.LegendInfo>();
            // Loop through all of the Layers in the Map Control.
            foreach (var myLayer in MyMap.Layers)
            {
                // Create a new LegendInfo object to put in the List<LegendInfo> collection.
                ESRI.ArcGIS.Client.Printing.LegendInfo myLegendInfo = new ESRI.ArcGIS.Client.Printing.LegendInfo();

                // Set the LegendInfo.LayerId to the Layer.ID to add it to the printed map's legend area.
                myLegendInfo.LayerId = myLayer.ID;

                //TODO: Add SubLayer IDs to LegendInfo
                var l = MyMap.Layers["MyDynamicService"] as ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer;
                List<int> legendLayerIntList = new List<int>();
                foreach (var s in l.Layers)
                {
                    if (s.ID == 0)
                    {
                        if (CapitalCities.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 1)
                    {
                        if (InterstateHighways.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 2)
                    {
                        if (Rivers.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 3)
                    {
                        if (Lakes.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 4)
                    {
                        if (StateBoundaries.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                }

                myLegendInfo.SubLayerIds = from x in legendLayerIntList
                                               select x as object;
                
                // Add a single LegendInfo into the List<LegendInfo> collection.
                myLegendInfos.Add(myLegendInfo);
            }
            // Set the LegendOptions.LegendInfo to the new constructed List<LegendInfo> objects.
            myLegendOptions.LegendInfos = myLegendInfos;
            // Set the LayoutOptions.LegendOptions to manage what the Legend looks like in the output map.
            myLayoutOptions.LegendOptions = myLegendOptions;

            PrintParameters printParameters = new PrintParameters(MyMap)
            {
                LayoutTemplate = (string)LayoutTemplates.SelectedItem,
                Format = (string)Formats.SelectedItem,
                CustomInputParameters = gpExtraInput
            };

            printParameters.LayoutOptions = myLayoutOptions;
            printTask.SubmitJobAsync(printParameters);
        }

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            CheckBox tickedCheckBox = sender as CheckBox;

            string serviceName = tickedCheckBox.Name;
            bool visible = (bool)tickedCheckBox.IsChecked;

            int layerIndex = (int)tickedCheckBox.Tag;

            ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer dynamicServiceLayer = MyMap.Layers[serviceName] as
                ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer;

            List<int> visibleLayerList =
                dynamicServiceLayer.VisibleLayers != null
                ? dynamicServiceLayer.VisibleLayers.ToList() : new List<int>();

            if (visible)
            {
                if (!visibleLayerList.Contains(layerIndex))
                    visibleLayerList.Add(layerIndex);
            }
            else
            {
                if (visibleLayerList.Contains(layerIndex))
                    visibleLayerList.Remove(layerIndex);
            }

            dynamicServiceLayer.VisibleLayers = visibleLayerList.ToArray();
        }

        public void ArcGISDynamicMapServiceLayer_Initialized(object sender, EventArgs e)
        {
            ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer dynamicServiceLayer =
                sender as ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer;
            if (dynamicServiceLayer.VisibleLayers == null)
                dynamicServiceLayer.VisibleLayers = GetDefaultVisibleLayers(dynamicServiceLayer);
        }

        private int[] GetDefaultVisibleLayers(ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer dynamicService)
        {
            List<int> visibleLayerIDList = new List<int>();

            ESRI.ArcGIS.Client.LayerInfo[] layerInfoArray = dynamicService.Layers;

            for (int index = 0; index < layerInfoArray.Length; index++)
            {
                if (layerInfoArray[index].DefaultVisibility)
                    visibleLayerIDList.Add(index);
            }
            return visibleLayerIDList.ToArray();
        }
    }
}

ArcGIS API for Flex のサンプル コード

ArcGIS API for Flex を使用している場合、下のサンプル コードを使用して独自の Web アプリケーションを構築できます。

下に示す ArcGIS API for Flex のサンプル コードでは、URL を前述の手順で作成したマップ サービスとジオプロセシング サービスに変更して、使用しているサーバ名に一致するようにしています。それらは、次の行で参照されています。

url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"/>
url="http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting"/>

AdvancedHighQualityPrinting.mxml のコード:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:esri="http://www.esri.com/2008/ags"
			   initialize="printTask.getServiceInfo()"
			   pageTitle="High-quality printing"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:samples="IncludeFiles.*">
	
	<!--
	This sample also uses the following files:
	IncludeFiles/LayerTOC.mxml - a datagrid with checkboxes for every layer in the map service
	IncludeFiles/LayerVizRenderer.mxml - The datagrid itemrenderer (LayerVizRenderer) will update the map service as users selects/clears checkboxes.
	-->
	
	<fx:Script>
		<![CDATA[
			import com.esri.ags.events.PrintEvent;
			import com.esri.ags.tasks.supportClasses.DataFile;
			import com.esri.ags.tasks.supportClasses.JobInfo;
			import com.esri.ags.tasks.supportClasses.ParameterValue;
			import mx.controls.Alert;

			private function printBtn_clickHandler(event:MouseEvent):void
			{
				myLegendLayer.subLayerIds = [];
				if (CapitalCities.selected)
				{				
					myLegendLayer.subLayerIds.push(0);					
				}				
				if (InterstateHighways.selected)					
				{					
					myLegendLayer.subLayerIds.push(1);					
				}				
				if (Rivers.selected)					
				{					
					myLegendLayer.subLayerIds.push(2);					
				}				
				if (Lakes.selected)					
				{					
					myLegendLayer.subLayerIds.push(3);					
				}				
				if (StateBoundaries.selected)					
				{					
					myLegendLayer.subLayerIds.push(4);					
				}		
				
				if (printTask.getServiceInfoLastResult.isServiceAsynchronous)					
				{					
					printTask.submitJob(printParameters);					
				}					
				else					
				{					
					printTask.execute(printParameters);					
				}				
			}
			
			private function printTask_jobCompleteHandler(event:PrintEvent):void
			{
				var jobInfo:JobInfo = event.jobInfo;
				if (jobInfo.jobStatus == JobInfo.STATUS_SUCCEEDED)
				{
					printTask.getResultData(jobInfo.jobId);
				}
				else
				{
					Alert.show(jobInfo.jobStatus);
				}
			}
			
			private function printTask_getResultDataCompleteHandler(event:PrintEvent):void
			{
				var dataFile:DataFile = event.parameterValue.value as DataFile;
				navigateToURL(new URLRequest(dataFile.url));
			}
			
			private function printTask_executeCompleteHandler(event:PrintEvent):void
			{
				var paramValue:ParameterValue = event.executeResult.results[0];
				var dataFile:DataFile = paramValue.value as DataFile;
				navigateToURL(new URLRequest(dataFile.url));
			}
		]]>
	</fx:Script>
	
	<fx:Declarations>
		<esri:PrintTask id="printTask"
						executeComplete="printTask_executeCompleteHandler(event)"
						fault="Alert.show(event.fault.faultString)"
						getResultDataComplete="printTask_getResultDataCompleteHandler(event)"
						jobComplete="printTask_jobCompleteHandler(event)"
						showBusyCursor="true"
						url="http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting"/>
		<esri:PrintParameters id="printParameters"
							  format="{formats.selectedItem}"
							  layoutTemplate="{layoutTemplates.selectedItem}"
							  map="{map}">
			<esri:customParameters>
				<fx:Object Georef_info="{Georef_info.selectedItem}"/>
			</esri:customParameters>
			<esri:layoutOptions>
				<esri:LayoutOptions title="My Map">
					<esri:legendOptions>
						<esri:LegendOptions>
							<esri:LegendLayer id="myLegendLayer" layerId="myDynamicService" />
						</esri:LegendOptions>
					</esri:legendOptions>
				</esri:LayoutOptions>
			</esri:layoutOptions>

		</esri:PrintParameters>
	</fx:Declarations>
	
	<s:controlBarLayout>
		<s:HorizontalLayout gap="10"
							paddingBottom="7"
							paddingLeft="10"
							paddingRight="10"
							paddingTop="7"
							verticalAlign="baseline"/>
	</s:controlBarLayout>
	<s:controlBarContent>
		<s:Label text="Layout Templates"/>
		<s:DropDownList id="layoutTemplates"
						width="175"
						dataProvider="{printTask.getServiceInfoLastResult.layoutTemplates}"/>
		
		<s:Label text="Formats"/>
		<s:DropDownList id="formats"
						width="100"
						dataProvider="{printTask.getServiceInfoLastResult.formats}"/>
		
		<s:Label text="Georef info?"/>
		<s:DropDownList id="Georef_info"
						width="100">		
			<s:dataProvider>
				<s:ArrayList source="[True,False]"/>
			</s:dataProvider>
		</s:DropDownList>
		
		<s:Button id="printBtn"
				  click="printBtn_clickHandler(event)"
				  enabled="{printTask.getServiceInfoLastResult != null}"
				  label="Export Map"/>
	</s:controlBarContent>
	
	
	<mx:HDividedBox x="164" width="867" height="100%">
		<esri:Map id="map" width="632" level="2" wrapAround180="true">
			<esri:ArcGISDynamicMapServiceLayer id="myDynamicService"
											   url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"/>
			<esri:extent>
				<esri:Extent id="myExtent" xmin="-2260000" ymin="-1500000" xmax="2250000" ymax="1220000"/>
			</esri:extent>
		</esri:Map>
		<samples:LayerTOC width="210" height="493"
						  mapLayer="{myDynamicService}"/>
		<s:VGroup>
		</s:VGroup>

	</mx:HDividedBox>
	<s:CheckBox id="CapitalCities" x="21" y="30" label="Capital Cities" selected="true"/>
	<s:CheckBox id="InterstateHighways" x="21" y="56" label="Interstate Highways" selected="true"/>
	<s:Label x="21" y="10" text="Include in Legend?"/>
	<s:CheckBox id="Rivers" x="21" y="82" label="Rivers" selected="true"/>
	<s:CheckBox id="Lakes" x="21" y="108" label="Lakes" selected="true"/>
	<s:CheckBox id="StateBoundaries" x="21" y="134" label="State Boundaries" selected="true"/>
</s:Application>

LayerTOC.mxml のコード:

<?xml version="1.0" encoding="utf-8"?>
<!-- Used by High Quality Printing mxml -->
<mx:DataGrid xmlns:fx="http://ns.adobe.com/mxml/2009"
             xmlns:mx="library://ns.adobe.com/flex/mx"
             width="100%" height="100%"
             resizableColumns="false"
             sortableColumns="false">

    <fx:Script>
        <![CDATA[
            import com.esri.ags.events.LayerEvent;
            import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;
            import com.esri.ags.layers.ArcIMSMapServiceLayer;
            import com.esri.ags.layers.Layer;
            import com.esri.ags.layers.supportClasses.LayerInfo;

            import mx.collections.ArrayList;
            import mx.collections.IList;
            import mx.utils.ObjectUtil;

            private var _layerInfos:Array;
            private var _layer:Layer;
            private var _layerChanged:Boolean;

            public function get mapLayer():Layer
            {
                return _layer;
            }

            public function set mapLayer(value:Layer):void
            {
                _layer = value;
                _layerChanged = true;
                invalidateProperties();
            }

            override protected function commitProperties():void
            {
                if (_layerChanged)
                {
                    _layerChanged = false;
                    if (mapLayer)
                    {
                        mapLayer.addEventListener(LayerEvent.UPDATE_END, removeBusyCursor, false, 0, true);
                        if (mapLayer.loaded)
                        {
                            setDataProvider();
                        }
                        else
                        {
                            mapLayer.addEventListener(LayerEvent.LOAD, layerLoadHandler, false, 0, true);
                        }
                    }
                }

                super.commitProperties();
            }

            private function setDataProvider():void
            {
                if (mapLayer is ArcGISDynamicMapServiceLayer)
                {
                    _layerInfos = ArcGISDynamicMapServiceLayer(mapLayer).layerInfos;
                }
                else if (mapLayer is ArcIMSMapServiceLayer)
                {
                    _layerInfos = ArcIMSMapServiceLayer(mapLayer).layerInfos;
                }

                if (_layerInfos)
                {
                    // make sure copy has typed LayerInfo objects
                    registerClassAlias("com.esri.ags.layers.supportClasses.LayerInfo", LayerInfo);
                    // create a copy since it'll be modified
                    _layerInfos = ObjectUtil.copy(_layerInfos) as Array;

                    // remove group layers and correct defaultVisibility
                    if (mapLayer is ArcGISDynamicMapServiceLayer)
                    {
                        var visibleLayers:Array = getDefaultVisibleLayers();
                        var layerInfos:Array = _layerInfos.concat(); // create a shallow clone
                        _layerInfos = [];
                        for each (var layerInfo:LayerInfo in layerInfos)
                        {
                            if (!layerInfo.subLayerIds) // skip group layers
                            {
                                layerInfo.defaultVisibility = visibleLayers.indexOf(layerInfo.layerId) != -1;
                                _layerInfos.push(layerInfo);
                            }
                        }
                    }

                    dataProvider = _layerInfos;
                }
            }

            private function getDefaultVisibleLayers():Array
            {
                var result:Array = [];

                for each (var layerInfo:LayerInfo in _layerInfos)
                {
                    if (layerInfo.parentLayerId >= 0 && result.indexOf(layerInfo.parentLayerId) == -1)
                    {
                        // layer is not visible if it's parent is not visible
                        continue;
                    }
                    if (layerInfo.defaultVisibility)
                    {
                        result.push(layerInfo.layerId);
                    }
                }

                return result;
            }

            private function layerLoadHandler(event:LayerEvent):void
            {
                setDataProvider();
            }

            public function showLayer(layerInfo:LayerInfo):void
            {
                var visibleLayers:IList;
                if (mapLayer is ArcGISDynamicMapServiceLayer)
                {
                    var dynamicLayer:ArcGISDynamicMapServiceLayer = mapLayer as ArcGISDynamicMapServiceLayer;
                    visibleLayers = dynamicLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        visibleLayers.addItem(layerInfo.layerId); // add id
                    }
                    else
                    {
                        visibleLayers = dynamicLayer.visibleLayers = getDynamicVisibleLayers();
                    }
                }
                else if (mapLayer is ArcIMSMapServiceLayer)
                {
                    var arcIMSLayer:ArcIMSMapServiceLayer = mapLayer as ArcIMSMapServiceLayer;
                    visibleLayers = arcIMSLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        visibleLayers.addItem(layerInfo.name); // add name
                    }
                    else
                    {
                        visibleLayers = arcIMSLayer.visibleLayers = getArcIMSVisibleLayers();
                    }
                }
                if (visibleLayers)
                {
                    cursorManager.setBusyCursor();
                }
            }

            public function hideLayer(layerInfo:LayerInfo):void
            {
                var visibleLayers:IList;
                if (mapLayer is ArcGISDynamicMapServiceLayer)
                {
                    var dynamicLayer:ArcGISDynamicMapServiceLayer = mapLayer as ArcGISDynamicMapServiceLayer;
                    visibleLayers = dynamicLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        var idIndex:int = visibleLayers.getItemIndex(layerInfo.layerId);
                        if (idIndex != -1)
                        {
                            visibleLayers.removeItemAt(idIndex);
                        }
                    }
                    else
                    {
                        visibleLayers = dynamicLayer.visibleLayers = getDynamicVisibleLayers();
                    }
                }
                else if (mapLayer is ArcIMSMapServiceLayer)
                {
                    var arcIMSLayer:ArcIMSMapServiceLayer = mapLayer as ArcIMSMapServiceLayer;
                    visibleLayers = arcIMSLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        var nameIndex:int = visibleLayers.getItemIndex(layerInfo.name);
                        if (nameIndex != -1)
                        {
                            visibleLayers.removeItemAt(nameIndex);
                        }
                    }
                    else
                    {
                        visibleLayers = arcIMSLayer.visibleLayers = getArcIMSVisibleLayers();
                    }
                }
                if (visibleLayers)
                {
                    cursorManager.setBusyCursor();
                }
            }

            private function getDynamicVisibleLayers():IList
            {
                var result:ArrayList = new ArrayList();

                for each (var layerInfo:LayerInfo in _layerInfos)
                {
                    if (layerInfo.defaultVisibility)
                    {
                        result.addItem(layerInfo.layerId);
                    }
                }

                return result;
            }

            private function getArcIMSVisibleLayers():IList
            {
                var result:ArrayList = new ArrayList();

                for each (var layerInfo:LayerInfo in _layerInfos)
                {
                    if (layerInfo.defaultVisibility)
                    {
                        result.addItem(layerInfo.name);
                    }
                }

                return result;
            }

            private function removeBusyCursor(event:Event):void
            {
                cursorManager.removeBusyCursor();
            }
        ]]>
    </fx:Script>

    <mx:columns>
        <mx:DataGridColumn width="70"
                           headerText="Visibility"
                           itemRenderer="IncludeFiles.LayerVizRenderer"/>
        <mx:DataGridColumn dataField="name" headerText="Layer Name"/>
    </mx:columns>

</mx:DataGrid>

LayerVizRenderer.mxml のコード:

<?xml version="1.0" encoding="utf-8"?>
<!-- Used by LayerTOC.mxml -->
<s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import com.esri.ags.layers.supportClasses.LayerInfo;

            private function cb_clickHandler(event:MouseEvent):void
            {
                var layerInfo:LayerInfo = LayerInfo(data);

                if (cb.selected)
                {
                    layerInfo.defaultVisibility = true;
                    LayerTOC(dataGridListData.owner).showLayer(layerInfo);
                }
                else
                {
                    layerInfo.defaultVisibility = false;
                    LayerTOC(dataGridListData.owner).hideLayer(layerInfo);
                }
            }
        ]]>
    </fx:Script>

    <s:CheckBox id="cb"
                click="cb_clickHandler(event)"
                horizontalCenter="0"
                selected="{LayerInfo(data).defaultVisibility}"/>

</s:MXDataGridItemRenderer>

ArcGIS API for JavaScript のサンプル コード

ArcGIS API for JavaScript を使用している場合、下のサンプル コードを使用して独自の Web アプリケーションを構築できます。

下に示す ArcGIS API for JavaScript のサンプル コードでは、URL を前述の手順で作成したマップ サービスとジオプロセシング サービスに変更して、使用しているサーバ名に一致するようにしています。それらは、次の行で参照されています。

var dynUrl = "http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer";
var printUrl = "http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting";

AdvancedHighQualityPrinting.html のコード:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css">  
    <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/"></script>
    <script type="text/javascript" language="Javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.PrintTask");
      dojo.require("dijit.form.Button");
      dojo.require("dijit.form.CheckBox");      
      dojo.require("dijit.form.ComboBox");
      
      var layer, map, visible = [];
      var printTask, params;
      
      function init() {
        var startExtent = new esri.geometry.Extent({"xmin":-2260000,"ymin":-1500000,"xmax":2250000,"ymax":1220000,"spatialReference":{"wkid":102008}});
        map = new esri.Map("map", {extent:startExtent});
        
        var dynUrl = "http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer";
        layer = new esri.layers.ArcGISDynamicMapServiceLayer(dynUrl, { "id": "ConterminousUSA" });
        
        if (layer.loaded) { 
          buildLayerList(layer); 
        } 
        else { 
          dojo.connect(layer, "onLoad", buildLayerList); 
        }
        
        
		var printUrl = "http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting";
		printTask = new esri.tasks.PrintTask(printUrl, {async: true});
		params = new esri.tasks.PrintParameters();
        params.map = map;     
      }
      
      
      function buildLayerList(layer) { 
        var items = dojo.map(layer.layerInfos,function(info,index){ 
          if (info.defaultVisibility) { 
            visible.push(info.id); 
          } 
          return "<input type='checkbox' class='list_item' checked='" + (info.defaultVisibility ? "checked" : "") + "' id='" + info.id + "' onclick='updateLayerVisibility();' /><label for='" + info.id + "'>" + info.name + "</label>"; 
        }); 
 
        dojo.byId("layer_list").innerHTML = items.join(); 
 
        layer.setVisibleLayers(visible); 
        map.addLayer(layer); 
 
      } 
 
      function updateLayerVisibility() { 
        var inputs = dojo.query(".list_item"), input; 
     
        visible = []; 
 
        dojo.forEach(inputs,function(input){ 
          if (input.checked) { 
              visible.push(input.id); 
          } 
          }); 
        //if there aren't any layers visible set the array to be -1 
        if(visible.length === 0){ 
          visible.push(-1); 
        } 
        layer.setVisibleLayers(visible); 
      } 
      
      
      
      function print(){
        var layout = dojo.byId("layout");
        var index = layout.selectedIndex;
		var selectedValue_layout = layout.options[index].value;
		var format = dojo.byId("format");
        var index = format.selectedIndex;
		var selectedValue_format = format.options[index].value;
		var georef_info = dojo.byId("georef_info");
        var index = georef_info.selectedIndex;
		var selectedValue_georef_info = georef_info.options[index].value;
		
		var legendLayer = new esri.tasks.LegendLayer();
		legendLayer.layerId = "ConterminousUSA";
		legendLayer.subLayerIds = [];
		if (CapitalCities.checked == true)
      	{
      		legendLayer.subLayerIds.push(0);
      	}
		if (InterstateHighways.checked == true)
      	{
      		legendLayer.subLayerIds.push(1);
      	}
      	if (Rivers.checked == true)
      	{
      		legendLayer.subLayerIds.push(2);
      	}
      	if (Lakes.checked == true)
      	{
      		legendLayer.subLayerIds.push(3);
      	}
      	if (StateBoundaries.checked == true)
      	{
      		legendLayer.subLayerIds.push(4);
      	}
		
        params.template = {layout: selectedValue_layout, format: selectedValue_format, layoutOptions: {legendLayers:[legendLayer]}};
        params.extraParameters = {Georef_info: selectedValue_georef_info};
        printTask.execute(params, printComplete);
      }
      
      function printComplete(result){
        window.open(result.url);
      }

      dojo.addOnLoad(init);

    </script>

  </head>

  <body class="claro">
    <div id="map" style="width:1000px; height:600px; border:1px solid #000;"></div>
    <br />
    Layout Template: 
    <select id="layout" >
      	<OPTION value="CentralUSA">CentralUSA</OPTION> 
		<OPTION value="ConterminuousUSA">ConterminuousUSA</OPTION>     
		<OPTION value="NortheasternUSA">NortheasternUSA</OPTION>
		<OPTION value="NorthwesternUSA">NorthwesternUSA</OPTION>
		<OPTION value="SouthernUSA">SouthernUSA</OPTION>
		<OPTION value="SouthwesternUSA">SouthwesternUSA</OPTION>
    </select>
    &nbsp;&nbsp;Format:
    <select id="format">
      	<OPTION value="PDF">PDF</OPTION> 
		<OPTION value="PNG">PNG</OPTION>     
    </select>
    &nbsp;&nbsp;Include Georef info?
    <select id="georef_info">
      	<OPTION value="True">True</OPTION> 
		<OPTION value="False">False</OPTION>     
    </select>
    <br /><br />
    Table of Contents: <br /><span id="layer_list"></span>
    <br /><br />
    Include in Legend: <br />
    <label><input type="checkbox" name="CapitalCities" checked="checked">Capital Cities</label>
	<label><input type="checkbox" name="InterstateHighways" checked="checked">Interstate Highways</label>
	<label><input type="checkbox" name="Rivers" checked="checked">Rivers</label>
	<label><input type="checkbox" name="Lakes" checked="checked">Lakes</label>
	<label><input type="checkbox" name="StateBoundaries" checked="checked">State Boundaries</label>
	<br /><br />
	<input type="button" id="print" value="Print" onclick="print();"/>
  </body>
</html>

Web アプリケーションの実行

前述した手順で作成した Web アプリケーションを実行します。Web アプリケーションを実行する手順については、必要に応じて ArcGIS Web API のドキュメントをご参照ください。ArcGIS for Silverlight の Web API アプリケーションのスクリーン キャプチャを下に示します。ここでは、コンテンツ ウィンドウで、[Capital Cities] をオフにしています。さらに、[Include in Legend] では、[State Boundaries] をオフにしています。

完成した Silverlight の Web アプリケーション

[Export Map] ボタンをクリックすると、しばらくして出力ファイルが自動的にポップアップ表示されます。下の図は、印刷に適した出力 PDF のサンプルを示しています。Web アプリケーションのコンテンツ ウィンドウ[Include in Legend] でレイヤがオフにされており、それがこの出力に反映されています。さらに、この PDF は、サービス レイヤの画像ではなく、複数のレイアウト テンプレートに段階分けされたベクタ データを使用しています。出力ファイルには、複数のテンプレート マップ ドキュメントに段階分けされた他のエレメント(凡例、データ フレームと座標系のダイナミック テキスト、および縮尺記号)も含まれます。ユーザが Georef info パラメータの値として True を選択した場合、出力 PDF にはジオリファレンス情報も含まれます。この情報は、地理空間位置ツールを使用して Adobe Reader で表示することができます。

出力 PDF

これで、arcpy.mapping を使用した高度な Web マップの印刷/エクスポートのチュートリアルは終了です。基本的な Web マップの印刷のチュートリアルについては、「チュートリアル: arcpy.mapping を使用した基本的な Web マップの印刷/エクスポート」をご参照ください。

関連トピック

6/13/2014