在本教程中,您将构建 web 应用程序,使最终用户能够导航至感兴趣区域并单击打印按钮。 输出为方便打印的 PDF 文档,其中包含了服务图层的矢量输出。
使用 ArcGIS API for JavaScript 中开箱即用的 PrintingTools 服务及其客户端打印微件从 Web 应用程序中进行导出,可输出高质量的服务图层图像。 但是,您可能需要矢量输出。 例如,矢量 PDF 输出在 PDF 查看应用程序中支持以下功能:切换图层可见性、查看要素属性以及查看地图坐标。 在将要构建的 Web 应用程序中,您会输出世界地形图底图服务的矢量化表示。 世界地形图底图服务的小区域的矢量子集是公开提供的。
注:
要生成含有本地矢量数据而非服务图层图像的输出文档,您必须具有访问相应矢量数据的权限。
Web 应用程序中打印按钮后的代码使用了 ArcGIS API for JavaScript 打印任务。 您将创建 Python 脚本,该脚本将作为打印任务所用的地理处理服务发布。 Python 脚本使用 arcpy.mapping 模块中的 ConvertWebMapToMapDocument 函数,该函数会将完整状态的 web 地图插入过渡的模板地图文档。 模板包含了地图服务中所有可能图层的矢量化表示。 arcpy.mapping 模块还可用于移除服务图层并导出至 PDF 文档,同时将已过渡的本地矢量数据保留在模板地图文档中。
输出为方便打印的 PDF 文档,其中包含了本地矢量数据而非服务图层的图像。
要完成本教程,您应熟悉 arcpy.mapping 模块 ArcGIS API for JavaScript、ArcMap 和 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 文件夹。
- 单击确定执行该工具。
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 Web Map 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 Web Map to a map document
result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd)
mxd = result.mapDocument
# Reference the data frame that contains the web map
# Note: ConvertWebMapToMapDocument renames the active data frame in the template_mxd "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 Web Map
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 中打印任务的工具签名相匹配。
- 单击添加脚本对话框上的完成。
- 添加 Web_Map_as_JSON 参数。
- 右键单击 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 = "https://MyServer:6443/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 应用程序的屏幕截图:
![示例 Web 应用程序 示例 Web 应用程序](GUID-FC895CB0-7FD1-4F16-B88D-2120931E3D8F-web.png)
放大至感兴趣区域并单击打印。 随即显示输出 PDF 文档。 输入为方便打印的 PDF 文档,其中包含了在布局模板中过渡的本地矢量数据,而非服务图层的图像。 以下是一个示例输出:
![示例 PDF 输出 示例 PDF 输出](GUID-3E16A62E-3D33-45D8-A10F-B8E69707E355-web.png)
使用 arcpy.mapping 进行基本 Web 地图打印和导出的教程到此结束。 有关高级方案的详细信息,请参阅使用 arcpy.mapping 进行的高级 Web 地图打印和导出教程。