Lernprogramm: Erweitertes Drucken/Exportieren von Webkarten mit arcpy.mapping

Komplexität: Experten Datenanforderung: Installiert mit Software

Die folgende Abbildung zeigt ein Beispiel für eine ArcGIS-Web-API-Anwendung, die Sie erstellen. In der Webanwendung hat der Endbenutzer folgende Möglichkeiten:

Webanwendung

Im Folgenden finden Sie ein Beispiel für eine ausgegebene PDF. Beachten Sie, dass deaktivierte Layer im Inhaltsverzeichnis und in der Legende der Webanwendung in der Ausgabe wirksam werden.

Ausgabe-PDF

Der Code hinter der Schaltfläche Karte exportieren verwendet den Druck-Task der ArcGIS-Web-API, die ab ArcGIS 10.1 for Desktop und ArcGIS 10.1 for Server verfügbar ist. In diesem Lernprogramm wird außerdem dargestellt, wie zusätzliche Parameter im Druck-Task übergeben werden, um beispielsweise Georeferenzierungsinformationen in die Ausgabe-PDF-Datei zu exportieren oder nicht. Die Möglichkeit, zusätzliche Parameter an den Druck-Task zu übergeben ist hilfreich, da Sie eine beliebige Anzahl gesonderter Parameter aus der Webanwendung zusammenstellen können. Zudem erstellen Sie ein Python-Skript, das als Georeferenzierungs-Service veröffentlicht und vom Druck-Task verwendet wird. Das Python-Skript verwendet die Funktion ConvertWebMapToMapDocument im arcpy.mapping-Modul, das den vollständigen Status der Webkarte in ein bereitgestelltes Vorlagenkartendokument einfügt. Sie werden mehrere Vorlagen bereitstellen, die dem Benutzer zur Auswahl stehen. Jede Vorlage enthält Vektoren, die mit allen möglichen Layern im Karten-Service äquivalent sind. Die bereitgestellte Vorlage kann außerdem andere Elemente wie eine Legende, dynamischen Text usw. enthalten. Das Modul arcpy.mapping bietet auch Funktionen, um Service-Layer zu identifizieren, sie gegen Layer auszutauschen, die auf lokale Daten verweisen, und um sie in eine Vielzahl von Formaten, wie beispielsweise PDF, zu exportieren.

Um dieses Lernprogramm abzuschließen, sollten Sie mit dem Modul arcpy.mapping, den ArcGIS-Web-APIs, ArcGIS for Desktop und ArcGIS for Server vertraut sein. Beispielcode für alle ArcGIS-Web-APIs sind in diesem Lernprogramm enthalten. Sie sollten außerdem mit den Hilfethemen zum Drucken in der Webanwendung vertraut sein:

Drucken in WebanwendungenErweiterte Druckfunktionen für Webkarten

Dieses Lernprogramm verwendet die Ordner MapTemplates und TemplateData im Installationsverzeichnis von ArcGIS for Desktop, das sich in der Regel unter C:\Program Files (x86)\ArcGIS\Desktop10.2 befindet. In diesem Lernprogramm wird davon ausgegangen, dass die Kartenvorlagen und Vorlagendaten vorhanden sind und nicht geändert wurden. In diesem Fall müssen Sie ArcGIS for Desktop möglicherweise neu installieren.

Kopieren der Lernprogrammdaten

Sie werden einige Kartenvorlagen im Installationsverzeichnis von ArcGIS for Desktop in einen neuen Ordner kopieren. Diese werden schließlich als bereitgestellte Kartenvorlagen in der Webanwendung verwendet.

Zuvor müssen Sie jedoch sicherstellen, dass eine Ordnerstruktur vorhanden ist, bei der ArcGIS for Server die Kartenvorlagendokumente und -daten erkennen kann, die in der Webanwendung verwendet werden. In diesem Lernprogramm wird vorausgesetzt, dass Sie über einen Ordner verfügen, der bei ArcGIS for Server registriert ist. Weitere Informationen zum Registrieren von Daten mit ArcGIS for Server finden Sie unter:

TippTipp:

Bei Verwendung von Vorlagenkartendokumenten in der Funktion ConvertWebMapToMapDocument wird empfohlen, die Daten zu verwenden, die bei ArcGIS for Server registriert sind. Falls Sie keine registrierten Daten verwenden möchten, werden die Vorlagenkartendokumente und -daten gepackt und auf den Server kopiert. Während des Packens werden Daten möglicherweise verschoben und verweisen mit relativen Pfaden auf eine Ordnerstruktur, die ConvertWebMapToMapDocument nicht auflösen kann. Weitere Informationen finden Sie im Hilfethema ConvertWebMapToMapDocument.

Schritte:
  1. Öffnen Sie eine neue, leere ArcMap-Sitzung.
  2. Navigieren Sie im Fenster Katalog zu dem registrierten Ordner. Erstellen Sie in dem registrierten Ordner namens USA einen neuen Ordner.
  3. Navigieren Sie im Fenster Katalog zum Ordner MapTemplates im ArcGIS for Desktop-Installationsverzeichnis. Dieser befindet sich in der Regel unter C:\Program Files (x86)\ArcGIS\Desktop10.2\MapTemplates. Navigieren Sie in der Struktur weiter nach unten zum Ordner Traditional Layouts\USA.
  4. Kopieren Sie im Fenster Katalog die folgenden Dateien und fügen Sie sie in den Ordner USA ein, den Sie im vorherigen Schritt erstellt haben: CentralUSA.mxd, ConterminousUSA.mxd, NortheasternUSA.mxd, NorthwesternUSA.mxd, SouthernUSA.mxd und SouthwesternUSA.mxd.
    Der Ordner "MapTemplates"
  5. Navigieren Sie im Fenster Katalog zum Ordner TemplateData im ArcGIS for Desktop-Installationsverzeichnis. Dieser befindet sich in der Regel unter C:\Program Files (x86)\ArcGIS\Desktop10.2\TemplateData.
  6. Kopieren Sie im Fenster Katalog TemplateData.gdb, und fügen Sie das Element in den Ordner USA ein, den Sie im vorherigen Schritt erstellt haben.
    Der Ordner "TemplateData"
  7. Der registrierte Ordner sieht in etwa wie folgt aus:
    Registrierter Ordner
    HinweisHinweis:

    Im Sreenshot oben lautet der Name des registrierten Ordners MyDataStore. Der registrierte Ordner kann einen beliebigen Namen haben.

Bereiten Sie die Kartendokumente vor, um sie als Vorlagen in der Webanwendung zu verwenden.

Die Kartendokumente müssen für die Verwendung als Vorlagen in ConvertWebMapToMapDocument vorbereitet werden.

Die Kartendokumente, die sich nun im registrierten Ordner befinden, müssen auf das Element TemplateData.gdb verweisen, das sich ebenfalls im registrierten Ordner befindet. Dies kann über die Benutzeroberfläche von ArcMap oder über ein Python-Skript erfolgen. Die letztere Methode kommt zur Anwendung.

HinweisHinweis:

Wenn Sie eigene Kartendokumentvorlagen in dem registrierten Ordner von Grund auf erstellt haben, müssen diese Schritte nicht ausgeführt werden.

Schritte:
  1. Öffnen Sie das Python-Fenster in ArcMap.
  2. Kopieren Sie das folgenden Skript und fügen Sie es in das Python-Fenster ein:
  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. Ändern Sie im Python-Fenster die Variable folderPath in den Pfad zu dem registrierten Ordner, der die MXDs enthält. Denken Sie daran, den Schrägstrich (/) in Ihrem Pfad zu verwenden.
  5. Ändern Sie im Python-Fenster die Variable newPath in den Speicherort von TemplateData.gdb in dem registrierten Ordner. Denken Sie daran, den Schrägstrich (/) in Ihrem Pfad zu verwenden.
  6. Das Skript sieht in etwa wie folgt aus:
  7. Positionieren Sie den Cursor rechts neben die letzte Zeile. Drücken Sie zweimal die EINGABETASTE, um das Skript auszuführen. Warten Sie, bis das Skript ausgeführt wird.

Die Kartendokumente können nun als Vorlagen in der Webanwendung verwendet werden.

Erstellen eines in der Webanwendung zu verwendenden Karten-Service

Ein Kartendokument muss als Karten-Service vorbereitet und veröffentlicht werden, um in der Webanwendung verwendet werden zu können. ConterminousUSA.mxd im registrierten Ordner wird als Karten-Service verwendet. Bevor Sie das Dokument auf dem Server veröffentlichen, müssen Sie es für die Veröffentlichung vorbereiten.

Schritte:
  1. Öffnen Sie ConterminousUSA.mxd in ArcMap.
  2. Die Karte wird standardmäßig in der Layout-Ansicht geöffnet. Wechseln Sie zur Ansicht Datenansicht, indem Sie im Hauptmenü von ArcMap Ansicht > Datenansicht auswählen.
  3. Deaktivieren Sie jetzt die Annotationsgruppe der Karte in diesem Kartendokument. Diese Karte enthält Kartengrafiken. Kartengrafiken erhöhen den Speicher-Footprint eines geladenen Dokuments, wodurch die Performance sinkt. Aufgrund dieser Auswirkungen werden Kartengrafiken in Karten-Services nicht unterstützt.
    1. Öffnen Sie die Datenrahmeneigenschaften Conterminous United States, indem Sie mit der rechten Maustaste auf den Namen des Datenrahmens und dann auf Eigenschaften klicken.
    2. Klicken Sie auf die Registerkarte Annotationsgruppen.
    3. Deaktivieren Sie die Gruppe <Standard>. Die Registerkarte Annotationsgruppen sieht in etwa so aus:
      Die Registerkarte "Annotationsgruppen"
    4. Klicken Sie im Dialogfeld Eigenschaften: Datenrahmen auf OK.
  4. Diese Karte verwendet Grundkarten-Layer. Grundkarten-Layer werden in ArcGIS for Server nicht veröffentlicht. Sie verschieben die Layer aus dem Grundkarten-Layer, indem Sie deren Gruppierung aufheben.
    1. Klicken Sie im Inhaltsverzeichnis mit der rechten Maustaste auf den Grundkarten-Layer, und klicken Sie dann auf Gruppierung aufheben.
    HinweisHinweis:

    Wenn Sie eigene Kartendokumentvorlagen in dem registrierten Ordner von Grund auf erstellt oder vorhandene Kartendokumentvorlagen verwendet haben, die keine Kartengrafiken oder Grundkarten-Layer enthielten, müssen diese Schritte nicht ausgeführt werden.

    Die Karte kann nun auf dem Server veröffentlicht werden. Falls Sie nicht mit Veröffentlichungsverfahren vertraut sind, lesen Sie den Abschnitt So veröffentlichen Sie einen Service.

  5. Klicken Sie auf Datei > Freigeben als > Service.
  6. Klicken Sie auf Service veröffentlichen.
  7. Klicken Sie auf Weiter.
  8. Wählen Sie eine Veröffentlichungs- oder Admin-Verbindung zu Ihrem ArcGIS for Server-Computer aus.
  9. Klicken Sie auf Weiter.
  10. Erstellen Sie einen neuen Ordner mit dem Namen USA.
  11. Klicken Sie auf Fortfahren.
  12. Klicken Sie oben rechts im Dialogfeld Service-Editor auf Veröffentlichen.

Dabei wird der Karten-Service erstellt, der in der Webanwendung verwendet wird.

Erstellen des Python-Skripts

Sie erstellen ein Python-Skript, das als benutzerdefinierter Geoverarbeitungs-Service verwendet wird.

Das Python-Skript in dem benutzerdefinierten Geoverarbeitungs-Service führt die Funktion ConvertWebMapToMapDocument aus, die eine Webkarte (im JSON.Format) konvertiert, um sie zu drucken oder in ein Kartendokument zu exportieren. Das Skript "arcpy.mapping" durchläuft alle Layer im Ausgabe-Kartendokument, wobei alle Layer, mit Ausnahme der Vektor-Layer, die den Service-Layern im Webkarten-JSON entsprechen, entfernt werden. Anschließend werden alle Layer in der Legende durchlaufen, wobei alle Layer der Legende, mit Ausnahme der Vektor-Layer, die den Service-Layern im Webkarten-JSON entsprechen, entfernt werden. In diesem Fall liest das Skript auch zusätzliche Parameter aus dem benutzerdefinierten Druck-Task, unabhängig davon, ob Georeferenzierungsinformationen in die Ausgabe-PDF-Datei exportiert werden sollen oder nicht. Das Kartendokument kann dann in das Format Ihrer Wahl, beispielsweise PDF, exportiert werden.

Schritte:
  1. Öffnen Sie eine beliebige Python-IDE, wie beispielsweise IDLE (die von ArcGIS for Desktop bereitgestellt wird).
  2. Kopieren Sie den folgenden Code und fügen Sie ihn in ein neues Python-Skript ein.
  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. Ändern Sie die Variable templatePath in den UNC-Pfad zu dem Ordner in Ihrem registrierten Ordner, der die Vorlagenkartendokumente enthält.
  5. HinweisHinweis:

    Wenn sich ArcGIS for Server, ArcGIS for Desktop und die registrierten Ordner alle auf demselben Computer befinden, sind keine UNS-Pfade zu den registrierten Ordnern erforderlich. Stattdessen können absolute Pfade verwendet werden.

  6. Speichern Sie das Python-Skript. Geben Sie dem Skript den Namen AdvancedHighQualityPrinting.py. Speichern Sie es in einem Ordner mit der Bezeichnung WebApp in dem registrierten Ordner.

Das Python-Skript kann nun einer Toolbox hinzugefügt werden.

Erstellen der Toolbox

Schritte:
  1. Navigieren Sie im Fenster Katalog in ArcMap zum Ordner WebApp in dem registrierten Ordner.
  2. Klicken Sie mit der rechten Maustaste auf den Ordner WebApp, und klicken Sie auf Neu > Toolbox. Geben Sie der Toolbox den Namen AdvancedHighQualityPrinting.py.
  3. Klicken Sie mit der rechten Maustaste auf die Toolbox AdvancedHighQualityPrinting, und klicken Sie auf Elementbeschreibung.
  4. Füllen Sie im Dialogfeld Elementbeschreibung die Elemente Tags und Zusammenfassung mit Text Ihrer Wahl aus. Sie können auch andere Elementbeschreibungen eingeben.
  5. Klicken Sie auf Speichern, und beenden Sie das Dialogfeld Elementbeschreibung.

Erstellen des Python-Skript-Werkzeugs

Als nächstes fügen Sie der Toolbox AdvancedHighQualityPrinting das Skript AdvancedHighQualityPrinting.py hinzu.

Schritte:
  1. Klicken Sie im Fenster Katalog mit der rechten Maustaste auf die Toolbox AdvancedHighQualityPrinting, und klicken Sie auf Hinzufügen > Skript.
  2. Geben Sie im Dialogfeld Skript hinzufügen AdvancedHighQualityPrinting für Name und Beschriftung ein.
  3. Klicken Sie auf Weiter.
  4. Navigieren Sie für die Skriptdatei zum Ordner WebApp in Ihrem registrierten Ordner, und wählen Sie AdvancedHighQualityPrinting.py.
  5. Klicken Sie im Dialogfeld Skript hinzufügen auf Weiter.
  6. Dem Skriptwerkzeug müssen fünf Parameter hinzugefügt werden.
    1. Die erste Parameter lautet Web Map as JSON. Dieser Parameter nimmt eine JSON-Darstellung des Status der zu exportierenden Karte an, wie er in der Webanwendung angezeigt wird. Die Eigenschaften entsprechen in etwa dem folgenden Screenshot:
      Der Parameter "Web_Map_as_JSON"
    2. Der nächste Parameter lautet Format – Das Format, in dem das Karten-Image zum Drucken bereitgestellt wird. Die Eigenschaften entsprechen in etwa dem folgenden Screenshot:
      Der Parameter "Format"
    3. Der nächste Parameter lautet Layout_Template – Das verwendete Vorlagenkartendokument. Die Eigenschaften entsprechen in etwa dem folgenden Screenshot:
      Der Parameter "Layout_Template"
    4. Der nächste Parameter lautet Georef_info – Eine boolesche Zeichenfolge, die den Export von Koordinateninformationen für die Ausgabe-PDF-Datei ermöglicht. Die Eigenschaften entsprechen in etwa dem folgenden Screenshot:
      Der Parameter "Georef_info"
    5. Der nächste Parameter lautet Output_File – Das Ausgabedatei, die erstellt wird. Die Eigenschaften entsprechen in etwa dem folgenden Screenshot:
      Der Parameter "Output_File"

      AchtungAchtung:

      Die Parameternamen Web_Map_as_JSON, Format, Layout_Template und Output_File müssen genauso buchstabiert sein wie angezeigt, damit sie mit der Werkzeugsignatur des Druck-Task in den ArcGIS-Web-APIs übereinstimmen. Weitere Informationen zu Parametern finden Sie unter Webkarte exportieren. Der Parameter Georef_info ist ein zusätzlicher Parameter, der an den Druck-Task übergeben wird und daher keiner Namenskonvention entsprechen muss.

    6. Klicken Sie im Dialogfeld Skript hinzufügen auf Fertig stellen.
  7. Klicken Sie mit der rechten Maustaste auf das Skriptwerkzeug AdvancedHighQualityPrinting, und klicken Sie auf Elementbeschreibung.
  8. Füllen Sie im Dialogfeld Elementbeschreibung die Elemente Tags und Zusammenfassung mit Text Ihrer Wahl aus. Füllen Sie außerdem die Dialogerklärung für alle fünf Parameter im Abschnitt Syntax des Dialogfeldes Elementbeschreibung aus. Sie können auch andere Elementbeschreibungen eingeben.

Ausführen des Werkzeugs

Das Werkzeug muss erfolgreich ausgeführt werden, um ein Ergebnis im Fenster Ergebnisse zu erstellen, das in ArcGIS for Server veröffentlicht werden kann. Dies weist auf ein interessantes Problem hin, das bei Testskripten auftritt, die ConvertWebMapToMapDocument verwenden. Für eine lokale Ausführung wird ein gültiges Webkarten-JSON benötigt. Die ArcGIS-Web-APIs stellen das Webkarten-JSON jedoch in der Webanwendung bereit, allerdings erst nachdem, das Skript veröffentlicht wurde. Um dies zu umgehen, können Sie das Test-JSON im Hilfethema ConvertWebMapToMapDocument verwenden. Außerdem können Sie das JSON so ändern, dass es Elemente enthält, die das Werkzeug erwartet und die dem von der Webanwendung bereitgestellten JSON ähneln. In diesem Lernprogramm aktiviert/deaktiviert der Benutzer der Webanwendung Service-Layer in der Karte und aktiviert/deaktiviert auch Layer in der Legende. Daher sollte in etwa die folgende JSON-Zeichenfolge für die Test-Webkarte verwendet werden:

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

Beachten Sie, dass der Layer 1 des Elements visibleLayers deaktiviert ist. Dies bedeutet, dass Layer 1 des Karten-Service nicht in der Ausgabe vorhanden ist. Beachten Sie außerdem die subLayerIDs in den legendOptions. In der Legende sind nur die Layer 0, 2 und 5 aktiviert. Dies ist mit dem von der Webanwendung zurückgegebenen JSON vergleichbar. Weitere Informationen finden Sie unter WebMap-JSON-Spezifikationen.

Wenn das Skriptwerkzeug ausgeführt wird, kann die JSON-Zeichenfolge kopiert und in den Eingabeparameter Web_Map_as_JSON eingefügt werden. Die Zeilenumbrüche müssen jedoch entfernt werden, damit die Zeichenfolge eine gültige Eingabe ist. Die JSON-Zeichenfolge, bei der die Zeilenumbrüche entfernt wurden, finden Sie unten:

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

Sie müssen auch den Namen des Servers (MyServer:6080, siehe oben) in den Namen Ihres ArcGIS for Server-Servers ändern.

TippTipp:

Zu Veröffentlichungszwecken können Sie festlegen, ob der Eingabeparameter Web_Map_as_JSON leer bleibt, da die ArcGIS-Web-APIs den Webkarten-JSON in der Webanwendung bereitstellen. Sie können den Eingabeparameter Web_Map_as_JSON leer lassen, vorausgesetzt, das Python-Skript wurde so geschrieben, dass leere Eingaben nicht zu Fehlern führen. Das Skript sucht beispielsweise Webkarten-Layer nicht nach Name. Wenn das Skript aufgrund eines Fehlers im Skript auf dem Server fehlschlägt, muss es lokal repariert und dann erneut auf dem Server veröffentlicht werden. Daher wird empfohlen, vor dem Veröffentlichen sicherzustellen, dass das Skript lokal funktioniert, indem ein Test mit einer gültigen JSON-Zeichenfolge für Webkarten oder mit einem Kartendokument zum Debuggen ausgeführt wird, das alle Elemente eines Webkarten-JSON enthält. Für dieses Lernprogramm wird eine gültige JSON-Zeichenfolge bereitgestellt.

Schritte:
  1. Klicken Sie im Fenster Katalog mit der rechten Maustaste auf das Skriptwerkzeug AdvancedHighQualityPrinting, und klicken Sie auf Öffnen.
  2. Kopieren Sie für den Eingabeparameter Web_Map_as_JSON die JSON-Zeichenfolge mit den entfernten Zeilenumbrüchen aus dem einzeiligen Codeblock oben, und fügen Sie sie in den Parameter Web_Map_as_JSON ein. Denken Sie daran, den Namen des Servers so zu ändern, dass er mit dem Ihres Servers übereinstimmt. Das Skriptwerkzeug-Dialogfeld AdvancedHighQualityPrinting sieht in etwa wie folgt aus:
    Das Skriptwerkzeug-Dialogfeld "AdvancedHighQualityPrinting"
  3. Übernehmen Sie alle Standardwerte für die anderen Parameter, und klicken Sie auf OK.
  4. Öffnen Sie das Ergebnisse-Fenster.
  5. Doppelklicken Sie auf das unten hervorgehobene Element Output_File, um die Ausgabe-Datei anzuzeigen.
    Das Dialogfeld "Ergebnisse"

    Dadurch wird die PDF geöffnet. Wie im Webkarten-JSON angegeben, muss in der PDF Layer 1 der Karte deaktiviert sein und in der Legende dürfen nur die Layer 0, 2 und 5 aktiviert sein.

Veröffentlichen des Ergebnisses

Das Ergebnis kann nun als Geoverarbeitungs-Service veröffentlicht werden. Wenn Sie nicht mit dem Veröffentlichen von Geoverarbeitungs-Services vertraut sind, finden Sie weitere Informationen unter:

Schritte:
  1. Klicken Sie im Ergebnisse -Fenster mit der rechten Maustaste auf das Ergebnis AdvancedHighQualityPrinting, und klicken Sie dann auf Freigeben als > Geoverarbeitungs-Service.
  2. Klicken Sie auf Service veröffentlichen.
  3. Klicken Sie auf Weiter.
  4. Wählen Sie eine Veröffentlichungs- oder Admin-Verbindung zu Ihrem ArcGIS for Server-Computer aus.
  5. Klicken Sie auf Weiter.
  6. Verwenden Sie den vorhandenen Ordner namens USA.
  7. Klicken Sie auf Fortfahren.
  8. Klicken Sie oben rechts im Dialogfeld Service-Editor auf Veröffentlichen.
  9. Nachdem sich die Veröffentlichung mit dem Skriptwerkzeug als erfolgreich herausgestellt hat, wird empfohlen, den Geoverarbeitungs-Service mithilfe einer GIS-Serververbindung zu ArcGIS for Server in ArcMap zu testen. Das Ergebnis des Geoverarbeitungs-Service wird im Fenster für Geoverarbeitungsergebnisse angezeigt.

Der Geoverarbeitungs-Service kann nun in den ArcGIS-Web-APIs verwendet werden.

Legen Sie fest, welche ArcGIS-Web-API zum Erstellen der Webanwendung verwendet werden soll.

Die ArcGIS-Web-APIs bieten ähnliche GIS-Funktionen, Sie können jedoch Ihre bevorzugte Entwicklerplattform auswählen. Jede API umfasst die erforderlichen Ressourcen. Lesen Sie die API-Referenz, sehen Sie sich Praxisbeispiele an, die Ihnen den Einstieg erleichtern und die Möglichkeiten zeigen, und treten Sie mit anderen über die Foren, Blogs und Code-Galerien in Kontakt. Eine detaillierte Darlegung der ersten Schritte zum Erstellen von Webanwendungen mit den einzelnen APIs ist nicht Thema dieses Lernprogramms. Weitere Informationen hierzu finden Sie in der API-Dokumentation. Weitere Informationen finden Sie unter:

Jede ArcGIS-Web-API verfügt über einen Druck-Task. Der Druck-Task weist eine URL-Eigenschaft auf, die den benutzerdefinierten Geoverarbeitungs-Service referenziert, den Sie zuvor erstellt haben. Weitere Informationen zum Druck-Task finden Sie in der ArcGIS-Web-API-Dokumentation.

Verwenden Sie in den folgenden Abschnitten die Codebeispiele für die ArcGIS-Web-API, die Sie zum Erstellen der Webanwendung verwenden.

Beispielcode für ArcGIS API for Silverlight

Wenn Sie ArcGIS API for Silverlight verwenden, erstellen Sie die Webanwendung mit dem folgenden Codebeispiel.

Ändern Sie im folgenden Codebeispiel für ArcGIS API for Silverlight die URL zu dem zuvor erstellten Karten-Service und Geoverarbeitungs-Service so, dass sie dem Servernamen entspricht. Sie werden in diesen Zeilen referenziert:

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

XAML-Code:

<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>

CodeBehind in 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();
        }
    }
}

Beispielcode für ArcGIS API for Flex

Wenn Sie ArcGIS API for Flex verwenden, erstellen Sie die Webanwendung mit dem folgenden Codebeispiel.

Ändern Sie im folgenden Codebeispiel für ArcGIS API for Flex die URL zu dem zuvor erstellten Karten-Service und Geoverarbeitungs-Service so, dass sie dem Servernamen entspricht. Sie werden in diesen Zeilen referenziert:

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

Code für 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>

Code für 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>

Code für 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>

Beispielcode für ArcGIS API for JavaScript

Wenn Sie ArcGIS API for JavaScript verwenden, erstellen Sie die Webanwendung mit dem folgenden Codebeispiel.

Ändern Sie im folgenden Codebeispiel für ArcGIS API for JavaScript die URL zu dem zuvor erstellten Karten-Service und Geoverarbeitungs-Service so, dass sie dem Servernamen entspricht. Sie werden in diesen Zeilen referenziert:

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

Code für 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>

Ausführen der Webanwendung

Führen Sie die Webanwendung aus, die Sie im vorherigen Schritt erstellt haben. Anweisungen zur Ausführung von Webanwendungen finden Sie bei Bedarf in der ArcGIS-Web-API-Dokumentation. Im Folgenden finden Sie einen Screenshot der ArcGIS for Silverlight-Web-API-Anwendung. Beachten Sie, dass Capital Cities im Table of Contents deaktiviert sind. Beachten Sie auch, dass State Boundaries in Include in Legend deaktiviert ist.

Abgeschlossene Silverlight-Anwendung

Nachdem Sie auf die Schaltfläche Karte exportieren geklickt haben, wird kurz darauf automatisch ein Popup-Fenster angezeigt. In der Abbildung unten wird ein Beispiel für eine druckerfreundliche Ausgabe-PDF gezeigt. Beachten Sie, dass deaktivierte Layer im Table of Contents und in der Include in Legend der Webanwendung in der Ausgabe wirksam werden. Zudem verwendet die PDF Vektordaten, die in den Layout-Vorlagen bereitgestellt wurden, anstelle eines Bildes mit Service-Layern. Die Ausgabedatei enthält außerdem andere Elemente, die in den Vorlagenkartendokumenten bereitgestellt wurden: eine Legende, einen Datenrahmen und dynamischen Text für Koordinatensysteme sowie eine Maßstabsleiste. Wenn der Benutzer den Parameter Georef info auf True festgelegt hat, enthält die Ausgabe-PDF ebenfalls Georeferenzierungsinformationen, die mit dem Werkzeug für räumliche Positionen in Adobe Reader angezeigt werden können.

Ausgabe-PDF

Damit ist das Lernprogramm für erweitertes Drucken/Exportieren von Webkarten mit arcpy.mapping abgeschlossen. Ein Lernprogramm mit Grundlagen zum Webkartendruck finden Sie unter Lernprogramm für grundlegendes Drucken/Exportieren von Webkarten.

Verwandte Themen

6/13/2014