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

複雑性: 中級 データ要件: ArcGIS.com

このチュートリアルでは、エンド ユーザが対象領域に移動して [Print] ボタンを押すことができる Web アプリケーションを構築します。出力は、サービス レイヤのベクタ出力を含む、印刷に適した PDF ドキュメントです。

すぐに使用できるPrintingTools サービスと ArcGIS Web API のクライアント印刷ウィジェットを使用して Web アプリケーションからエクスポートすると、サービス レイヤの高品質な画像を出力できます。ただし、ベクタ出力が必要になることがあります。たとえば、ベクタ PDF 出力は、PDF 表示アプリケーションでレイヤ表示の切り替え、フィーチャ属性の表示、およびマップ座標の表示をサポートします。これから構築する Web アプリケーションでは、World Topographic ベースマップ サービスと同等のベクタを出力します。World Topographic ベースマップ サービスのベクタの小さな領域のサブセットは、ArcGIS Resources で公開されています。

注意注意:

サービス レイヤの画像ではなく、ローカル ベクタ データを含む出力ドキュメントを生成するには、対応するベクタ データにアクセスする必要があります。

下の図に、構築する Web アプリケーションを示します。

Web アプリケーション

この Web アプリケーションの [Print] ボタンに実装されているコードは、ArcGIS 10.1 for Server 以降で使用可能な、ArcGIS Web API の [Print Task] を使用します。ジオプロセシング サービスとして公開され、[Print Task] が使用する Python スクリプトを作成します。この Python スクリプトは、arcpy.mapping モジュールの ConvertWebMapToMapDocument 関数を使用して、完全な状態の Web マップをテンプレート マップ ドキュメントに挿入します。テンプレートには、マップ サービス内の選択可能なすべてのレイヤと同等のベクタが含まれます。arcpy.mapping モジュールは、テンプレート マップ ドキュメントに段階分けされたローカル ベクタ データを残してサービス レイヤを削除し、PDF にエクスポートする機能も備えています。

[Print] ボタンをクリックすると、サービス レイヤの画像ではなく、ローカル ベクタ データを含む印刷に適した PDF ドキュメントが出力されます。

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

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

ArcGIS Resource からのベクタ データの取得

マップ ドキュメント テンプレートで使用するベクタ データを含む zip ファイルを、ArcGIS Resources の Community Maps Template Gallery からダウンロードできます。

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

ヒントヒント:

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

手順:
  1. 新しい空の ArcMap セッションを開きます。
  2. カタログ ウィンドウで、登録済みフォルダを参照します。登録済みフォルダ内に、「BasicTutorial」という名前の新しいフォルダを作成します。
  3. ArcGIS Resources の Community Maps Template Gallery に移動します。[World Topographic Map Template] を選択します。
  4. [ダウンロード] ボタンをクリックして、World Topographic Map Template の zip ファイルをコンピュータにダウンロードします。
  5. zip ファイルの内容を、登録済みフォルダ内の BasicTutorial フォルダに解凍します。
  6. 登録済みフォルダは、次の図のようになります。
    登録済みフォルダ
    注意注意:

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

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

Python スクリプトの作成

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

カスタム ジオプロセシング印刷サービスの Python スクリプトは、ConvertWebMapToMapDocument 関数を実行します。この関数は、印刷またはエクスポートする Web マップ(JSON 形式)をマップ ドキュメントに変換します。次に、このスクリプトは、JSON Web マップ内のサービス レイヤに対応するベクタ レイヤを残して、出力マップ ドキュメント内のサービス レイヤを削除します。JSON Web マップには、Web アプリケーションのマップの範囲も含まれています。最後に、このスクリプトは、マップ ドキュメントを PDF ドキュメントにエクスポートします。

手順:
  1. 任意のPython IDEArcGIS for Desktop に付属する IDLE など)を開きます。
  2. 以下のコードをコピーして新しい Python スクリプトに貼り付けます。
  3. import arcpy
    import os
    import uuid
    
    # Input WebMap json
    Web_Map_as_JSON = arcpy.GetParameterAsText(0)
    
    # The template location in the server data store
    templateMxd = '//MyComputer/MyDataStore/BasicTutorial/LG_062912_10.1/LG_062912_10.1/LGIM_World_Topo_Map_v1.5.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]
    
    # Remove the service layer
    # This will just leave the vector layers from the template
    for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
        if lyr.isServiceLayer:
            arcpy.mapping.RemoveLayer(df, lyr)
            
    # Use the uuid module to generate a GUID as part of the output name
    # This will ensure a unique output name
    output = 'WebMap_{}.pdf'.format(str(uuid.uuid1()))
    Output_File = os.path.join(arcpy.env.scratchFolder, output)
    
    # Export the WebMap
    arcpy.mapping.ExportToPDF(mxd, Output_File) 
    
    # Set the output parameter to be the output file of the server job
    arcpy.SetParameterAsText(1, Output_File)
    
    # Clean up - delete the map document reference
    filePath = mxd.filePath
    del mxd, result
    os.remove(filePath)
    
  4. templateMxd 変数の値を、テンプレート マップ ドキュメントが含まれる登録済みフォルダ内のフォルダへの UNC パスに変更します。
  5. 注意注意:

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

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

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

BasicTutorial.py スクリプトを実行するカスタム ジオプロセシング ツールを作成します。

手順:
  1. ArcMap のカタログ ウィンドウで、登録済みフォルダ ディレクトリ内の WebApp フォルダを参照します。
  2. [WebApp] フォルダを右クリックして、[新規作成] [ツールボックス] の順にクリックします。ツールボックスに、「BufferService」という名前を付けます。
  3. [BasicTutorial] ツールボックスを右クリックして、[アイテム説明] をクリックします。
  4. [アイテム説明] ダイアログ ボックスで、任意のテキストを使用して[タグ] アイテムと [サマリ] アイテムに入力します。必要に応じて、他のアイテム説明も入力します。
  5. [保存] をクリックして [アイテム説明] ダイアログ ボックスを終了します。
  6. カタログ ウィンドウで [BasicTutorial] ツールボックスを右クリックし、[追加] [スクリプト] の順にクリックします。
  7. [スクリプトの追加] ダイアログ ボックスで、[名前][ラベル] の両方に「BasicTutorial」と入力します。
  8. [次へ] をクリックします。
  9. スクリプト ファイルを選択するために、登録済みフォルダ内の WebApp フォルダを参照して、BasicTutorial.py を選択します。
  10. [次へ] をクリックします。
  11. 2 つのパラメータをスクリプト ツールに追加する必要があります。
    1. 1 つ目のパラメータは、Web_Map_as_JSON です。このパラメータには、Web アプリケーションに表示されている、エクスポートするマップの状態を表す JSON 表現を入力します。プロパティの値を、次の図の値に合わせてください。
      Web_Map_as_JSON パラメータのプロパティ
    2. 2 つ目のパラメータは、Output_File です。作成する出力ファイルを指定します。プロパティの値を、次の図の値に合わせてください。
      Output_File パラメータのプロパティ

      注意注意:

      Web_Map_as_JSON、および Output_File の各パラメータ名は、ArcGIS Web API の [Print Task] のツール シグネチャに一致するように、示されたとおりに正確に記述する必要があります。

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

ツールの実行

ツールを正常に実行して、ArcGIS for Server で公開できる結果を [結果] ウィンドウに作成する必要があります。

手順:
  1. カタログ ウィンドウで [BasicTutorial] スクリプト ツールを右クリックし、[開く] をクリックします。
  2. Web_Map_as_JSON 入力パラメータを空白のままにします。
    ヒントヒント:

    公開する目的の場合、ArcGIS Web API が Web アプリケーションで JSON Web マップを提供することになるため、Web_Map_as_JSON 入力パラメータを空白のままにすることができます。空白の入力によってエラーが発生しない方法で Python スクリプトが記述されている場合に限り、Web_Map_as_JSON 入力パラメータを空白のままにすることができます。たとえば、スクリプトが Web マップ レイヤを名前で検索しない場合です。

  3. [OK] をクリックします。ツールの実行が終わるのを待ちます。

これで、結果をジオプロセシング サービスとして公開する準備が整いました。

結果の公開

ジオプロセシング サービスの公開に慣れていない場合は、以下をご参照ください。

手順:
  1. [結果] ウィンドウを開きます
  2. [現在のセッション] を展開します。
  3. [BasicTutorial] の結果を右クリックし、[共有] [ジオプロセシング サービス] の順にクリックします。
  4. [サービスを公開] をオンにします。
  5. [次へ] をクリックします。
  6. ArcGIS for Server コンピュータへの公開接続または管理接続を選択します。
  7. [次へ] をクリックします。
  8. [次へ] をクリックします。
  9. [続行] をクリックします。
  10. [サービス エディタ] ダイアログ ボックスの右上隅にある [公開] をクリックします。

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

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

ArcGIS Web API には、GIS 機能に類似した機能が用意されています。ユーザは、好みに合わせて開発プラットフォームを選択することができます。各 API を使用した Web アプリケーションの構築の概要説明については、このチュートリアルの対象外です。それについては、API のドキュメントをご参照ください。詳細については、次のトピックをご参照ください。

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

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

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

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

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

var printUrl = "http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial";

BasicTutorial.html のコード

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
  	<title>Webmap Printing</title>
    <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/?v=3.0"></script>
    <script type="text/javascript" language="Javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.PrintTask");
      var printTask, params;
      
      function init() {
		      // set the extent to the Naperville area - which matches the extent of the template map document
        var startExtent = new esri.geometry.Extent({"xmin":-9815098,"ymin":5124020, "xmax":-9811168,"ymax":5127339, "spatialReference":{"wkid":102100}});
        											
        var map = new esri.Map("map", {extent:startExtent});
        
        // add tiled map service to webmap
        var tiledUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer";
        var tiledLayer = new esri.layers.ArcGISTiledMapServiceLayer(tiledUrl);
        map.addLayer(tiledLayer);
		      var printUrl = "http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial";
		      printTask = new esri.tasks.PrintTask(printUrl, {async: true});
		      params = new esri.tasks.PrintParameters();
        params.map = map;  
      }
      
      function print(){
      	var ptemplate = new esri.tasks.PrintTemplate();
      	// use the extent of the webmap in the output PDF
      	ptemplate.preserveScale = false;
      	params.template = ptemplate;
        printTask.execute(params, printComplete);
      }
      
      function printComplete(result){
        window.open(result.url);
      }

      dojo.addOnLoad(init);

    </script>
  </head>
  <body class="claro">
  	 <input type="button" id="print" value="Print" onclick="print();"/>
    <div id="map" style="width:1000px; height:600px; border:1px solid #000;"></div>
  </body>
</html>

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

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

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

url="http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial"/>

BasicTutorial.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">
	
	<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;
			
			public var preserveScale:Boolean = true;
			
			private function printBtn_clickHandler(event:MouseEvent):void
			{
				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="false"
						url="http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial"/>
		<esri:PrintParameters id="printParameters"
							  preserveScale="false"
							  map="{map}">
		</esri:PrintParameters>
		
		<esri:Extent id="initialExtent"
					 xmin="-9815098" ymin="5124020" xmax="-9811168" ymax="5127339">
			<esri:SpatialReference wkid="102100"/>
		</esri:Extent>
		
	</fx:Declarations>
	
	<s:controlBarLayout>
		<s:HorizontalLayout gap="10"
							paddingBottom="7"
							paddingLeft="10"
							paddingRight="10"
							paddingTop="7"
							verticalAlign="baseline"/>
	</s:controlBarLayout>
	<s:controlBarContent>
		<s:Button id="printBtn"
				  click="printBtn_clickHandler(event)"
				  enabled="{printTask.getServiceInfoLastResult != null}"
				  label="Print"/>
	</s:controlBarContent>

	<esri:Map id="map" extent="{initialExtent}">
		
		<esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"/>
	</esri:Map>
	
</s:Application>

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

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

XAML コード

<UserControl x:Class="Basic_Tutorial.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="-9815098,5124020,-9811168,5127339">
            <esri:Map.Layers>
                <esri:ArcGISTiledMapServiceLayer ID="MyTiledService" 
                    Url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"/>
            </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 />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Button x:Name="Print" Content="Print" Click="ExportMap_Click" 
                            Grid.Row="1" Grid.Column="0" Margin="2"/>
                </Grid>
            </Border>
        </StackPanel>
    </Grid>
</UserControl>

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

printTask = new PrintTask("http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial");

背後にある C# のコード

using System;
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client.Printing;
using ESRI.ArcGIS.Client.Tasks;


namespace Basic_Tutorial
{
    public partial class MainPage : UserControl
    {
        PrintTask printTask;
        public MainPage()
        {
            InitializeComponent();
            printTask = new PrintTask("http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial");
            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;

            PrintParameters printParameters = new PrintParameters(MyMap)
            {

            };
            printTask.SubmitJobAsync(printParameters);
        }
    }
}

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

前述した手順で作成した Web アプリケーションを実行します。Web アプリケーションを実行する手順については、必要に応じて ArcGIS Web API のドキュメントをご参照ください。ArcGIS API for JavaScript の Web アプリケーションのスクリーン キャプチャを下に示します。

Web アプリケーションのサンプル

対象領域を拡大して、[Print] ボタンをクリックします。しばらくして、出力 PDF ドキュメントが自動的にポップアップ表示されます。この出力は、サービス レイヤの画像ではなく、複数のレイアウト テンプレートに段階分けされたローカル ベクタ データを含む、印刷に適した PDF ドキュメントです。この出力のサンプルを下に示します。

PDF 出力のサンプル

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

関連トピック

5/20/2014