在本教程中,您将构建 web GIS 应用程序,使最终用户能够导航至感兴趣区域并单击打印按钮。输出为方便打印的 PDF 文档,其中包含了服务图层矢量输出。
使用 ArcGIS API for JavaScript 中开箱即用的打印工具服务及其客户端打印微件从 Web 应用程序中进行导出,可输出高质量的服务图层图像。但是,有时需要矢量输出。例如,矢量 PDF 输出在 PDF 查看应用程序中支持以下功能:切换图层可见性、查看要素属性以及查看地图坐标。在将要构建的 Web 应用程序中,您会输出世界地形图底图服务的矢量化表示。世界地形图底图服务的小区域的矢量子集是公开提供的。
注:
要生成含有本地矢量数据而非服务图层图像的输出文档,您必须具有访问相应矢量数据的权限。
下图显示了将要构建的 Web 应用程序。
Web 应用程序中打印按钮后的代码使用了 ArcGIS API for JavaScript 打印任务,该任务从 ArcGIS 10.1 for Server 开始提供。您将创建 Python 脚本,该脚本将作为打印任务所用的地理处理服务发布。Python 脚本使用 arcpy.mapping 模块中的 ConvertWebMapToMapDocument 函数,该函数会将完整状态的 web 地图插入过渡的模板地图文档。 模板包含了地图服务中所有可能图层的矢量化表示。arcpy.mapping 模块还可用于移除服务图层并导出至 PDF,同时将已过渡的本地矢量数据保留在模板地图文档中。
单击打印按钮后,将会输出方便打印的 PDF 文档,该文档包含了本地矢量数据而非服务图层的图像。
要完成本教程,应熟悉 arcpy.mapping 模块、ArcGIS API for JavaScript、ArcGIS Desktop 和 ArcGIS Server。您还应逐渐熟悉在 web 应用程序帮助主题中打印:
获取矢量数据
下载包含已过渡地图文档模板中使用的矢量数据的压缩文件。在此之前,需要确保存在一个 ArcGIS Server 可以在其中查看将用于 web 应用程序的模板地图文档和数据的文件夹结构。本教程假定存在注册到 ArcGIS Server 的文件夹。有关将数据注册到 ArcGIS Server 的详细信息,请参阅以下内容:
提示:
在 ConvertWebMapToMapDocument 函数中使用模板地图文档时,最佳做法是使用注册到 ArcGIS Server 的数据。如果选择不使用注册的数据,那么模板地图文档和数据将打包复制到服务器。在打包过程中,数据可能移动并带着相对路径重新指向 ConvertWebMapToMapDocument 无法解析的文件夹结构。有关详细信息,请参阅 ConvertWebMapToMapDocument。
- 打开新的空 ArcMap 会话。
- 在目录窗口中,浏览至已注册文件夹。在已注册文件夹中创建一个名为 BasicTutorial 的新文件夹。
- 在 Web 浏览器中,转到世界地形图模板下载。
- 通过单击打开 > 下载按钮,将世界地形图模板压缩文件下载至您的计算机。
- 出现提示时,请选择另存为并将压缩文件保存到已注册文件夹中的 BasicTutorial 文件夹。
- 在 ArcMap 中打开提取包地理处理工具。该工具会将压缩地图模板解包到已注册的文件夹中。in_package 参数是您刚刚下载的压缩文件。output_folder 参数是已注册文件夹中的 BasicTutorial 文件夹。
- 单击确定按钮,执行该工具。
- 已注册文件夹应如下图所示。
注:
在上方的屏幕截图中,已注册文件夹名为 MyDataStore。已注册文件夹的名称可随意设置。
WorldTopo_103Templatev2_288k_to_1k.mxd 地图文档现已准备就绪,可以在 Web 应用程序中使用。
创建 Python 脚本
您将创建用作自定义地理处理打印服务的 Python 脚本。
自定义地理处理打印服务中的 Python 脚本执行 ConvertWebMapToMapDocument 函数,可转换想要打印或导出至地图文档的 Web 地图(以 JSON 格式)。该脚本随后会移除输出地图文档中的服务图层,保留与 Web 地图 JSON 中服务图层相对应的矢量图层。Web 地图 JSON 还包含了 Web 应用程序中的地图范围。最后,该脚本将地图文档导出至 PDF 文档。
- 打开任意的 Python IDE,如 IDLE(ArcGIS Desktop 附带)。
- 将以下代码复制并粘贴到新的 Python 脚本中。
- 将 templateMxd 变量更改为包含模板地图文档的已注册文件夹中的文件夹 UNC 路径。
- 保存 Python 脚本。命名脚本 BasicTutorial.py。将其保存至已注册文件夹中名为 WebApp 的文件夹内。
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 = r"\\MyComputer\MyDataStore\BasicTutorial\v103\WorldTopo_103Templatev2_288k_to_1k.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)
注:
如果 ArcGIS Server、ArcMap 和已注册文件夹都在同一台计算机上,则无需已注册文件夹的 UNC 路径。但可以使用绝对路径。
创建 Python 脚本工具
您将创建运行 BasicTutorial.py 脚本的自定义地理处理工具。
- 在 ArcMap 的目录窗口中,浏览至已注册文件夹目录中的 WebApp 文件夹。
- 右键单击 WebApp 文件夹并单击新建 > 工具箱。将该工具箱命名为 BasicTutorial。
- 右键单击 BasicTutorial 工具箱并单击项目描述。
- 在项目描述对话框中,使用所选文本填充标签和摘要项目。或者填写其他项目描述。
- 单击保存并退出项目描述对话框。
- 在目录窗口中,右键单击 BasicTutorial 工具箱并单击添加 > 脚本。
- 在添加脚本对话框中,为名称和标注输入 BasicTutorial。
- 单击下一步。
- 对于脚本文件,浏览至已注册文件夹中的 WebApp 文件夹并选择 BasicTutorial.py。
- 单击下一步。
- 需要添加两个参数至脚本工具。
- 第一个参数为 Web_Map_as_JSON。该参数采用要在地图在 Web 应用程序中显示时导出的地图状态的 JSON 表示。属性应与以下内容相匹配:
- 另一参数为 Output_File,即将创建的输出文件。属性应与以下内容相匹配:
警告:
Web_Map_as_JSON 和 Output_File 参数名称必须完全按照以下所示拼写,以便与 ArcGIS Web API 中打印任务的工具签名相匹配。
- 单击添加脚本对话框上的完成。
- 右键单击 BasicTutorial 脚本工具并单击项目描述。
- 在项目描述对话框中,使用所选文本填充标签和摘要项目。同样,使用所选文本填充项目描述对话框语法部分内所有四个参数的对话框说明。或者填写其他项目描述。
执行工具
必须成功执行工具才能在结果窗口中创建可发布到 ArcGIS Server 的结果。
- 在目录窗口中,右键单击 BasicTutorial 脚本工具,然后单击打开。
- 将 Web_Map_as_JSON 输入参数留空。
提示:
出于发布目的,可将 Web_Map_as_JSON 输入参数留空,因为 ArcGIS API for JavaScript 会在 Web 应用程序中提供 web 地图 JSON。如果 Python 脚本的写入方式使其在空白输入时仍能正常执行,则可将 Web_Map_as_JSON 输入参数留空。例如,脚本不会按名称查找 Web 地图图层。
- 单击确定。等待工具完成执行。
结果现已准备就绪,可作为地理处理服务发布。
发布结果
如果您不熟悉有关发布地理处理服务的信息,请参阅以下内容:
- 打开结果窗口。
- 展开当前会话。
- 右键单击 BasicTutorial 结果并单击共享为 > 地理处理服务。
- 选择发布服务。
- 单击下一步。
- 选择指向 ArcGIS Server 计算机的发布或管理员连接。
- 单击下一步。
- 单击下一步。
- 单击继续。
- 在服务编辑器对话框的右上角,单击发布。
地理处理服务现已准备就绪,可以在 ArcGIS API for JavaScript 中使用。
ArcGIS API for JavaScript 示例代码
使用以下示例代码构建 Web 应用程序。
在以下 ArcGIS API for JavaScript 代码示例中,将 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 of the web app to same extent as the template map document
var startExtent = new esri.geometry.Extent({
"xmin" : -13043333,
"ymin" : 3836078,
"xmax" : -13030585,
"ymax" : 3853683,
"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>
运行 Web 应用程序
运行在上一步骤中创建的 Web 应用程序。如有必要,请参阅 ArcGIS API for JavaScript 文档获取运行 Web 应用程序的说明。Web 应用程序的屏幕截图如下。
放大至感兴趣区域并单击打印按钮。稍后,输出 PDF 文档将自动弹出。输入为方便打印的 PDF 文档,其中包含了在布局模板中过渡的本地矢量数据,而非服务图层的图像。请参阅如下示例输出:
使用 arcpy.mapping 进行基本 Web 地图打印和导出的教程到此结束。有关高级方案的详细信息,请参阅使用 arcpy.mapping 进行的高级 Web 地图打印和导出教程。