Le blog francophone consacré
aux technologies Esri

Utiliser Arcade pour vos expressions dynamiques dans ArcGIS

Arcade est un langage d'expressions pouvant être utilisé sur l'ensemble de la plateforme 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, 
  • pour définir le texte de vos étiquettes, 
  • pour personnaliser le contenu des fenêtres contextuelles, 
  • pour calculer les valeurs d'un champ.

  
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.

   
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.
   
  
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":


 
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.


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'affaire de chacun des magasins de ma table.

  
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 langage 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 3ième mot d'une chaîne (dont les mots sont séparés par un espace):
Split($feature.MonChamp,' ')[3]

Extraire la 4iè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 tout en minuscule:
Lower($feature.MonChamp)
   
Mettre tout 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:
Expression:
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"

Calculer la date et l'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')
//Retourne cette date: 19/03/2017 00:00:00
   
Créer une date à partir d'une époque Unix (depuis 01/01/1970 en millisecondes):
Date(1476987783555)
//Retourne cette date: 19/03/2017 13:57:45

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 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;imyPaths);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
 
 
   
Autres expressions utiles

Mettre les valeurs d'un champ à "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')
  

Partager cet article:

Rejoindre la discussion

    Les commentaires à propos de cet article: