Arcade est un langage d'expressions pouvant être utilisé sur l'ensemble du
système ArcGIS. Basé sur une syntaxe simple (inspirée de Python et de
JavaScript), Arcade est supporté dans l'ensemble des applications web, mobiles
et bureautiques ArcGIS. Par exemple, une expression définie sur les étiquettes
d'une couche dans ArcGIS Pro sera également exécutée une fois les contenus
publiés et affichés dans une carte web, et inversement. Arcade peut être utilisé
dans différents contextes pour :
- contrôler le rendu des entités d'une couche,
- définir le texte de vos étiquettes,
- personnaliser le contenu des fenêtres contextuelles,
- calculer les valeurs d'un champ,
- définir des comportements dans vos formulaires intelligents,
- personnaliser des sources de données dans vos tableaux de bord,
- ...
Il devient important aujourd'hui de savoir l'utiliser pour pouvoir tirer
profit de tout son potentiel. Dans de nombreux cas, avec de simples
expressions vous implémenterez des comportements avancés et vous vous
simplifierez grandement la vie. Comme je l'ai fait il y a quelques années
avec Python, qui reste toujours un langage incontournable pour l'automatisation des
tâches d'administration et d'analyse dans ArcGIS, je vous propose une série
d'exemples d'expressions qui, je l'espère, couvriront la majorité de vos
besoins :
Quelques éléments de base avant de commencer...
L'objectif du langage d'Arcade est de pouvoir définir une expression plus
ou moins évoluée qui au final doit renvoyer une valeur. Pour cela, il
dispose d'une librairie de fonctions et de variables prédéfinies simples
et performantes pour répondre aux besoins du contexte dans lequel vous
exécutez cette expression (calcul de champ, rendu de couche, étiquetage,
fenêtre contextuelle, ...).
Lors de la rédaction de votre expression, elle pourra être écrite sur une
seule ligne ou sur plusieurs lignes. Par exemple, l'expression ci-dessous
calcule le pourcentage d'évolution entre les valeurs du champ POP_2016 et
POP_2017.
// Retour implicite
($feature.POP_2017 / $feature.POP_2016) * 100
Dans l'expression ci-dessus, la valeur de l'expression est retournée de
manière explicite. L'utilisation explicite de l'instruction
"return" permettra de lever toute ambiguïté le cas échéant.
// Retour explicite
return ($feature.POP_2017 / $feature.POP_2016) * 100
Dans le contexte d'une expression plus évoluée, rédigée sur plusieurs
lignes, il sera d'autant plus important de définir la valeur à retourner
que votre expression contiendra probablement plusieurs variables.
Vous pourrez préciser de manière implicite la variable à retourner en la
mentionnant à la fin de votre expression, comme ici avec la variable
"somme":
// Retour implicite
var tableau = [10,20,30,40,50,60,70]
var somme = 0;
for(var n in tableau){
somme += tableau[n];
}
somme;
Cependant, il est préférable de définir la valeur à retourner de manière
explicite, notamment pour sa lisibilité, en utilisant l'instruction
"
return" évoquée précédemment.
// Retour explicite
var tableau = [10,20,30,40,50,60,70]
var somme = 0;
for(var n in tableau){
somme += tableau[n];
}
return somme;
Un autre point important du langage Arcade concerne les variables
globales. Commençant par le caractère "
$", elles permettent
d'accéder à des objets spécifiques hérités du contexte (profil) dans
lequel est exécuté l'expression. Par exemple, la variable
"
$feature" représente chacune des entités d'une couche lorsque vous
calculez un champ ou une expression d'étiquetage. Autre exemple, la
variable "
$map" représentera la carte courante dans le contexte
d'une expression d'étiquetage.
L'expression ci-dessous permet de diviser par 1000 les valeurs du champ
contenant le chiffre d'affaires de chacun des magasins de ma table.
$feature.CA2017 / 1000
On notera également qu'à la différence d'autre langages (comme Python par
exemple), Arcade ne possède qu'un seul type d'objet numérique :
Number.
Enfin, dernier élément important avant de découvrir différents exemples,
vous noterez qu'Arcade est un langage qui n'est pas sensible à la casse.
Expressions sur les chaînes de caractères
Concaténer deux champs de type chaîne de caractères:
$feature.MonChamp1 + $feature.MonChamp2
Concaténer deux champs de type chaîne de caractères avec un espace entre les
deux chaînes:
$feature.MonChamp1 + ' ' + $feature.MonChamp2
ou
Concatenate([$feature.MonChamp1,$feature.MonChamp2],' ')
Concaténer plusieurs champs dont certains sont de type numérique (ici: le
champ Hauteur):
'La hauteur du bâtiment ' + $feature.IdBat + ' est de ' + Text($feature.Hauteur) + ' m.'
Concaténer plusieurs champs de type chaîne de caractères en intégrant un
saut de ligne (Attention, pour le moment ce saut de ligne n'est pas reconnu
dans le cas d'une expression utilisé pour un étiquetage):
$feature.MonChamp1 + TextFormatting.NewLine + $feature.MonChamp2
Calculer le nombre de caractères d'une chaîne:
Count($feature.MonChamp)
Remplacer un caractère par un autre caractère:
Replace($feature.MonChamp, 'é', 'e')
Remplacer les valeurs nulles du champ par la chaîne "Aucune donnée":
DefaultValue($feature.MonChamp, 'Aucune donnée')
Extraire le premier caractère d'une chaîne:
Left($feature.MonChamp,1)
Extraire le deuxième caractère d'une chaîne:
Mid($feature.MonChamp,1,1)
Extraire le dernier caractère d'une chaîne:
Right($feature.MonChamp,1)
Extraire l'avant-dernier caractère d'une chaîne:
Mid($feature.MonChamp,Count($feature.MonChamp)-2,1)
Extraire les 5 premiers caractères d'une chaîne:
Left($feature.MonChamp,5)
Extraire les 3 derniers caractères d'une chaîne:
Right($feature.MonChamp,3)
Extraire une partie quelconque d'une chaîne (ici: neuvième, dixième et
onzième caractère):
Mid($feature.MonChamp,8,3)
Extraire le 4ième mot d'une chaîne (dont les mots sont séparés par un
espace):
Split($feature.MonChamp,' ')[3]
Extraire la 5ième mot d'une chaîne dont les mots sont séparés par une
virgule:
Split($feature.MonChamp,',')[4]
Retirer les espaces inutiles en fin de chaîne:
var end_spaces = 0
for(var i=Count($feature.MonChamp)-1; i>0; i--) {
if($feature.MonChamp[i]==' ')
{
end_spaces += 1;
}
else
{
break
}
}
return Left($feature.MonChamp,Count($feature.MonChamp)-end_spaces);
Retirer les espaces inutiles en début de chaîne:
var end_spaces = 0
for(var i=Count($feature.MonChamp)-1; i>0; i--) {
if($feature.MonChamp[i]==' ')
{
end_spaces += 1;
}
else
{
break
}
}
return Left($feature.MonChamp,Count($feature.MonChamp)-end_spaces);
Retirer les espaces inutiles en début et fin de chaîne:
var end_spaces = 0
for(var i=0; i
$feature.MonChamp)); i++) { if($feature.MonChamp[i]==' ')
{
end_spaces += 1;
}
else
{
break
}
}
return Right($feature.MonChamp,Count($feature.MonChamp)-end_spaces);
Mettre tous les caractères des valeurs d'un champ en minuscule:
Lower($feature.MonChamp)
Mettre tous les caractères des valeurs d'un champ en majuscule:
Upper($feature.MonChamp)
Mettre le premier caractère en majuscule et le reste en minuscule:
Proper($feature.MonChamp, firstword)
Mettre une majuscule au début de chaque mot:
Proper($feature.MonChamp, everyword)
Insérer une simple-quote dans une chaîne:
'Voici l\'insertion d\'apostrophes'
Insérer une double-quote dans une chaîne:
'Voici \"la citation\"'
Choisir une chaîne de manière aléatoire parmi une liste de chaîne:
var my_list = ['Pomme','Poire','Orange','Kiwi','Fraise']
return my_list[Floor(Random()*Count(my_list))]
Compter le nombre de lettres distinctes dans une chaîne de caractères:
var my_string = $feature.MonChamp;
var my_array = [];
for(var i=0; my_string; i++) {
my_array[i]= my_string[i]
}
return Count(Distinct(my_array))
Expressions sur les valeurs numériques
Convertir une chaîne en numérique:
Number($feature.MonChamp)
Remplacer les valeurs nulles par la valeur 0:
DefaultValue($feature.MonChamp,0)
Arrondir à l'entier inférieur ou supérieur selon les règles mathématiques
classiques:
Round($feature.MonChamp)
Arrondir à l'entier supérieur:
Ceil($feature.MonChamp)
Arrondir à l'entier inférieur:
Floor($feature.MonChamp)
Arrondir à la 3ème décimale:
Round($feature.MonChamp,3)
Générer un nombre entier aléatoire entre 0 et 9:
Round(Random()*9)
Générer un nombre décimal aléatoire entre 0 et 1:
Random()
Générer un nombre décimal aléatoire entre 20 et 80:
20 + (Random()*60)
Calculer la valeur absolue d'un nombre:
Abs($feature.MonChamp)
Calculer l'opposé d'un nombre:
var myNumber = $feature.MonChamp
return -myNumber
Calculer le modulo d'un nombre:
$feature.MonChamp % 360
Calculer le carré d'un nombre:
Pow($feature.MonChamp,2)
Calculer le cube d'un nombre
Pow($feature.MonChamp,3)
Calculer la racine carrée d'un nombre
Sqrt($feature.MonChamp)
Calculer la racine cubique d'un nombre
Pow($feature.MonChamp,1/3)
Calculer le volume d'une sphère à partir du champ contenant le rayon (exemple
d'utilisation de la constant Pi):
4 / 3 * PI * Pow($feature.Rayon,3)
Calculer la valeur minimum de plusieurs champs
Min([$feature.Champ1,$feature.Champ2,$feature.Champ3,$feature.Champ4])
Calculer la valeur maximum de plusieurs champs
Max([$feature.Champ1,$feature.Champ2,$feature.Champ3,$feature.Champ4])
Calculer la somme des valeurs de plusieurs champs
Sum([$feature.Champ1,$feature.Champ2,$feature.Champ3,$feature.Champ4])
Calculer la moyenne des valeurs de plusieurs champs
Mean([$feature.Champ1,$feature.Champ2,$feature.Champ3,$feature.Champ4])
Calculer l'écart-type des valeurs de plusieurs champs
Stdev([$feature.Champ1,$feature.Champ2,$feature.Champ3,$feature.Champ4])
Calculer la différence entre la valeur du champ et la valeur minimum de ce
champ sur l'ensemble de la table (ou la couche)
$feature.Champ1 - Min($layer,"Champ1")
Calculer la différence entre la valeur du champ et la valeur maximum de ce
champ sur l'ensemble de la table (ou la couche)
$feature.Champ1 - Max($layer,"Champ1")
Calculer la différence entre la valeur du champ et la valeur moyenne de ce
champ sur l'ensemble de la table (ou la couche)
$feature.Champ1 - Mean($layer,"Champ1")
Expressions sur les dates
Calculer la date courante:
Now()
ou
Date()
Calculer la date courante en tant que chaîne de caractères:
Text(Now(),'DD/MM/Y')
//Retourne cette chaîne: "26/12/2018"
Créer une date et heure courante:
Text(Now(), 'DD/MM/Y HH:mm:ss')
//Retourne cette chaîne: "26/12/2018 15:46:27"
Créer une date et heure spécifique (standard ISO 8601):
Date('2017-03-19T13:57:45')
//Retourne cette date: 19/03/2017 13:57:45
Créer une date spécifique:
Date('2017-03-19')
Créer une date à partir d'une époque Unix (depuis 01/01/1970 en millisecondes):
Date(1476987783555)
Calculer le nombre de jours compris entre la date actuelle et la date d'un
champ:
var startDate = Date()
var endDate = $feature.MonChampDate;
return DateDiff(startDate, endDate, 'days');
Calculer le nombre de secondes compris entre la date actuelle et la date d'un
champ:
var startDate = Date()
var endDate = $feature.MonChampDate;
return DateDiff(startDate, endDate, 'seconds');
Calculer une date en ajoutant 3 mois à la date d'un champ:
var myDate = $feature.MonChampDate;
return DateAdd(myDate, 3, 'months');
Calculer une date en ajoutant 10 jours à la date d'un champ:
var myDate = $feature.MonChampDate;
return DateAdd(myDate, 10, 'days');
Calculer une date en ajoutant 12 heures à la date d'un champ:
var myDate = $feature.MonChampDate;
return DateAdd(myDate, 12, 'hours');
Calculer le jour de la semaine (1, 2, 3,...) de la date d'un champ:
Weekday($feature.MonChampDate);
Calculer le jour de la semaine (par exemple: lundi) de la date d'un champ:
var j = Weekday($feature.MonChampDate);
var jour = Decode(j,
1, 'Lundi',
2, 'Mardi',
3, 'Mercredi',
4, 'Jeudi',
5, 'Vendredi',
6, 'Samedi',
7, 'Dimanche','');
return jour
Calculer une date à partir d'un champ contenant des
timestamps:
Date($feature.MonChampTimestamp)
Calculer des
timestamps à partir d'un champ contenant des dates:
Number($feature.MonChampDate)
Calculer une date locale à partir d'un champ contenant des dates UTC:
ToLocal($feature.MonChampDate)
Calculer une date UTC à partir d'un champ contenant des dates locales:
ToUTC($feature.MonChampDate)
Expressions sur les géométries
Calculer le X du centroïde des géométries des entités:
Centroid($feature).x
Calculer le Y du centroïde des géométries des entités:
Centroid($feature).y
Calculer le Z du centroïde des géométries des entités:
Centroid($feature).z
Calculer le périmètre des polygones ou la longueur des polylignes dans les
unités de la couche:
Length($feature)
Calculer le périmètre géodésique des polygones ou la longueur géodésique des
polylignes dans les unités de la couche:
LengthGeodetic($feature)
Calculer le périmètre des polygones ou la longueur des polylignes dans les
unités de votre choix (ici en kilomètres):
Length($feature, 'kilometers')
Calculer le périmètre des polygones 3D ou la longueur des polylignes 3D
dans les unités de la couche en tenant compte du Z des entités :
Length3D($feature)
Calculer le périmètre des polygones 3D ou la longueur des polylignes 3D dans les unités de votre choix (ici en mètres) en tenant compte du Z des entités :
Length3D($feature
, 'meters')
Calculer la superficie des polygones dans les unités de la couche:
Area($feature)
Calculer la superficie géodésique des polygones dans les unités de la couche:
AreaGeodetic($feature)
Calculer la superficie des polygones dans les unités de votre choix (ici en
km2):
Area($feature, 'square-kilometers')
Calculer la superficie des polygones dans les unités de votre choix (ici en
hectares):
Area($feature,'hectares')
Calculer le X du premier sommet des polylignes:
var myPath = Geometry($feature).paths[0]
return myPath[0].x
Calculer le X du premier sommet des polygones:
var myRing = Geometry($feature).rings[0]
return myRing[0].x
Calculer le X du dernier sommet des polylignes (dans le cas de polygone
mono-partie, le premier et le dernier sommet sont les mêmes):
var myPath = Geometry($feature).paths[0]
return myPath[Count(myPath)-1].x
Calculer le X du dernier sommet des polylignes (dans le cas de polygone
mono-partie, le premier et le dernier sommet sont les mêmes):
var myRing = Geometry($feature).rings[0]
return myRing[Count(myRing)-1].x
Calculer le X du coin inférieur-gauche de l'enveloppe des polylignes ou des
polygones:
var ext = Extent($feature)
return ext.xmin
Calculer le Y du coin inférieur-gauche de l'enveloppe des polylignes ou des
polygones:
var ext = Extent($feature)
return ext.ymin
Calculer la largeur de l'enveloppe des polylignes ou des polygones:
var ext = Extent($feature)
return ext.xmax - ext.xmin
Calculer la hauteur de l'enveloppe des polylignes ou des polygones:
var ext = Extent($feature)
return ext.ymax - ext.ymin
Calculer le nombre de parties composant la géométrie d'entités linéaires:
var myPaths = Geometry($feature).paths
return Count(myPaths)
Calculer le nombre de parties composant la géométrie d'entités surfaciques:
var myRings = Geometry($feature).rings
return Count(myRings)
Calculer le nombre de sommets composant la géométrie d'entités linéaires:
var myPaths = Geometry($feature).paths;
var nb_points = 0;
for (var i=0;myPaths;i++){
var myPath = myPaths[i];
nb_points += Count(myPath);
}
return nb_points
Calculer le nombre de sommets composant la géométrie d'entités surfaciques:
var myRings = Geometry($feature).rings;
var nb_points = 0;
for (var i=0;imyRings);i++){
var myRing = myRings[i];
nb_points += Count(myRing);
}
return nb_points
Accéder à des données d'autres couches
Récupérer la valeur d'un champ depuis une entité située dans une autre
couche. Ici on récupère le code de la zone (CodeZone) dans la couche "Zones"
dans laquelle se trouve l'entité ($feature) ponctuelle, linéaire ou
surfacique:
for (var my_zone in FeatureSetByName($map,"Zones")){
if (Intersects($feature, Geometry(my_zone))){
return my_zone.CodeZone;
}
}
Compter le nombre d'entités (ici des bâtiments) contenus dans la géométrie
courante (ici des parcelles cadastrales). Vous noterez que l'on fait tout
d'abord une intersection puis la comparaison avec les centroïdes des
bâtiments pour ne pas garder les bâtiments qui touchent la limite de la
parcelle tout en étant à l'extérieur de celle-ci:
var intersected_features = Intersects(FeatureSetByName($map,"Bâtiments"), $feature);
var n=0;
for (var my_feature in intersected_features)
{
var my_centroid = Centroid(my_feature);
Console(my_centroid);
if (Within(my_centroid,$feature)){
n++;
}
}
return Text(n, '#');
Récupérer la distance minimum entre l'entité courante et l'entité la plus
proche dans une autre couche (ici la couche "Mes Enseignes"). Dans cet
exemple, la distance maximum de recherche est fixée à 100 kilomètres:
var my_buffer = Buffer($feature, 100, 'kilometers');
var dist_min = Infinity;
for (var my_feature in Intersects(FeatureSetByName($map,"Mes Enseignes"),my_buffer))
{
var d = Distance($feature,my_feature,'kilometers');
dist_min = IIF(d < dist_min, d, dist_min);
}
return dist_min
Manipuler des tableaux de données
Vous aurez peut-être besoin de manipuler des tableaux de données. Voici
donc quelques fonctions intéressantes...
Créer un tableau:
var couleurs = ['orange', 'rouge', 'vert']
Récupérer le deuxième élément d'un tableau:
var couleurs = ['orange', 'rouge', 'vert']
couleurs[1]
// retourne 'rouge'
Connaître le nombre d'éléments d'un tableau:
var couleurs = ['orange', 'rouge', 'vert']
Count(couleurs)
// retourne 3
Ajouter une valeur à un tableau:
var couleurs = ['orange', 'rouge', 'vert'];
couleurs.Push('Noir');
// couleurs = ['orange', 'rouge', 'vert', 'Noir']
Trier les éléments d'un tableau par ordre croissant :
var couleurs = ['orange', 'rouge', 'vert', 'bleu', 'violet']
Sort(couleurs)
// retourne ['bleu', 'orange', 'rouge', 'vert', 'violet']
Trier les éléments d'un tableau par ordre décroissant (pour des éléments
simples ou plus complexes comme des tableaux de tableaux):
var couleurs = ['orange', 'rouge', 'vert', 'bleu', 'violet']
Sort(couleurs)
// retourne ['violet', 'vert', 'rouge', 'orange', 'bleu']
Trier les éléments d'un tableau par ordre décroissant (pour des éléments
simples de type String ou Number):
var couleurs = ['orange', 'rouge', 'vert', 'bleu', 'violet']
Reverse(Sort(couleurs))
// retourne ['violet', 'vert', 'rouge', 'orange', 'bleu']
Récupérer et supprimer la dernière valeur d'un tableau:
var couleurs = ['orange', 'rouge', 'vert'];
derniereCouleur = Pop(couleurs);
// derniereCouleur = 'vert' et couleurs = ['orange', 'rouge']
Compter le nombre de valeurs uniques dans un tableau:
var couleurs = ['orange', 'orange', 'vert', 'rouge', 'vert']
var couleursUniques = Distinct(couleurs)
// couleursUniques = ['orange', 'vert', 'rouge']
Tester si certaines valeurs sont vides dans un tableau:
var tableau = [$feature.champ1, $feature.champ2, $feature.champ3, $feature.champ4]
Any(tableau, isEmpty)
// retourne True si une des valeurs est vide, sinon retourne False
Autres expressions utiles
Retourner une valeur vide (Null):
Null
Construire une chaîne à partir des valeurs de différents champs en
utilisant un séparateur:
Concatenate([$feature.Jour,$feature.Mois,$feature.Annee],"/")
Construire une chaîne en mettant les "0" nécessaires à droite de la valeur
numérique (ici un exemple où on force le nombre à faire 4 caractères, par
exemple pour 0.75 on obtiendra la chaîne "0.750":
Text($feature.MonChampNum, '0.000')
Construire une chaîne en mettant les "0" nécessaires à gauche de la valeur
numérique (ici un exemple où on force le nombre à faire 4 caractères, par
exemple pour 82 on obtiendra la chaîne "0082":
Text($feature.MonChampNum, '0000')
Retourner le nom de l'utilisateur actuellement connecté:
var userInfo = GetUser();
if(HasValue(userInfo, "username")){
return userInfo.username;
}
Retourner le nom complet de l'utilisateur actuellement
connecté:
var userInfo = GetUser();
if(HasValue(userInfo, "fullName")){
return userInfo. fullName;
}
Retourner l'ID de l'utilisateur actuellement connecté:
var userInfo = GetUser();
if(HasValue(userInfo, "id")){
return userInfo.id;
}
Retourner l'email de l'utilisateur actuellement connecté:
var userInfo = GetUser();
if(HasValue(userInfo, "email")){
return userInfo.email;
}
Retourner les groupes auxquels appartient l'utilisateur actuellement connecté:
var userInfo = GetUser();
if(HasValue(userInfo, "groups")){
return userInfo.groups;
}
Retourner la langue du contexte applicatif exécutant l'expression Arcade:
var env = GetEnvironment()
var locale = IIF(HasValue(env, "locale"), env.locale, "");
return locale;
// retourne par exemple 'en-us', 'fr-fr', ...
Retourner la version du contexte applicatif exécutant l'expression Arcade:
var env = GetEnvironment()
var locale = IIF(HasValue(env, "version"), env.version , "");
return locale;
// retourne par exemple '1.23'
Retourner la version du contexte applicatif exécutant l'expression Arcade:
var env = GetEnvironment()
var locale = IIF(HasValue(env, "application"),
env. application,"");
// retourne par exemple 'ArcGISMapViewer'
Pour plus d'informations sur les différents profils, le guide de référence des fonctions et la syntaxe des expressions Arcade, il est important de consulter
la documentation en ligne.
Note: Cet article a été publié initialement le 23/01/2019 et mis à jour le 17/08/2023