Didacticiel : impression/exportation avancée de cartes Web avec arcpy.mapping

Complexité : Avancé Exigences en matière de données : Installé avec le logiciel

L'illustration ci-dessous montre une application API Web ArcGIS d'exemple que vous allez créer. Dans l'application Web, l'utilisateur final pourra :

Application Web 

Vous trouverez un exemple de fichier PDF en sortie ci-dessous. Notez que les couches qui étaient désactivées dans la table des matières et dans la légende de l'application Web sont reflétées dans la sortie.

PDF en sortie

Le code sous-jacent au bouton Exporter la carte utilise la tâche d'impression des API Web ArcGIS qui sont disponibles dans ArcGIS 10.1 for Desktop et ArcGIS 10.1 for Server. Ce didacticiel vous montrera également comment transmettre des paramètres supplémentaires à la tâche d'impression, par exemple pour exporter ou non des informations de géoréférencement dans le fichier PDF en sortie. La possibilité de transmettre des paramètres supplémentaires à la tâche d'impression est utile, car elle vous permet de collecter n'importe quel nombre de paramètres supplémentaires à partir de l'application Web. Vous allez également créer un script Python qui sera publié en tant que service de géotraitement que la tâche d'impression utilisera. Le script Python utilise la fonction ConvertWebMapToMapDocument du module arcpy.mapping qui insérera l'état complet de la carte Web dans le document ArcMap de modèle intermédiaire. Vous allez créer plusieurs modèles intermédiaires parmi lesquels l'utilisateur pourra choisir. Chaque modèle contient des équivalents vectoriels de toutes les couches possibles dans le service de carte. Les modèles intermédiaires peuvent également contenir d'autres éléments, tels qu'une légende, un texte dynamique, etc. Le module arcpy.mapping offre par ailleurs des fonctionnalités visant à identifier les couches de service afin de les échanger contre des couches pointant vers des données locales et à exporter vers différents formats, par exemple PDF.

Pour suivre ce didacticiel, vous devez connaître le module arcpy.mapping, les API Web ArcGIS, ArcGIS for Desktop et ArcGIS for Server. Un code d'exemple pour toutes les API Web d'ArcGIS est inclus dans ce didacticiel. Vous devez également connaître les rubriques d'aide sur l'impression dans l'application Web :

Impression dans les applications WebImpression avancée de cartes Web

Ce didacticiel utilise les dossiers MapTemplates et TemplateData du répertoire d'installation d'ArcGIS for Desktop qui se trouve généralement à l'emplacement suivant : C:\Program Files (x86)\ArcGIS\Desktop10.2. Ce didacticiel suppose la présence des modèles de carte et des données de modèle et qu'ils n'ont pas été modifiés. Si ce n'est pas le cas, il est possible que vous deviez réinstaller ArcGIS for Desktop.

Copie des données du didacticiel

Vous allez copier certains des modèles de carte du répertoire d'installation d'ArcGIS for Desktop dans un nouveau dossier. Ils pourront être utilisés comme modèles de carte intermédiaires dans l'application Web.

Avant cela, vous devez vous assurer qu'une structure de dossiers est en place, dans laquelle ArcGIS for Server peut voir les documents ArcMap modèles et les données qui seront utilisés dans l'application Web. Ce didacticiel part du principe que vous avez déjà inscrit un dossier auprès d'ArcGIS for Server. Pour plus d'informations sur l'inscription de données auprès d'ArcGIS for Server, reportez-vous à la rubrique :

AstuceAstuce:

Lorsque vous utilisez des documents ArcMap modèles dans la fonction ConvertWebMapToMapDocument, il est recommandé d'utiliser des données inscrites auprès d'ArcGIS for Server. Si vous choisissez de ne pas utiliser les données inscrites, les documents ArcMap de modèle et les données seront empaquetés et copiés sur le serveur. Au cours de l'empaquetage, les données peuvent être déplacées et redirigées avec les chemins relatifs vers une structure de dossiers que ConvertWebMapToMapDocument ne peut pas résoudre. Pour plus d'informations, reportez-vous à la rubrique d'aide ConvertWebMapToMapDocument.

Etapes :
  1. Ouvrez une nouvelle session ArcMap vierge.
  2. Dans la fenêtre Catalogue, accédez à votre dossier inscrit. Créez un dossier dans votre dossier inscrit nommé USA.
  3. Dans la fenêtre Catalogue, accédez au dossier MapTemplates du dossier d'installation d'ArcGIS for Desktop. Il se trouve généralement à l'emplacement suivant : C:\Program Files (x86)\ArcGIS\Desktop10.2\MapTemplates. Accédez ensuite au dossier Traditional Layouts\USA.
  4. Dans la fenêtre Catalogue, copiez et collez les fichiers suivants dans le dossier USA que vous avez créé dans une étape précédente : CentralUSA.mxd, ConterminousUSA.mxd, NortheasternUSA.mxd, NorthwesternUSA.mxd, SouthernUSA.mxd et SouthwesternUSA.mxd.
    Dossier MapTemplates
  5. Dans la fenêtre Catalogue, accédez au dossier TemplateData du dossier d'installation d'ArcGIS for Desktop. Il se trouve généralement à l'emplacement suivant : C:\Program Files (x86)\ArcGIS\Desktop10.2\TemplateData.
  6. Dans la fenêtre Catalogue, copiez et collez TemplateData.gdb dans le dossier USA que vous avez créé dans une étape précédente.
    Dossier MapTemplates
  7. Le dossier inscrit doit être semblable à celui-ci :
    Dossier inscrit
    RemarqueRemarque :

    Dans la capture d'écran ci-dessus, le dossier inscrit s'appelle MyDataStore. Vous pouvez changer le nom du dossier inscrit comme il vous plaît.

Préparer les documents ArcMap pour les utiliser comme modèles dans l'application Web

Les documents ArcMap doivent être préparés à être utilisés comme modèles dans ConvertWebMapToMapDocument.

Les documents ArcMap qui sont maintenant dans le dossier inscrit doivent être redirigés vers TemplateData.gdb, qui se trouve également dans le dossier inscrit. Pour ce faire, vous pouvez utiliser l'interface utilisateur ArcMap ou un script Python. La dernière approche sera utilisée.

RemarqueRemarque :

Si vous étiez en train de créer entièrement vos propres modèles de carte dans le dossier inscrit, ces étapes ne seraient pas nécessaires.

Etapes :
  1. Ouvrez la fenêtre Python dans ArcMap.
  2. Copiez et collez le script suivant dans la fenêtre 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. Dans la fenêtre Python, changez la variable folderPath pour qu'elle corresponde au chemin d'accès au dossier inscrit dans lequel se trouve les modèles de carte (MXD). N'oubliez pas d'utiliser la barre oblique (/) dans le chemin d'accès.
  5. Dans la fenêtre Python, changez la variable newPath pour qu'elle corresponde à l'emplacement de TemplateData.gdb dans le dossier inscrit. N'oubliez pas d'utiliser la barre oblique (/) dans le chemin d'accès.
  6. Le script doit ressembler à ce qui suit :
  7. Placez le curseur à droite de la dernière ligne. Appuyez deux fois sur la touche Entrée pour exécuter le script. Attendez que le script s'exécute.

Les documents ArcMap sont maintenant prêts à être utilisés comme modèles dans l'application Web.

Créer un service de carte à utiliser dans l'application Web

Un document ArcMap doit être préparé et publié en tant que service de carte pour être utilisé dans l'application Web. ConterminousUSA.mxd dans le dossier inscrit sera utilisé comme service de carte. Avant de le publier sur votre serveur, vous devez le préparer à la publication.

Etapes :
  1. Ouvrez ConterminousUSA.mxd dans ArcMap.
  2. Par défaut, la carte s'ouvre en mode Mise en page. Passez en mode Données en sélectionnant Affichage > Mode Données dans le menu principal ArcMap.
  3. Vous allez maintenant désactiver le groupe d’annotations cartographiques dans ce document ArcMap. Cette carte contient des graphiques de carte. Les éléments graphiques de la carte augmentent l'impact sur la mémoire d'un document chargé, entraînant ainsi une dégradation des performances. En raison de ces effets secondaires, les éléments graphiques de la carte ne sont pas pris en charge dans les services de carte.
    1. Ouvrez les propriétés du bloc de données Etats limitrophes des Etats-Unis en cliquant avec le bouton droit de la souris sur le nom du bloc de données dans la table des matières, puis en sélectionnant Propriétés.
    2. Cliquez sur l'onglet Groupes d'annotations.
    3. Décochez le groupe <Par défaut>. L'onglet Groupe d'annotations doit maintenant ressembler à ceci :
      Onglet Groupe d'annotations
    4. Cliquez sur OK dans la boîte de dialogue Propriétés du bloc de données.
  4. Cette carte utilise des couches de fond de carte. Il est impossible de publier des couches de fond de carte dans ArcGIS for Server. Vous allez retirer les couches de la couche de fond de carte en les dissociant.
    1. Dans la table des matières, cliquez sur la couche de fond de carte avec le bouton droit de la souris, puis cliquez sur Dissocier.
    RemarqueRemarque :

    Si vous étiez en train de créer entièrement vos propres modèles de carte ou d'utiliser des modèles de document ArcMap existants ne contenant aucun graphique de carte ou couche de fond de carte, ces étapes ne seraient pas nécessaires.

    La carte est maintenant prête à être publiée sur votre serveur. Si vous ne connaissez pas la procédure de publication, suivez les instructions de la rubrique Procédure de publication d'un service.

  5. Cliquez sur Fichier > Partager en tant que > Service.
  6. Cliquez sur Publier un service.
  7. Cliquez sur Suivant.
  8. Choisissez une connexion d'éditeur ou d'administrateur sur l'ordinateur sur lequel est installé ArcGIS for Server.
  9. Cliquez sur Suivant.
  10. Créez un dossier nommé USA.
  11. Cliquez sur Continuer.
  12. En haut à droite de la boîte de dialogue Editeur de services, cliquez sur Publier.

Cette opération a pour effet de créer un service de carte qui sera utilisé dans l'application Web.

Créer le script Python

Vous allez créer un script Python qui sera utilisé en tant que service de géotraitement personnalisé.

Le script Python dans le service de géotraitement personnalisé exécute la fonction ConvertWebMapToMapDocument qui convertit une carte Web (au format JSON) que vous prévoyez d'imprimer ou d'exporter vers un document ArcMap. Le script arcpy.mapping parcourt ensuite toutes les couches du document ArcMap en sortie, en supprimant toutes les couches à l'exception des couches vectorielles qui correspondent aux couches de service dans la carte Web au format JSON. Il parcourt ensuite toutes les couches de la légende, en supprimant toutes les couches de légende à l'exception des couches vectorielles qui correspondent aux couches de service dans la légende de la carte Web au format JSON. Le script lit également les paramètres supplémentaires à partir de la tâche d'impression personnalisée, dans ce cas pour exporter ou non des informations de géoréférencement dans le fichier PDF en sortie. Le document ArcMap peut ensuite être exporté au format de votre choix, par exemple au format PDF.

Etapes :
  1. Ouvrez un IDE Python, tel qu'IDLE (livré avec ArcGIS for Desktop).
  2. Copiez et collez le code suivant dans un nouveau script 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. Changez la variable templatePath pour qu'elle corresponde au chemin UNC du dossier dans votre dossier inscrit qui contient les documents ArcMap de modèle.
  5. RemarqueRemarque :

    Si ArcGIS for Server, ArcGIS for Desktop et le dossier inscrit se trouvent tous sur la même machine, les chemins UNC du dossier inscrit ne sont pas nécessaires. Vous pouvez en revanche utiliser des chemins absolus.

  6. Enregistrez le script Python. Nommez le script AdvancedHighQualityPrinting.py. Enregistrez-le dans un dossier nommé WebApp au sein du dossier inscrit.

Le script Python est maintenant prêt à être ajouté à une boîte à outils.

Créez la boîte à outils

Etapes :
  1. Dans la fenêtre Catalogue d'ArcMap, accédez au dossier WebApp dans le dossier inscrit.
  2. Cliquez avec le bouton droit sur le dossier WebApp et cliquez sur Nouveau > Boîte à outils. Nommez la boîte à outils AdvancedHighQualityPrinting.
  3. Cliquez avec le bouton droit sur la boîte à outils AdvancedHighQualityPrinting, puis cliquez sur Description d'élément.
  4. Dans la boîte de dialogue Description d'élément, renseignez les éléments Balises et Résumé avec le texte de votre choix. Vous pouvez également indiquer d'autres descriptions d'éléments.
  5. Cliquez sur Enregistrer et quittez la boîte de dialogue Description d'élément.

Créer un outil Python

Vous allez ensuite ajouter le script AdvancedHighQualityPrinting.py à la boîte à outils AdvancedHighQualityPrinting.

Etapes :
  1. Dans la fenêtre Catalogue, cliquez avec le bouton droit sur la boîte à outils AdvancedHighQualityPrinting et sélectionnez Ajouter > Script.
  2. Dans la boîte de dialogue Ajouter un script, entrez AdvancedHighQualityPrinting à la fois dans Nom et dans Etiquette.
  3. Cliquez sur Suivant.
  4. Pour Fichier script, accédez au dossier WebApp dans votre dossier inscrit et sélectionnez AdvancedHighQualityPrinting.py.
  5. Cliquez sur Suivant dans la boîte de dialogue Ajouter un script.
  6. Vous devez ajouter cinq paramètres à l'outil de script.
    1. Le premier paramètre sera Web_Map_as_JSON. Ce paramètre utilise une représentation JSON de l'état de la carte à exporter telle qu'elle apparaît dans l'application Web. Les propriétés doivent correspondre à la capture d'écran suivante :
      Paramètre Web_Map_as_JSON
    2. Le paramètre suivant sera Format, c'est-à-dire le format dans lequel l'image cartographique à imprimer sera proposée. Les propriétés doivent correspondre à la capture d'écran suivante :
      Paramètre Format
    3. Le paramètre suivant sera Layout_Template, c'est-à-dire le document ArcMap de modèle qui sera utilisé. Les propriétés doivent correspondre à la capture d'écran suivante :
      Paramètre Layout_Template
    4. Le prochain paramètre sera Georef_info, une chaîne booléenne qui permet d'exporter les informations du système de coordonnées dans le fichier PDF en sortie. Les propriétés doivent correspondre à la capture d'écran suivante :
      Paramètre Georef_info
    5. Le paramètre suivant sera Output_File, c'est-à-dire le fichier en sortie qui sera créé. Les propriétés doivent correspondre à la capture d'écran suivante :
      Paramètre Output_File

      AttentionAttention :

      Les noms des paramètres Web_Map_as_JSON, Format, Layout_Template et Output_File doivent être orthographiés exactement comme illustré, afin qu'ils correspondent à la signature d'outil de la tâche d'impression dans les API Web d'ArcGIS. Pour en savoir plus sur les paramètres, reportez-vous à la rubrique Exporter Web Map. Le paramètre Georef_info est un paramètre supplémentaire qui sera transmis à la tâche d'impression. Il n'a par conséquent besoin de se conformer à aucune convention d'affectation de noms.

    6. Cliquez sur Terminer dans la boîte de dialogue Ajouter un script.
  7. Cliquez avec le bouton droit sur l'outil de script AdvancedHighQualityPrinting, puis cliquez sur Description d'élément.
  8. Dans la boîte de dialogue Description d'élément, renseignez les éléments Balises et Résumé avec le texte de votre choix. Renseignez également le champ Explication de boîte de dialogue pour les cinq paramètres dans la section Syntaxe de la boîte de dialogue Description d'élément. Vous pouvez également indiquer d'autres descriptions d'éléments.

Exécuter l'outil

L'outil doit être exécuté sans erreur pour générer dans la fenêtre Résultats un résultat pouvant être publié dans ArcGIS for Server. Ceci illustre le problème intéressant des scripts de test qui utilisent ConvertWebMapToMapDocument. Pour une exécution en local, une carte Web JSON valide est nécessaire. Cependant, les API Web d'ArcGIS fournissent la carte Web JSON dans l'application Web, mais uniquement après la publication du script. Pour résoudre ce problème, vous pouvez utiliser le JSON de test qui se trouve dans la rubrique d'aide ConvertWebMapToMapDocument. En outre, vous pouvez modifier le JSON pour qu'il contienne les éléments que l'outil attend et qu'il ressemble au JSON que vous obtiendrez de l'application Web. Pour ce didacticiel, l'utilisateur de l'application Web va activer/désactiver les couches de service dans la carte et ensuite activer/désactiver les couches dans la légende. Par conséquent, une chaîne JSON de carte Web test de ce type doit être utilisée :

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

Notez que la couche 1 de l'élément visibleLayers est désactivée. Cela signifie que la couche numéro un dans le service de carte ne sera pas présente dans la sortie. Notez par ailleurs les valeurs subLayerIDs dans legendOptions. Seules les couches 0, 2 et 5 apparaîtront dans la légende. La situation est la même que pour le JSON qui sera renvoyé par l'application Web. Pour plus d'informations, reportez-vous à la rubrique Spécifications JSON des cartes Web.

Lorsque vous exécutez l'outil de script, la chaîne JSON peut être copiée et collée dans le paramètre en entrée Web_Map_as_JSON. Vous devez toutefois supprimer les sauts de ligne pour que la chaîne soit une entrée valide. Voici la chaîne JSON dont les sauts de ligne ont été supprimés :

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

Vous devez également changer le nom du serveur (MyServer:6080 ci-dessus) et spécifier celui de votre serveur ArcGIS for Server.

AstuceAstuce:

Pour la publication, vous pouvez laisser le paramètre en entrée Web_Map_as_JSON vierge, car les API Web d'ArcGIS fourniront la chaîne JSON de la carte Web dans l'application Web. Vous pouvez laisser le paramètre en entrée Web_Map_as_JSON vierge si le script Python a été écrit de manière ne pas échouer avec une entrée vierge. Par exemple, si le script ne recherche pas les couches des cartes Web en fonction de leur nom. Si le script échoue sur le serveur en raison d'une erreur dans le script, il doit être corrigé en local avant d'être republié sur le serveur. Il est par conséquent conseillé de s'assurer que le script fonctionne en local avant de le publier, en testant avec une chaîne JSON de carte Web valide ou en utilisant un document ArcMap de débogage qui contient tous les éléments qui seraient dans la chaîne JSON de carte Web. Pour ce didacticiel, nous allons fournir une chaîne JSON valide.

Etapes :
  1. Dans la fenêtre Catalogue, cliquez avec le bouton droit sur l'outil de script AdvancedHighQualityPrinting et sélectionnez Ouvrir.
  2. Pour le paramètre en entrée Web_Map_as_JSON, copiez et collez la chaîne JSON avec les sauts de ligne supprimés à partir du bloc de code sur une seule ligne ci-dessus dans le paramètre Web_Map_as_JSON. N'oubliez pas de changer le nom du serveur pour qu'il corresponde à celui de votre serveur. La boîte de dialogue de l'outil de script AdvancedHighQualityPrinting doit ressembler à ceci :
    Boîte de dialogue de l'outil de script AdvancedHighQualityPrinting
  3. Acceptez toutes les valeurs par défaut des autres paramètres et cliquez sur OK.
  4. Ouvrez la fenêtre Résultats.
  5. Double-cliquez sur Output_File, mis en surbrillance ci-dessous, pour afficher le fichier PDF en sortie.
    Boîte de dialogue Résultats

    Cette opération ouvre le fichier PDF. Comme indiqué dans la chaîne JSON de carte Web, la couche numéro un du PDF doit être désactivée sur la carte et seules les couches 0, 2 et 5 doivent apparaître dans la légende.

Publier le résultat

Le résultat est maintenant prêt à être publié en tant que service de géotraitement. Si vous ne connaissez pas la publication des services de géotraitement, reportez-vous aux rubriques :

Etapes :
  1. Dans la fenêtre Résultats, cliquez avec le bouton droit sur le résultat AdvancedHighQualityPrinting et sélectionnez Partager en tant que > Service de géotraitement.
  2. Cliquez sur Publier un service.
  3. Cliquez sur Suivant.
  4. Choisissez une connexion d'éditeur ou d'administrateur sur l'ordinateur sur lequel est installé ArcGIS for Server.
  5. Cliquez sur Suivant.
  6. Utiliser le dossier existant USA.
  7. Cliquez sur Continuer.
  8. En haut à droite de la boîte de dialogue Editeur de services, cliquez sur Publier.
  9. Après la publication de l'outil de script, il est conseillé de tester le service de géotraitement dans ArcMap avec une connexion au serveur SIG vers votre ArcGIS for Server. Le résultat du service de géotraitement s'affiche dans la fenêtre Résultats de géotraitement.

Le service de géotraitement est maintenant prêt à être utilisé dans les API Web d'ArcGIS.

Choisissez quelle API Web d'ArcGIS vous voulez utiliser pour créer l'application Web.

Les API Web d'ArcGIS offrent des fonctionnalités SIG similaires : il vous appartient de sélectionner votre plate-forme de développement préférée. Chaque API fournit les ressources dont vous avez besoin. Lisez la référence API, affichez les exemples fonctionnels qui vous aideront à démarrer et qui illustrent les opérations possibles et communiquez avec les autres utilisateurs via les forums, les blogs et les bibliothèques de codes. Ce didacticiel n'explique pas en détail comment créer des applications Web avec chaque API. Consultez la documentation de l'API pour plus de détails. Pour en savoir plus, consultez les rubriques suivantes :

Chaque API Web d'ArcGIS possède une tâche d'impression. La tâche d'impression comporte une propriété URL qui référencera le service de géotraitement personnalisé que vous avez créé plus tôt. Consultez la documentation sur l'API Web d'ArcGIS pour plus d'informations sur la tâche d'impression.

Dans les sections ci-dessous, utilisez les exemples de code pour l'API Web d'ArcGIS que vous avez utilisée pour créer votre application Web.

Exemple de code ArcGIS for Silverlight

Si vous utilisez ArcGIS API for Silverlight, utilisez l'exemple de code suivant pour créer votre application Web.

Dans les exemples de code ArcGIS API for Silverlight ci-dessous, changez l'URL du service de carte et du service de géotraitement que vous avez créés au cours des étapes précédentes pour utiliser le nom de votre serveur. Ils sont référencés dans ces lignes :

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

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

Code sous-jacent 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();
        }
    }
}

Exemple de code ArcGIS for Flex

Si vous utilisez ArcGIS API for Flex, utilisez l'exemple de code suivant pour créer votre application Web.

Dans les exemples de code ArcGIS API for Flex ci-dessous, changez l'URL du service de carte et du service de géotraitement que vous avez créés au cours des étapes précédentes pour utiliser le nom de votre serveur. Ils sont référencés dans ces lignes :

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

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

Exemple de code ArcGIS API for JavaScript

Si vous utilisez ArcGIS API for JavaScript, utilisez l'exemple de code suivant pour créer votre application Web.

Dans l'exemple de code ArcGIS API for JavaScript ci-dessous, changez l'URL du service de carte et du service de géotraitement que vous avez créés au cours des étapes précédentes pour utiliser le nom de votre serveur. Ils sont référencés dans ces lignes :

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

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

Exécuter l'application Web

Exécutez l'application Web que vous avez créée au cours de l'étape précédente. Consultez la documentation sur l'API Web d'ArcGIS pour savoir comment exécuter les applications Web, le cas échéant. Vous trouverez ci-dessous une capture d'écran de l'application de l'API Web ArcGIS for Silverlight. Notez que la couche Capitales est désactivée dans la table des matières. Notez également que la couche Limites des états est désactivée dans la légende.

Application Web Silverlight terminée

Une fois que vous avez cliqué sur le bouton Exporter la carte, un fichier en sortie va automatiquement apparaître au bout d'un moment. L'illustration ci-dessous présente un exemple de document PDF en sortie imprimable. Notez que les couches qui étaient désactivées dans la table des matières et dans la légende de l'application Web sont reflétées dans la sortie. De plus, le PDF utilise des données vectorielles qui ont été placées dans les modèles de mise en page au lieu d'une image de cache tuilées des couches de service. Le fichier en sortie contiendra également d'autres éléments qui ont été placés dans les documents ArcMap de modèle : une légende, du texte dynamique de bloc de données et de système de coordonnées, ainsi qu'une barre d'échelle. Si l'utilisateur a défini le paramètre Georef info sur True, le PDF en sortie contiendra également des informations de géoréférencement qui peuvent être affichées dans Adobe Reader avec l'outil de localisation géospatiale.

PDF en sortie

Ceci conclut le didacticiel sur l'impression/exportation avancée de cartes Web avec arcpy.mapping. Pour consulter le didacticiel sur l'impression basique de cartes Web, consultez le didacticiel sur l'impression/exportation basique de cartes Web.

Thèmes connexes

5/10/2014