Le blog francophone consacré
aux technologies Esri

Publier des contenus avec l'API Python ArcGIS

Je poursuis ma série de tutoriels consacrée à l'usage de l'API ArcGIS for Python. Aujourd'hui, je vous propose de voir quelques unes des instructions les plus courantes pour automatiser la publication de contenus sur votre portail ArcGIS.

  
Le Notebook présenté ci-dessous est téléchargeable ici.

Tuto 2: Publier des contenus

Ce tutoriel a pour objectif d'illustrer comment l'API Python ArcGIS vous permet de publier des contenus sur votre portail ArcGIS. Les exemples de code ci-dessous pourront vous permettre d'élaborer des scripts plus évolués automatisant la publication, en batch, de différentes sources de données en tant que contenus sur le portail et de les partager avec les membres de votre organisation.
In [26]:
from IPython.display import display
from arcgis.gis import GIS

my_gis = GIS('https://www.arcgis.com', 'username', 'password')
In [4]:
my_gis

Publier un simple fichier, par exemple, un document PDF.

Définissons tout d'abord les chemins d'accès à l'image d'aperçu et au fichier PDF:
In [16]:
thumbnail_image = '/Users/glavenu/Documents/Temp/PDF/pdf.png'
PDF_file = '/Users/glavenu/Documents/Temp/PDF/Viroflay/REGLEMENT_du_PLU.pdf'
Voyons tout d'abord comment créer un dossier dans vos contenus:
In [139]:
AGOL_folder = 'Documents PDF'
my_gis.content.create_folder(AGOL_folder)
Out[139]:
{'id': '0f6fc464f70d4f4383fde2144e392725',
 'title': 'Documents PDF',
 'username': 'glavenu_esrifrance'}
Et ci-dessous, l'instruction permettant l'ajout du document PDF dans les contenus de mon portail.
In [20]:
item = my_gis.content.add({'type':'PDF', 'title': 'Réglement du PLU - Viroflay','Description': 'Réglement du PLU de la commune de Viroflay','tags': 'PDF,Viroflay'}, PDF_file, thumbnail_image,None,None,AGOL_folder)  
display(item)
Réglement du PLU - Viroflay
PDF by glavenu_esrifrance
Last Modified: octobre 21, 2018
0 comments, 0 views

Publier un fichier CSV en tant que simple table

La publication d'un fichier csv en tant que table s'effectue en deux étapes. Tout d'abord, vous devez charger le fichier CSV dans vos contenus (ici dans un dossier nommé "Démo"):
In [10]:
csv_file = '/Users/glavenu/Documents/Temp/Production_Miel_Par_Région_En_2017.csv'
csv_item = my_gis.content.add({'type':'CSV','title':'Production de miel par Région en 2017'}, csv_file,None,None,None,'Démo')
display(csv_item)
Production de miel par Région en 2017
CSV by glavenu_esrifrance
Last Modified: octobre 22, 2018
0 comments, 0 views
Une fois la source de données chargée, vous devez la publier en tant que service:
In [11]:
csv_lyr = csv_item.publish()
csv_lyr
Out[11]:
Production de miel par Région en 2017
Feature Layer Collection by glavenu_esrifrance
Last Modified: octobre 22, 2018
0 comments, 0 views
Pour publier un fichier Excel, vous suivrez exactement la même démarche.

Publier un fichier CSV en tant que couche d'entités

Dasn l'exemple ci-dessous, le fichier CSV contient des champs de longitude (lng) et de latitude (lat) permettant de créer une couche d'entités ponctuelles.
In [22]:
csv_file = '/Users/glavenu/Documents/Temp/Unités_et_établissements_Croix_Rouge_française.csv'
csv_item = my_gis.content.add({'type':'CSV','title':'Unités et établissements de la Croix-Rouge Française'}, csv_file,None,None,None,'Démo')

csv_lyr = csv_item.publish({"name":"Unites_Etab_CroixRouge","locationType":"coordinates","latitudeFieldName":"lat","longitudeFieldName":"lng"})
csv_lyr
Out[22]:
Unités et établissements de la Croix-Rouge Française
Feature Layer Collection by glavenu_esrifrance
Last Modified: octobre 22, 2018
0 comments, 0 views
Après avoir publié votre couche d'entités, vous pouvez modifier les paramètres de partage de cette dernière. Pour cela, vous utiliserez la méthode "share" sur votre élément (ici on partage la couche de manière "publique"):
In [20]:
csv_lyr.share(everyone=True, org=True, groups=None, allow_members_to_edit=False)
# Pour mémoire, la syntaxe suivante est également possible
csv_lyr.share(True,True,None,False)
Out[20]:
{'itemId': '8683ffed483446978b5e231cd3dcb687', 'notSharedWith': []}

Publier un fichier de formes (shapefile) ...

La démarche à suivre pour publier un fichier de formes est très similaire à ce que l'on vient de voir précédement. Il s'agit de charger la source de données (le Shapefile dans un fichier ZIP) puis dans un deuxième temps de publier cette source de données en tant que couche d'entités hébergées. Dans cet exemple, j'utilise un minimum de paramétrage mais vous pouvez bien entendu décrire l'ensemble des métadonnées ainsi que les images miniatures des éléments que vous ajoutez dans vos contenus.
In [47]:
my_shapefile = '/Users/glavenu/Documents/Temp/Departements.zip'
shp_item = my_gis.content.add({'type':'Shapefile','title':'Limites des départements de métropoles'},my_shapefile,None,None,None,'Démo')

shp_lyr = shp_item.publish({"name":"Limites_departements_metropoles"})
shp_lyr
Out[47]:
Limites des départements de métropoles
REQUIRED: A summary of the intentions with which the data set was developed.Feature Layer Collection by glavenu_esrifrance
Last Modified: octobre 23, 2018
0 comments, 0 views
Comptons le nombre d'entités de la couche.
In [76]:
from arcgis.features import FeatureLayer

shpFL = FeatureLayer.fromitem(shp_lyr)
num_rec = shpFL.query(where="1=1", return_count_only=True)
num_rec
Out[76]:
96

... et créer une vue sur la couche d'entités résultante

Imaginons maintenant que vous souhaitiez créer une vue pour n'afficher que les départements d'Ile-de-France. A l'aide de l'objet "FeatureLayerCollectionManager" et de la méthode "create_view", vous pouvez créer une nouvelle vue sur la couche d'entités précédement publiée.
In [79]:
from arcgis.features.managers import FeatureLayerCollectionManager

flc = FeatureLayerCollectionManager(shp_lyr.url,my_gis)

my_view = flc.create_view("Départements Ile-de-France",spatial_reference=None, extent=None, allow_schema_changes=True, updateable=False, capabilities='Query', view_layers=None)
my_view
Out[79]:
Départements Ile-de-France
Feature Layer Collection by glavenu_esrifrance
Last Modified: octobre 23, 2018
0 comments, 0 views
Maintenant que la vue est créée, il ne reste plus qu'à spécifier l'ensemble de définition pour restreindre la vue aux département de la région Ile-de-France.
In [82]:
from arcgis.features import FeatureLayer

viewFL = FeatureLayer.fromitem(my_view)
viewFL.manager.update_definition({'viewDefinitionQuery': "NOM_REGION = 'ILE-DE-FRANCE'"})
Out[82]:
{'success': True}
Comptons le nombre d'entités de la vue.
In [81]:
num_rec = viewFL.query(where="1=1", return_count_only=True)
num_rec
Out[81]:
8

Publier une Géodatabase Fichier

Ci-dessous, un exemple de publication de couche(s) hébergée(s) à partir d'une Géodatabase Fichier. Le principe est exactement le même que pour un fichier de formes.
In [138]:
my_GDB = '/Users/glavenu/Documents/Temp/Presidentielles_2017.gdb.zip'
GDB_item = my_gis.content.add({'type':'File Geodatabase','title':'Résultats Présidentielle 2017'}, my_GDB,None,None,None,'Démo')

GDB_lyr = GDB_item.publish({"name":"Resultats_presidentielles_2017"})
GDB_lyr
Out[138]:
Résultats Présidentielle 2017
Feature Layer Collection by glavenu_esrifrance
Last Modified: octobre 23, 2018
0 comments, 0 views
On notera que la publication de paquetage (tpk, vtpk ou slpk) en tant que couches hébergées se fait exactement de la même manière.

Publier un DataFrame Pandas

Pandas est une librairie d'analyse de données très populaire dans l'écosystème Python. Les objets "DataFrame" de Pandas permettent de stocker et d'analyser des informations tabulaire d'une manière extrêmement puissante avec très peu de code. En utilisant la librairie Pandas, vous pouvez intégrer des données tabulaires d'origines très diverses et les croiser facilement avec des données de votre SIG. En utilisant l'API Python ArcGIS vous pourrez à tout moment publier ces DataFrames en tant que tables sur votre portail pour les utiliser dans les apps ArcGIS ou simplement les partager avec d'autres utilisateurs. Si ces tabeaux de données contiennent des informations de localisation, vous pourrez même les publier en tant que couches d'entités.

Ci-dessous, un exemple très simple montrant comment joindre 2 DataFrame pour ensuite publier le résultat en tant que couche d'entités.
Nous commençons par créer un premier DataFrame à partir d'un tableau NumPy. Ce tableau contient des mesures de hateur d'eau sur des stations piézométriques.
In [89]:
import numpy as np
import pandas as pd

data_mesures = np.array([['Station','mesure_2016','mesure_2017','mesure_2018'],
                ['ST_01',10.2,12.9,11.6],
                ['ST_02',10.1,11.9,11.8],
                ['ST_03',11.3,12.7,10.1],
                ['ST_04',10.6,11.5,11.2],
                ['ST_05',12.1,10.7,13.1]])
In [90]:
df_mesures = pd.DataFrame(data=data_mesures[1:,1:], index=data_mesures[1:,0], columns=data_mesures[0,1:])
In [116]:
df_mesures
Out[116]:

mesure_2016 mesure_2017 mesure_2018
ST_01 10.2 12.9 11.6
ST_02 10.1 11.9 11.8
ST_03 11.3 12.7 10.1
ST_04 10.6 11.5 11.2
ST_05 12.1 10.7 13.1
Nous poursuivons avec la création d'un deuxième DataFrame, il contient les stations de mesures et leurs coordonnées.
In [99]:
data_stations = np.array([['Station','latitude','longitude'],
                ['ST_01',48.225,2.851],
                ['ST_02',48.178,2.901],
                ['ST_03',48.320,2.708],
                ['ST_04',48.606,2.544],
                ['ST_05',48.051,2.334]])
In [100]:
df_stations = pd.DataFrame(data=data_stations[1:,1:], index=data_stations[1:,0], columns=data_stations[0,1:])
In [115]:
df_stations
Out[115]:

latitude longitude
ST_01 48.225 2.851
ST_02 48.178 2.901
ST_03 48.32 2.708
ST_04 48.606 2.544
ST_05 48.051 2.334
Nous réalisons ensuite la joiture entre les statinos et les mesures piézométriques.
In [129]:
df = df_stations.join(df_mesures, lsuffix='_stations', rsuffix='_mesures')
In [130]:
df
Out[130]:

latitude longitude mesure_2016 mesure_2017 mesure_2018
ST_01 48.225 2.851 10.2 12.9 11.6
ST_02 48.178 2.901 10.1 11.9 11.8
ST_03 48.32 2.708 11.3 12.7 10.1
ST_04 48.606 2.544 10.6 11.5 11.2
ST_05 48.051 2.334 12.1 10.7 13.1
Il s'agit maintenant de transformer ce "DataFrame" en une collection d'entités (FeatureCollection). On notera que les colonnes "latitude" et "longitude" sont reconnues automatiquement.
In [131]:
fc = my_gis.content.import_data(df)
Construisons la chaîne JSON complète permettant la publication d'une couche sur le portail.
In [136]:
import json
stations_json = json.dumps({"featureCollection": {"layers": [dict(fc.layer)]}}) 
Il nous reste à publier cette source de données en tant que collection d'entités.
In [135]:
stations_item_properties = {'title': 'Mes stations et mesures', 'description':'Mes stations et les mesures 2016 à 2018',
'tags': 'arcgis python api, pandas, csv','text':stations_json,'type':'Feature Collection'}
stations_item = my_gis.content.add(stations_item_properties)
stations_item
Out[135]:
Mes stations et mesures
Feature Collection by glavenu_esrifrance
Last Modified: octobre 23, 2018
0 comments, 0 views
Pour conclure sur les DataFrames, on notera que l'API Python ArcGIS propose une classe SpatialDataFrame qui permet de manipuler des tables avec des colonnes spatiales et ainsi de réaliser des analyses très puissantes combinant les critères attributaires et géographiques des colonnes de votre DataFrame.


Partager cet article:

Rejoindre la discussion

    Les commentaires à propos de cet article:

2 commentaires :

Rémi a dit…

Bonjour,

Merci pour ces tutos !

A l'image de la publication de données depuis ArcMap ou ArcGIS Pro vers AGOL, comment faire pour publier une classe d'entité présente dans une géodatabase fichier en local vers AGOL avec cette API ?

De même, comment réitérer l'opération pour écraser cette données sur AGOL en re-publiant la classe d'entité depuis la géodatabase en local vers AGOL ?

Merci

Gaëtan Lavenu a dit…

Bonjour,

Merci pour ce retour. La publication de données locales vers un portail ArcGIS est clairement dans les objectifs de cette API Python ArcGIS. J'ai prévu de traiter le sujet dans un prochain tuto.