Web上で高品質な地図印刷を実現する方法


JavaScript や Flex、Silverlight の Web アプリケーション上で地図を印刷する場合、画面上の地図をキャプチャして簡易的な印刷をすることができます。今回ご紹介するのは、より高品質な印刷を実現するために、サーバ側で PDF 出力を行い、クライアントにダウンロードする方法です。以前のバージョンではArcObjects を利用する必要がありましたが、ArcGIS 10 より、拡張された Python ライブラリ(ArcPy)を用いることにより、簡単な実装で Web 上から高品質な印刷が可能になりました。

ここでは、以下のような手順で Web 上で PDF 出力を行うサンプルを作成します。
1. PDF 出力を行う Python スクリプトを作成
2. 1 のスクリプトを使い、モデルを作成
3. 2 のモデルをジオプロセシング サービスとして公開
4. ArcGIS API for JavaScript API から 3 のサービスを呼び出し、PDF 出力を行うサンプルを作成

1. サンプル Python スクリプト

# -*- coding: cp932 -*-
import arcpy, os# マップ ドキュメントからデータフレームを取得
mxd = arcpy.mapping.MapDocument(r”D:sampledemo.mxd”)
df = arcpy.mapping.ListDataFrames(mxd)[0]

# Extent の入力パラメータを受取り、データフレームの Extent を設定
xmin = arcpy.GetParameterAsText(0)
ymin = arcpy.GetParameterAsText(1)
xmax = arcpy.GetParameterAsText(2)
ymax = arcpy.GetParameterAsText(3)
df.extent = arcpy.Extent(float(xmin), float(ymin), float(xmax), float(ymax))

# ArcGIS Server のジョブ ディレクトリに PDF をエクスポート
outFilePath = arcpy.env.scratchWorkspace + “\output.pdf”
arcpy.mapping.ExportToPDF(mxd, outFilePath)

# 出力パラメータに作成した PDF をセット
arcpy.SetParameterAsText(4, outFilePath.replace(“\”,os.sep))

del df
del mxd


2. ジオプロセシング サービスのためのモデルを作成

上記の Python スクリプトをモデルとして作成します。

手順1.新規にツールボックスを作成し、スクリプトを追加します。
01_2

手順2.上記の Python スクリプト ファイルを追加し、パラメータを設定します。
02_2

手順3.モデルを作成し、パラメータを設定します。
03_2

手順4.全ての変数をモデルパラメータに設定します。パラメータの順番が Python スクリプトの入力パラメータ順と異なる場合は上から順になるように修正します。
04_2

3. ジオプロセシング サービスを作成

上記で作成したモデルを ArcGIS Server のジオプロセシング サービスとして公開します。
05_2

4. サンプルの JavaScript

ここでは一番簡単に試すことができる JavaScript のサンプルコードを載せておきましたので、お試しください。誌面の制約上、エラー処理や待機中の処理などは省略し、サンプルを実行するための最低限のコードのみを記述しています。下記、{マップ サービスのURL} に任意の ArcGIS Server のダイナミック マップ サービス、{ジオプロセシング サービスのURL} に上記で作成したジオプロセシング サービスを設定します。クライアントにロードされた PDF ファイルは、別ウィンドウで開くようにしています。

JavaScript のサンプル

<!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" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>PDF出力サンプル</title>
    <link rel="stylesheet" 
      type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.1/js/dojo/dijit/themes/claro/claro.css">
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.1"></script>
    <script type="text/javascript">
      dojo.require("esri.map");

var gp, map;
function init() {
map = new esri.Map(“map”);

var dynamicMapServiceLayer = new esri.layers.ArcGISDynamicMapServiceLayer(“{マップ サービスのURL}”);
gp = new esri.tasks.Geoprocessor(“{ジオプロセシング サービスのURL}”);

map.addLayer(dynamicMapServiceLayer);
}

function exportToPDF(){
var params = {
“xmin”:map.extent.xmin,
“ymin”:map.extent.ymin,
“xmax”:map.extent.xmax,
“ymax”:map.extent.ymax
}
gp.submitJob(params, completeCallback);
}
function completeCallback(jobInfo){
if(jobInfo.jobStatus !== “esriJobFailed”){
gp.getResultData(jobInfo.jobId,”output_pdf”, downloadFile);
}
}
function downloadFile(outputFile){
window.open(outputFile.value.url,”print”);
}

dojo.addOnLoad(init);
</script>
</head>
<body class=”claro”>
<div id=”map” style=”width:900px; height:600px; border:1px solid #000;”></div>
<button dojoType=”dijit.form.Button”  onClick=”exportToPDF();”>PDF出力</button>
</body>
</html>

今回は簡単にお試し頂けるように Extent のみパラメータを設定しましたが、パラメータを追加すれば、以下のようなことも比較的簡単に実現できます。
・表示するレイヤ情報を渡し、必要なレイヤのみ出力する。
・画面表示と同じ縮尺、または指定した縮尺での出力。
・タイトルなどを画面上で設定したものにする。

■注意事項
今回ご紹介した Python や JavaScript のコードは、サンプルとして提供しておりますのでサポート対象外となります。従って、サンプルプログラムに関するご質問はお受けできません。
また、本サンプルを使用して生じたいかなる障害についても、弊社では責任を負いかねますことを予めご了承願います。

■関連リンク
ESRI ジャパン Web サイト:
ArcGIS Server 製品概要