Verwenden eines Geoverarbeitungs-Service in Python-Skripten
Sie können ein Python-Skript schreiben, um einen Geoverarbeitungs-Service auf verschiedene Weise auszuführen und zu verwenden. Die häufigste Methode, ein Skript auszuführen, stellt die Verwendung von ArcPy dar. ArcPy verfügt über integrierte Methoden, um eine Verbindung zum Service herzustellen, diesen auszuführen und das Ergebnis zu verarbeiten. Sie können aber auch mithilfe des Services-Verzeichnisses integrierte Python-Module verwenden, um unter Verwendung einer JSON-Struktur zur Übermittlung von Ergebnissen REST-Aufrufe durchzuführen. Um diese Methode zu verwenden, müssen Sie einen Client von Grund auf mit Python-Code erstellen. Die meisten Skripte verwenden ArcPy zum Verbinden mit und Verwenden von Geoverarbeitungs-Services.
Vorgehensweise mit ArcPy
Sie können über das Fenster Python in ArcMap, ein Skriptwerkzeug oder ein eigenständiges Skript auf einen Geoverarbeitungs-Service zugreifen. Zum Verbinden mit und Verwenden von Geoverarbeitungs-Services wird eine URL verwendet.
Stellen Sie mit ImportToolbox eine Verbindung zu einem Service her.
# arcpy.ImportToolbox("http://<hostname>:<port>/arcgis/services;<optional folder>/<service name>","<optional alias>")
arcpy.ImportToolbox("http://degrassi:6080/arcgis/services;GPFolder/BufferService","PointAlias")
Der Pfad, der zum Importieren des Werkzeugs verwendet wird, ist die URL des Geoverarbeitungs-Service.ImportToolbox akzeptiert zwei Parameter: die URL zum Service und einen optionalen Alias für die Toolbox. Der URL-Parameter ist in zwei Teile unterteilt, die mit Strichpunkt getrennt werden (;). Der erste Teil ist die URL (oder der Link) zum Service-Endpunkt, und der zweite Teil ist der Servicename (optional steht vor dem Servicenamen ein Ordnername).
Ein Geoverarbeitungs-Service kann entweder synchron oder asynchron ausgeführt werden. Als jemand, der Python-Skripte erstellt, müssen Sie verstehen, wie der Service ausgeführt wird, um ihn zu verwenden. Die Eigenschaft IsSynchronous kann verwendet werden, um den Ausführungstyp eines Service zu bestimmen. Wenn ein Service synchron ausgeführt wird, werden die Ergebnisse automatisch zurückgegeben, aber es können erst nach Abschluss des Service Aktionen durchgeführt werden. Bei asynchronen Services muss der aktuelle Status der Ausführung regelmäßig abgefragt werden. Wenn die Ausführung des Service abgeschlossen ist, kann auf das Ergebnis zugegriffen werden.
Der folgende Python-Code zeigt, wie eine Verbindung zu einem asynchronen Geoverarbeitungs-Service hergestellt wird. Darüber hinaus wird demonstriert, wie dieser mithilfe von ArcPy-Funktionen ausgeführt wird, wie die Ergebnisse abgerufen werden und wie diese weiter verarbeitet werden. Wenn Sie beim Ausführen des Tasks eine Ergebnisvariable festlegen, kann der Status mithilfe einer While-Schleife überprüft werden. Der Task ist abgeschlossen, wenn der Statuscode 4 (erfolgreich) oder höher ausgegeben wird.
Verwenden eines asynchronen GV-Service, um einen Puffer zu erstellen und das Ergebnis lokal zu speichern
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')
Weitere Informationen zum Ergebnisobjekt und zu Statuscodes sowie zum Erstellen von Raster- und Kartenbildausgaben finden Sie im Hilfethema Verwenden von Werkzeugen in Python.
Vorgehensweise mit REST
Eine andere (weniger gängige) Methode, einen Geoverarbeitungs-Service zu verwenden, ist, eine Anwendung zu erstellen, die REST-Aufrufe ausführt. Als Datenaustauschformat wird JSON verwendet. Bei dieser Methode müssen Sie sowohl zum Senden der Anforderung als auch zum Verarbeiten der Antwort Code schreiben.
Das Senden und Empfangen von REST-Meldungen ist komplizierter, da Sie für sämtliche Aspekte der Syntax der Ein- und Ausgaben selbst zuständig sind. Der Vorteil beim Senden und Empfangen von REST-Meldungen ist, dass sie kontinuierlich zurückgegeben werden. Eine Anfrage kann über eine HTTP-GET-Methode gesendet werden, und eine Antwort kann als JSON strukturiert zurückkommen. Die zentralen Python-Bibliotheken unterstützen das Senden einer HTTP-GET-Anforderung und Funktionen, die das Lesen und Analysieren von JSON-Meldungen erleichtern.
Das folgende Beispiel verwendet einen Service auf den Esri Beispielservern und zeigt, wie Sie eine Verbindung zum Service herstellen, eine Anforderung senden und eine Antwort verarbeiten würden.
Senden der Anforderung
Beispielserver1 enthält z. B. einen Geoverarbeitungs-Service zur Erstellung von Sichtfeldern und ist über http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Elevation erreichbar. Dieser Service verwendet einen Punkt und eine Entfernung als Eingabe und gibt ein Feature-Set zurück. Mit den folgenden Eingaben kann der Service besser verstanden werden:
Parametername | Eingabewert |
---|---|
Input Observation Point (GPFeatureRecordSetLayer) | {"geometryType" : "esriGeometryPoint", "spatialReference" : {"wkid" : 54003}, 'features':[{'geometry':{'x': -13308192.1956127, 'y': 4221903.58555983}}]} |
Viewshed Distance (GPLinearUnit) | { 'distance' : 8.5, 'units' : 'esriMiles' } |
Format (Format, das die Ausgabe aufweisen wird) | JSON |
Diese Anforderung gibt den JSON-Code der vom Service aus sichtbaren Positionen zurück. Die vollständige URL, die zur Erstellung der Anforderung verwendet wird, kann in der Adressleiste eines Webbrowers verwendet werden.
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
Die URL kann mithilfe des Python-Moduls urllib oder urllib2 gesendet werden. Der folgende Python-Code würde die obige Anforderung ähnlich ausführen, wie wenn das Service-Verzeichnis verwendet oder der Link in die Adressleiste eines Webbrowsers kopiert wird.
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)
Das Ergebnisobjekt wird als Zeichenfolge zurückgegeben. Es gibt mehrere unterschiedliche Methoden, um eine Anforderung zu erstellen und ein Ergebnis zu analysieren; das obige Beispiel stellt nur eine Methode dar. Der von einem Geoverarbeitungs-Service zurückgegebene JSON-Code kann mithilfe von json.loads() in einem Wörterbuch abgelegt werden, wie im vorherigen Beispiel gezeigt. Je nach der Ausgabe des Geoverarbeitungs-Service kann dies die beste Methode sein. Möglicherweise müssen Sie aber andere Optionen prüfen, um die Ausgabe von einem Geoverarbeitungs-Service zu verarbeiten, wenn dieser in Python über REST verwendet wurde.
Achten Sie beim Arbeiten mit Ergebnis-Features darauf, dass es für Ihren Arbeitsablauf sinnvoll ist, die tatsächlichen XY-Paare zu verwenden, da Sie die tatsächlichen Features nicht in einem Format erhalten, das Geometrien in ArcGIS unterstützt.
Bei einem asynchronen Service müssen Sie – ähnlich wie beim obigen Beispiel bei Verwendung von ArcPy – regelmäßig den Status des Tasks abfragen, um zu sehen, ob der Task beendet ist. Ihr Python-Code könnte in der Statusmeldung jobStatus nach dem Ausdruck esriJobSucceeded oder esriJobFailed suchen, der beim Überprüfen des Auftragsstatus zurückgegeben wird. Das folgende Codebeispiel zeigt eine Technik für das Arbeiten mit einem asynchronen Geoverarbeitungs-Service (unter Verwendung von 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"
Erste Schritte mit Python, ArcPy und Skriptwerkzeugen
Wenn Sie mit Python, ArcPy und Skriptwerkzeugen noch nicht vertraut sind, finden Sie in der Tabelle unten einige Themen, die Ihnen bei den ersten Schritten helfen.
Hilfethema | Inhalt |
---|---|
Kurzer Überblick über das Erstellen von benutzerdefinierten Werkzeugen | Grundlegende Konzepte beim Erstellen eigener Geoverarbeitungswerkzeuge |
Einführung in Python und ArcPy. Von diesen Themen gelangen Sie zu ausführlicheren Themen über Python und das ArcPy-Site-Paket. | |
Kurzer Überblick über das Erstellen von Werkzeugen in Python | Einführung in das Erstellen von benutzerdefinierten Skriptwerkzeugen mit Python. |
Nachdem Sie sich mit dem Erstellen von Skriptwerkzeugen vertraut gemacht haben, wird häufig auf dieses Thema verwiesen, da es ausführlich erläutert, wie Sie Skriptwerkzeug-Parameter definieren. |