教程:使用 arcpy.mapping 进行高级的高质量 web 地图打印/导出

复杂程度:高级 数据要求:随软件安装

下图显示了一个待创建的 ArcGIS web API 应用程序的示例。在 web 应用程序中,最终用户将可以:

Web 应用程序

默认情况下,使用 ArcGIS web API 中的打印工具服务及其客户端打印微件从 web 应用程序中导出服务图层的缓存图像,该缓存图像的分辨率可能过低(例如 96 dpi),无法进行大幅面打印或高质量的制图输出。而本教程将介绍如何输出含有高质量服务图层矢量输出的易于打印的文档。

以下为输出 PDF 示例。请注意,在 web 应用程序的内容列表图例中关闭的图层将反映在输出中。

输出 PDF

导出地图按钮后的代码将使用 ArcGIS web API 的打印任务,该打印任务在 ArcGIS 10.1 for Desktop 中可用。本教程还会介绍如何将额外参数传递到打印任务中,例如是否将地理配准信息导出为输出 PDF 文件。将额外参数传递到打印任务这一功能非常有用,通过它可以从 web 应用程序收集任意数量的额外参数。您还可以创建可发布为地理处理服务的 Python 脚本,该地理处理服务可被打印任务所使用。Python 脚本使用 arcpy.mapping 模块中的 ConvertWebMapToMapDocument 函数,该函数会将 web 地图的完整状态插入分段的模板地图文档。您可以将其分段为几个模板,用户可以从中进行选择。每个模板都包含地图服务中所有可能图层的矢量等效表示。分段的模板也可以包含其它元素,如图例、动态文本等。arcpy.mapping 模块还提供识别服务图层并用该服务图层交换指向本地数据的图层并导出为多种格式(如 PDF)的功能。

要完成本教程,应熟悉 arcpy.mapping 模块、ArcGIS web APIArcGIS for DesktopArcGIS 10.1 for Server。本教程中包含所有 ArcGIS web API 的示例代码。还应逐渐熟悉 web 应用程序帮助主题中的打印:

在 web 应用程序中打印web 地图高级打印

本教程使用 ArcGIS for Desktop 安装目录中的 MapTemplatesTemplateData 文件夹,它们通常位于 C:\Program Files (x86)\ArcGIS\Desktop10.1。本教程假定地图模板和模板数据存在且未经修改。如果情况不是这样,则可能需要重新安装 ArcGIS for Desktop

复制教程数据

ArcGIS for Desktop 安装目录中的一些地图模板复制到一个新的文件夹中。这些模板最终将用作 web 应用程序中的分段地图模板。

在此之前,需要确保存在一个文件夹结构以便 ArcGIS for Server 可以查看将用于 web 应用程序的模板地图文档和数据。本教程假定存在注册到 ArcGIS for Server 的文件夹。有关将数据注册到 ArcGIS for Server 的详细信息,请参阅:

提示提示:

ConvertWebMapToMapDocument 函数中使用模板地图文档时,最好的做法是使用注册到 ArcGIS for Server 的数据。如果选择不使用注册的数据,那么模板地图文档和数据将打包并复制到服务器。在打包过程中, 数据可能被移动并带着相对路径重新指向 ConvertWebMapToMapDocument 无法解析的文件夹结构。有关详细信息,请参阅 ConvertWebMapToMapDocument 帮助主题。

步骤:
  1. 打开新的空 ArcMap 会话。
  2. 目录窗口中,导航至已注册的文件夹。在已注册的文件夹中创建一个名为 USA 的新文件夹。
  3. 目录窗口中,导航至 ArcGIS for Desktop 安装目录中的 MapTemplates 文件夹。该文件夹通常位于 C:\Program Files (x86)\ArcGIS\Desktop10.1\MapTemplates。进一步导航至 Traditional Layouts\USA 文件夹。
  4. 目录窗口中,将以下文件复制并粘贴到您在上一步骤中所创建的 USA 文件夹:CentralUSA.mxd、ConterminousUSA.mxd、NortheasternUSA.mxd、NorthwesternUSA.mxd、SouthernUSA.mxdSouthwesternUSA.mxd
    MapTemplates 文件夹
  5. 目录窗口中,导航至 ArcGIS for Desktop 安装目录中的 TemplateData 文件夹。该文件夹通常位于 C:\Program Files (x86)\ArcGIS\Desktop10.1\TemplateData
  6. 目录窗口中,将 TemplateData.gdb 复制并粘贴到您在上一步骤中所创建的 USA 文件夹:
    TemplateData 文件夹
  7. 此已注册文件夹应与下图类似:
    已注册文件夹
    注注:

    在上方的屏幕截图中,已注册文件夹名为 MyDataStore。已注册文件夹的名称可随意设置。

准备地图文档以用作 web 应用程序中的模板

需要准备地图文档以用作 ConvertWebMapToMapDocument 中的模板。

现在位于已注册文件夹中的地图文档需要重新指向同样位于已注册文件夹中的 TemplateData.gdb。此操作可通过 ArcMap 用户界面或 Python 脚本来完成。这里将使用后一种方法。

注注:

如果您在已注册文件夹中从头开始创作自己的地图文档模板,则不需要执行这些步骤。

步骤:
  1. 打开 ArcMap 中的 Python 窗口
  2. 将以下脚本复制并粘贴到 Python 窗口中:
  3. import arcpy, os
    
    # The path to the registered folder where the template MXDs reside
    folderPath = "C:/MyDataStore/USA"
    
    # The location of TemplateData.gdb within the registered folder
    newPath = "C:/MyDataStore/USA/TemplateData.gdb"
    
    # Loop through all MXDs in the specified folder and change the layer's data source to the new path
    for filename in os.listdir(folderPath):
        fullpath = os.path.join(folderPath, filename)
        if os.path.isfile(fullpath):
            basename, extension = os.path.splitext(fullpath)
            if extension.lower() == ".mxd":
                mxd = arcpy.mapping.MapDocument(fullpath)
                mxd.findAndReplaceWorkspacePaths(arcpy.mapping.ListLayers(mxd)[1].workspacePath, newPath)
                mxd.save()
    print "done"
    
  4. Python 窗口中,将 folderPath 变量更改为模板 MXD 所在的已注册文件夹路径。请记得在路径中使用正斜线 (/)
  5. Python 窗口中,将 newPath 变量更改为已注册文件夹中 TemplateData.gdb 的位置。请记得在路径中使用正斜线 (/)
  6. 脚本应如下所示:
  7. 将光标置于最后一行的右侧。按两次 Enter 键以执行该脚本。等待脚本执行。

现在,地图文档即可用作 web 应用程序中的模板。

创建要在 web 应用程序中使用的地图服务

需要准备地图文档并将其作为地图服务进行发布,以便在 web 应用程序中进行使用。已注册文件夹中的 ConterminousUSA.mxd 将用作地图服务。在将其发布到服务器前,需要做好将其发布的准备。

步骤:
  1. 打开 ArcMap 中的 ConterminousUSA.mxd
  2. 默认情况下,地图将在布局视图中打开。选择 ArcMap 主菜单中的视图 > 数据视图来切换到数据视图
  3. 接下来关闭该地图文档中的“地图注记组”。该地图包含地图图形。地图图形会增加已加载的文档的内存需求量,从而可导致性能降低。由于具有这些副作用,因此在地图服务中不支持地图图形。
    1. 右键单击内容列表中数据框的名称,然后单击属性,打开美国本土数据框属性。
    2. 单击注记组选项卡。
    3. 取消选中<默认>组。此时,注记组选项卡应如下图所示:
      注记组选项卡
    4. 数据框属性 对话框上,单击确定
  4. 该地图使用底图图层底图图层不会发布到 ArcGIS for Server。通过取消分组,将图层移出底图图层。
    1. 右键单击内容列表中的底图图层,然后单击取消分组
    注注:

    如果您从头开始创作自己的地图文档模板,或正在使用不包含地图图形或底图图层的现有地图文档模板,则不需要执行这些步骤。

    地图现在即可发布到服务器。如果不熟悉发布过程,请查看如何发布服务

  5. 单击文件 > 共享为 > 服务
  6. 单击发布服务
  7. 单击下一步
  8. 选择指向 ArcGIS 10.1 for Server 计算机的发布或管理连接。
  9. 单击下一步
  10. 创建名为 USA 的新文件夹。
  11. 单击继续
  12. 单击服务编辑器对话框右上角的发布

这将创建将用于 web 应用程序的地图服务。

创建 Python 脚本

您将创建用作自定义地理处理服务的 Python 脚本。

自定义地理处理服务中的 Python 脚本将执行 ConvertWebMapToMapDocument 函数,该函数可将待打印或导出的 web 地图(JSON 格式)转换为地图文档。然后 arcpy.mapping 脚本在输出地图文档的所有图层中循环,除与 web 地图 JSON 中的服务图层相对应的矢量图层之外,其他所有图层均被移除。接着该脚本将在图例的所有图层中循环,移除除了与 web 地图 JSON 图例中的服务图层相对应的矢量图层之外的所有图例图层。在这种情况下,无论是否为了将地理配准信息导出为输出 PDF 文件,脚本都将读取自定义打印任务中的额外参数。随后可将地图文档导出为所选的格式,如 PDF。

步骤:
  1. 打开任意的 Python IDE,如 IDLE(ArcGIS for Desktop 的附带文件)。
  2. 将以下代码复制并粘贴到新的 Python 脚本中。
  3. import arcpy
    import os
    import uuid
    
    # The template location in the registered folder (as UNC path)
    templatePath = '//MyComputerName/MyDataStore/USA'
    
    # Input WebMap 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" 
        
    # Extra parameter - georef_info
    Georef_info = arcpy.GetParameterAsText(3)
    if Georef_info == '#' or not Georef_info:
        Georef_info = "False"
    
    # Convert Georef_info string to boolean
    if Georef_info.lower() == 'false': 
        Georef_info_bol = False
    elif Georef_info.lower() == 'true': 
        Georef_info_bol = True
    
    # Get the requested map document
    templateMxd = os.path.join(templatePath, Layout_Template + '.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]
    
    # 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)
                    
    # Reference the legend in the map document
    legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT")[0]
    
    # Get a list of service layers that are on in the legend because the incoming 
    # JSON can specify which service layers/sublayers are on/off in the legend
    legendServiceLayerNames = [lslyr.name for lslyr in legend.listLegendItemLayers() 
                               if lslyr.isServiceLayer and not lslyr.isGroupLayer]
    
    # Remove vector layers from the legend where the corresponding service layer 
    # is also off in the legend
    for lvlyr in legend.listLegendItemLayers():
        if not lvlyr.isServiceLayer \
        and lvlyr.name not in legendServiceLayerNames \
        and not lvlyr.isGroupLayer \
        and lvlyr.name in vectorLayersNames:
            legend.removeItem(lvlyr)
    
    # 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)
            
    # ConvertWebMapToMapDocument renames the active dataframe in the template_mxd to "Webmap".
    # Lets rename it to something more meaningful.
    df.name = Layout_Template
    
    # 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 WebMap
    if Format.lower() == 'pdf':
        arcpy.mapping.ExportToPDF(mxd, Output_File, georef_info=Georef_info_bol) 
    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(4, Output_File)
    
    # Clean up - delete the map document reference
    filePath = mxd.filePath
    del mxd, result
    os.remove(filePath)
    
  4. templatePath 变量更改为包含模板地图文档的已注册文件夹中的文件夹 UNC 路径。
  5. 注注:

    如果 ArcGIS for ServerArcGIS for Desktop 和已注册文件夹都在同一计算机上,则不需要已注册文件夹的 UNC 路径。此时,可使用绝对路径来代替。

  6. 保存 Python 脚本。将脚本命名为 AdvancedHighQualityPrinting.py。将其保存到已注册文件夹中名为 WebApp 的文件夹内。

现在即可将 Python 脚本添加到工具箱。

创建工具箱

步骤:
  1. 在 ArcMap 的目录窗口中,导航至已注册文件夹中的 WebApp 文件夹。
  2. 右键单击 WebApp 文件夹,然后单击新建 > 工具箱。将该工具箱命名为 AdvancedHighQualityPrinting
  3. 右键单击 AdvancedHighQualityPrinting 工具箱,然后单击项目描述
  4. 项目描述对话框中,使用所选文本填充标签汇总项目。也可以填入其他项目描述。
  5. 单击保存并退出项目描述对话框。

创建 Python 脚本工具

接下来,将 AdvancedHighQualityPrinting.py 脚本添加到 AdvancedHighQualityPrinting 工具箱。

步骤:
  1. 目录窗口中,右键单击 AdvancedHighQualityPrinting 工具箱,然后单击添加 > 脚本
  2. 添加脚本对话框中,在名称标签中都输入 AdvancedHighQualityPrinting
  3. 单击下一步
  4. 对于脚本文件,导航至已注册文件夹中的 WebApp 文件夹并选择 AdvancedHighQualityPrinting.py
  5. 单击添加脚本对话框中的下一步
  6. 需要将五个参数添加到脚本工具。
    1. 第一个参数是 Web_Map_as_JSON。该参数采用地图在 Web 应用程序中显示时导出的地图状态的 JSON 表示。属性应与以下屏幕截图相匹配:
      Web_Map_as_JSON 参数
    2. 下一个参数是 Format - 传送打印用的地图图像时所使用的格式。属性应与以下屏幕截图相匹配:
      Format 参数
    3. 下一个参数是 Layout_Template - 将要使用的模板地图文档。属性应与以下屏幕截图相匹配:
      Layout_Template 参数
    4. 下一个参数是 Georef_info - 可将坐标系信息导出为输出 PDF 文件的布尔型字符串。属性应与以下屏幕截图相匹配:
      Georef_info 参数
    5. 下一个参数是 Output_File - 将要创建的输出文件。属性应与以下屏幕截图相匹配:
      Output_File 参数

      警告警告:

      Web_Map_as_JSON、Format、Layout_TemplateOutput_File 参数的名称必须完全按照以上所示拼写,以匹配 ArcGIS web API 中打印任务的工具签名。有关参数的详细信息,请参阅导出 web 地图Georef_info 参数为将要传递到打印任务的额外参数,因而没有需要遵循的命名约定。

    6. 单击添加脚本对话框中的完成
  7. 右键单击 AdvancedHighQualityPrinting 脚本工具,然后单击项目描述
  8. 项目描述对话框中,使用所选文本填充标签汇总项目。也要填充项目描述对话框的语法部分中五个参数的对话框说明。也可以填入其他项目描述。

执行工具

需要成功执行工具以在结果窗口中创建可发布到 ArcGIS for Server 的结果。这说明了关于使用 ConvertWebMapToMapDocument 的测试脚本的一个有趣的问题。为了在本地执行,它需要有效的 webmap JSON。但是只有脚本发布后, ArcGIS web API 才在 web 应用程序中提供 webmap JSON。要解决这个问题,可以使用 ConvertWebMapToMapDocument 帮助主题中的测试 JSON。此外,还可以修改 JSON,使其包含工具所需要的元素,以及与将要从 web 应用程序中得到的 JSON 相似的元素。在本教程中,web 应用程序的用户能够打开/关闭地图中的服务图层,也可以打开/关闭图例中的图层。因此,应使用如下所示的测试 web 地图 JSON 字符串:

{
    "operationalLayers": [
        {
            "url": "http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer",
            "title": "MyDynamicService",
            "opacity": 1,
            "id": "MyDynamicService",
            "visibility": true,
            "visibleLayers": [
                0,
                2,
                3,
                4,
                5,
                6,
                7
            ]
        }
    ],
    "mapOptions": {
        "extent": {
            "xmin": -2200000,
            "ymin": 500000,
            "xmax": -1300000,
            "ymax": 1300000,
            "spatialReference": {
                "wkid": 102008
            }
        },
        "scale": 5000000,
        "rotation": 0
    },
    "layoutOptions": {
        "copyrightText": "",
        "authorText": "",
        "legendOptions": {
            "operationalLayers": [
                {
                    "id": "MyDynamicService",
                    "subLayerIds": [
                        0,
                        2,
                        5
                    ]
                }
            ]
        }
    }
}

请注意,visibleLayers 元素的图层 1 是关闭的。这意味着地图服务中的图层一不会出现在输出中。还要注意 legendOptions 中的 subLayerIDs。在图例中,只有图层 025 是打开的。这与从 web 应用程序返回的 JSON 相似。有关详细信息,请参阅 WebMap JSON 规范

运行脚本工具时,可将 JSON 字符串复制并粘贴到 Web_Map_as_JSON 输入参数中。但是必须删除换行符以确保字符串为有效输入。以下是已删除换行符的 JSON 字符串:

{"operationalLayers":[{"url":"http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer","title":"MyDynamicService","opacity":1,"id":"MyDynamicService","visibility":true,"visibleLayers":[0,2,3,4,5,6,7]}],"mapOptions":{"extent":{"xmin":-2200000,"ymin":500000,"xmax":-1300000,"ymax":1300000,"spatialReference":{"wkid":102008}},"scale":5000000,"rotation":0},"layoutOptions":{"copyrightText":"","authorText":"","legendOptions":{"operationalLayers":[{"id":"MyDynamicService","subLayerIds":[0,2,5]}]}}}

还需将服务器名称(原来是 MyServer:6080)更改为 ArcGIS for Server 服务器的名称。

提示提示:

出于发布目的,可以选择将 Web_Map_as_JSON 输入参数留空,因为 ArcGIS web API 会在 web 应用程序中提供 web 地图 JSON。如果 Python 脚本的写入方式使其在空白输入时仍能正常执行,则可将 Web_Map_as_JSON 输入参数留空。例如,脚本不通过名称查找 web 地图图层。如果脚本由于脚本错误在服务器上失败,则必须在本地将其修复,然后重新发布到服务器。因此,在发布前最好在本地确认脚本能够执行,这可以通过测试有效的 web 地图 JSON 字符串或使用包含 web 地图 JSON 中的所有要素的调试地图文档来完成。本教程将提供一个有效的 JSON 字符串。

步骤:
  1. 目录窗口中,右键单击 AdvancedHighQualityPrinting 脚本工具,然后单击打开
  2. 对于 Web_Map_as_JSON 输入参数,将已删除换行符的 JSON 字符串从上面的单行代码块复制并粘贴到 Web_Map_as_JSON 参数。请不要忘记更改服务器名称以匹配服务器。AdvancedHighQualityPrinting 脚本工具对话框应如下图所示:
    AdvancedHighQualityPrinting 脚本工具对话框
  3. 接受其他参数的所有默认值并单击确定
  4. 打开结果窗口
  5. 双击下方高亮显示的 Output_File 以查看输出 PDF。
    结果对话框

    这将打开 PDF。如 web 地图 JSON 中指定的那样,PDF 地图中的图层 1 应关闭;且在图例中应只有图层 025 是打开的。

发布结果

现在即可将结果作为地理处理服务发布。如果不熟悉如何发布地理处理服务,请参阅:

步骤:
  1. 结果窗口中,右键单击 AdvancedHighQualityPrinting 结果,然后单击共享为 > 地理处理服务
  2. 单击发布服务
  3. 单击下一步
  4. 选择指向 ArcGIS 10.1 for Server 计算机的发布或管理连接。
  5. 单击下一步
  6. 使用名为 USA 的现有文件夹。
  7. 单击继续
  8. 单击服务编辑器对话框右上角的发布
  9. 成功发布脚本工具后,最好使用指向 ArcGIS for Server 的 GIS 服务器连接来测试 ArcMap 中的地理处理服务。可以在地理处理结果窗口中查看地理处理服务的结果。

现在即可将地理处理服务用于 ArcGIS web API 中。

选择想要用来创建 web 应用程序的 ArcGIS web API。

ArcGIS web APIs 提供类似的 GIS 功能;您需要选择您偏好的开发平台。每种 API 都为您提供了所需资源。有关详细信息可阅读相应的 API 参考、查看有助于入门和显示各种可能情况的操作示例,以及通过论坛、博客和代码库与其他人员进行交流。本教程不包含关于利用每种 API 开始构建 web 应用程序的详细介绍。有关此介绍的详细信息,请参阅 API 文档。有关详细信息,请参阅:

每个 ArcGIS web API 都具有打印任务打印任务具有一个引用之前所创建的自定义地理处理服务的 URL 属性。有关打印任务的详细信息,请参阅 ArcGIS web API 文档。

在以下部分中,使用您正在处理的 ArcGIS web API 代码示例来构建 web 应用程序。

ArcGIS API for Silverlight 示例代码

如果您正在使用 ArcGIS API for Silverlight,那么请使用以下示例代码来构建 web 应用程序。

在下方的 ArcGIS API for Silverlight 代码示例中,将 URL 更改为您在之前步骤中所创建的地图服务和地理处理服务,以匹配服务器名称。以下各行将对其进行引用:

Url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"
printTask = new PrintTask("http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting");

XAML 代码:

<UserControl x:Class="TestSilverlightApplication1.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="-2260000,-1500000,2250000,1220000">
            <esri:Map.Layers>
                <esri:ArcGISDynamicMapServiceLayer ID="MyDynamicService" 
                    Url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"
                    Initialized="ArcGISDynamicMapServiceLayer_Initialized"/>
            </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 />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="LayoutTemplates" Grid.Row="0" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="LayoutTemplates" ItemsSource="{Binding LayoutTemplates}" Grid.Row="0" Grid.Column="1" Width="100" Margin="2"/>
                    <TextBlock Text="Formats" Grid.Row="1" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="Formats" Grid.Row="1" ItemsSource="{Binding Formats}"  Grid.Column="1" Width="100" Margin="2"/>
                    <TextBlock Text="Georef info?" Grid.Row="2" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="Georef_info" Grid.Row="2" Grid.Column="1" Width="100" Margin="2">
                        <ComboBoxItem Content="True"></ComboBoxItem>
                        <ComboBoxItem Content="False"></ComboBoxItem>
                    </ComboBox>
                    <Button x:Name="Print" Content="Export Map" Click="ExportMap_Click" 
                            Grid.Row="3" Grid.Column="0" Margin="2"/>

                </Grid>
            </Border>
        </StackPanel>

        <StackPanel Orientation="Vertical" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Center" >
            <Border Background="#99919191" BorderThickness="1" CornerRadius="5"
                HorizontalAlignment="Right" VerticalAlignment="Top"
                Margin="20,20,20,30" Padding="10" BorderBrush="Black">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="15" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="Table of Contents" Foreground="White" Grid.Row="0" >
                    <TextBlock.Effect>
                        <DropShadowEffect ShadowDepth="1" />
                    </TextBlock.Effect>
                    </TextBlock>
                    <ListBox Name="TOCListBox" Margin="0,5,0,0" ItemsSource="{Binding ElementName=MyMap, Path=Layers.[MyDynamicService].Layers}" 
                         Grid.Row="1">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <CheckBox Margin="2"
                                  Name="MyDynamicService"
                                  Content="{Binding Name}" 
                                  IsChecked="{Binding DefaultVisibility}" 
                                  Tag="{Binding ID}"
                                  ClickMode="Press" 
                                  Click="CheckBox_Click" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </Grid>
            </Border>
        </StackPanel>

        <StackPanel Orientation="Vertical" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Bottom" >
            <Border Background="#99919191" BorderThickness="1" CornerRadius="5"
                HorizontalAlignment="Right" VerticalAlignment="Top"
                Margin="20,20,20,30" Padding="10" BorderBrush="Black">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="18" />
                        <ColumnDefinition Width="62" />
                        <ColumnDefinition Width="6" />
                        <ColumnDefinition Width="56" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="15" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="Include in Legend" Foreground="White" Grid.ColumnSpan="4">
                    <TextBlock.Effect>
                        <DropShadowEffect ShadowDepth="1" />
                    </TextBlock.Effect>
                    </TextBlock>
                    <ListBox Name="LegendListBox" Margin="0,5,0,0" Grid.Row="1" Grid.ColumnSpan="4">
                        <ListBoxItem>
                            <CheckBox x:Name="CapitalCities" Content="Capital Cities" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="InterstateHighways" Content="Interstate Highways" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="Rivers" Content="Rivers" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="Lakes" Content="Lakes" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                        <ListBoxItem>
                            <CheckBox x:Name="StateBoundaries" Content="State Boundaries" IsChecked="True" ClickMode="Press"></CheckBox>
                        </ListBoxItem>
                    </ListBox>
                </Grid>
            </Border>
        </StackPanel>

    </Grid>


</UserControl>

C# 中的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client.Printing;
using ESRI.ArcGIS.Client.Tasks;

namespace TestSilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        PrintTask printTask;
        public MainPage()
        {
            InitializeComponent();
            printTask = new PrintTask("http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting");
            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;
            ComboBoxItem typeItem = (ComboBoxItem)Georef_info.SelectedItem;
            string value = typeItem.Content.ToString();
            var gpExtraInput = new List<GPParameter>();
            gpExtraInput.Add(new GPString("Georef_info", value));

            // Specify the LayoutOptions to provide marginalia in the output map.
            ESRI.ArcGIS.Client.Printing.LayoutOptions myLayoutOptions = new ESRI.ArcGIS.Client.Printing.LayoutOptions();
            // Define the LegendOptions. This will show specified Layers in the printed map's legend area.
            ESRI.ArcGIS.Client.Printing.LegendOptions myLegendOptions = new ESRI.ArcGIS.Client.Printing.LegendOptions();

            // Define a List<LegendInfo> objects to put in the LegendOptions.
            List<ESRI.ArcGIS.Client.Printing.LegendInfo> myLegendInfos = new List<ESRI.ArcGIS.Client.Printing.LegendInfo>();
            // Loop through all of the Layers in the Map Control.
            foreach (var myLayer in MyMap.Layers)
            {
                // Create a new LegendInfo object to put in the List<LegendInfo> collection.
                ESRI.ArcGIS.Client.Printing.LegendInfo myLegendInfo = new ESRI.ArcGIS.Client.Printing.LegendInfo();

                // Set the LegendInfo.LayerId to the Layer.ID to add it to the printed map's legend area.
                myLegendInfo.LayerId = myLayer.ID;

                //TODO: Add SubLayer IDs to LegendInfo
                var l = MyMap.Layers["MyDynamicService"] as ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer;
                List<int> legendLayerIntList = new List<int>();
                foreach (var s in l.Layers)
                {
                    if (s.ID == 0)
                    {
                        if (CapitalCities.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 1)
                    {
                        if (InterstateHighways.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 2)
                    {
                        if (Rivers.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 3)
                    {
                        if (Lakes.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                    else if (s.ID == 4)
                    {
                        if (StateBoundaries.IsChecked == true)
                        {
                            legendLayerIntList.Add(s.ID);
                        }
                    }
                }

                myLegendInfo.SubLayerIds = from x in legendLayerIntList
                                               select x as object;
                
                // Add a single LegendInfo into the List<LegendInfo> collection.
                myLegendInfos.Add(myLegendInfo);
            }
            // Set the LegendOptions.LegendInfo to the new constructed List<LegendInfo> objects.
            myLegendOptions.LegendInfos = myLegendInfos;
            // Set the LayoutOptions.LegendOptions to manage what the Legend looks like in the output map.
            myLayoutOptions.LegendOptions = myLegendOptions;

            PrintParameters printParameters = new PrintParameters(MyMap)
            {
                LayoutTemplate = (string)LayoutTemplates.SelectedItem,
                Format = (string)Formats.SelectedItem,
                CustomInputParameters = gpExtraInput
            };

            printParameters.LayoutOptions = myLayoutOptions;
            printTask.SubmitJobAsync(printParameters);
        }

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            CheckBox tickedCheckBox = sender as CheckBox;

            string serviceName = tickedCheckBox.Name;
            bool visible = (bool)tickedCheckBox.IsChecked;

            int layerIndex = (int)tickedCheckBox.Tag;

            ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer dynamicServiceLayer = MyMap.Layers[serviceName] as
                ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer;

            List<int> visibleLayerList =
                dynamicServiceLayer.VisibleLayers != null
                ? dynamicServiceLayer.VisibleLayers.ToList() : new List<int>();

            if (visible)
            {
                if (!visibleLayerList.Contains(layerIndex))
                    visibleLayerList.Add(layerIndex);
            }
            else
            {
                if (visibleLayerList.Contains(layerIndex))
                    visibleLayerList.Remove(layerIndex);
            }

            dynamicServiceLayer.VisibleLayers = visibleLayerList.ToArray();
        }

        public void ArcGISDynamicMapServiceLayer_Initialized(object sender, EventArgs e)
        {
            ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer dynamicServiceLayer =
                sender as ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer;
            if (dynamicServiceLayer.VisibleLayers == null)
                dynamicServiceLayer.VisibleLayers = GetDefaultVisibleLayers(dynamicServiceLayer);
        }

        private int[] GetDefaultVisibleLayers(ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer dynamicService)
        {
            List<int> visibleLayerIDList = new List<int>();

            ESRI.ArcGIS.Client.LayerInfo[] layerInfoArray = dynamicService.Layers;

            for (int index = 0; index < layerInfoArray.Length; index++)
            {
                if (layerInfoArray[index].DefaultVisibility)
                    visibleLayerIDList.Add(index);
            }
            return visibleLayerIDList.ToArray();
        }
    }
}

ArcGIS API for Flex 示例代码

如果您正在使用 ArcGIS API for Flex,那么请使用以下示例代码来构建 web 应用程序。

在下方的 ArcGIS API for Flex 代码示例中,将 URL 更改为您在之前步骤中所创建的地图服务和地理处理服务,以匹配服务器名称。以下各行将对其进行引用:

url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"/>
url="http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting"/>

AdvancedHighQualityPrinting.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"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:samples="IncludeFiles.*">
	
	<!--
	This sample also uses the following files:
	IncludeFiles/LayerTOC.mxml - a datagrid with checkboxes for every layer in the map service
	IncludeFiles/LayerVizRenderer.mxml - The datagrid itemrenderer (LayerVizRenderer) will update the map service as users selects/clears checkboxes.
	-->
	
	<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;

			private function printBtn_clickHandler(event:MouseEvent):void
			{
				myLegendLayer.subLayerIds = [];
				if (CapitalCities.selected)
				{				
					myLegendLayer.subLayerIds.push(0);					
				}				
				if (InterstateHighways.selected)					
				{					
					myLegendLayer.subLayerIds.push(1);					
				}				
				if (Rivers.selected)					
				{					
					myLegendLayer.subLayerIds.push(2);					
				}				
				if (Lakes.selected)					
				{					
					myLegendLayer.subLayerIds.push(3);					
				}				
				if (StateBoundaries.selected)					
				{					
					myLegendLayer.subLayerIds.push(4);					
				}		
				
				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="true"
						url="http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting"/>
		<esri:PrintParameters id="printParameters"
							  format="{formats.selectedItem}"
							  layoutTemplate="{layoutTemplates.selectedItem}"
							  map="{map}">
			<esri:customParameters>
				<fx:Object Georef_info="{Georef_info.selectedItem}"/>
			</esri:customParameters>
			<esri:layoutOptions>
				<esri:LayoutOptions title="My Map">
					<esri:legendOptions>
						<esri:LegendOptions>
							<esri:LegendLayer id="myLegendLayer" layerId="myDynamicService" />
						</esri:LegendOptions>
					</esri:legendOptions>
				</esri:LayoutOptions>
			</esri:layoutOptions>

		</esri:PrintParameters>
	</fx:Declarations>
	
	<s:controlBarLayout>
		<s:HorizontalLayout gap="10"
							paddingBottom="7"
							paddingLeft="10"
							paddingRight="10"
							paddingTop="7"
							verticalAlign="baseline"/>
	</s:controlBarLayout>
	<s:controlBarContent>
		<s:Label text="Layout Templates"/>
		<s:DropDownList id="layoutTemplates"
						width="175"
						dataProvider="{printTask.getServiceInfoLastResult.layoutTemplates}"/>
		
		<s:Label text="Formats"/>
		<s:DropDownList id="formats"
						width="100"
						dataProvider="{printTask.getServiceInfoLastResult.formats}"/>
		
		<s:Label text="Georef info?"/>
		<s:DropDownList id="Georef_info"
						width="100">		
			<s:dataProvider>
				<s:ArrayList source="[True,False]"/>
			</s:dataProvider>
		</s:DropDownList>
		
		<s:Button id="printBtn"
				  click="printBtn_clickHandler(event)"
				  enabled="{printTask.getServiceInfoLastResult != null}"
				  label="Export Map"/>
	</s:controlBarContent>
	
	
	<mx:HDividedBox x="164" width="867" height="100%">
		<esri:Map id="map" width="632" level="2" wrapAround180="true">
			<esri:ArcGISDynamicMapServiceLayer id="myDynamicService"
											   url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"/>
			<esri:extent>
				<esri:Extent id="myExtent" xmin="-2260000" ymin="-1500000" xmax="2250000" ymax="1220000"/>
			</esri:extent>
		</esri:Map>
		<samples:LayerTOC width="210" height="493"
						  mapLayer="{myDynamicService}"/>
		<s:VGroup>
		</s:VGroup>

	</mx:HDividedBox>
	<s:CheckBox id="CapitalCities" x="21" y="30" label="Capital Cities" selected="true"/>
	<s:CheckBox id="InterstateHighways" x="21" y="56" label="Interstate Highways" selected="true"/>
	<s:Label x="21" y="10" text="Include in Legend?"/>
	<s:CheckBox id="Rivers" x="21" y="82" label="Rivers" selected="true"/>
	<s:CheckBox id="Lakes" x="21" y="108" label="Lakes" selected="true"/>
	<s:CheckBox id="StateBoundaries" x="21" y="134" label="State Boundaries" selected="true"/>
</s:Application>

LayerTOC.mxml 代码:

<?xml version="1.0" encoding="utf-8"?>
<!-- Used by High Quality Printing mxml -->
<mx:DataGrid xmlns:fx="http://ns.adobe.com/mxml/2009"
             xmlns:mx="library://ns.adobe.com/flex/mx"
             width="100%" height="100%"
             resizableColumns="false"
             sortableColumns="false">

    <fx:Script>
        <![CDATA[
            import com.esri.ags.events.LayerEvent;
            import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;
            import com.esri.ags.layers.ArcIMSMapServiceLayer;
            import com.esri.ags.layers.Layer;
            import com.esri.ags.layers.supportClasses.LayerInfo;

            import mx.collections.ArrayList;
            import mx.collections.IList;
            import mx.utils.ObjectUtil;

            private var _layerInfos:Array;
            private var _layer:Layer;
            private var _layerChanged:Boolean;

            public function get mapLayer():Layer
            {
                return _layer;
            }

            public function set mapLayer(value:Layer):void
            {
                _layer = value;
                _layerChanged = true;
                invalidateProperties();
            }

            override protected function commitProperties():void
            {
                if (_layerChanged)
                {
                    _layerChanged = false;
                    if (mapLayer)
                    {
                        mapLayer.addEventListener(LayerEvent.UPDATE_END, removeBusyCursor, false, 0, true);
                        if (mapLayer.loaded)
                        {
                            setDataProvider();
                        }
                        else
                        {
                            mapLayer.addEventListener(LayerEvent.LOAD, layerLoadHandler, false, 0, true);
                        }
                    }
                }

                super.commitProperties();
            }

            private function setDataProvider():void
            {
                if (mapLayer is ArcGISDynamicMapServiceLayer)
                {
                    _layerInfos = ArcGISDynamicMapServiceLayer(mapLayer).layerInfos;
                }
                else if (mapLayer is ArcIMSMapServiceLayer)
                {
                    _layerInfos = ArcIMSMapServiceLayer(mapLayer).layerInfos;
                }

                if (_layerInfos)
                {
                    // make sure copy has typed LayerInfo objects
                    registerClassAlias("com.esri.ags.layers.supportClasses.LayerInfo", LayerInfo);
                    // create a copy since it'll be modified
                    _layerInfos = ObjectUtil.copy(_layerInfos) as Array;

                    // remove group layers and correct defaultVisibility
                    if (mapLayer is ArcGISDynamicMapServiceLayer)
                    {
                        var visibleLayers:Array = getDefaultVisibleLayers();
                        var layerInfos:Array = _layerInfos.concat(); // create a shallow clone
                        _layerInfos = [];
                        for each (var layerInfo:LayerInfo in layerInfos)
                        {
                            if (!layerInfo.subLayerIds) // skip group layers
                            {
                                layerInfo.defaultVisibility = visibleLayers.indexOf(layerInfo.layerId) != -1;
                                _layerInfos.push(layerInfo);
                            }
                        }
                    }

                    dataProvider = _layerInfos;
                }
            }

            private function getDefaultVisibleLayers():Array
            {
                var result:Array = [];

                for each (var layerInfo:LayerInfo in _layerInfos)
                {
                    if (layerInfo.parentLayerId >= 0 && result.indexOf(layerInfo.parentLayerId) == -1)
                    {
                        // layer is not visible if it's parent is not visible
                        continue;
                    }
                    if (layerInfo.defaultVisibility)
                    {
                        result.push(layerInfo.layerId);
                    }
                }

                return result;
            }

            private function layerLoadHandler(event:LayerEvent):void
            {
                setDataProvider();
            }

            public function showLayer(layerInfo:LayerInfo):void
            {
                var visibleLayers:IList;
                if (mapLayer is ArcGISDynamicMapServiceLayer)
                {
                    var dynamicLayer:ArcGISDynamicMapServiceLayer = mapLayer as ArcGISDynamicMapServiceLayer;
                    visibleLayers = dynamicLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        visibleLayers.addItem(layerInfo.layerId); // add id
                    }
                    else
                    {
                        visibleLayers = dynamicLayer.visibleLayers = getDynamicVisibleLayers();
                    }
                }
                else if (mapLayer is ArcIMSMapServiceLayer)
                {
                    var arcIMSLayer:ArcIMSMapServiceLayer = mapLayer as ArcIMSMapServiceLayer;
                    visibleLayers = arcIMSLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        visibleLayers.addItem(layerInfo.name); // add name
                    }
                    else
                    {
                        visibleLayers = arcIMSLayer.visibleLayers = getArcIMSVisibleLayers();
                    }
                }
                if (visibleLayers)
                {
                    cursorManager.setBusyCursor();
                }
            }

            public function hideLayer(layerInfo:LayerInfo):void
            {
                var visibleLayers:IList;
                if (mapLayer is ArcGISDynamicMapServiceLayer)
                {
                    var dynamicLayer:ArcGISDynamicMapServiceLayer = mapLayer as ArcGISDynamicMapServiceLayer;
                    visibleLayers = dynamicLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        var idIndex:int = visibleLayers.getItemIndex(layerInfo.layerId);
                        if (idIndex != -1)
                        {
                            visibleLayers.removeItemAt(idIndex);
                        }
                    }
                    else
                    {
                        visibleLayers = dynamicLayer.visibleLayers = getDynamicVisibleLayers();
                    }
                }
                else if (mapLayer is ArcIMSMapServiceLayer)
                {
                    var arcIMSLayer:ArcIMSMapServiceLayer = mapLayer as ArcIMSMapServiceLayer;
                    visibleLayers = arcIMSLayer.visibleLayers;
                    if (visibleLayers)
                    {
                        var nameIndex:int = visibleLayers.getItemIndex(layerInfo.name);
                        if (nameIndex != -1)
                        {
                            visibleLayers.removeItemAt(nameIndex);
                        }
                    }
                    else
                    {
                        visibleLayers = arcIMSLayer.visibleLayers = getArcIMSVisibleLayers();
                    }
                }
                if (visibleLayers)
                {
                    cursorManager.setBusyCursor();
                }
            }

            private function getDynamicVisibleLayers():IList
            {
                var result:ArrayList = new ArrayList();

                for each (var layerInfo:LayerInfo in _layerInfos)
                {
                    if (layerInfo.defaultVisibility)
                    {
                        result.addItem(layerInfo.layerId);
                    }
                }

                return result;
            }

            private function getArcIMSVisibleLayers():IList
            {
                var result:ArrayList = new ArrayList();

                for each (var layerInfo:LayerInfo in _layerInfos)
                {
                    if (layerInfo.defaultVisibility)
                    {
                        result.addItem(layerInfo.name);
                    }
                }

                return result;
            }

            private function removeBusyCursor(event:Event):void
            {
                cursorManager.removeBusyCursor();
            }
        ]]>
    </fx:Script>

    <mx:columns>
        <mx:DataGridColumn width="70"
                           headerText="Visibility"
                           itemRenderer="IncludeFiles.LayerVizRenderer"/>
        <mx:DataGridColumn dataField="name" headerText="Layer Name"/>
    </mx:columns>

</mx:DataGrid>

LayerVizRenderer.mxml 代码:

<?xml version="1.0" encoding="utf-8"?>
<!-- Used by LayerTOC.mxml -->
<s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import com.esri.ags.layers.supportClasses.LayerInfo;

            private function cb_clickHandler(event:MouseEvent):void
            {
                var layerInfo:LayerInfo = LayerInfo(data);

                if (cb.selected)
                {
                    layerInfo.defaultVisibility = true;
                    LayerTOC(dataGridListData.owner).showLayer(layerInfo);
                }
                else
                {
                    layerInfo.defaultVisibility = false;
                    LayerTOC(dataGridListData.owner).hideLayer(layerInfo);
                }
            }
        ]]>
    </fx:Script>

    <s:CheckBox id="cb"
                click="cb_clickHandler(event)"
                horizontalCenter="0"
                selected="{LayerInfo(data).defaultVisibility}"/>

</s:MXDataGridItemRenderer>

ArcGIS API for JavaScript 示例代码

如果您正在使用 ArcGIS API for JavaScript,那么请使用以下示例代码来构建 web 应用程序。

在下方的 ArcGIS API for JavaScript 代码示例中,将 URL 更改为您在之前步骤中所创建的地图服务和地理处理服务,以匹配服务器名称。以下各行将对其进行引用:

var dynUrl = "http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer";
var printUrl = "http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting";

AdvancedHighQualityPrinting.html 代码:

<!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,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/3.0/"></script>
    <script type="text/javascript" language="Javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.PrintTask");
      dojo.require("dijit.form.Button");
      dojo.require("dijit.form.CheckBox");      
      dojo.require("dijit.form.ComboBox");
      
      var layer, map, visible = [];
      var printTask, params;
      
      function init() {
        var startExtent = new esri.geometry.Extent({"xmin":-2260000,"ymin":-1500000,"xmax":2250000,"ymax":1220000,"spatialReference":{"wkid":102008}});
        map = new esri.Map("map", {extent:startExtent});
        
        var dynUrl = "http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer";
        layer = new esri.layers.ArcGISDynamicMapServiceLayer(dynUrl, { "id": "ConterminousUSA" });
        
        if (layer.loaded) { 
          buildLayerList(layer); 
        } 
        else { 
          dojo.connect(layer, "onLoad", buildLayerList); 
        }
        
        
		var printUrl = "http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting";
		printTask = new esri.tasks.PrintTask(printUrl, {async: true});
		params = new esri.tasks.PrintParameters();
        params.map = map;     
      }
      
      
      function buildLayerList(layer) { 
        var items = dojo.map(layer.layerInfos,function(info,index){ 
          if (info.defaultVisibility) { 
            visible.push(info.id); 
          } 
          return "<input type='checkbox' class='list_item' checked='" + (info.defaultVisibility ? "checked" : "") + "' id='" + info.id + "' onclick='updateLayerVisibility();' /><label for='" + info.id + "'>" + info.name + "</label>"; 
        }); 
 
        dojo.byId("layer_list").innerHTML = items.join(); 
 
        layer.setVisibleLayers(visible); 
        map.addLayer(layer); 
 
      } 
 
      function updateLayerVisibility() { 
        var inputs = dojo.query(".list_item"), input; 
     
        visible = []; 
 
        dojo.forEach(inputs,function(input){ 
          if (input.checked) { 
              visible.push(input.id); 
          } 
          }); 
        //if there aren't any layers visible set the array to be -1 
        if(visible.length === 0){ 
          visible.push(-1); 
        } 
        layer.setVisibleLayers(visible); 
      } 
      
      
      
      function print(){
        var layout = dojo.byId("layout");
        var index = layout.selectedIndex;
		var selectedValue_layout = layout.options[index].value;
		var format = dojo.byId("format");
        var index = format.selectedIndex;
		var selectedValue_format = format.options[index].value;
		var georef_info = dojo.byId("georef_info");
        var index = georef_info.selectedIndex;
		var selectedValue_georef_info = georef_info.options[index].value;
		
		var legendLayer = new esri.tasks.LegendLayer();
		legendLayer.layerId = "ConterminousUSA";
		legendLayer.subLayerIds = [];
		if (CapitalCities.checked == true)
      	{
      		legendLayer.subLayerIds.push(0);
      	}
		if (InterstateHighways.checked == true)
      	{
      		legendLayer.subLayerIds.push(1);
      	}
      	if (Rivers.checked == true)
      	{
      		legendLayer.subLayerIds.push(2);
      	}
      	if (Lakes.checked == true)
      	{
      		legendLayer.subLayerIds.push(3);
      	}
      	if (StateBoundaries.checked == true)
      	{
      		legendLayer.subLayerIds.push(4);
      	}
		
        params.template = {layout: selectedValue_layout, format: selectedValue_format, layoutOptions: {legendLayers:[legendLayer]}};
        params.extraParameters = {Georef_info: selectedValue_georef_info};
        printTask.execute(params, printComplete);
      }
      
      function printComplete(result){
        window.open(result.url);
      }

      dojo.addOnLoad(init);

    </script>

  </head>

  <body class="claro">
    <div id="map" style="width:1000px; height:600px; border:1px solid #000;"></div>
    <br />
    Layout Template: 
    <select id="layout" >
      	<OPTION value="CentralUSA">CentralUSA</OPTION> 
		<OPTION value="ConterminuousUSA">ConterminuousUSA</OPTION>     
		<OPTION value="NortheasternUSA">NortheasternUSA</OPTION>
		<OPTION value="NorthwesternUSA">NorthwesternUSA</OPTION>
		<OPTION value="SouthernUSA">SouthernUSA</OPTION>
		<OPTION value="SouthwesternUSA">SouthwesternUSA</OPTION>
    </select>
    &nbsp;&nbsp;Format:
    <select id="format">
      	<OPTION value="PDF">PDF</OPTION> 
		<OPTION value="PNG">PNG</OPTION>     
    </select>
    &nbsp;&nbsp;Include Georef info?
    <select id="georef_info">
      	<OPTION value="True">True</OPTION> 
		<OPTION value="False">False</OPTION>     
    </select>
    <br /><br />
    Table of Contents: <br /><span id="layer_list"></span>
    <br /><br />
    Include in Legend: <br />
    <label><input type="checkbox" name="CapitalCities" checked="checked">Capital Cities</label>
	<label><input type="checkbox" name="InterstateHighways" checked="checked">Interstate Highways</label>
	<label><input type="checkbox" name="Rivers" checked="checked">Rivers</label>
	<label><input type="checkbox" name="Lakes" checked="checked">Lakes</label>
	<label><input type="checkbox" name="StateBoundaries" checked="checked">State Boundaries</label>
	<br /><br />
	<input type="button" id="print" value="Print" onclick="print();"/>
  </body>
</html>

运行 web 应用程序

运行之前步骤中所创建的 web 应用程序。有关运行 web 应用程序的说明,如有必要,请参阅 ArcGIS web API 文档。以下是 ArcGIS for Silverlight web API 应用程序的屏幕截图。请注意,内容列表中的首都是关闭的。包含在图例中州界是关闭的。

已完成的 Silverlight web 应用程序

单击导出地图按钮,稍后会自动弹出输出文件。下图显示的是易于打印的输出 PDF 示例。请注意,在 web 应用程序的内容列表图例中的关闭图层则会显示在输出中。此外,PDF 使用在布局模板中分段的高质量矢量数据,而非服务图层的切片缓存图像。这样可以生成更高质量的制图输出。输出文件中还会包含在模板地图文档中分段的其他元素:图例、数据框和坐标系动态文本,以及比例尺。如果用户将 Georef info 参数选择为 True,那么输出 PDF 还将包含可使用“地理空间位置工具”在 Adobe Reader 中进行查看的地理配准信息。

输出 PDF

高级的高质量 web 地图打印/导出教程到此结束。有关基本 web 地图打印教程的详细信息,请参阅基本高质量 web 地图打印/导出教程

相关主题

9/15/2013