摘要
将要打印或导出的 Web 地图(JSON 格式)转换为地图文档。可在最终打印或导出地图文档之前对其进行进一步修改。
讨论
ConvertWebMapToMapDocument 函数将您想要打印或导出的 Web 地图转换为地图文档。文档转换后,地图文档中存在 Web 地图的完整状态。随即可对地图文档进行进一步修改,然后将其最终打印或导出为常用格式(如 PDF)。使用 ArcGIS API for JavaScript 从 Web GIS 应用程序打印地图时,最常使用 ConvertWebMapToMapDocument 函数。
ConvertWebMapToMapDocument 函数主要用于需要使用 arcpy.mapping 函数修改或导出 Web 地图的工作流。可以使用 ConvertWebMapToMapDocument 函数处理的部分工作流示例如下:
- 交换本地矢量数据的服务图层 - 在 arcpy.mapping 脚本中,服务图层可以被识别出并与指向本地数据的图层进行交换。通常需要矢量输出(而不是服务图层)时需要此函数。例如,矢量 PDF 输出在 PDF 查看应用程序中支持以下功能:切换图层可见性、查看要素属性以及查看地图坐标。完成交换矢量数据服务图层的一种方法是使用过渡模板地图文档,该模板地图文档包含所有可能服务图层的矢量等效表示。执行 ConvertWebMapToMapDocument 函数后,依次执行输出地图文档中的所有图层,移除与 Web 地图内服务图层相对应的矢量图层以外的所有图层。当使用已拥有的相应矢量数据交换自身服务时,可以使用此工作流。
- 创建地图册 - 如果在 template_mxd 上启用数据驱动页面,则可以生成地图系列。此外,还可以以 PDF 格式导出输出地图文档,并使用 PDFDocument 类将其插入到其他 PDF 中来创建完整的地图册。
- 使用高级选项导出 - 所有的 arcpy.mapping 导出函数都具有很多高级选项。例如,ExportToPDF 函数具有用于控制栅格和矢量压缩、定义颜色空间、嵌入字体等的参数。
- 控制图例的外观 - arcpy.mapping 模块提供用于移除图例项或修改其样式项目的功能,可使用 LegendElement 类和 ListStyleItems 函数通过自定义设置来实现此功能。
如果您已经获取了一个用于地图打印的 Python 脚本,可以在地理处理脚本工具中封装该脚本。您随后可将脚本工具作为 ArcGIS Server 地理处理服务发布。ArcGIS API for JavaScript 中包含了打印任务,您可在 Web GIS 应用程序中使用。打印任务具有 URL 属性,该属性指向所创建的地理处理服务的 REST URL。
有关地理处理服务的详细信息,请参阅以下内容:
在 ArcGIS Web API 的地理处理服务中使用 ConvertWebMapToMapDocument 时,脚本工具的参数名称必须与 ArcGIS Web API 打印任务参数相匹配:
参数名称 | 数据类型 | 说明 |
---|---|---|
Web_Map_as_JSON | 字符串 | 当地图在 Web 应用程序中显示时,待导出的地图状态的 JSON 表示。通过 ArcGIS Web API(JavaScript、Flex 和 Silverlight),开发人员可以从 web 应用程序中轻松获得此 JSON 字符串。 |
Output_File | 文件 | 输出文件名。文件扩展名取决于格式参数。 |
格式 | 字符串 | 传送打印用地图影像时所使用的格式。接受以下字符串:
|
Layout_Template | 字符串 | 可以是列表中某个模板的名称,也可以是关键字 MAP_ONLY。选择 MAP_ONLY 或传递空字符串时,输出地图不会包含任何页面布局的周围要素(例如标题、图例和比例尺)。 |
从 web 应用程序打印地图时,最常使用 ConvertWebMapToMapDocument 函数。当您使用 ArcGIS Web API 打印任务时,不需要创建 Web 地图 JSON;因为 API 会为您解决这个问题。但是,只有在本地运行脚本之后,才能发布并在 Web API 中使用该脚本。本地运行脚本时,可以使用任何有效的 web 地图 JSON 字符串。要成功运行脚本,可能需要与 web 应用程序返回的字符串类似的 JSON 字符串。请参阅 ExportWebMap 规范来了解对此文本进行格式化的方式。示例字符串如下:
{
"layoutOptions": {
"titleText": "Simple WebMap JSON example"
},
"operationalLayers": [
{
"url": "http://maps1.arcgisonline.com/ArcGIS/rest/services/USA_Federal_Lands/MapServer",
"visibility": true
}
],
"exportOptions": {
"outputSize": [
1500,
1500
]
},
"mapOptions": {
"extent": {
"xmin": -13077000,
"ymin": 4031000,
"xmax": -13023000,
"ymax": 4053000
}
},
"version": "1.4"
}
运行脚本工具时,JSON 字符串可复制并粘贴到 Web_Map_as_JSON 输入参数中。但是,必须移除字符串中的换行符,该字符串才能成为有效输入。移除了换行符的 JSON 字符串示例如下:
{"layoutOptions": {"titleText": "Simple WebMap JSON example"},"operationalLayers": [{"url": "http://maps1.arcgisonline.com/ArcGIS/rest/services/USA_Federal_Lands/MapServer","visibility": true}],"exportOptions": {"outputSize": [1500,1500]},"mapOptions": {"extent": {"xmin": -13077000,"ymin": 4031000,"xmax": -13023000,"ymax": 4053000}},"version": "1.4"}
当您在地理处理服务中使用封装 ConvertWebMapToMapDocument 的 Python 脚本时,您需要确保 ArcGIS Server 可以看到 Web 应用程序中使用的模板地图文档和数据。最佳做法是使用通过 ArcGIS Server 注册的文件夹。有关注册数据的详细信息,请参阅以下内容:
在注册的文件夹中制作模板地图文档时,最佳做法是使用相对路径。这样,ArcGIS Server 就可以在地图文档位置相对的注册文件夹中找到数据。有关详细信息,请参阅引用地图中的数据。
除了创建自己的模板地图文档之外,还可以使用随软件提供的预先制作的模板。这些模板位于 <installation_directory>\Templates\ExportWebMapTemplates。这些模板包含图例、当前日期动态文本、比例尺和比例文本等地图元素。
默认情况下,Web 应用程序的注释叠加或客户端图像将存储在内存工作空间中。内存工作空间是临时性的,将在关闭应用程序时被删除。要创建包含注释叠加的输出地图文档的永久副本,请先指定 notes_gdb,然后使用合并地图或打包地图地理处理工具来创建输出地图文档副本。仅在计划创建输出地图文档永久副本时,才会需要指定 notes_gdb。参阅下面的代码示例 2。如果 Web 地图不包含注释叠加,您可以使用 MapDocument 类的 saveACopy 方法来创建输出地图文档的永久复本。
arcpy.mapping 模块还提供了用于在输出地图文档的布局中控制图例外观的方法。要移除图例项,请参阅 LegendElement 类中的 removeItem 方法。下面列出的高级教程将对此工作流进行说明。要更新图例项,请参阅 LegendElement 类中的 updateItem 方法以及 ListStyleItems 方法。
如果 Web 应用程序使用动态图层,则图层类中的 updateLayerFromJSON 函数可用于更新与 Web 地图 JSON 中动态图层的图层定义混合的模板中过渡的矢量图层属性(例如,符号系统)。如果 Web 应用程序允许更改动态图层的符号系统并且您希望将服务图层替换为过渡的矢量数据,但仍保留 Web 应用程序中更新的符号系统,则上述操作将十分有用。参阅下面的代码示例 6。
请确保阅读下列教程。这些教程演示了使用 ConvertWebMapToMapDocument 工作流进行矢量打印和导出的整个过程:创作过渡模板地图文档、创作 Python 脚本、创建地理处理服务、创建 Web 应用程序。
语法
ConvertWebMapToMapDocument (webmap_json, {template_mxd}, {notes_gdb}, {extra_conversion_options})
参数 | 说明 | 数据类型 |
webmap_json | 用于以 JavaScript 对象表示法 (JSON) 打印的 web 地图 有关详细信息,请参阅 ExportWebMap JSON 规范。通过 ArcGIS Web API(JavaScript、Flex 和 Silverlight),开发人员可以从 web 应用程序中轻松获得此 JSON 字符串。 | String |
template_mxd | 用于表示用作页面布局模板的地图文档 (.mxd) 的路径和文件名的字符串。Web 地图内容将被插入至保存 template_mxd 时处于活动状态的数据框。template_mxd 文件的活动数据框(以及所有其他数据框)中的图层将被保存于输出 mapDocument 中。 (默认值为 None) | String |
notes_gdb | 用于表示新建或现有文件地理数据库或现有企业地理数据库连接(其中应写入图形特征)的路径的字符串。只有在 Web 地图 JSON 的图形特征需要永久保存时,此参数才可用。大多数情况下,并不需要此参数,因为将使用临时内存工作空间存储图形特征。此参数可用于保存图形特征至永久存储,如果您计划将地图文档用于需要从磁盘保存或加载的操作(例如,打包或合并)时,这将是至关重要的。路径必须以 .gdb 或 .sde 扩展名为结尾。 (默认值为 None) | String |
extra_conversion_options | 受保护服务凭据的字典。在 Web 地图 JSON 需要用户名和密码进行查看时,则需要此参数。字典中接受的关键字如下:
以下是一个键值对的示例:
当存在多个受保护服务时,可使用连接文件列表:
(默认值为 None) | Dictionary |
返回值
数据类型 | 说明 |
tuple | 返回 Python 命名的 Web 地图和请求属性的元组:
|
代码示例
ConvertWebMapToMapDocument 示例 1
在本示例中,该脚本分别在 Web 地图 JSON、模板地图文档以及该 Web 地图将附加到的现有 PDF 文档中读取。将 ConvertWebMapToMapDocument 函数中的输出地图文档以 PDF 格式导出,再使用 PDFDocument 类将其插入到其他 PDF 文件中。
import arcpy
import os
import uuid
# The template location in the server data store
templatePath = '//MyMachine/MyDataStore/WebMap'
# Input WebMap json
Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# Input Layout template
Layout_Template = arcpy.GetParameterAsText(1)
if Layout_Template == '#' or not Layout_Template:
Layout_Template = "Landscape11x17"
# PDF Title Page
PDF_Title = arcpy.GetParameterAsText(2)
if PDF_Title == '#' or not PDF_Title:
PDF_Title = "TitlePage.PDF"
# PDF End Page
PDF_End = arcpy.GetParameterAsText(3)
if PDF_End == '#' or not PDF_End:
PDF_End = "ContactInfo.PDF"
# Get the requested map document
templateMxd = os.path.join(templatePath, Layout_Template + '.mxd')
# Get the requested PDF files
PDF_Title_File = os.path.join(templatePath, PDF_Title)
PDF_End_File = os.path.join(templatePath, PDF_End)
# Convert the WebMap to a map document
result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON,
templateMxd)
mxd = result.mapDocument
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name
WebMapPDF = os.path.join(arcpy.env.scratchFolder,
'WebMap_{}.pdf'.format(str(uuid.uuid1())))
# Export the WebMap to PDF
arcpy.mapping.ExportToPDF(mxd, WebMapPDF)
# Create a new "master" output PDF Document
# Append Title, WebMap and End PDFs to it
Output_Name = os.path.join(arcpy.env.scratchFolder,
'OutputWithWebMap_{}.pdf'.format(str(uuid.uuid1())))
pdfDoc = arcpy.mapping.PDFDocumentCreate(Output_Name)
pdfDoc.appendPages(PDF_Title_File)
pdfDoc.appendPages(WebMapPDF)
pdfDoc.appendPages(PDF_End_File)
pdfDoc.saveAndClose()
# Set the output parameter to be the output PDF
arcpy.SetParameterAsText(4, Output_Name)
# Clean up - delete the map document reference
filePath = mxd.filePath
del mxd, result
os.remove(filePath)
ConvertWebMapToMapDocument 示例 2
本例中,ConsolidateMap 地理处理工具用于创建包含注释叠加的输出地图文档的永久副本。
import arcpy import os import uuid
# The template location in the registered folder templatePath = '//MyMachine/Austin/WebMap'
# Input web map 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 = "Landscape11x17"
# Get the requested map document templateMxd = os.path.join(templatePath, Layout_Template + '.mxd')
# Since we are making a permanent copy of the notes overlays,
# we need to specify a notes geodatabase notes = os.path.join(arcpy.env.scratchFolder, 'mynotes.gdb')
# Convert the web map to a map document result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd, notes) mxd = result.mapDocument
# Save the web map and notes overlays to a new map document using ConsolidateMap arcpy.ConsolidateMap_management(mxd.filePath,
os.path.join(arcpy.env.scratchFolder, 'ConsolidateWebMap'))
# Clean up - delete the map document reference filePath = mxd.filePath del mxd, result
os.remove(filePath)
ConvertWebMapToMapDocument 示例 3
本例中,使用了过渡模板地图文档,其中包含所有可能服务图层的矢量等效表示。执行 ConvertWebMapToMapDocument 函数后,该脚本对输出地图文档中的所有图层进行循环,从而移除所有图层(与 Web 地图 JSON 中的服务图层相对应的矢量图层除外)。随后将输出地图文档布局导出为 PDF 或 PNG 格式。
import arcpy import os import uuid
# The template location in the registered folder templatePath = '//MyComputerName/MyDataStore/USA'
# Input web map 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"
# Get the requested map document templateMxd = os.path.join(templatePath, Layout_Template + '.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 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)
# 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)
# 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 web map if Format.lower() == 'pdf':
arcpy.mapping.ExportToPDF(mxd, Output_File) 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(3, Output_File)
# Clean up - delete the map document reference filePath = mxd.filePath del mxd, result os.remove(filePath)
ConvertWebMapToMapDocument 示例 4
本例中,使用了过渡模板地图文档,其中包含所有可能服务图层的矢量等效表示。执行 ConvertWebMapToMapDocument 函数后,该脚本对输出地图文档中的所有图层进行循环,从而移除所有图层(与 Web 地图 JSON 中的服务图层相对应的矢量图层除外)。然后使用 DPI,应用 Web 应用程序中指定的 ConvertWebMapToMapDocument 函数返回的输出高度值和输出宽度值将输出地图文档的数据视图导出为 PNG。
import arcpy import os import uuid
# Input web map json Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# The template location in the registered folder templatePath = '//MyComputerName/MyDataStore/FederalLands'
# Get the template map document templateMxd = os.path.join(templatePath, 'FederalLands.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 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)
# 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)
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name output = 'WebMap_{}.png'.format(str(uuid.uuid1())) Output_File = os.path.join(arcpy.env.scratchFolder, output)
# Export the web map arcpy.mapping.ExportToPNG(mxd, Output_File, df, result.outputSizeWidth, result.outputSizeHeight, result.DPI)
# 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)
ConvertWebMapToMapDocument 示例 5
此例中,用户提供了与在模板地图文档中启用的数据驱动页面对应的页面范围。随后页面范围导出为多页 PDF 文档。
import arcpy import os import uuid
# The template location in the registered folder templatePath = '//MyComputerName/MyDataStore/WebMap'
# Input WebMap json Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# Data Driven Page numbers as comma delimited string DDP_Pages = arcpy.GetParameterAsText(1) if DDP_Pages == '#' or not DDP_Pages:
DDP_Pages = "1, 3, 10-13"
# Get the template map document templateMxd = os.path.join(templatePath, 'DDP.mxd')
# Convert the WebMap to a map document result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd)
mxd = result.mapDocument
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name Output_Name = os.path.join(arcpy.env.scratchFolder, 'WebMap_{}.pdf'.format(str(uuid.uuid1())))
# Export the WebMap Data Driven Pages to PDF mxd.dataDrivenPages.exportToPDF(Output_Name, "RANGE", DDP_Pages)
# Set the output parameter to be the output PDF arcpy.SetParameterAsText(2, Output_Name)
# Clean up - delete the map document reference filePath = mxd.filePath del mxd, result os.remove(filePath)
ConvertWebMapToMapDocument 示例 6
在此示例中,图层类中的 updateLayerFromJSON 函数用于更新与 Web 地图 JSON 中动态图层的图层定义混合的模板中过渡的矢量图层属性(例如,符号系统)。如果 Web 应用程序允许更改动态图层的符号系统并且您希望将服务图层替换为过渡的矢量数据,但仍保留 Web 应用程序中更新的符号系统,则上述操作将十分有用。
import arcpy import os import uuid import json
# The template location in the server data store templatePath = '//MyMachine/MyDataStore/WebMap'
# Input WebMap json Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# Input Layout template Layout_Template = arcpy.GetParameterAsText(1) if Layout_Template == '#' or not Layout_Template:
Layout_Template = "Landscape11x17"
# Get the requested map document templateMxd = os.path.join(templatePath, Layout_Template + '.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 dataframe in the template_mxd to "Webmap"
df = arcpy.mapping.ListDataFrames(mxd, 'Webmap')[0]
# Reference the staged vector data that corresponds to the dynamic layer in the JSON
# This is the layer that will get updated based on the layer definition in the JSON lyr = arcpy.mapping.ListLayers(mxd, "U.S. States (Generalized)", df)[0]
# Read the JSON and extract the layer definition
# In this case we have hardcoded it to second operational layer data = json.loads(Web_Map_as_JSON) layerDefinition = data["operationalLayers"][1]["layerDefinition"]
# Update the staged vector layer with the layer definition (e.g. renderer info) from the JSON lyr.updateLayerFromJSON(layerDefinition)
# Remove all service layers. This will leave only staged vector layers. for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
if slyr.isServiceLayer:
arcpy.mapping.RemoveLayer(df, slyr)
# 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(2, Output_File)
# Clean up - delete the map document reference filePath = mxd.filePath del mxd, result os.remove(filePath)