Parfois, il est nécessaire de pouvoir gérer les pièces jointes d'une certaine manière, dans cet article nous aborderons certains concepts et plus tard sur mon github vous trouverez plusieurs exemples que vous pouvez modifier à votre goût.<\/P>
Pour commencer, pour pouvoir accéder aux services d'ArcGIS Enterprise (Portal) ou ArcGIS Online, la bibliothèque arcgis est requise, donc si vous ne l'avez pas installée, vous devez le faire (elle est incluse lors de l'installation d'ArcGIS Pro ou dans le Python d'ArcGIS Enterprise).<\/P>
Cette première section vous permettra d'accéder à votre Portal ou ArcGIS Online<\/P>
#Se connecter au Portal
PORTAL = GIS("url", "usuario","contraseña")<\/P>
Selon ce que vous faites, il peut être nécessaire d'obtenir le token, cela est utilisé essentiellement lorsque vous souhaitez voir l'url des pièces jointes et que le service n'est pas public.<\/P>
token = PORTAL._con.token<\/P>
Après cela, nous pouvons déjà accéder au service, l'api de arcgis permet d'accéder aux objets stockés dans le Portal ou ArcGIS Online, pour cela depuis notre site nous accéderons à l'adresse du service (c'est celui qui a l'icône jaune avec rouge). (C'est un texte donc il doit être entre guillemets)<\/P>
servicio = PORTAL.content.get('item id')<\/P>
Ensuite, lorsque nous accédons à cette partie, nous pouvons voir les différentes couches et tables que possède le service que nous consultons, par conséquent il est nécessaire de placer le numéro qui indique l'indice de couche ou table, et ici je dois préciser que si nous avons par exemple : une entité géographique et une table elles auront toutes deux l'indice 0, cela parce que le système détecte comme une liste de couches et une liste de tables dans le service, donc dans le cas où il existe une couche et une table elles ont toutes deux l'indice 0. Maintenant bien si on a deux couches et une table, il y aura une couche avec un indice 0, l'autre avec 1 et la table sera 0. J'espère ne pas causer de confusion avec ça haha.<\/P>
Le fait est que pour paramétrer j'ai fait ce qui suit:<\/P>
num_capa=int(indice)<\/P>
Note : c'est une donnée numérique donc vous écrivez simplement la valeur<\/P>
Comme indiqué précédemment, il peut exister des couches ou des tables, de cette façon, il se peut aussi que les pièces jointes se trouvent dans une couche ou une table, donc j'ai vu la nécessité d'ajouter quelque chose comme ça à l'outil:<\/P>
tipo="ici on écrit capa ou tabla"
if tipo=="capa":
capa=(servicio.layers)[num_capa]
elif tipo=="tabla":
capa =(servicio.tables)[num_capa]<\/P>
Pour construire l'URL, la même API d'Esri nous indique comment l'obtenir, seulement elle ne le fait pas comme un texte mais comme un objet, donc j'ai fait ce qui suit en utilisant la bibliothèque python re:<\/P>
cap_url=str(re.findall('htt.*'+str(num_capa), str(capa)))
cap_url=str(cap_url)[2:-2]<\/P>
De cette façon elle transforme l'objet en string (texte)<\/P>
Maintenant, nous devons identifier le dossier dans lequel nous allons enregistrer les pièces jointes
carpeta=r"adresse du dossier souhaité"<\/P>
Un autre paramètre que j'utilise est un champ texte vide où je stockerai l'adresse où sont stockées les pièces jointes, de cette façon on peut paramétrer avec le dataframe de pandas et c'est exactement ce que nous ferons ici:<\/P>
sdf = capa.query(where="nom du champ"+" IS NULL").sdf<\/P>
De cette façon la requête ira uniquement vers ceux qui ont ce champ vide<\/P>
Après cela on génère une liste vide qui capturera les enregistrements que nous allons inclure dans une édition, cela sera très important plus tard car cela permet d'insérer les données dans la liste vide et de les envoyer à la méthode d'édition, selon ce que nous faisons.<\/P>
elementos_a_actualizar = []<\/P>
Maintenant oui nous devons itérer sur la couche ou table qui contient les pièces jointes<\/P>
#Itérer à travers le dataframe
for index, row in sdf.iterrows():
objID=str("champ contenant l'objectid")
Attachments = capa.attachments.get_list(oid=objID)<\/P>
Dans la même itération j'ai mis un if, comme vous pouvez voir dans les lignes précédentes une liste est créée dans Attachments, par conséquent une caractéristique des listes est que nous pouvons compter le nombre d'éléments et c'est précisément ce que fait le if, car on va interroger uniquement là où cette liste est supérieure à 0, ainsi nous serons doublement sûrs de travailler uniquement avec des données qui ont des pièces jointes.<\/P>
if len(Attachments)>0:<\/P>
Dans cette condition nous allons itérer sur les pièces jointes correspondant à chaque ObjectId de la couche principale:<\/P>
for k in range(len(Attachments)):
attachmentId = Attachments[k]['id']
attachmentName = Attachments[k]['name']
img_url = cap_url+"\/{0}\/attachments\/{1}".format(objID,attachmentId)+"?token="+token
fileName = os.path.join(carpeta, attachmentName)<\/P>
Comme vous pouvez le voir, on obtient l'Id de la pièce jointe et son nom, avec cela je concatène l'url obtenue précédemment avec l'objectid de la couche ou table et l'Id de la pièce jointe. Ainsi on obtient une URL unique pour chaque pièce jointe.<\/P>
Avec cela il est aussi possible de concaténer l'adresse du dossier que j'avais précédemment et le nom du fichier que possède la pièce jointe.<\/P>
Avec cela on peut jouer un peu, dans ce cas je vais vous montrer quelque chose pour que le système sache si une pièce jointe avec le même nom a déjà été téléchargée dans le dossier indiqué, par conséquent il ne téléchargerait pas cette pièce jointe. Mais il est aussi possible de lui dire qu'il crée un dossier pour chaque élément et qu'il y télécharge toutes les pièces jointes correspondant à cet enregistrement. Dans ce cas je vais faire en sorte qu'il crée le fichier, une autre fois je vous montrerai comment créer le dossier, qui soit dit en passant se trouve dans le script de descarga adjuntos du github.<\/A><\/P>Bon comme je disais voici la partie pour vérifier si la pièce jointe existe:<\/P>
existe_archiv=os.path.exists(fileName)
if existe_archiv is True:
arcpy.AddMessage("Ne pas télécharger")
else:
arcpy.AddMessage("Télécharger ShapeFile "+attachmentName)<\/P>
Comme vous pouvez le voir j'utilise ici les bibliothèques os et arcpy, celle d'os sert à vérifier l'existence ou non du fichier dans le dossier indiqué et arcpy ici sert à renvoyer un message dans ArcGIS, qui soit dit en passant si vous ne l'utilisez pas vous pouvez remplacer ici arcpy.AddMessage par print.<\/P>
Maintenant avec l'URL nous pouvons télécharger les pièces jointes<\/P>
try:
arcpy.AddMessage("Obtention de l'URL du ShapeFile")
request=urllib.request.urlretrieve(img_url)
req = requests.get(img_url)
file = open(fileName, 'wb')
for chunk in req.iter_content(100000):
file.write(chunk)
file.close()
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
arcpy.AddMessage("ShapeFile "+attachmentName+ " téléchargé correctement dans le dossier " + carpeta)
Acá borra el adjunto de la capa
capa.attachments.delete(objID,attachmentId)
Acá vamos a capturar el error para mostrarlo en el sistema (en mi caso estaba descargando shapefiles, por eso el mensaje dice eso.
except urllib.error.HTTPError as err:
arcpy.AddMessage("Erreur " + str(err.code) + " aucun ShapeFile à télécharger ou problème de connexion")
En este momento y dentro de la identación del if (donde nous demandions de nous renvoyer là où la liste avait plus de 0 éléments) nous utiliserons la méthode qui capturera les données et les annexera à notre liste vide.<\/P>
#Mettre à jour le champ de l'adresse du dossier
selection=capa.query(where="champ de l'objectid"+"="+objID)
elem_actualizar=(selection.features[0])
elem_actualizar.attributes["nom du champ"]=str(fileName)<\/P>
Maintenant, nous annexerons les enregistrements que nous capturons qui ont des pièces jointes et le champ qui contiendra l'adresse vide
elements_a_actualizar.append(elem_actualizar)<\/P>
Après avoir annexé ces données dans la liste vide, avec cette méthode, nous procéderons à utiliser la liste pour éditer les éléments. Cela se fait en dehors de l'itération du dataframe, c'est-à-dire en dehors de tout.<\/P>
capa.edit_features(updates=elements_a_actualizar)<\/P>
Comme vous pouvez le voir, updates indique qu'il est égal à la liste vide qui avait été indiquée précédemment.<\/P>
Et c'est tout, j'ai plusieurs exemples dans mon
GitHub<\/A>, dans ceux-ci je télécharge des pièces jointes et je les supprime du service, ou simplement je les télécharge, ou dans un autre cas, je télécharge des pièces jointes qui sont des shapefiles et je les joins à un autre service comme de nouvelles entités, je peux volontiers vous expliquer comment ils fonctionnent plus tard.<\/P>Une autre chose très importante que je dois préciser est que le toolbox qui se trouve en pièce jointe est pour la version 3 et suivantes, si vous avez une version antérieure à 2.9, il faut configurer le toolbox, c'est pourquoi je joins aussi les scripts pour que vous puissiez le personnaliser. Je laisse ici un
lien<\/A> qui est un petit guide pour configurer des outils avec des versions inférieures à 2.9<\/STRONG><\/P>J'espère que cela vous aidera<\/P>
<\/P>