Manchmal ist es notwendig, Anhänge auf irgendeine Weise verwalten zu können. In diesem Artikel werden wir bestimmte Konzepte behandeln und später auf meinem GitHub mehrere Beispiele bereitstellen, die Sie nach Belieben anpassen können.<\/P>
Um zu beginnen, um auf die Dienste von ArcGIS Enterprise (Portal) oder ArcGIS Online zugreifen zu können, wird die Bibliothek arcgis benötigt. Wenn Sie diese nicht installiert haben, müssen Sie dies tun (sie ist enthalten, wenn ArcGIS Pro oder das Python von ArcGIS Enterprise installiert wird).<\/P>
Dieser erste Abschnitt ermöglicht Ihnen den Zugriff auf Ihr Portal oder ArcGIS Online.<\/P>
#Mit dem Portal verbinden
PORTAL = GIS("url", "Benutzer","Passwort")<\/P>
Je nachdem, was Sie tun, kann es notwendig sein, das Token zu erhalten. Dies wird im Grunde verwendet, wenn Sie die URL der Anhänge sehen möchten und der Dienst nicht öffentlich ist.<\/P>
token = PORTAL._con.token<\/P>
Danach können wir auf den Dienst zugreifen. Die arcgis API erlaubt den Zugriff auf die im Portal oder ArcGIS Online gespeicherten Objekte. Dazu greifen wir von unserer Seite aus auf die Adresse des Dienstes zu (es ist der mit dem gelben und roten Symbol). (Es ist ein Text, daher muss er in Anführungszeichen stehen)<\/P>
dienst = PORTAL.content.get('item id')<\/P>
Wenn wir diesen Teil aufrufen, können wir die verschiedenen Layer und Tabellen sehen, die der abgefragte Dienst besitzt. Daher muss die Nummer angegeben werden, die den Index des Layers oder der Tabelle angibt. Hier muss ich klarstellen, dass wenn wir zum Beispiel eine geografische Entität und eine Tabelle haben, beide den Index 0 haben. Das liegt daran, dass das System eine Liste von Layern und eine Liste von Tabellen innerhalb des Dienstes erkennt. Daher haben im Fall einer vorhandenen Schicht und einer Tabelle beide den Index 0. Wenn es zwei Layer und eine Tabelle gibt, hat ein Layer den Index 0, der andere 1 und die Tabelle ist 0. Ich hoffe, ich verursache damit keine Verwirrung hehe.<\/P>
Das Problem ist, dass ich zur Parametrisierung Folgendes gemacht habe:<\/P>
num_layer=int(index)<\/P>
Hinweis: Es ist ein numerischer Wert, daher schreiben Sie einfach den Wert.<\/P>
Wie zuvor erwähnt, können Layer oder Tabellen existieren. Ebenso können sich die Anhänge in einem Layer oder einer Tabelle befinden. Deshalb sah ich mich gezwungen, so etwas zum Werkzeug hinzuzufügen:<\/P>
typ="hier schreibt man layer oder tabelle"
if typ=="layer":
layer=(dienst.layers)[num_layer]
elif typ=="tabelle":
layer =(dienst.tables)[num_layer]<\/P>
Um die URL zu erstellen, zeigt uns die Esri API selbst, wie man sie erhält. Allerdings macht sie das nicht als Text sondern als Objekt. Deshalb habe ich Folgendes mit der Python-Bibliothek re gemacht:<\/P>
layer_url=str(re.findall('htt.*'+str(num_layer), str(layer)))
layer_url=str(layer_url)[2:-2]<\/P>
So wird das Objekt in einen String (Text) umgewandelt.<\/P>
Jetzt müssen wir den Ordner identifizieren, in dem wir die Anhänge speichern wollen.
ordner=r"Pfad des gewünschten Ordners"<\/P>
Ein weiterer Parameter, den ich verwende, ist ein leeres Textfeld, in dem ich den Pfad speichere, wo die Anhänge gespeichert sind. So kann man mit dem pandas DataFrame parametrisieren und genau das machen wir hier:<\/P>
sdf = layer.query(where="Feldname"+" IS NULL").sdf<\/P>
So geht die Abfrage nur an diejenigen mit diesem leeren Feld.<\/P>
Danach wird eine leere Liste erstellt, die die Datensätze erfasst, die wir in einer Bearbeitung einschließen werden. Das wird später sehr wichtig sein, da es erlaubt, Daten in die leere Liste einzufügen und sie an die Bearbeitungsmethode zu senden, je nachdem was wir tun.<\/P>
elemente_zu_aktualisieren = []<\/P>
Jetzt müssen wir über den Layer oder die Tabelle iterieren, die die Anhänge enthält.<\/P>
#Über das DataFrame iterieren
for index, row in sdf.iterrows():
objID=str("Feld mit objectid")
Anhänge = layer.attachments.get_list(oid=objID)<\/P>
Innerhalb derselben Iteration habe ich ein if gesetzt. Wie Sie in den vorherigen Zeilen sehen können, wird eine Liste in Attachments erstellt. Eine Eigenschaft von Listen ist es, dass wir die Anzahl der Elemente zählen können und genau das macht das if: Wir fragen nur dort ab, wo diese Liste größer als 0 ist. So sind wir doppelt sicher, dass wir nur mit Daten arbeiten, die Anhänge haben.<\/P>
if len(Anhänge)>0:<\/P>
Innerhalb dieser Bedingung iterieren wir über die Anhänge für jede ObjectId des Hauptlayers:<\/P>
for k in range(len(Anhänge)):
attachmentId = Anhänge[k]['id']
attachmentName = Anhänge[k]['name']
bilde_url = layer_url+"\/{0}\/attachments\/{1}".format(objID,attachmentId)+"?token="+token
fileName = os.path.join(ordner, attachmentName)<\/P>
Wie Sie sehen können, wird die Id des Anhangs und der Name erhalten. Damit verbinde ich die zuvor erhaltene URL mit der ObjectId des Layers oder der Tabelle und der Id des Anhangs. So erhält man eine eindeutige URL für jeden Anhang.<\/P>
Damit ist es auch möglich, den Pfad des zuvor genannten Ordners mit dem Dateinamen des Anhangs zu verknüpfen.<\/P>
Damit kann man etwas spielen. In diesem Fall zeige ich Ihnen etwas, damit das System weiß, ob ein Anhang mit demselben Namen bereits im angegebenen Ordner heruntergeladen wurde und diesen Anhang daher nicht herunterladen würde. Es ist aber auch möglich zu sagen, dass für jedes Element ein Ordner erstellt wird und alle Anhänge dieses Eintrags dort heruntergeladen werden. In diesem Fall werde ich es so machen, dass es die Datei erstellt. Bei anderer Gelegenheit zeige ich Ihnen wie man den Ordner erstellt – dieser befindet sich übrigens im Skript von descarga adjuntos del github.<\/A><\/P>Also wie gesagt hier der Teil zum Überprüfen ob der Anhang existiert:<\/P>
existiert_datei=os.path.exists(fileName)
if existiert_datei is True:
arcpy.AddMessage("Nicht herunterladen")
else:
arcpy.AddMessage("ShapeFile herunterladen "+attachmentName)<\/P>
Wie Sie sehen können verwende ich hier die Bibliotheken os und arcpy. os dient dazu zu prüfen ob die Datei im angegebenen Ordner existiert oder nicht und arcpy dient hier dazu eine Nachricht innerhalb von ArcGIS zurückzugeben – falls Sie arcpy nicht verwenden wollen können Sie arcpy.AddMessage hier durch print ersetzen.<\/P>
Jetzt können wir mit der URL die Anhänge herunterladen.<\/P>
try:
""""""""""""""""""""""""""""
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
try:
arcpy.AddMessage("Hole URL des ShapeFiles")
request=urllib.request.urlretrieve(bilde_url)
req = requests.get(bilde_url)
file = open(fileName, 'wb')
for chunk in req.iter_content(100000):
file.write(chunk)
file.close()
arcpy.AddMessage("ShapeFile " + attachmentName + " erfolgreich im Ordner " + ordner + " heruntergeladen")
#Aktualisieren des Feldes mit dem Ordnerpfad
auswahl=capa.query(where="campo del objectid"+"="+objID)
elem_aktualisieren=(auswahl.features[0])
elem_aktualisieren.attributes["nombre del campo"]=str(fileName)<\/P>
Jetzt fügen wir die Datensätze hinzu, die wir erfassen und die Anhänge haben und das Feld, das den leeren Pfad enthalten wird
elementos_a_actualizar.append(elem_aktualisieren)<\/P>
Nachdem wir diese Daten in der leeren Liste angehängt haben, werden wir mit dieser Methode die Liste verwenden, um die Elemente zu bearbeiten. Dies geschieht außerhalb der Iteration des Dataframes, also außerhalb von allem.<\/P>
capa.edit_features(updates=elementos_a_actualizar)<\/P>
Wie Sie sehen können, zeigt updates an, dass es gleich der zuvor angegebenen leeren Liste ist.<\/P>
Und das ist alles, ich habe mehrere Beispiele in meinem
GitHub<\/A>, in denen ich Anhänge herunterlade und sie vom Service lösche, oder sie einfach nur herunterlade, oder in einem anderen Fall lade ich Anhänge herunter, die Shapefiles sind, und füge sie einem anderen Service als neue Entitäten hinzu. Gerne kann ich Ihnen später erklären, wie sie funktionieren.<\/P>Eine weitere sehr wichtige Sache, die ich klarstellen muss, ist, dass das angehängte toolbox für Version 3 und höher ist. Wenn Sie eine Version vor 2.9 haben, müssen Sie das toolbox konfigurieren. Deshalb füge ich auch die Skripte bei, damit Sie es anpassen können. Hier lasse ich einen
Link<\/A>, der eine kleine Anleitung zum Konfigurieren von Werkzeugen mit Versionen unter 2.9 ist.<\/STRONG><\/P>Ich hoffe, es hilft Ihnen<\/P>
<\/P>