Можно написать скрипт Python для его запуска и использования сервиса геообработки несколькими способами. Основной способ запуска скрипта — это использование ArcPy. ArcPy имеет встроенные методы для подключения, выполнения и обработки результатов сервиса. Кроме того, использование каталога сервисов позволяет использовать встроенные модули Python для вызовов REST с использованием структуры JSON в целях передачи результатов. Для использования этих возможностей необходимо создать клиент "с нуля" с кодом Python. Большинство скриптов подключаются и используют сервисы геообработки через ArcPy.
Способ ArcPy
Доступ к сервису геообработки можно получить через окно Python в ArcMap, через инструмент-скрипт или отдельный скрипт. Для подключения и использования сервиса геообработки используется URL-адрес.
Подключитесь к сервису с помощью ImportToolbox.
# arcpy.ImportToolbox("http://<hostname>:<port>/arcgis/services;<optional folder>/<service name>","<optional alias>")
arcpy.ImportToolbox("http://degrassi:6080/arcgis/services;GPFolder/BufferService","PointAlias")
Путь, используемый для импорта инструмента, — это URL-адрес сервиса геообработки.ImportToolbox принимает два параметра: URL-адрес сервиса и дополнительный псевдоним набора инструментов. Параметр URL-адреса разделяется на две части с использованием точки с запятой (;). Первая часть — это URL-адрес (или ссылка) конечной точки, а вторая — имя сервиса (дополнительно; имя папки предшествует имени сервиса).
Сервис геообработки может выполняться синхронно или асинхронно. Создатель сценариев Python должен понимать, как выполняется сервис, чтобы эффективно его использовать. Свойство IsSynchronous можно задействовать для определения типа выполнения сервиса. Если сервис выполняется синхронно, результат возвращается автоматически, но, до завершения работы инструмента нельзя предпринимать никаких действий. При использовании асинхронных сервисов, следует периодически опрашивать текущий статус выполнения. После выполнения сервиса можно получить доступ к результатам.
В следующем коде Python показано, как подключиться к асинхронному сервису геообработки и, задействуя функции ArcPy, получить результаты и обработать их. При настройке переменной результата во время выполнения задачи можно настроить цикл while для проверки статуса. Задача завершается после возвращения кода состояния 4 (успешно) или выше.
Использование асинхронного сервиса геообработки для создания буфера и локального сохранения результатов
import arcpy
import time
arcpy.ImportToolbox("http://sampleserver1.arcgisonline.com/ArcGIS/services;Elevation/ESRI_Elevation_World", "viewshedAlias")
result = arcpy.Viewshed_viewshedAlias(r'c:\data\inputPoint.shp', "10000 Kilometers")
while result.status < 4:
print result.status
time.sleep(0.2)
print "Execution Finished"
result.getMessages()
arcpy.CopyFeatures_management(result.getOutput(0), 'localResult.shp')
Дополнительные сведения о результирующем объекте и кодах состояния, а также создании выходных растровых и картографических изображений доступны в разделе справки Использование инструментов в Python.
Способ REST
Альтернативным (но менее распространенным) способом использования сервиса геообработки является построение приложение, осуществляющего вызовы REST, с использованием JSON в качестве формата обмена данными. При использовании этого метода необходимо написать код как для отправки запроса, так и для обработки ответа.
Отправка и получение сообщений REST требует большего участия разработчика, так как следует самостоятельно обрабатывать все аспекты синтаксиса для входных и выходных объектов. Положительным свойством отправки и получения сообщений REST является их согласованность при возврате. Запрос может быть послан с помощью метода HTTP GET, а ответ вернется структурированным как JSON. Ключевые библиотеки Python поддерживают и отправку запроса с помощью HTTP GET, и функции, которые упрощают чтение и обработку сообщений JSON.
В приведенном ниже примере используется сервис с серверов примеров Esri и показывается, как следует подключаться к сервису, отправлять запрос и обрабатывать ответ.
Отправка запроса
Например, SampleServer1 содержит сервис геообработки для создания областей видимости. Доступ к нему осуществляется по адресу http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Elevation. Этот сервис использует в качестве входных данных точку и расстояние, а возвращает набор объектов. Следующие входные данные позволят лучше понять работу сервиса:
Имя параметра | Входное значение |
---|---|
Входная точка наблюдения (GPFeatureRecordSetLayer) | {"geometryType" : "esriGeometryPoint", "spatialReference" : {"wkid" : 54003}, 'features':[{'geometry':{'x': -13308192.1956127, 'y': 4221903.58555983}}]} |
Расстояние области видимости (GPLinearUnit) | { 'distance' : 8.5, 'units' : 'esriMiles' } |
Формат (формат выходных данных) | JSON |
Этот запрос приведет к возвращению из сервиса JSON видимых местоположений. В адресной строке веб-браузера можно использовать полный URL-адрес, с помощью которого был создан запрос.
http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Elevation/ESRI_Elevation_World/GPServer/Viewshed/execute?Input_Observation_Point={%22features%22%3A[{%22geometry%22%3A{%22x%22%3A-13308192.1956127%2C%22y%22%3A4221903.58555983}}]}&Viewshed_Distance={+%27distance%27+%3A+8.5%2C+%27units%27+%3A+%27esriMiles%27+}&env%3AoutSR=&env%3AprocessSR=&f=pjson
URL-адрес может быть предоставлен с помощью модуля Python urllib или urllib2. Следующий код Python приведет к выполнению приведенного выше запроса способом, аналогичным использованию каталога сервиса или копированию ссылки в адресную строку веб-браузера.
import urllib
import json
inPts = {"geometryType" : "esriGeometryPoint",
"spatialReference" : {"wkid" : 54003},
'features':[{'geometry':{'x': -13308192.1956127,'y': 4221903.58555983}}]}
dist = {'distance':8.5,'units':'esriMiles'}
data = {'Input_Observation_Point': inPts,
'Viewshed_Distance': dist,
'f': 'pjson'}
URL = 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Elevation/ESRI_Elevation_World/GPServer/Viewshed/execute'
result = urllib.urlopen(URL, urllib.urlencode(data)).read()
print json.loads(result)
Результирующий объект возвращается в виде строки. Существует ряд различных методов, которые можно использовать для выполнения запроса и обработки результата; приведенный выше пример — это лишь один из методов. JSON, возвращаемый от сервиса геообработки, может быть размещен в словарь с помощью json.loads(), как показано в предыдущем примере. В зависимости от выходных данных сервиса геообработки, это может быть наилучшим способом, или может понадобиться рассмотреть другие варианты обработки выходных данных сервиса геообработки при их использовании в Python с применением REST.
Сервис, который выполняется асинхронно, нуждается в периодическом запросе статуса задачи, чтобы узнать, завершена ли она (аналогично вышеприведенному примеру с использованием ArcPy). Код Python может искать фразу esriJobSucceeded или esriJobFailed в сообщении статуса jobStatus, которое возвращается при проверке статуса задания. В приведенном ниже примере кода демонстрируется один из способов работы с асинхронным сервисом геообработки (с использованием submitJob).
import urllib, json, time
inPts = {"geometryType" : "esriGeometryPoint",
"spatialReference" : {"wkid" : 54003},
'features':[{'geometry':{'x': -13308192.1956127,'y': 4221903.58555983}}]}
dist = {'distance':8.5,'units':'esriMiles'}
data = {'Input_Observation_Point': inPts,
'Viewshed_Distance': dist,
'f': 'pjson'}
taskUrl = "http://localhost:6080/arcgis/rest/services/WorldViewshed/GPServer/viewshed"
submitUrl = taskUrl + "/submitJob"
submitResponse = urllib.urlopen(submitUrl, urllib.urlencode(data))
submitJson = json.loads(submitResponse.read())
if 'jobId' in submitJson:
jobID = submitJson['jobId']
status = submitJson['jobStatus']
jobUrl = taskUrl + "/jobs/" + jobID
while status == "esriJobSubmitted" or status == "esriJobExecuting":
print "checking to see if job is completed..."
time.sleep(1)
jobResponse = urllib.urlopen(jobUrl, "f=json")
jobJson = json.loads(jobResponse.read())
if 'jobStatus' in jobJson:
status = jobJson['jobStatus']
if status == "esriJobSucceeded":
if 'results' in jobJson:
resultsUrl = jobUrl + "/results/"
resultsJson = jobJson['results']
for paramName in resultsJson.keys():
resultUrl = resultsUrl + paramName
resultResponse = urllib.urlopen(resultUrl, "f=json")
resultJson = json.loads(resultResponse.read())
print resultJson
if status == "esriJobFailed":
if 'messages' in jobJson:
print jobJson['messages']
else:
print "no jobId found in the response"
Знакомство с Python, ArcPy и инструментами-скриптами
Если вы не знакомы с Python, ArcPy и инструментами-скриптами, ниже приведены ссылки, которые помогут вам ознакомиться с этими темами.
Раздел справки | Ресурсы |
---|---|
Краткий обзор процесса создания пользовательских инструментов | Основные принципы создания собственных инструментов геообработки. |
Вводные статьи о языках Python и ArcPy. После знакомства с ними можно переходить к более подробным сведениям о Python и ArcPy. | |
Вводная статья о создании пользовательских инструментов-скриптов с помощью Python. | |
После того как вы ознакомились с процессом создания инструмента-скрипта, можно переходить к подробному описанию установки его параметров. |