Tutorial: impresión/exportación avanzadas de mapas Web de alta calidad mediante arcpy.mapping

Complejidad: Avanzado Requisito de datos: Instalado con el software

La siguiente ilustración muestra un ejemplo de aplicación de API Web de ArcGIS que va a crear. En la aplicación Web, el usuario final podrá:

Aplicación web

De forma predeterminada, la exportación desde una aplicación Web utilizando el servicio de Herramientas de impresión y sus widgets de impresión de cliente en las API Web de ArcGIS genera una imagen en caché de las capas de servicio, que puede tener una resolución demasiado baja (por ejemplo, 96 dpi) para impresiones a gran formato o salidas cartográficas de alta calidad. En este tutorial se le enseña, en lugar de ello, a generar un documento apto para su impresión que contiene una salida de vectores de alta calidad para capas de servicio.

A continuación figura un ejemplo de salida en PDF. Tenga en cuenta que las capas que se hayan desactivado en la Tabla de contenido y en la Leyenda, en la aplicación Web, se reflejarán en la salida.

PDF resultante

El código que subyace al botón Exportar mapa utiliza la tarea Imprimir de las API Web de ArcGIS, disponible con ArcGIS 10.1 for Desktop. En este tutorial también se enseñará a transmitir parámetros extra a la tarea Imprimir; por ejemplo, si exportar o no información de georreferenciación al archivo PDF de salida. La posibilidad de transmitir parámetros adicionales a la tarea Imprimir es de utilidad porque permite recopilar cualquier número de parámetros adicionales desde la aplicación Web. También creará una secuencia de comandos de Python que se publicará como servicio de geoprocesamiento que usará la tarea Imprimir. La secuencia de comandos de Python utiliza la función ConvertWebMapToMapDocument del módulo arcpy.mapping, que insertará el estado completo del mapa Web en un documento de mapa de plantilla presentado. Presentará varias plantillas entre las que podrá elegir el usuario. Cada plantilla contiene equivalentes en vectores de todas las capas posibles en el servicio de mapas. Las plantillas presentadas también pueden contener otros elementos, como una leyenda, texto dinámico, etc. El módulo arcpy.mapping también ofrece funciones para identificar capas de servicio y cambiarlas por capas que apunten a datos locales, así como para exportar a distintos formatos; por ejemplo, PDF.

Para completar este tutorial, debe estar familiarizado con el módulo arcpy.mapping, las API Web de ArcGIS, ArcGIS for Desktop y ArcGIS 10.1 for Server. En este tutorial se incluyen ejemplos de código de todas las API Web de ArcGIS. También debe familiarizarse con la impresión en los temas de ayuda de la aplicación Web:

Imprimir en aplicaciones WebOpciones avanzadas para imprimir mapas Web

En este tutorial se utilizan las carpetas MapTemplates y TemplateData del directorio de instalación de ArcGIS for Desktop, que suele estar en C:\Program Files (x86)\ArcGIS\Desktop10.1. En este tutorial se da por supuesto que las plantillas de mapa y los datos de plantilla están presentes y no se han modificado. Si no es el caso, tal vez deba volver a instalar ArcGIS for Desktop.

Copiar los datos del tutorial

Copiará algunas de las plantillas de mapa del directorio de instalación de ArcGIS for Desktop a una nueva carpeta. Estas plantillas se acabarán utilizando como plantillas de mapa presentadas en la aplicación Web.

Antes de hacerlo, debe asegurarse de que haya una estructura de carpetas en la que ArcGIS for Server pueda ver los documentos de mapa de plantilla y los datos que se usarán en la aplicación Web. En este tutorial se da por supuesto que tiene una carpeta registrada con ArcGIS for Server. Para obtener más información sobre cómo registrar los datos con ArcGIS for Server, consulte:

SugerenciaSugerencia:

Cuando utilice documentos de mapa de plantilla en la función ConvertWebMapToMapDocument, lo más recomendable es usar datos que estén registrados con ArcGIS for Server. Si opta por no usar datos registrados, los documentos de mapa de plantilla y los datos se empaquetarán y copiarán en el servidor. Durante el empaquetamiento, los datos pueden moverse y asignarse con rutas relativas hasta una estructura de carpetas que ConvertWebMapToMapDocument no puede resolver. Para obtener más información, consulte el tema de ayuda ConvertWebMapToMapDocument.

Pasos:
  1. Abra una nueva sesión vacía de ArcMap.
  2. En la ventana Catálogo, desplácese hasta la carpeta registrada. Cree una nueva carpeta en la carpeta registrada llamada USA.
  3. En la ventana Catálogo, desplácese hasta la carpeta MapTemplates, en el directorio de instalación de ArcGIS for Desktop. Suele encontrarse en C:\Program Files (x86)\ArcGIS\Desktop10.1\MapTemplates. Siga desplazándose hasta la carpeta Traditional Layouts\USA.
  4. En la ventana Catálogo, copie y pegue los siguientes archivos en la carpeta USA que creó en el paso anterior: CentralUSA.mxd, ConterminousUSA.mxd, NortheasternUSA.mxd, NorthwesternUSA.mxd, SouthernUSA.mxd y SouthwesternUSA.mxd.
    Carpeta MapTemplates
  5. En la ventana Catálogo, desplácese hasta la carpeta TemplateData, en el directorio de instalación de ArcGIS for Desktop. Suele encontrarse en C:\Program Files (x86)\ArcGIS\Desktop10.1\TemplateData.
  6. En la ventana Catálogo, copie y pegue TemplateData.gdb en la carpeta USA que creó en un paso anterior.
    Carpeta TemplateData
  7. La carpeta registrada debe tener un aspecto similar al siguiente:
    Carpeta registrada
    NotaNota:

    En la captura de pantalla anterior, la carpeta registrada se llama MyDataStore. La carpeta registrada puede tener el nombre que desee.

Prepare los documentos de mapa que usar como plantillas en la aplicación Web.

Los documentos de mapa deben prepararse para su uso como plantillas en ConvertWebMapToMapDocument.

Los documentos de mapa que están ahora en la carpeta registrada deben asignarse a TemplateData.gdb, que también está en la carpeta registrada. Esto puede hacerse a través de la interfaz de usuario de ArcMap o con una secuencia de comandos de Python. Se utilizará el segundo método.

NotaNota:

Si estaba creando desde cero sus propias plantillas de documento de mapa en la carpeta registrada, estos pasos no serán necesarios.

Pasos:
  1. Abra la ventana de Python en ArcMap.
  2. Copie y pegue la siguiente secuencia de comandos en la ventana de 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. En la ventana de Python, cambie la variable folderPath para que sea la ruta hasta la carpeta registrada en la que residen los MXD de la plantilla. Recuerde usar barras inclinadas (/) en la ruta.
  5. En la ventana de Python, cambie la variable newPath para que sea la ubicación de TemplateData.gdb en la carpeta registrada. Recuerde usar barras inclinadas (/) en la ruta.
  6. La secuencia de comandos debe tener este aspecto:
  7. Coloque el cursor a la derecha de la última línea. Pulse la tecla Intro dos veces para ejecutar la secuencia de comandos. Espere a que la secuencia de comandos se ejecute.

Los documentos de mapa ya están listos para ser utilizados como plantillas en la aplicación Web.

Crear un servicio de mapa que utilizar en la aplicación Web

Para poder usarse en la aplicación Web, un documento de mapa debe prepararse y publicarse como servicio de mapa. Se utilizará ConterminousUSA.mxd, en la carpeta registrada, como servicio de mapa. Antes de publicarlo en el servidor, debe prepararlo para la publicación.

Pasos:
  1. Abra ConterminousUSA.mxd en ArcMap.
  2. De forma predeterminada, el mapa se abrirá en vista de diseño. Cambie a la vista de datos seleccionando Vista > Vista de datos en el menú principal de ArcMap.
  3. Ahora desactivará el grupo de anotaciones de mapa en este documento de mapa. Este mapa contiene gráficos de mapa. Los gráficos de mapa aumentan la huella de memoria de un documento cargado, lo que produce una degradación del rendimiento. Debido a estos efectos secundarios, los gráficos de mapa no son compatibles con los servicios de mapas.
    1. Abra las propiedades del marco de datos Conterminous United States haciendo clic con el botón derecho en el nombre del marco de datos, en la tabla de contenido, y haciendo clic en Propiedades.
    2. Haga clic en la ficha Grupos de anotaciones.
    3. Desmarque el grupo <Predeterminado>. La pestaña Grupos de Anotación debe tener ahora este aspecto:
      Pestaña Grupos de Anotación
    4. Haga clic en Aceptar en el cuadro de diálogo Propiedades del marco de datos.
  4. Este mapa utiliza capas de mapa base. Las capas de mapa base no se publicarán en ArcGIS for Server. Moverá las capas fuera de la capa de mapa base desagrupando esta.
    1. Haga clic con el botón derecho en la capa de mapa base, en la tabla de contenido, y haga clic en Desagrupar.
    NotaNota:

    Si estaba creando desde cero sus propias plantillas de documento de mapa o estaba usando plantillas existentes de documento de mapa que no contuvieran gráficos de mapa o capas de mapa base, estos pasos no serán necesarios.

    El mapa ya está listo para publicarse en el servidor. Si no está familiarizado con el proceso de publicación, revise cómo publicar un servicio.

  5. Haga clic en Archivo > Compartir como > Servicio.
  6. Haga clic en Publicar un servicio.
  7. Haga clic en Siguiente.
  8. Elija una conexión de publicación o administración con el equipo de ArcGIS 10.1 for Server.
  9. Haga clic en Siguiente.
  10. Cree una nueva carpeta llamada USA.
  11. Haga clic en Continuar.
  12. En la esquina superior derecha del Editor de servicios, haga clic en Publicar.

Con esto se creará el servicio de mapa que se usará en la aplicación Web.

Crear la secuencia de comandos de Python

Creará una secuencia de comandos de Python que se usará como servicio de geoprocesamiento personalizado.

La secuencia de comandos de Python en el servicio de geoprocesamiento personalizado ejecuta la función ConvertWebMapToMapDocument, que convierte un mapa Web (en formato JSON) que pretenda imprimir o exportar a un documento de mapa. A continuación, la secuencia de comandos arcpy.mapping recorre todas las capas del documento de mapa de salida, eliminando todas las capas excepto las de vectores que se correspondan con las capas de servicio en el JSON del mapa Web. A continuación, recorre todas las capas de la leyenda, eliminando todas las leyendas excepto las capas de vectores que se correspondan con las capas de servicio en la leyenda del JSON del mapa Web. La secuencia de comandos también leerá parámetros adicionales desde la tarea de impresión personalizada; en este caso, si exportar o no información de georreferenciación al archivo PDF de salida. A continuación, el documento de mapa puede exportarse al formato que elija; por ejemplo, PDF.

Pasos:
  1. Abra cualquier IDE de Python, como IDLE (que viene con ArcGIS for Desktop).
  2. Copie y pegue el siguiente código en una nueva secuencia de comandos de 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. Cambie la variable templatePath para que sea la ruta UNC hasta la carpeta de la carpeta registrada que contiene los documentos de mapa de la plantilla.
  5. NotaNota:

    Si ArcGIS for Server, ArcGIS for Desktop y la carpeta registrada están en el mismo equipo, las rutas UNC hasta la carpeta registrada no serán necesarias. En lugar de ello, pueden usarse rutas absolutas.

  6. Guarde la secuencia de comandos de Python. Dé a la secuencia de comandos el nombre AdvancedHighQualityPrinting.py. Guárdelo en una carpeta llamada WebApp dentro de la carpeta registrada.

La secuencia de comandos de Python ya está lista para agregarse a una caja de herramientas.

Cree la caja de herramientas

Pasos:
  1. En la ventana Catálogo, en ArcMap, desplácese hasta la carpeta WebApp, en la carpeta registrada.
  2. Haga clic con el botón derecho en la carpeta WebApp y haga clic en Nuevo > Caja de herramientas. Dé a la caja de herramientas el nombre AdvancedHighQualityPrinting.
  3. Haga clic con el botón derecho en la caja de herramientas AdvancedHighQualityPrinting y haga clic en Descripción del elemento.
  4. En el cuadro de diálogo Descripción del elemento, rellene los elementos Etiquetas y Resumen con el texto que elija. Si lo desea, rellene las demás descripciones del elemento.
  5. Haga clic en Guardar y salga del cuadro de diálogo Descripción del elemento.

Crear una herramienta de secuencia de comandos de Python

A continuación, agregará la secuencia de comandos AdvancedHighQualityPrinting.py a la caja de herramientas AdvancedHighQualityPrinting.

Pasos:
  1. En la ventana Catálogo, haga clic con el botón derecho en la caja de herramientas AdvancedHighQualityPrinting y haga clic en Agregar > Secuencia de comandos.
  2. En el cuadro de diálogo Agregar secuencia de comandos, escriba AdvancedHighQualityPrinting en Nombre y en Etiqueta.
  3. Haga clic en Siguiente.
  4. Para el valor de Archivo de secuencia de comandos, desplácese hasta la carpeta WebApp, en la carpeta registrada, y seleccione AdvancedHighQualityPrinting.py.
  5. En el cuadro de diálogo Agregar secuencia de comandos, haga clic en Siguiente.
  6. Se deben añadir cinco parámetros a la herramienta de secuencia de comandos.
    1. El primer parámetro será Web_Map_as_JSON. Este parámetro toma una representación JSON del estado del mapa que se va a exportar tal y como aparece en la aplicación Web. Las propiedades deben coincidir con la siguiente captura de pantalla:
      Parámetro Web_Map_as_JSON
    2. El siguiente parámetro será Format: el formato en el que se presentará la imagen de mapa para imprimir. Las propiedades deben coincidir con la siguiente captura de pantalla:
      Parámetro Format
    3. El siguiente parámetro será Layout_Template: el documento de mapa de plantilla que se utilizará. Las propiedades deben coincidir con la siguiente captura de pantalla:
      Parámetro Layout_Template
    4. El siguiente parámetro será Georef_info: una cadena booleana de caracteres que permite exportar información del sistema de coordenadas al archivo PDF de salida. Las propiedades deben coincidir con la siguiente captura de pantalla:
      Parámetro Georef_info
    5. El siguiente parámetro será Output_File: el archivo de salida que se creará. Las propiedades deben coincidir con la siguiente captura de pantalla:
      Parámetro Output_File

      PrecauciónPrecaución:

      Los nombres de parámetro Web_Map_as_JSON, Format, Layout_Template y Output_File deben escribirse exactamente como se muestra, para que coincidan con la firma de la herramienta de la tarea Imprimir en las API Web de ArcGIS. Para obtener más información sobre los parámetros, consulte Exportar mapa Web. El parámetro Georef_info es un parámetro adicional que se transmitirá a la tarea Imprimir y, por lo tanto, no tiene que adecuarse a ninguna convención de nomenclatura.

    6. En el cuadro de diálogo Agregar secuencia de comandos, haga clic en Finalizar.
  7. Haga clic con el botón derecho en la herramienta de secuencia de comandos AdvancedHighQualityPrinting y haga clic en Descripción del elemento.
  8. En el cuadro de diálogo Descripción del elemento, rellene los elementos Etiquetas y Resumen con el texto que elija. Además, rellene el campo Explicación del cuadro de diálogo de los cinco parámetros que hay en la sección Sintaxis del cuadro de diálogo Descripción del elemento. Si lo desea, rellene las demás descripciones del elemento.

Ejecutar la herramienta

La herramienta debe ejecutarse correctamente para poder crear un resultado en la ventana Resultados que pueda publicarse en ArcGIS for Server. Esto sirve para ilustrar un problema interesante con las secuencias de comandos de prueba que utilizan ConvertWebMapToMapDocument. Para ejecutarse localmente, necesita un JSON de mapa Web válido. No obstante, las API Web de ArcGIS ofrecen el JSON de mapa Web en la aplicación Web, aunque solo después de que se haya publicado la secuencia de comandos. Para solventar esto, puede usar el JSON de prueba que se encuentra en el tema de ayuda ConvertWebMapToMapDocument. Además, puede modificar el JSON para que contenga elementos que espera la herramienta y que serán similares a los del JSON que obtendrá de la aplicación Web. En este tutorial, el usuario de la aplicación Web va a activar y desactivar capas de servicio en el mapa, además de en la leyenda. Por tanto, deberá usarse una cadena de caracteres JSON de mapa Web de prueba como esta:

{
    "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
                    ]
                }
            ]
        }
    }
}

Observe que el elemento visibleLayers tiene la capa 1 desactivada. Esto significa que la capa uno del servicio de mapa no estará presente en la salida. Observe también los subLayerIDs en legendOptions. En la leyenda solo estarán las capas 0, 2 y 5. Esto es similar al JSON que devolverá la aplicación Web. Para obtener más información, consulte las Especificaciones del JSON de mapa Web.

Cuando se está ejecutando la herramienta de secuencia de comandos, la cadena de caracteres JSON puede copiarse y pegarse en el parámetro de entrada Web_Map_as_JSON. Sin embargo, es necesario eliminar los saltos de línea para que la cadena de caracteres sea una entrada válida. La cadena de caracteres JSON con los saltos de línea eliminados se muestra a continuación:

{"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]}]}}}

También debe cambiar el nombre del servidor (MyServer:6080, más arriba) por el de su servidor de ArcGIS for Server.

SugerenciaSugerencia:

A efectos de publicación, puede optar por dejar el parámetro de entrada Web_Map_as_JSON en blanco, ya que las API Web de ArcGIS proporcionarán el JSON de mapa Web en la aplicación Web. Puede dejar el parámetro de entrada Web_Map_as_JSON en blanco siempre que la secuencia de comandos de Python se haya escrito de tal forma que no provoque errores si se queda en blanco. Por ejemplo, la secuencia de comandos no busca capas del mapa Web por nombre. Si la secuencia de comandos provoca un fallo en el servidor debido a un error, tendrá que arreglarse localmente y, a continuación, volverse a publicar en el servidor. Por lo tanto, es aconsejable asegurarse de que la secuencia de comandos funcione localmente antes de publicarla, probando con una cadena de caracteres JSON de mapa Web válida o usando un documento de mapa de depuración que contenga todos los elementos que habría en el JSON de mapa Web. En este tutorial, facilitaremos una cadena de caracteres JSON válida.

Pasos:
  1. En la ventana Catálogo, haga clic con el botón derecho en la herramienta de secuencia de comandos AdvancedHighQualityPrinting y haga clic en Abrir.
  2. Para el parámetro de entrada Web_Map_as_JSON, copie y pegue la cadena de caracteres JSON con los saltos de línea eliminados desde el bloque de código de una sola línea que figura más arriba en el parámetro Web_Map_as_JSON. No olvide cambiar el nombre del servidor para que coincida con el suyo. El cuadro de diálogo de la herramienta de secuencia de comandos AdvancedHighQualityPrinting debe tener este aspecto:
    Cuadro de diálogo de la herramienta de secuencia de comandos AdvancedHighQualityPrinting
  3. Acepte todos los valores predeterminados de los demás parámetros y haga clic en Aceptar.
  4. Abra la ventana Resultados.
  5. Haga doble clic en Output_File, resaltado a continuación, para ver el PDF de salida.
    Cuadro de diálogo Resultados

    De esta manera se abrirá el PDF. Tal y como se especifica en el JSON de mapa Web, el PDF debe tener la capa uno desactivada en el mapa, y solo las capas 0, 2 y 5 activadas en la leyenda.

Publique el resultado

El resultado ya está listo para publicarse como servicio de geoprocesamiento. Si no está familiarizado con la publicación de los servicios de geoprocesamiento, consulte:

Pasos:
  1. En la ventana Resultados, haga clic con el botón derecho en el resultado AdvancedHighQualityPrinting y haga clic en Compartir como > Servicio de geoprocesamiento.
  2. Haga clic en Publicar un servicio.
  3. Haga clic en Siguiente.
  4. Elija una conexión de publicación o administración con el equipo de ArcGIS 10.1 for Server.
  5. Haga clic en Siguiente.
  6. Utilice la carpeta existente llamada USA.
  7. Haga clic en Continuar.
  8. En la esquina superior derecha del Editor de servicios, haga clic en Publicar.
  9. Después de la correcta publicación de la herramienta de secuencias de comandos, es aconsejable probar el servicio de geoprocesamiento en ArcMap utilizando una conexión de servidor SIG a ArcGIS for Server. Puede ver el resultado del servicio de geoprocesamiento en la ventana Resultados de geoprocesamiento.

El servicio de geoprocesamiento ya está listo para utilizarse en las API Web de ArcGIS.

Elija qué API Web de ArcGIS desea usar para crear la aplicación Web.

Las API Web de ArcGIS ofrecen una funcionalidad SIG similar; es decir, puede elegir la plataforma para desarrollador que prefiera. Cada API proporciona los recursos que necesita. Lea la referencia de API; consulte las muestras de trabajo que le ayudan a comenzar y le muestran todas las posibilidades, y comuníquese con otros usuarios a través de los foros, blogs y galerías de códigos. Escapa al ámbito de este tutorial entrar en detalles sobre cómo crear aplicaciones Web con cada API. Consulte la documentación de la API para ello. Para obtener más información, consulte:

Cada API Web de ArcGIS tiene una tarea Imprimir. La tarea Imprimir tiene una propiedad URL que hará referencia al servicio de geoprocesamiento personalizado que creó anteriormente. Consulte la documentación de la API Web de ArcGIS para obtener más información sobre la tarea Imprimir.

En las secciones siguientes, use los códigos de ejemplo correspondientes a la API Web de ArcGIS en la que trabaje para crear su aplicación Web.

Código de ejemplo de ArcGIS API for Silverlight

Si está usando ArcGIS API for Silverlight, use el siguiente código de ejemplo para crear su aplicación Web.

En los siguientes códigos de ejemplo de ArcGIS API for Silverlight, cambie la URL al servicio de mapa y servicio de geoprocesamiento que creó en los pasos anteriores para que coincida con el nombre de su servidor. Se mencionan en estas líneas:

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

Código 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ódigo subyacente en 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();
        }
    }
}

Código de ejemplo de ArcGIS API for Flex

Si está usando ArcGIS API for Flex, use el siguiente código de ejemplo para crear su aplicación Web.

En los siguientes códigos de ejemplo de ArcGIS API for Flex, cambie la URL al servicio de mapa y servicio de geoprocesamiento que creó en los pasos anteriores para que coincida con el nombre de su servidor. Se mencionan en estas líneas:

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

Código para 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>

Código para 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>

Código para 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>

Código de ejemplo de ArcGIS API for JavaScript

Si está usando ArcGIS API for JavaScript, use el siguiente código de ejemplo para crear su aplicación Web.

En el siguiente código de ejemplo de ArcGIS API for JavaScript, cambie la URL al servicio de mapa y servicio de geoprocesamiento que creó en los pasos anteriores para que coincida con el nombre de su servidor. Se mencionan en estas líneas:

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

Código para 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>

Ejecutar la aplicación Web

Ejecute la aplicación Web que creó en el paso anterior. Consulte la documentación de la API Web de ArcGIS para obtener instrucciones sobre cómo ejecutar las aplicaciones Web, si es necesario. A continuación figura una captura de pantalla de la aplicación de la API Web de ArcGIS for Silverlight. Observe que Capital Cities está desactivada en la Tabla de contenido. Observe además que State Boundaries está desactivada en Incluir en la leyenda.

Aplicación Web Silverlight completada

Poco después de hacer clic en el botón Exportar mapa, aparecerá automáticamente un archivo de salida. La siguiente ilustración muestra un ejemplo de PDF de salida apto para su impresión. Observe que las capas que se habían desactivado en la Tabla de contenido y en Incluir en la leyenda, en la aplicación Web, se reflejan en la salida. Además, el PDF utiliza datos de vector de alta calidad que se presentaron en las plantillas de diseño, en lugar de imágenes de caché en teselas de las capas de servicio. Esto genera una salida cartográfica de mayor calidad. El archivo de salida también contendrá otros elementos que se presentaron en los documentos de mapa de plantilla: una leyenda, marco de datos, texto dinámico del sistema de coordenadas y una barra de escala. Si el usuario seleccionó el parámetro Georef info para que fuera True, el PDF de salida también contendrá información de georreferenciación, que puede verse en Adobe Reader utilizando la herramienta de localización geoespacial.

PDF resultante

Aquí concluye el tutorial de impresión/exportación avanzadas de mapas Web de alta calidad. Para ver un tutorial de impresión básica de mapas Web, consulte el tutorial de impresión/exportación básicas de mapas Web de alta calidad.

Temas relacionados

9/12/2013