Sie können ein Python-Skript schreiben, um ein Web-Werkzeug oder einen Geoverarbeitungsservice auf verschiedene Weise auszuführen und zu verwenden. Die häufigste Methode der Skriptausführung stellt die Verwendung von ArcPy dar. ArcPy verfügt über integrierte Methoden, um eine Verbindung mit einem Service herzustellen, diesen auszuführen und das Ergebnis zu verarbeiten. Um über die ArcGIS REST API auf den Service zugreifen, verwenden Sie alternativ integrierte Python-Module für REST-Aufrufe mit einer JSON-Struktur zur Übermittlung von Ergebnissen. Um diese Methode zu verwenden, müssen Sie einen Client mit Python-Code von Grund auf neu erstellen. Die meisten Skripte verwenden ArcPy zum Verbinden mit und Verwenden von Geoverarbeitungsservices.
Hinweis:
In den folgenden Beispielen wird ein Geoverarbeitungsservice auf einem verbundenen ArcGIS Server verwendet. Sie verwenden in Python nie das entsprechende Element des Web-Werkzeugs aus dem Portal.
Verwenden von ArcPy
Web-Werkzeuge können über das Python-Fenster in ArcGIS Pro, ein Skriptwerkzeug oder ein eigenständiges Skript aufgerufen werden. Die Funktion ImportToolbox verwendet eine Service-URL und andere Werte zum Herstellen einer Verbindung mit einem Web-Werkzeug und zu dessen Verwendung.
Beispiel: Herstellen einer Verbindung zu einem Service über ImportToolbox mit einer SOAP-URL, zu einem Service in einem Ordner, mit Benutzername und Kennwort.
arcpy.ImportToolbox("https://organization.example.com/<context>/services;GPFolder/BufferService;serverusername;serverpassword")
Ein Web-Werkzeug oder Geoverarbeitungsservice kann entweder synchron oder asynchron ausgeführt werden. Wenn Sie Python-Skripte erstellen, müssen Sie verstehen, wie der Service ausgeführt wird, um ihn zu verwenden. Mit der Eigenschaft IsSynchronous kann festgelegt werden, ob ein Service synchron oder asynchron ausgeführt wird. 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. Wenn ein Service asynchron ausgeführt wird, muss der aktuelle Status regelmäßig abgefragt werden. Wenn die Ausführung des Service abgeschlossen ist, können Sie auf das Ergebnis zugreifen.
Der folgende Python-Code zeigt, wie eine Verbindung mit einem asynchronen Geoverarbeitungsservice hergestellt wird. Der Code verwendet ArcPy-Funktionen, um den Service auszuführen, das Ergebnis abzurufen und es weiter zu verarbeiten. Wenn Sie beim Ausführen des Tasks eine Ergebnisvariable festlegen, kann der Status des Result-Objekts mithilfe einer while-Schleife überprüft werden. Der Task ist abgeschlossen, wenn der Statuscode 4 (erfolgreich) oder höher ausgegeben wird.
Verwenden Sie einen asynchronen Service, um einen Puffer zu erstellen und das Ergebnis lokal zu speichern.
import arcpy
import time
arcpy.ImportToolbox("https://organization.example.com/<context>/services;Elevation/viewshedAlias;serverusername;serverpassword")
result = arcpy.viewshedAlias.Viewshed(r'c:\data.gdb\inputPoint', "10000 Kilometers")
while result.status < 4:
print(result.status)
time.sleep(0.2)
print("Tool finished")
print(result.getMessages())
arcpy.management.CopyFeatures(result, r'c:\results.gdb\result')
Weitere Informationen zum Verwenden von Werkzeugen in Python
Verwenden des REST-Endpunkts
Eine andere Methode der Verwendung eines Web-Werkzeugs ist das Schreiben eines Skripts, das REST-Aufrufe ausführt. Als Datenaustauschformat wird JSON verwendet. Bei diesem Ansatz müssen Sie zum Senden der Anforderung und 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 zuständig sind. Wenn REST-Meldungen gesendet und empfangen werden, werden sie kontinuierlich zurückgegeben. Eine Anforderung kann über eine HTTP GET- oder HTTP POST-Methode gesendet werden, und eine Antwort kann als JSON strukturiert zurückkommen.
Das folgende Beispiel zeigt, wie Sie eine Anforderung senden und eine Antwort verarbeiten.
Senden der Anforderung
Ein Geoverarbeitungsservice zum Erstellen von Sichtfeldern beispielsweise ist über https://organization.example.com/<context>/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 |
---|---|
Eingabe-Beobachterpunktposition (GPFeatureRecordSetLayer) | {"geometryType": "esriGeometryPoint", "spatialReference": {"wkid": 54003}, 'features':[{'geometry': {'x': -13308192.1956127, 'y': 4221903.58555983}}]} |
Sichtfeldentfernung (GPLinearUnit) | {'distance': 8.5, 'units': 'esriMiles'} |
Format (das Format der Ausgabe) | 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.
https://organization.example.com/<context>/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 bei Verwendung des Services-Verzeichnisses oder beim Kopieren des Links in die Adressleiste eines Webbrowsers.
import urllib.request as urlopen
import urllib.parse as urlencode
import urllib.request as request
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 = 'https://organization.example.com/<context>/rest/services/Elevation/ESRI_Elevation_World/GPServer/Viewshed/execute'
req = request.Request(URL, urlencode.urlencode(data).encode('UTF-8'))
response = urlopen.urlopen(req)
response_bytes = response.read()
print(json.loads(response_bytes.decode('UTF-8')))
Das Result-Objekt wird als Zeichenfolge zurückgegeben. Sie können verschiedene Methoden verwenden, um eine Anforderung zu erstellen und ein Ergebnis zu parsen; das obige Beispiel stellt nur eine dieser Methoden dar. Der von einem Web-Werkzeug zurückgegebene JSON-Code kann mithilfe von json.loads() in einem Wörterbuch abgelegt werden. Je nach der Ausgabe des Web-Werkzeugs kann dies die beste Methode sein. Möglicherweise müssen Sie aber andere Optionen prüfen, um die Ausgabe bei Verwendung in Python über REST zu verarbeiten.
Hinweis:
Achten Sie beim Arbeiten mit Ergebnis-Featuren darauf, dass es für Ihren Workflow sinnvoll ist, die tatsächlichen x,y-Paare zu verwenden, da Sie die tatsächlichen Features nicht in einem Format erhalten, das die Geometrie von ArcPy unterstützt.
Bei einem asynchronen Service müssen Sie, ähnlich wie beim obigen Beispiel bei Verwendung von ArcPy, regelmäßig den Status eines Tasks überprüfen, 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 Web-Werkzeug (unter Verwendung von submitJob):
import urllib.request as urlopen
import urllib.parse as urlencode
import urllib.request as request
import json
import time
def sendReq(URL, data=None):
req = request.Request(URL, urlencode.urlencode(data).encode('UTF-8'))
response = urlopen.urlopen(req)
response_bytes = response.read()
return json.loads(response_bytes.decode('UTF-8'))
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 = "https://organization.example.com/<context>/rest/services/Elevation/GPServer/viewshed"
submitUrl = taskUrl + "/submitJob"
submitJson = sendReq(submitUrl, data)
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)
jobJson = sendReq(jobUrl, {"f": "json"})
if 'jobStatus' in jobJson.keys():
status = jobJson['jobStatus']
if status == "esriJobSucceeded":
if 'results' in jobJson:
resultsJson = jobJson['results']
for paramName in resultsJson.keys():
resultsUrl = jobUrl + "/" + resultsJson[paramName]['paramUrl']
resultJson = sendReq(resultsUrl, {"f": "json"})
print(resultJson)
if status == "esriJobFailed":
if 'messages' in jobJson.keys():
print(jobJson['messages'])
else:
print("No jobId found in the response")