Руководство: Расширенная печать/экспорт веб-карт с помощью arcpy.mapping

Уровень сложности: Расширенный Требования к данным: Установлено с ПО

Иллюстрация ниже показывает пример веб-приложения веб-API ArcGIS, которое вы должны построить. В этом веб-приложении конечный пользователь будет иметь возможность:

Веб-приложение

Пример выходного PDF показан ниже. Обратите внимание, что слои, которые были отключены в Таблице содержания (Table of Contents) и Легенде (Legend) в веб-приложении, отражены в выходных данных.

Выходная PDF

Код, закрепленный в веб-приложении за кнопкой Экспортировать карту (Export Map), использует Задачу печати (Print Task) веб-API ArcGIS, которая доступна в ArcGIS 10.1 for Desktop и ArcGIS 10.1 for Server. В этом руководстве также показывается, как передать дополнительные параметры в Задачу печати (Print Task), например, нужно ли экспортировать информацию о географической привязке в выходной файл PDF. Возможность передачи дополнительных параметров в Задачу печати (Print Task) является полезной, поскольку позволяет собрать любое количество дополнительных параметров из веб-приложения. Вы также создадите скрипт Python, который будет опубликован как сервис геообработки, используемый Задачей печати (Print Task). Скрипт Python использует функцию ConvertWebMapToMapDocument в модуле arcpy.mapping, который вставит все элементы веб-карты в промежуточный шаблон документа карты. Вы изготовите несколько шаблонов, из которых пользователь сможет выбирать. Каждый шаблон содержит векторные эквиваленты всех возможных слоев в картографическом сервисе. Промежуточные шаблоны могут также содержать другие элементы, такие как легенда, динамический текст и так далее. В модуле arcpy.mapping также предусмотрена функциональная возможность идентификации слоев сервисов и выгрузки их для слоев, которые указывают на локальные данные, а также возможность экспорта во множество форматов, например в PDF.

Чтобы завершить изучение данного руководства, вы должны хорошо ориентироваться в модуле arcpy.mapping, веб-интерфейсах веб-API ArcGIS, ArcGIS for Desktopи ArcGIS for Server. Данное руководство содержит примеры кода для всех веб-API ArcGIS. Вам также следует ознакомиться с печатью в разделах справки веб-приложения:

Печать в веб-приложениях (Printing in web applications)Расширенные функции печати для веб-карт (Advanced printing for web maps)

Данное руководство использует папки MapTemplates и TemplateData в установочной директории ArcGIS for Desktop, обычно расположенной в C:\Program Files (x86)\ArcGIS\Desktop10.2. Это руководство предполагает, что шаблоны карт и данные шаблонов присутствуют и не были изменены. Если это не так, то вам следует переустановить ArcGIS for Desktop.

Копирование данных для обучения

Скопируйте некоторые из шаблонов карт в новую папку в установочной директории ArcGIS for Desktop. Эти шаблоны, в конечном итоге, будут использоваться в качестве промежуточных шаблонов карт в веб-приложении.

Прежде чем вы это сделаете, необходимо убедиться в наличии структуры папок в том местоположении, где ArcGIS for Server может видеть документы шаблонов карт и данные, которые будут использоваться в веб-приложении. В этом руководстве подразумевается, что у вас уже есть папка, зарегистрированная на ArcGIS for Server. Дополнительные сведения по регистрации данных на ArcGIS for Server см. в разделах:

ПодсказкаПодсказка:

При использовании шаблонов документов карт в функции ConvertWebMapToMapDocument рекомендуется использовать данные, которые зарегистрированы на ArcGIS for Server. Если не использовать зарегистрированные данные, то шаблоны документов карт и данные будут упакованы и скопированы на сервер. Во время упаковки данные могут перемещаться и использоваться в качестве источника с соответствующими путями к структуре папок, которые не могут быть разрешены ConvertWebMapToMapDocument. Для получения дополнительной информации см. раздел справки ConvertWebMapToMapDocument.

Шаги:
  1. Начните новый сеанс ArcMap.
  2. В окне Каталог (Catalog) перейдите к своей зарегистрированной папке. Создайте новую папку в вашей зарегистрированной папке под названием USA.
  3. В окне Каталог (Catalog) переместитесь в папку MapTemplates в установочной директории ArcGIS for Desktop. Она обычно располагается на C:\Program Files (x86)\ArcGIS\Desktop10.2\MapTemplates. Далее переместитесь вниз к папке Traditional Layouts\USA.
  4. В окне Каталог (Catalog) скопируйте и вставьте следующие файлы в папку USA, созданную вами на предыдущем шаге: CentralUSA.mxd, ConterminousUSA.mxd, NortheasternUSA.mxd, NorthwesternUSA.mxd, SouthernUSA.mxd и SouthwesternUSA.mxd.
    Папка MapTemplates
  5. В окне Каталог (Catalog) переместитесь в папку TemplateData в установочной директории ArcGIS for Desktop. Она обычно располагается на C:\Program Files (x86)\ArcGIS\Desktop10.2\TemplateData.
  6. В окне Каталог (Catalog) , скопируйте и вставьте TemplateData.gdb в папку USA, созданную вами в предыдущем шаге.
    Папка TemplateData
  7. Зарегистрированная папка должна выглядеть подобно этому:
    Зарегистрированная папка
    ПримечаниеПримечание:

    На снимке экрана вверху зарегистрированная папка имеет имя MyDataStore. Ваша зарегистрированная папка может иметь любое имя.

Подготовка документов карты для использования в качестве шаблонов в веб-приложении

Документы карт должны быть подготовлены для использования в качестве шаблонов в ConvertWebMapToMapDocument.

Документы карт, которые сейчас находятся в зарегистрированной папке, должны явиться ресурсами для TemplateData.gdb, которая также размещается в зарегистрированной папке. Это может быть выполнено с помощью пользовательского интерфейса ArcMap или с применением скрипта Python. Будет использоваться последний подход .

ПримечаниеПримечание:

Если вы создали ваш собственный шаблон документа карты с нуля в зарегистрированной папке, то эти шаги не потребуются.

Шаги:
  1. Откройте Окно Python (Python Window) в ArcMap.
  2. Скопируйте приведенный ниже скрипт и вставьте его в Окно Python (Python Window):
  3. import arcpy, os
    
    # The path to the registered folder where the template MXDs reside
    folderPath = "C:/MyDataStore/USA"
    
    # The location of TemplateData.gdb within the registered folder
    newPath = "C:/MyDataStore/USA/TemplateData.gdb"
    
    # Loop through all MXDs in the specified folder and change the layer's data source to the new path
    for filename in os.listdir(folderPath):
        fullpath = os.path.join(folderPath, filename)
        if os.path.isfile(fullpath):
            basename, extension = os.path.splitext(fullpath)
            if extension.lower() == ".mxd":
                mxd = arcpy.mapping.MapDocument(fullpath)
                mxd.findAndReplaceWorkspacePaths(arcpy.mapping.ListLayers(mxd)[1].workspacePath, newPath)
                mxd.save()
    print "done"
    
  4. В окне Python Window, измените переменную folderPath на путь к зарегистрированной папке, в которую перемещены файлы шаблонов MXDs. Не забывайте использовать косую черту (/) в вашем пути.
  5. В окне Python Window, измените переменную newPath на местоположение TemplateData.gdb в зарегистрированной папке. Не забывайте использовать косую черту (/) в вашем пути.
  6. Скрипт должен выглядеть следующим образом:
  7. Переместите курсор в правую часть последней строки. Нажмите клавишу ENTER дважды для выполнения скрипта. Подождите, пока скрипт выполнится.

Документы карты теперь готовы для использования в качестве шаблонов в веб-приложении.

Создайте картографический сервис для использования в веб-приложении.

Документ карты должен быть подготовлен и опубликован как картографический сервис, чтобы его можно было использовать в веб-приложении. ConterminousUSA.mxd в зарегистрированной папке будет использован в качестве картографического сервиса. Перед его публикацией на сервере, вам необходимо подготовить его к публикации.

Шаги:
  1. Откройте ConterminousUSA.mxd в ArcMap.
  2. По умолчанию карта откроется в виде компоновки. Переключитесь на вид данных посредством выбора Вид (View) > Вид данных (Data View) в главном меню ArcMap.
  3. Теперь вы выключите Группу аннотаций карты (Map Annotation Group) в данном документе карты. Данная карта содержит графику карты. Графика карты увеличивает объем использования памяти для загруженного документа, что приводит к снижению производительности. Из-за таких побочных эффектов графика карты не поддерживается в картографических сервисах.
    1. Откройте свойства фрейма данных Conterminous United States, щелкнув правой кнопкой мыши на имени фрейма данных в таблице содержания и выбрав Свойства (Properties).
    2. Откройте закладку Группы аннотаций (Annotation Groups).
    3. Снимите отметку с группы <Default>. Закладка Группы аннотаций (Annotation Groups) должна выглядеть следующим образом:
      Закладка Группы аннотаций (Annotation Groups)
    4. Нажмите OK в диалоговом окне Свойства фрейма данных (Data Frame Properties).
  4. Данная карта использует слои базовой карты. Слои базовой карты не публикуются на ArcGIS for Server. Вы будете двигать слои из слоя базовой карты посредством его разгруппировки.
    1. Щелкните правой кнопкой мыши слой базовой карты в таблице содержания и выберите Разгруппировать (Ungroup).
    ПримечаниеПримечание:

    Если вы создали ваш собственный шаблон документа карты с нуля или использовали существующие шаблоны документа карты, не содержащие графики карты или слоев базовой карты, то эти шаги не потребуются.

    Карта теперь готова к публикации на вашем сервере. Если вы не знакомы с публикацией процессов, пожалуйста ознакомьтесь с тем, как публиковать сервис.

  5. Щелкните Файл (File) > Опубликовать как (Share As) > Сервис (Service).
  6. Щелкните Опубликовать сервис (Publish a Service).
  7. Щелкните Далее (Next).
  8. Выберите издательское или административное подключение к компьютеру с ArcGIS for Server.
  9. Щелкните Далее (Next).
  10. Создайте новую папку под названием USA.
  11. Нажмите кнопку Продолжить (Continue).
  12. В верхнем правом углу диалогового окна Редактор сервисов (Service Editor) щелкните Опубликовать (Publish).

Это позволит создать картографический сервис, который будет использоваться в веб-приложении.

Создание скрипта Python

Вы создадите скрипт Python, который будет использоваться как пользовательский сервис геообработки.

Скрипт Python в пользовательском сервисе геообработки выполняет функцию ConvertWebMapToMapDocument, которая конвертирует веб-карту (в формате JSON), которую вы собираетесь вывести на печать или экспортировать в документ карты. ПСкрипт arcpy.mapping затем просматривает все слои выходного документа карты и удаляет все слои, кроме векторных, которые соответствуют сервисным слоям в веб-карте JSON. Затем он просматривает все слои в легенде, и удаляет все слои легенды, кроме векторных, которые соответствуют сервисным слоям в легенде веб-карты JSON. Данный скрипт будет также считывать дополнительные параметры из пользовательской задачи печати, в данном случае, следует или нет экспортировать информацию о географической привязке в выходной файл PDF. Документ карты может быть экспортирован в формат по вашему выбору, например, в формат PDF.

Шаги:
  1. Откройте любой Python IDE, например, – IDLE (который поставляется с ArcGIS for Desktop).
  2. Скопируйте и вставьте следующий код в новый скрипт Python.
  3. import arcpy
    import os
    import uuid
    
    # The template location in the registered folder (as UNC path)
    templatePath = '//MyComputerName/MyDataStore/USA'
    
    # Input WebMap json
    Web_Map_as_JSON = arcpy.GetParameterAsText(0)
    
    # Format for output
    Format = arcpy.GetParameterAsText(1)
    if Format == '#' or not Format:
        Format = "PDF" 
    
    # Input Layout template
    Layout_Template = arcpy.GetParameterAsText(2)
    if Layout_Template == '#' or not Layout_Template:
        Layout_Template = "NorthwesternUSA" 
        
    # Extra parameter - georef_info
    Georef_info = arcpy.GetParameterAsText(3)
    if Georef_info == '#' or not Georef_info:
        Georef_info = "False"
    
    # Convert Georef_info string to boolean
    if Georef_info.lower() == 'false': 
        Georef_info_bol = False
    elif Georef_info.lower() == 'true': 
        Georef_info_bol = True
    
    # Get the requested map document
    templateMxd = os.path.join(templatePath, Layout_Template + '.mxd')
    
    # Convert the WebMap to a map document
    result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd)
    mxd = result.mapDocument
    
    # Reference the data frame that contains the webmap
    # Note: ConvertWebMapToMapDocument renames the active dataframe in the template_mxd to "Webmap"
    df = arcpy.mapping.ListDataFrames(mxd, 'Webmap')[0]
    
    # Get a list of all service layer names in the map
    serviceLayersNames = [slyr.name for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df) 
                          if slyr.isServiceLayer and slyr.visible and not slyr.isGroupLayer]
    
    # Create a list of all possible vector layer names in the map that could have a 
    # corresponding service layer
    vectorLayersNames = [vlyr.name for vlyr in arcpy.mapping.ListLayers(mxd, data_frame=df) 
                         if not vlyr.isServiceLayer and not vlyr.isGroupLayer]
    
    # Get a list of all vector layers that don't have a corresponding service layer
    removeLayerNameList = [vlyrName for vlyrName in vectorLayersNames 
                           if vlyrName not in serviceLayersNames]
    
    # Remove all vector layers that don't have a corresponding service layer
    for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
        if not lyr.isGroupLayer \
        and not lyr.isServiceLayer \
        and lyr.name in removeLayerNameList \
        and lyr.name in vectorLayersNames:
            arcpy.mapping.RemoveLayer(df, lyr)
                    
    # Reference the legend in the map document
    legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT")[0]
    
    # Get a list of service layers that are on in the legend because the incoming 
    # JSON can specify which service layers/sublayers are on/off in the legend
    legendServiceLayerNames = [lslyr.name for lslyr in legend.listLegendItemLayers() 
                               if lslyr.isServiceLayer and not lslyr.isGroupLayer]
    
    # Remove vector layers from the legend where the corresponding service layer 
    # is also off in the legend
    for lvlyr in legend.listLegendItemLayers():
        if not lvlyr.isServiceLayer \
        and lvlyr.name not in legendServiceLayerNames \
        and not lvlyr.isGroupLayer \
        and lvlyr.name in vectorLayersNames:
            legend.removeItem(lvlyr)
    
    # Remove all service layers
    # This will leave only vector layers that had corresponding service layers
    for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
        if slyr.isServiceLayer:
            arcpy.mapping.RemoveLayer(df, slyr)
            
    # ConvertWebMapToMapDocument renames the active dataframe in the template_mxd to "Webmap".
    # Lets rename it to something more meaningful.
    df.name = Layout_Template
    
    # Use the uuid module to generate a GUID as part of the output name
    # This will ensure a unique output name
    output = 'WebMap_{}.{}'.format(str(uuid.uuid1()), Format)
    Output_File = os.path.join(arcpy.env.scratchFolder, output)
    
    # Export the WebMap
    if Format.lower() == 'pdf':
        arcpy.mapping.ExportToPDF(mxd, Output_File, georef_info=Georef_info_bol) 
    elif Format.lower() == 'png':
        arcpy.mapping.ExportToPNG(mxd, Output_File)
    
    # Set the output parameter to be the output file of the server job
    arcpy.SetParameterAsText(4, Output_File)
    
    # Clean up - delete the map document reference
    filePath = mxd.filePath
    del mxd, result
    os.remove(filePath)
    
  4. Измените переменную templatePath, чтобы она представляла путь UNC к папке в вашей зарегистрированной папке, содержащей шаблоны документов карт.
  5. ПримечаниеПримечание:

    Если ArcGIS for Server и ArcGIS for Desktop, и зарегистрированная папка размещены на одном компьютере, то пути UNC к зарегистрированной папке не требуются. Вместо них могут использоваться абсолютные пути.

  6. Сохраните скрипт Python. Назовите скрипт AdvancedHighQualityPrinting.py. Сохраните его в папке под названием WebApp в зарегистрированной папке.

Скрипт Python теперь готов к добавлению в набор инструментов.

Создайте набор инструментов

Шаги:
  1. В окне Каталог (Catalog) в ArcMap перейдите к папке WebApp в зарегистрированной папке.
  2. Щелкните правой кнопкой мыши папку WebApp и выберите Создать (New) > Набор инструментов (Toolbox). Назовите набор инструментов AdvancedHighQualityPrinting.
  3. Щелкните правой кнопкой набор инструментов AdvancedHighQualityPrinting, а затем нажмите Описание элемента (Item Description).
  4. В диалоговом окне Описание элемента (Item Description) в элементах Теги (Tags) и Сводка (Summary) введите любой выбранный вами текст. Дополнительно, заполните другие описания элементов.
  5. Щелкните Сохранить (Save) и выйдите из диалогового окна Описание элемента (Item Description).

Создание инструмента-скрипта Python

Далее, вы добавите скрипт AdvancedHighQualityPrinting.py в набор инструментов AdvancedHighQualityPrinting.

Шаги:
  1. В окне Каталог (Catalog) щелкните правой кнопкой набор инструментов AdvancedHighQualityPrinting и щелкните Добавить (Add) > Скрипт (Script).
  2. В диалоговом окне Добавить скрипт (Add Script), введите AdvancedHighQualityPrinting и для Имени (Name), и для Надписи (Label).
  3. Щелкните Далее (Next).
  4. Для параметра Файла скрипта (Script File) переместитесь в папку WebApp в зарегистрированной папке и выберите AdvancedHighQualityPrinting.py.
  5. Щелкните Далее (Next) в диалоговом окне Добавить скрипт (Add Script).
  6. Пять параметров должны быть добавлены в инструмент-скрипт.
    1. Первый из параметров – Web_Map_as_JSON. Этот параметр получает представление JSON о состоянии карты для экспорта, как только она отобразится в веб-приложении. Свойства должны соответствовать следующему снимку экрана:
      Параметр Web_Map_as_JSON
    2. Следующий параметр Format – формат, в котором будет предоставлено изображение карты для печати. Свойства должны соответствовать следующему снимку экрана:
      Параметр Format
    3. Следующий параметр Layout_Template – шаблон документа карты, который будет использован. Свойства должны соответствовать следующему снимку экрана:
      Параметр Layout_Template
    4. Следующий параметр Georef_info – логическая (Boolean) строка, позволяющая экспортировать информацию о системе координат в выходной файл PDF. Свойства должны соответствовать следующему снимку экрана:
      Параметры Georef_info
    5. Следующий параметр – Выходной файл (Output_File) – выходной файл, который будет создан. Свойства должны соответствовать следующему снимку экрана:
      Параметр Output_File

      ВниманиеВнимание:

      Имена параметров Web_Map_as_JSON, Format, Layout_Template и Output_File должны вводиться так, как показано, с точностью до буквы, чтобы они соответствовали подписи инструмента Задача печати (Print Task) в веб-API ArcGIS. Более подробно о параметрах см. раздел Экспорт веб-карт. Параметр Georef_info является дополнительным параметром, который будет передан в Задачу печати (Print Task) и, поэтому, не имеет соглашения о наименовании для требуемого соответствия.

    6. Щелкните Готово (Finish) в диалоговом окне Добавить скрипт (Add Script).
  7. Щелкните правой кнопкой инструмент-скрипт AdvancedHighQualityPrinting и выберите Описание элемента (Item Description).
  8. В диалоговом окне Описание элемента (Item Description), заполните поля Теги (Tags) и Сводка (Summary) любым выбранным вами текстом. Также введите любой выбранный вами текст в поле Пояснение диалога (Dialog Explanation) для всех пяти параметров в секции Синтаксис (Syntax) диалогового окна Описание элемента (Item Description). Дополнительно, заполните другие описания элементов.

Выполните инструмент

Инструмент должен быть выполнен успешно, чтобы в окне Результаты (Results) появился результат, который мог бы быть опубликован на ArcGIS for Server. Это иллюстрирует интересную проблему с тестированием скриптов, которые используют ConvertWebMapToMapDocument. Для локального выполнения требуется корректная веб-карта JSON. Однако, веб-API ArcGIS предоставляет веб-карту JSON в веб-приложении, но только после того, как скрипт будет опубликован. Чтобы обойти это, вы можете использовать тест JSON, который приведен в разделе справки ConvertWebMapToMapDocument. Кроме того, вы можете изменить JSON для включения элементов, которых ожидает инструмент, и это будет подобно тому, как будто вы получили JSON из веб-приложения. Для данного руководства, пользователь веб-приложения будет включать и выключать слои сервиса на карте, а также, в дальнейшем, включать и выключать слои в легенде. Поэтому следует использовать тестовую строку веб-карты JSON подобную следующей:

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

Заметьте, что элемент visibleLayers включает выключенный слой 1. Это означает, что слой один представляет собой картографический сервис, который не будет присутствовать в выходных данных. Также отметьте subLayerIDs в legendOptions. Только слои 0, 2и 5 будут присутствовать в легенде. Это похоже на JSON, который будет возвращен из веб-приложения. Для получения подробной информации см. раздел Спецификации WebMap JSON.

При запуске инструмента-скрипта, строку JSON можно скопировать и вставить во входной параметр Web_Map_as_JSON. Однако переносы строк необходимо удалить. Строка JSON с удаленными переносами строк представлена ниже:

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

Вам также следует изменить имя сервера (MyServer:6080, выше) на соответствующее имя в вашем ArcGIS for Server.

ПодсказкаПодсказка:

Для целей публикации, вы можете оставить входной параметр Web_Map_as_JSON пустым, поскольку веб-карта JSON будет обеспечена веб-API ArcGIS в веб-приложении. Входной параметр Web_Map_as_JSON может быть оставлен пустым при условии, что скрипт Python был написан таким образом, чтобы он мог работать и при пустом входном параметре. Например, скрипт не ищет слои веб-карт по имени. Если скрипт не работает на сервере из-за ошибки, ее необходимо исправить локально, затем снова опубликовать его на сервере. Поэтому, перед публикацией рекомендуется убедиться, что скрипт работает локально, проверив его со строкой JSON подходящей веб-карты или использовав отладочный документ карты, который содержит все элементы, присутствующие в JSON веб-карты. Для данного руководства мы предоставляем корректную строку JSON.

Шаги:
  1. В окне Каталог (Catalog) щелкните правой кнопкой инструмент-скрипт AdvancedHighQualityPrinting и щелкните Открыть (Open).
  2. Для входного параметра Web_Map_as_JSON скопируйте и вставьте строку JSON с удаленными разрывами строк из блока кода единой строки выше в параметр Web_Map_as_JSON. Не забудьте изменить имя сервера для соответствия вашему сервером. Диалоговое окно инструмента-скрипта AdvancedHighQualityPrinting должно выглядеть подобно следующему:
    Диалоговое окно инструмента-скрипта AdvancedHighQualityPrinting
  3. Примите все установленные по умолчанию значения для остальных параметров и нажмите кнопку OK.
  4. Откройте окно Результаты (Results).
  5. Дважды щелкните Выходной файл (Output_File), выделенный ниже, для просмотра выходного PDF.
    Диалоговое окно Результаты (Results)

    Это вызовет открытие PDF. Как определено в веб-карте JSON, PDF должен иметь слой один выключенным в карте; и только слои 0, 2 и 5 должны присутствовать в легенде.

Публикация результата

Теперь результат готов для публикации как в качестве сервиса геообработки. Если вы не знакомы с публикацией сервисов геообработки, обратитесь к следующим разделам:

Шаги:
  1. В окне Результаты (Results), щелкните правой кнопкой мыши результат AdvancedHighQualityPrinting и выберите Общий доступ (Share As) > Сервис геообработки (Geoprocessing Service).
  2. Щелкните Опубликовать сервис (Publish a Service).
  3. Щелкните Далее (Next).
  4. Выберите издательское или административное подключение к компьютеру с ArcGIS for Server.
  5. Щелкните Далее (Next).
  6. Используйте существующую папку под названием USA.
  7. Нажмите кнопку Продолжить (Continue).
  8. В верхнем правом углу диалогового окна Редактор сервисов (Service Editor) щелкните Опубликовать (Publish).
  9. После успешной публикации инструмента-скрипта, хорошей практикой является протестировать сервис геообработки в ArcMap, используя подключение ГИС-сервера к вашему ArcGIS for Server. Вы можете увидеть результат сервиса геообработки в окне Результаты геообработки (Geoprocessing Results).

Теперь сервис геообработки подготовлен для использования в веб-API ArcGIS.

Выбор веб-API ArcGIS, который будет использоваться для создания веб-приложения

ArcGIS Web API предлагают аналогичную ГИС-функциональность; вам только нужно выбрать предпочитаемую платформу разработки. Каждый API предоставляет необходимые вам ресурсы. Прочитайте справочную информацию по API, просмотрите работающие примеры, которые помогут вам начать и покажут вам, что это возможно; и общайтесь с другими специалистами через форумы, блоги и галереи кодов. Данное руководство не ставит свой целью подробное рассмотрение начала работы по построению веб-приложений с каждым API. Более подробную информацию можно найти в документации по API. Для получения дополнительной информации см.:

Каждый веб-API ArcGIS имеет Задачу печати (Print Task). Задача печать (Print Task) имеет свойство URL, в котором содержится ссылка на ранее созданный вами пользовательский сервис геообработки. Пожалуйста, обратитесь к документации по веб-API ArcGIS для получения дополнительной информации о задаче Задача печати (Print Task).

В следующих разделах используйте образцы кодов для веб-API ArcGIS, которые вы вводите для создания своего веб-приложения.

Образец кода ArcGIS API for Silverlight

Если вы используете ArcGIS API for Silverlight, используйте следующий образец кода для создания своего веб-приложения.

В следующих примерах кода ArcGIS API for Silverlight измените URL на картографический сервис и сервис геообработки, который был вами создан на предыдущих шагах, чтобы он соответствовал имени вашего сервера. Они ссылаются на следующие строки:

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

Код XAML:

<UserControl x:Class="TestSilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:esri="http://schemas.esri.com/arcgis/client/2009">

    <Grid x:Name="LayoutRoot" Background="White">

        <esri:Map x:Name="MyMap" Extent="-2260000,-1500000,2250000,1220000">
            <esri:Map.Layers>
                <esri:ArcGISDynamicMapServiceLayer ID="MyDynamicService" 
                    Url="http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer"
                    Initialized="ArcGISDynamicMapServiceLayer_Initialized"/>
            </esri:Map.Layers>
        </esri:Map>

        <StackPanel Orientation="Vertical" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Top" >
            <Border x:Name="PrintPanel" CornerRadius="10" BorderBrush="Gray" BorderThickness="1" Background="White" HorizontalAlignment="Left" 
                    VerticalAlignment="Top" Margin="15" Padding="10">
                <Border.Effect>
                    <DropShadowEffect/>
                </Border.Effect>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="LayoutTemplates" Grid.Row="0" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="LayoutTemplates" ItemsSource="{Binding LayoutTemplates}" Grid.Row="0" Grid.Column="1" Width="100" Margin="2"/>
                    <TextBlock Text="Formats" Grid.Row="1" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="Formats" Grid.Row="1" ItemsSource="{Binding Formats}"  Grid.Column="1" Width="100" Margin="2"/>
                    <TextBlock Text="Georef info?" Grid.Row="2" Grid.Column="0" Margin="2"/>
                    <ComboBox x:Name="Georef_info" Grid.Row="2" Grid.Column="1" Width="100" Margin="2">
                        <ComboBoxItem Content="True"></ComboBoxItem>
                        <ComboBoxItem Content="False"></ComboBoxItem>
                    </ComboBox>
                    <Button x:Name="Print" Content="Export Map" Click="ExportMap_Click" 
                            Grid.Row="3" Grid.Column="0" Margin="2"/>

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

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

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

    </Grid>


</UserControl>

Код в C#:

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

namespace TestSilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        PrintTask printTask;
        public MainPage()
        {
            InitializeComponent();
            printTask = new PrintTask("http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting");
            printTask.DisableClientCaching = true;
            printTask.JobCompleted += new EventHandler<PrintJobEventArgs>(printTask_JobCompleted);
            printTask.GetServiceInfoCompleted += new EventHandler<ServiceInfoEventArgs>(printTask_GetServiceInfoCompleted);
            printTask.GetServiceInfoAsync();
        }

        void printTask_GetServiceInfoCompleted(object sender, ServiceInfoEventArgs e)
        {
            PrintPanel.DataContext = e.ServiceInfo;
        }


        void printTask_JobCompleted(object sender, PrintJobEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.PrintResult != null)
                    System.Windows.Browser.HtmlPage.Window.Navigate(e.PrintResult.Url, "_blank");
            }
        }

        private void ExportMap_Click(object sender, RoutedEventArgs e)
        {

            if (printTask == null || printTask.IsBusy) return;
            ComboBoxItem typeItem = (ComboBoxItem)Georef_info.SelectedItem;
            string value = typeItem.Content.ToString();
            var gpExtraInput = new List<GPParameter>();
            gpExtraInput.Add(new GPString("Georef_info", value));

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

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

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

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

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

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

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

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

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

            int layerIndex = (int)tickedCheckBox.Tag;

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

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

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

            dynamicServiceLayer.VisibleLayers = visibleLayerList.ToArray();
        }

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

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

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

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

Образец кода ArcGIS API for Flex

Если вы используете ArcGIS API for Flex, используйте следующий образец кода для создания своего веб-приложения.

В следующих примерах кода ArcGIS API for Flex измените URL на картографический сервис и сервис геообработки, который был вами создан на предыдущих шагах, чтобы он соответствовал имени вашего сервера. Они ссылаются на следующие строки:

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

Код для AdvancedHighQualityPrinting.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:esri="http://www.esri.com/2008/ags"
			   initialize="printTask.getServiceInfo()"
			   pageTitle="High-quality printing"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:samples="IncludeFiles.*">
	
	<!--
	This sample also uses the following files:
	IncludeFiles/LayerTOC.mxml - a datagrid with checkboxes for every layer in the map service
	IncludeFiles/LayerVizRenderer.mxml - The datagrid itemrenderer (LayerVizRenderer) will update the map service as users selects/clears checkboxes.
	-->
	
	<fx:Script>
		<![CDATA[
			import com.esri.ags.events.PrintEvent;
			import com.esri.ags.tasks.supportClasses.DataFile;
			import com.esri.ags.tasks.supportClasses.JobInfo;
			import com.esri.ags.tasks.supportClasses.ParameterValue;
			import mx.controls.Alert;

			private function printBtn_clickHandler(event:MouseEvent):void
			{
				myLegendLayer.subLayerIds = [];
				if (CapitalCities.selected)
				{				
					myLegendLayer.subLayerIds.push(0);					
				}				
				if (InterstateHighways.selected)					
				{					
					myLegendLayer.subLayerIds.push(1);					
				}				
				if (Rivers.selected)					
				{					
					myLegendLayer.subLayerIds.push(2);					
				}				
				if (Lakes.selected)					
				{					
					myLegendLayer.subLayerIds.push(3);					
				}				
				if (StateBoundaries.selected)					
				{					
					myLegendLayer.subLayerIds.push(4);					
				}		
				
				if (printTask.getServiceInfoLastResult.isServiceAsynchronous)					
				{					
					printTask.submitJob(printParameters);					
				}					
				else					
				{					
					printTask.execute(printParameters);					
				}				
			}
			
			private function printTask_jobCompleteHandler(event:PrintEvent):void
			{
				var jobInfo:JobInfo = event.jobInfo;
				if (jobInfo.jobStatus == JobInfo.STATUS_SUCCEEDED)
				{
					printTask.getResultData(jobInfo.jobId);
				}
				else
				{
					Alert.show(jobInfo.jobStatus);
				}
			}
			
			private function printTask_getResultDataCompleteHandler(event:PrintEvent):void
			{
				var dataFile:DataFile = event.parameterValue.value as DataFile;
				navigateToURL(new URLRequest(dataFile.url));
			}
			
			private function printTask_executeCompleteHandler(event:PrintEvent):void
			{
				var paramValue:ParameterValue = event.executeResult.results[0];
				var dataFile:DataFile = paramValue.value as DataFile;
				navigateToURL(new URLRequest(dataFile.url));
			}
		]]>
	</fx:Script>
	
	<fx:Declarations>
		<esri:PrintTask id="printTask"
						executeComplete="printTask_executeCompleteHandler(event)"
						fault="Alert.show(event.fault.faultString)"
						getResultDataComplete="printTask_getResultDataCompleteHandler(event)"
						jobComplete="printTask_jobCompleteHandler(event)"
						showBusyCursor="true"
						url="http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting"/>
		<esri:PrintParameters id="printParameters"
							  format="{formats.selectedItem}"
							  layoutTemplate="{layoutTemplates.selectedItem}"
							  map="{map}">
			<esri:customParameters>
				<fx:Object Georef_info="{Georef_info.selectedItem}"/>
			</esri:customParameters>
			<esri:layoutOptions>
				<esri:LayoutOptions title="My Map">
					<esri:legendOptions>
						<esri:LegendOptions>
							<esri:LegendLayer id="myLegendLayer" layerId="myDynamicService" />
						</esri:LegendOptions>
					</esri:legendOptions>
				</esri:LayoutOptions>
			</esri:layoutOptions>

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

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

Код для LayerTOC.mxml:

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

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

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

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

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

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

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

                super.commitProperties();
            }

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

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

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

                    dataProvider = _layerInfos;
                }
            }

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

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

                return result;
            }

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

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

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

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

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

                return result;
            }

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

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

                return result;
            }

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

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

</mx:DataGrid>

Код для LayerVizRenderer.mxml:

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

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

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

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

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

</s:MXDataGridItemRenderer>

Образец кода ArcGIS API for JavaScript

Если вы используете ArcGIS API for JavaScript, используйте следующий образец кода для создания своего веб-приложения.

В следующих примерах кода ArcGIS API for JavaScript измените URL на картографический сервис и сервис геообработки, который был вами создан на предыдущих шагах, чтобы он соответствовал имени вашего сервера. Они ссылаются на следующие строки:

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

Код для AdvancedHighQualityPrinting.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css">  
    <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/"></script>
    <script type="text/javascript" language="Javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.PrintTask");
      dojo.require("dijit.form.Button");
      dojo.require("dijit.form.CheckBox");      
      dojo.require("dijit.form.ComboBox");
      
      var layer, map, visible = [];
      var printTask, params;
      
      function init() {
        var startExtent = new esri.geometry.Extent({"xmin":-2260000,"ymin":-1500000,"xmax":2250000,"ymax":1220000,"spatialReference":{"wkid":102008}});
        map = new esri.Map("map", {extent:startExtent});
        
        var dynUrl = "http://MyServer:6080/arcgis/rest/services/USA/ConterminousUSA/MapServer";
        layer = new esri.layers.ArcGISDynamicMapServiceLayer(dynUrl, { "id": "ConterminousUSA" });
        
        if (layer.loaded) { 
          buildLayerList(layer); 
        } 
        else { 
          dojo.connect(layer, "onLoad", buildLayerList); 
        }
        
        
		var printUrl = "http://MyServer:6080/arcgis/rest/services/USA/AdvancedHighQualityPrinting/GPServer/AdvancedHighQualityPrinting";
		printTask = new esri.tasks.PrintTask(printUrl, {async: true});
		params = new esri.tasks.PrintParameters();
        params.map = map;     
      }
      
      
      function buildLayerList(layer) { 
        var items = dojo.map(layer.layerInfos,function(info,index){ 
          if (info.defaultVisibility) { 
            visible.push(info.id); 
          } 
          return "<input type='checkbox' class='list_item' checked='" + (info.defaultVisibility ? "checked" : "") + "' id='" + info.id + "' onclick='updateLayerVisibility();' /><label for='" + info.id + "'>" + info.name + "</label>"; 
        }); 
 
        dojo.byId("layer_list").innerHTML = items.join(); 
 
        layer.setVisibleLayers(visible); 
        map.addLayer(layer); 
 
      } 
 
      function updateLayerVisibility() { 
        var inputs = dojo.query(".list_item"), input; 
     
        visible = []; 
 
        dojo.forEach(inputs,function(input){ 
          if (input.checked) { 
              visible.push(input.id); 
          } 
          }); 
        //if there aren't any layers visible set the array to be -1 
        if(visible.length === 0){ 
          visible.push(-1); 
        } 
        layer.setVisibleLayers(visible); 
      } 
      
      
      
      function print(){
        var layout = dojo.byId("layout");
        var index = layout.selectedIndex;
		var selectedValue_layout = layout.options[index].value;
		var format = dojo.byId("format");
        var index = format.selectedIndex;
		var selectedValue_format = format.options[index].value;
		var georef_info = dojo.byId("georef_info");
        var index = georef_info.selectedIndex;
		var selectedValue_georef_info = georef_info.options[index].value;
		
		var legendLayer = new esri.tasks.LegendLayer();
		legendLayer.layerId = "ConterminousUSA";
		legendLayer.subLayerIds = [];
		if (CapitalCities.checked == true)
      	{
      		legendLayer.subLayerIds.push(0);
      	}
		if (InterstateHighways.checked == true)
      	{
      		legendLayer.subLayerIds.push(1);
      	}
      	if (Rivers.checked == true)
      	{
      		legendLayer.subLayerIds.push(2);
      	}
      	if (Lakes.checked == true)
      	{
      		legendLayer.subLayerIds.push(3);
      	}
      	if (StateBoundaries.checked == true)
      	{
      		legendLayer.subLayerIds.push(4);
      	}
		
        params.template = {layout: selectedValue_layout, format: selectedValue_format, layoutOptions: {legendLayers:[legendLayer]}};
        params.extraParameters = {Georef_info: selectedValue_georef_info};
        printTask.execute(params, printComplete);
      }
      
      function printComplete(result){
        window.open(result.url);
      }

      dojo.addOnLoad(init);

    </script>

  </head>

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

Запуск веб-приложения

Запустите веб-приложение, которое вы создали в предыдущем шаге. Обратитесь к документации веб-API ArcGIS с инструкциями по запуску веб-приложений, если это необходимо. Ниже показан снимок экрана веб-приложения ArcGIS for Silverlight web API. Заметьте, что слой Capital Cities выключен в Таблице содержания (Table of Contents)). Также заметьте, что слой State Boundaries выключен в Включить в Легенду (Include in Legend)Включить в Легенду (Include in Legend).

Завершенное веб-приложение Silverlight

После нажатия кнопки Экспортировать карту (Export Map), выходной файл через мгновение будет автоматически отображен. На иллюстрации ниже показан пример настроенного на печать выходного файла PDF. Обратите внимание, что слои, которые были отключены в Таблице содержания (Table of Contents) и в Включить в легенду (Include in Legend) в веб-приложении, отражены в выходных данных. Более того, PDF использует векторные данные, которые были вставлены в шаблонах компоновки, вместо изображения слоев сервисов. Выходной файл будет также содержать другие элементы, которые были вставлены в шаблоны документов карт: легенды, фрейм данных и систему координат, динамический текст и масштабную линейку. Если пользователь устанавливает параметр Georef info как Истина (True), то выходной PDF будет также содержать информацию о географической привязке, которая может быть просмотрена в Adobe Reader с использованием Инструмента пространственного местонахождения (Geospatial Location Tool).

Выходная PDF

Это завершает руководство пользователя по усовершенствованной печати/экспорту веб-карт с помощью arcpy.mapping. Информацию по основам печати веб-карт см. в основах печати/экспорта веб-карт.

Связанные темы

5/10/2014