Ocelet

Types de base et initialisation de variables

Cette section de la documentation est consacrée aux types de base du langage Ocelet. Ces types peuvent être utilisés lors de la déclaration d'une variable, ou d'une propriété d'entité. Une type est en quelque sorte la nature de la variable ou de la propriété : du texte, une valeur numérique, un polygone par exemple.

Le langage Ocelet reprend un certain nombre de types de base du langage Java : Boolean, Double, Float, Integer, Long, String mais il en contient d'autres qui ont été ajoutés pour les besoins spécifiques de la modélisation de dynamiques spatiales.

A chacun de ces types de base sont associées des fonctions qui permettent d'effectuer des opérations spécifiques à ce type. Par exemple il existe une fonction length() qui permet d'obtenir la longueur du texte contenu dans les variables de type String. Autre exemple, il existe une fonction area() qui permet d'obtenir la surface des variables de type Polygon ou MultiPolygon.

Nous abordons dans un premier temps la méthode générale pour initialiser une variable. Nous distinguons ensuite les trois sortes de types (simples, composites, collections), afin de présenter les différences en matière de création de variables et d'initialisation. Enfin chaque type est détaillé ainsi que les fonctions qui lui sont spécifiques.

Contenu

Syntaxe générale d'initialisation de variable

Comme on peut le voir dans le chapitre relatif aux instructions de base d'Ocelet, on peut déclarer une constante avec le mot clé fix et une variable avec le mot clé let et l'on doit en même temps indiquer une valeur initiale à placer dans la constante ou la variable.

La syntaxe générale pour fournir cette valeur initiale est la suivante :

identifiant = new type ( valeurs initiales )

Voici quelques exemples d'initialisation de constantes et de variables respectant cette syntaxe :

let temperature = new Double(25.0)
fix lis_altitudes = new List<Double>()
let isActive = new Boolean(true)
fix nb_annees = new Integer(12)
fix contour = new Polygon()

Dans la pratique on n'est pas toujours obligé d'utiliser cette syntaxe. Il existe d'autres fonctions et méthodes pour fournir des valeurs initiales, mais elles sont différentes selon qu'il s'agit de type simples, de types composites, ou de collections.

Retour en début de page  

Types simples, types composites, collections, et initialisation de variables

Nous ferons la distinction entre trois sortes de types afin d'expliquer ce qui les différencie dans la façon d'initialiser des variables (ou des propriétés d'entités)

Les types simples

Il s'agit de types de variables qui ne contiennent qu'un seule valeur :

L'initialisation de variables ou constantes avec des types simples peut être allégée, sans faire appel au mot clé new et même sans préciser le type. Ocelet va tenter de deviner le type d'après le contenu écrit derrière le =. Ce mécanisme est généralement appelé inférence de type.

Par exemple on pourra écrire :

let temp = 34.7
fix nom = "Bellecombe"
let isActive = true

au lieu de

let temp = new Double(34.7)
fix nom = new String("Bellecombe")
let isActive = new Boolean(true)

Pour que l'inférence de type soit correcte, il faut être rigoureux dans la façon dont on initialise une variable. Par exemple si on écrit let g = 0, la variable g sera considérée comme un Integer. Pour que cette variable soit de type Double il faudra l'initialiser avec 0.0. Vous pouvez vous reporter à la documentation détaillée de chacun des types pour connaitre les syntaxes exactes garantissant que le type inféré sera le bon.


Les types composites

Il s'agit de type contenant un nombre fini (et connu à l'avance) de valeurs. Ces valeurs pouvant être soit de type simple, soit d'un type composite, soit une collection. Les types composites de base d'Ocelet sont :

  • Cell
  • Color
  • DateTime
  • Line et MultiLine
  • Point et MultiPoint
  • Polygon et MultiPolygon

A ces types de base, on peut ajouter les types composites définis par vous même que l'on appelle les Structure. Enfin Les entités, les relations, les datafacers que vous définissez dans un modèle peuvent eux aussi être considérés comme des types composites, au moins parce que les règles de création et d'initialisation de variable à appliquer dans leurs cas sont les mêmes que pour les types composites.

Dans le cas général, on peut toujours créer une variable (ou une constante) sans fournir aucune valeur d'initialisation et ce sont des valeurs par défaut qui seront utilisées. Comme on ne passe aucun argument dans les parenthèses, celles-ci peuvent être retirées.

Par exemple on peut écrire :

let now = new DateTime
let mycolor = new Color
let contour = new Polygon

La valeur par défaut dépend bien sur du type. Ici la variable now contiendra la date et l'heure du moment ou l'instruction a été exécutée; mycolor contiendra un gris clair; et contour sera un polygone vide (ne contenant aucun point).

Certains types composites disposent de fonctions spécifiques d'initialisation

La syntaxe pour utiliser ces fonctions d'initialisation est la suivante :

identifiant = type | fonction d'initialisation ( arguments de la fonction)

On remarquera l'absence du mot clé new dans ce cas. Voici quelques exemples respectant cette forme d'initialisation :

let start = DateTime|fromString("dd-MM-YYYY","01-02-2016")
let mycolor = Color|rgba(255,230,230,128)
let position = Point|xy(570680.0,4832818.0)

Il faut se référer à la documentation de chaque type pour connaitre la liste des fonctions d'initialisation disponibles et les arguments à leur passer.

Il faut enfin savoir que l'on peut écrire soi-même des fonctions d'initialisation pour les entités que l'on définit. Se reporter pour cela à la documentation portant sur les entités (voir le mot clé init).


Les collections

Ce sont des types contenant un certain nombre de valeurs que l'on ne connait pas forcément à l'avance. Ces types de collections sont :

  • List
  • Keymap
  • Group

On commence par créer une collection vide, puis on ajoutera des objets dans un second temps. Au moment de la création d'une nouvelle collection, il faut indiquer de quel type sont les objets que l'on va placer dans cette collection.

La syntaxe est de la forme :

identifiant = new type de collection <type du contenu>

Par exemple on peut préparer une liste de nombres entiers avec :

fix serie = new List<Integer>

puis ajouter des valeurs :

serie.add(5)
serie.add(8)
serie.add(3)

La fonction qui permet d'ajouter des valeurs dépend du type de collection. Ainsi la fonction add() est présente pour List et Group mais pas dans Keymap par exemple.

Dans l'exemple ci-dessus, on remarquera que la liste est créée sous la forme d'une constante (on a utilisé fix plutot que let). En effet, la liste elle même, c'est à dire le contenant, n'a pas vocation à changer, cela n'empèchera pas d'ajouter ou de retirer du contenu. Cela dit, il serait possible de placer cette liste dans une variable (avec let) si l'on désire par la suite remplacer cette liste par une autre dans cette variable. Dans ce dernier cas cela signifie que c'est un contenant (la première liste) qui sera remplacé par un autre contenant (une seconde liste).

Enfin à l'image de certains types composites, les types de collection List et Group possèdent une fonction d'initialisation of() qui permet de créer une collection et de la remplir avec du contenu en une seule instruction. Le type du contenu est déduit de ce que l'on ajoute, et bien entendu tous les objets ajoutés doivent être de même type.

Exemples :

fix series = List|of(5,8,3)
fix semaine = List|of("lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche")
Retour en début de page  

Types de valeurs numériques

Double

Nombre décimal en double précision (encodé sur 64bits). Il s'agit du type utilisé par défaut dans Ocelet lorsque l'on déclare une variable initialisée avec un nombre décimal. Mais on peut aussi forcer la valeur numérique à être de type Double en ajoutant la lettre D à la fin :

let t = 0.12
let u = 2D
let v = 0.1546D
let h = 1.234e4

t, u,v et h seront toutes de type Double. Dans cet exemple la valeur 1.234e4 est exprimée en notation scientifique, elle équivalente à 1.234 x 10000 = 12340.0

Dans la définition d'une propriété d'entité ou de relation, on n'initialise pas directement la propriété, et il est donc nécessaire d'indiquer le type voulu :

entity Station {
  property Double temp
}


Float

Nombre décimal en simple précision (encodé sur 32bits). Si l'on veut initialiser une variable avec une valeur décimale en type Float is est nécessaire d'ajouter la lettre F à la fin :

let u = 2F
let h = 1.234e4
let v = 0.1546F

u,v et h seront toutes trois de type Float. Dans cet exemple la valeur 1.234e4 est exprimée en notation scientifique, elle équivalente à 1.234 x 10000 = 12340.0

Dans la définition d'une propriété d'entité ou de relation, on n'initialise pas directement la propriété, et il est donc nécessaire d'indiquer le type voulu :

entity Station {
  property Float temp
}


Integer

Nombre entier (encodé sur 32bits). Il s'agit du type utilisé par défaut dans Ocelet lorsque l'on déclare une variable initialisée avec un nombre entier :

let u = 2
let h = 4e5

_u et h seront de type Integer. Dans cet exemple la valeur 4e5 est exprimée en notation scientifique, elle équivalente à 4 x 100000 = 400000

Dans la définition d'une propriété d'entité ou de relation, on n'initialise pas directement la propriété, et il est donc nécessaire d'indiquer le type voulu :

entity Station {
  property Integer temp
}


Long

Nombre entier long (encodé sur 64bits). Ce n'est pas le type utilisé par défaut dans Ocelet lorsque l'on déclare une variable initialisée avec un nombre entier. Pour initialiser une variable avec un entier long il faut impérativement ajouter la lettre L à la fin du nombre:

let u = 2L

u sera de type Long.

Dans la définition d'une propriété d'entité ou de relation, on n'initialise pas directement la propriété, et il est donc nécessaire d'indiquer le type voulu :

entity Station {
  property Long temp
}


Conversion de types numériques

Il arrive que la manipulation de variables de types numériques différents entraine des conflits de typage qui doivent être résolus. On fait alors appel à des fonctions de conversion de type.

Un tel conflit peut survenir si l'on essaye d'arondir un nombre qui est de type Double pour l'affecter à une variable qui est de type Integer :

let t=112.5  // t est de type : Double
let f=0      // f est de type Integer
f=round(t)   // Conflit de type

La fonction round() produit effectivement un nombre entier, mais comme t est de type Double, round(t) va produire un nombre de type Long. Et le conflit vient ici du fait que l'on ne peut pas affecter un Long à une variable de type Integer parce qu'il y a un risque de perdre de l'information si ce nombre est très grand. C'est donc à vous de forcer la conversion de type si vous estimez que ce risque n'existe pas dans le contexte de votre programme. Dans le cas présent on utilisera la fonction de conversion intValue() :

let t=112.5  // t est de type : Double
let f=0      // f est de type Integer
f=round(t).intValue()   // Pas de conflit de type, on obtient bien un Integer

Les fonctions de conversion de type numérique sont :

  • Double doubleValue()
  • Float floatValue()
  • Integer intValue()
  • Long longValue()


Fonctions d'initialisation des types numériques

Ces fonctions permettent la création d'une valeur d'un type numérique donné, autrement qu'en fournissant directement sa valeur. Elles sont disponibles pour tous les types numériques :

  • valueOf( Double nombre )
  • valueOf( String texte )

Exemple :

let t = 25  // t est de type Integer
let u = Double|valueOf(t) // u sera un Double
let v = Double|valueOf("240")  // Crée un Double à partir du texte "240"
Retour en début de page  

Types thématiques

Boolean

Type qui représente un état binaire : soit vrai soit faux.

let v=true

Une variable de type Boolean peut être utilisée dans un test :

if (v) println("Ok.") else println("Not ok.")


Color

Type utilisé pour contenir une couleur. Les variables de type Color sont particulièrement utiles pour donner des indications de style lorsque l'on produit des cartes en résultat de simulation.

Color est un type composite, c'est à dire constitué de plusieurs composantes. La déclaration d'une variable de type Color sans autre précision fournir une couleur par défaut (gris clair) :

let defautColor = new Color

Pour choisir les composantes on passe donc par une fonction d'initialisation.

    Fonctions d'initialisation
  • rgb(Integer rouge, Integer vert, Integer bleu) : rouge, vert, bleu sont des entiers compris entre 0 et 255. Ils représentent les composantes de la couleur que l'on souhaite obtenir.
  • rgba(Integer rouge, Integer vert, Integer bleu, Integer alpha) : alpha est aussi un entier compris entre 0 et 255 et représente un niveau d'opacité (souvent nommé alpha channel). La valeur 0 est totalement transparente, la valeur 255 est totalement opaque.
  • text(String rvb) : cette fonction d'initialisation a été ajoutée pour pouvoir obtenir une couleur directement à partir d'une représentation textuelle de ses composantes, telle qu'on peut la trouver dans certains formats de fichiers comme CSS (Cascading Style Sheet) par exemple. Ces deux formes d'expression sont valides :

    • "#RRVVBB" : composantes rouge, verte et bleue exprimées en hexadécimal. Pour chaque composante, 00 est le minimum et FF est le maximum.
    • "#RRVVBBAA" composantes rouge, verte, bleue et opacité exprimées en hexadécimal.

Exemples :

let color1 = Color|rgb(255,255,168)      // produit un jaune pale totalement opaque
let color2 = Color|rgba(255,128,255,128) // produit un rose avec 50% de transparence
let color3 = Color|text("#FF80FF80")     // produit un rose avec 50% de transparence
    Fonctions d'usage

Une fois que l'on dispose d'une variable de type Color, on peut lui appliquer les fonctions suivantes :

  • Color darker( Double proportion ) : Produit une nouvelle couleur, plus foncée que la couleur d'origine, selon la proportion fournie. proportion est une valeur de type Double comprise entre 0 et 1.
  • Color lighter( Double proportion ) : Produit une nouvelle couleur, plus claire que la couleur d'origine, selon la proportion fournie. proportion est une valeur de type Double comprise entre 0 et 1.
  • List<Color> colorRange( Integer nombre_de_couleurs , Color couleur ) : Produit un dégradé de couleurs sous la forme d'une liste (de type List< Color >). Le nombre de couleurs intermédiaire contenu dans cette liste est indiqué par un nombre entier. La fonction va donc produire un dégradé de couleurs entre la couleur à laquelle on applique la fonction et l'autre couleur fournie.
  • String toString() : Produit une représentation textuelle de la couleur, sous la forme "rgb(r,v,b)"

Exemples :

let color1 = Color|rgb(255,255,168) // jaune pale
let color4 = color1.darker(0.5)     // beige : rgb(127,127,84)
let degrad = color1.colorRange(8,Color|rgb(0,128,255)) // Dégradé de jaune vers bleu en 8 couleurs


DateTime

Type permettant la manipulation de dates et d'heures. Ce type est pratique pour intégrer des champs d'information temporelle dans les données issues de simulation.

Attention : le type DateTime n'existe dans Ocelet que depuis la version 2.0. Il remplace le type Date qui était utilisé jusque là. Le type Date est considéré comme obsolete et l'éditeur d'Ocelet barre le type Date quand on essaye de l'utiliser pour indiquer qu'il est préférable d'utiliser le nouveau type DateTime. La principale différence entre les types Date et DateTime est que les fonctions pour changer la date ou l'heure affectaient directement le contenu des variables de type Date mais elle n'affectent pas le contenu des variables de type DateTime. Avec le type DateTime, il n'est donc plus nécessaire de faire un clonage de date pour en obtenir une copie. Mais il faut desormais récupérer le résultat des fonctions modifiant la date ou l'heure (voir les exemples indiqués plus loin).

Il est possible de créer un exemplaire de DateTime sans initialiser le contenu, la variable contiendra alors la date et l'heure de l'ordinateur au moment de l'exécution de cette instruction :

let now = new DateTime

DateTime est un type composite, c'est à dire constitué de plusieurs composantes : année, mois, jour, heure, minutes, secondes et millisecondes. L'initialisation d'une variable de type DateTime peut se faire à l'aide d'une fonction d'initialisation.

Fonctions d'initialisation
  • ymd(Integer année, Integer mois, Integer jour) : Produit une DateTime à partir de trois nombres entiers fournis, représentant l'année, le mois et le jour. Dans ce cas, l'heure sera à 00:00:00.
  • fromString(String format , String date ) Produit une DateTime à partir d'un texte dont le format est décrit par un motif. Le motif est constitué de caractères qui désignent un élément de date ou d'heure, voir le tableau des motifs de formatage.

Exemples :

let date1 = DateTime|ymd(2010, 12, 25)  // DateTime produit: 25 dec. 2010 00:00:00
let date2 = DateTime|fromString("yyyy-MM-dd kk:mm","2010-12-25 15:30") // DateTime produit: 25 dec. 2010 15:30:00
    Fonctions d'usage

Les fonctions disponibles sur le type DateTime sont nombreuses. Nous les avons classées par groupes de fonctions similaires.

Ajout de temps à une date

Comme cela est indiqué par le type de retour de ces fonctions, elles renvoient toutes un nouvel exemplaire de DateTime. La variable sur laquelle on applique l'une de ces fonctions n'est pas modifiée. Autrement dit, si l'on veut obtenir ou nouvelle date ou heure dans la même variable, il faut lui affecter le résultat renvoyé.

  • DateTime addYears(Integer nb_annees) : Ajoute le nombre d'années indiqué à la date.
  • DateTime addMonths(Integer nb_mois) : Ajoute le nombre de mois indiqué à la date.
  • DateTime addWeeks(Integer nb_semaines) : Ajoute le nombre de semaines indiqué à la date.
  • DateTime addDays(Integer nb_jours) : Ajoute le nombre de jours indiqué à la date.
  • DateTime addHours(Integer nb_heures) : Ajoute le nombre d'heures indiqué à la date.
  • DateTime addMinutes(Integer nb_minutes) : Ajoute le nombre de minutes indiqué à la date.
  • DateTime addSeconds(Integer nb_secondes) : Ajoute le nombre de secondes indiqué à la date.

Exemple :

let date3 = DateTime|fromString("yyyy-MM-dd","2010-01-20")
date3 = date3.addWeeks(2) // Ajout de 2 semaines => 3 fev. 2010
Lecture d'un élément d'une varialbe DateTime

Ces fonctions renvoient toutes un nombre entier qui correspond à un des éléments de la date ou de l'heure. Le nom de chaque fonction indique l'élément renvoyé.

  • Integer getYear() : Renvoie l'année
  • Integer getMonth() : Renvoie le mois
  • Integer getDayOfWeek() : Renvoie le jour de la semaine
  • Integer getDayOfMonth() : Renvoie le jour du mois
  • Integer getDayOfYear() : Renvoie le jour de l'année.
  • Integer getHour() : Renvoie l'heure
  • Integer getMinute() : Renvoie les minutes
  • Integer getSecond() :Renvoie les secondes
  • Integer getMillisecond(): Renvoie les millisecondes
  • Long getTimeAsMilliseconds() : Renvoie un entier long qui correspond au nombre de millisecondes écoulées depuis minuit pour cette date. Autrement dit l'heure courante de cette date est convertie en millisecondes.
Changement d'un élément de date ou d'heure

Ces fonctions prennent toutes un nombre entier comme paramètre et renvoient un nouvel exemplaire de DateTime. La variable sur laquelle la fonction est appellée n'est pas modifiée. Le nom de chaque fonction indique l'élément modifié.

  • DateTime setYear(Integer annee) : Change l'année
  • DateTime setMonth(Integer mois) : Change le mois
  • DateTime setDayOfWeek(Integer jour) : Change le jour dans la semaine
  • DateTime setDayOfMonth(Integer jour) : Change le jour dans le mois
  • DateTime setDayOfYear(Integer jour) : Change le jour dans l'année
  • DateTime setHour(Integer heures) : Change l'heure
  • DateTime setMinute(Intger minutes) : Change les minutes
  • DateTime setSecond(Integer secondes) : Change les secondes
  • DateTime setMillisecond(Integer millisecondes) : Change les millisecondes

Exemple :

let date3 = DateTime|fromString("yyyy-MM-dd","2010-01-20")
date4 = date3.setMonth(5) // Change le mois: date4 = 20 mai 2010
// Dans cet exemple on a récupéré le résultat dans date4
// la date et l'heure de la variable date3 n'ont pas changé.
Comparaison de DateTimes
  • Boolean isAfter(DateTime date) : Renvoie une valeur de type Boolean. Renvoie true (vrai) si la date (et l'heure) fournie est postérieure à la date sur laquelle on appelle cette fonction.
  • Boolean isBefore(DateTime date) : Renvoie une valeur de type Boolean. Renvoie true (vrai) si la date fournie est antérieure à la date sur laquelle on appelle cette fonction.

Exemple :

let date1 = DateTime|fromString("yyyy-MM-dd","2010-01-20")
let date2 = DateTime|fromString("yyyy-MM-dd","2010-02-22")
date1.isAfter(date2)  // => false
date1.isBefore(date2) // => true
Conversion en texte
  • String toString() : Produit une représentation textuelle de la date et de l'heure en utilisant le formatage par défaut.
  • String toString( String format ) : Produit une représentation textuelle de la date et de l'heure en utilisant le formatage spécifié par le motif fourni. Le motif est construit à l'aide de caractères qui désignent un élément de date ou d'heure, voir le tableau des motifs de formatage.

Exemple :

let date1 = DateTime|fromString("dd/MM/yy","22/02/10")
println("Date : "+date1.toString("yyyy-MM-dd"))  // Texte affiché => Date : 2010-02-22

Lorsque l'on utilise un formatage sur une variable de type DateTime, ce formattage est conservé. Autrement dit ce formattage devient le formattage d'affichage par défaut de la date et l'heure pour cette variable, il n'est plus nécessaire de l'indiquer.


Motifs de formatage de date et heure
Caractère Element d'heure ou de date Exemples
G Epoque chrétienne ap. J.-C.
y Année 1996; 96
Y Année 2009; 09
M Mois de l'année Juillet; Jul; 07
w Semaine dans l'année 27
W Semaine dans le mois 3
D Jour dans l'année 239
d Jour dans le mois 10
F Jour de la semaine dans le mois 2 (2eme mercredi du mois)
E Nom du jour de la semaine Vendredi; Ven
u Numéro du jour de la semaine (1 = Lundi, :.., 7 = Dimanche) 1
a Marqueur matin ou après-midi PM
H Heure du jour (0-23) 0
k Heure du jour (1-24) 24
K Heure dans la demi-journée (0-11) 0
h Heure dans la demi-journée (1-12) 12
m Minutes dans l'heure 30
s Second dans la minute 55
S Millisecondes 978
z Fuseau horaire Pacific Standard Time; PST; GMT-08:00
Z Fuseau horaire -0800
X Fuseau horaire -08; -0800; -08:00


String

Ce type représente une série de caractères qui constitue un texte. Il est possible d'initialiser une variable de type String directement avec un texte, ce texte doit être encadré par le caractère ".

Exemple :

let nom = "Curepipe"
    Fonctions d'usage
  • Integer compareTo( String texte ) : compare notre texte avec celui fourni en paramètre. Cette comparaison distingue les majuscules de minuscules.
    • Retourne 0 si les deux textes sont identiques.
    • Retourne un entier inférieur à 0 si notre texte est avant le texte fourni en paramètre (ordre alphabéthique).
    • Retourne un entier supérieur à 0 si notre texte est après le texte fourni en paramètre (ordre alphabéthique).
  • Integer compareToIgnoreCase( String texte ) : compare notre texte avec celui fourni en paramètre. Cette comparaison ne fait pas de différence entre majuscules et minuscules.
    • Retourne 0 si les deux textes sont identiques.
    • Retourne un entier inférieur à 0 si notre texte est avant le texte fourni en paramètre (ordre alphabéthique).
    • Retourne un entier supérieur à 0 si notre texte est après le texte fourni en paramètre (ordre alphabéthique).
  • String concat( String texte ) : Ajoute le texte fourni au bout du notre.
  • Boolean endsWith( String texte ) : Renvoie true (vrai) si le texte fourni termine le notre.
  • Boolean equals( String texte ) : Renvoie true (vrai) si le texte fourni est identique au notre. Cette comparaison fait la distinction entre les majuscules et les minuscules.
  • Boolean equalsIgnoreCase( String texte ) : Renvoie true (vrai) si le texte fourni est identique au notre. Cette comparaison ne fait pas de différence entre majuscules et minuscules.
  • Integer indexOf( String texte ) : Renvoie la position du texte fourni dans le notre, ou -1 si celui-ci ne s'y trouve pas.
  • Integer indexOf( String texte , Integer index ) : Renvoie la position du texte fourni dans le notre en commençant la recherche à partir de l'index, ou -1 si celui-ci ne s'y trouve pas.
  • Integer lastIndexOf( String texte ) : Renvoie la position de la dernière occurence du texte fourni à l'intérieur du notre.
  • Integer lastIndexOf( String texte , Integer index ): Renvoie la position de la dernière occurence du texte fourni à l'intérieur du notre, en commençant la recherche à partir de l'index donné.
  • Integer length() : Donne le nombre de caractères dans le texte.
  • Boolean startsWith(String prefix) : Renvoie true (vrai) si notre texte commence par le texte fourni.
  • Boolean startsWith(String prefix, Integer index) : Renvoie true (vrai) si le texte fourni est situé à index donné à l'intérieur de notre texte.
  • String substring(Integer index) : Retourne la fin du texte en partant de l'index fourni.
  • String substring(Integer debut, Integer fin) : Retourne la partie du texte située entre les index debut et fin.
  • String toLowerCase() : Passe le texte en minuscules.
  • String toUpperCase() : Passe le texte en majuscules.
  • String trim() : Elimine les blancs au début et à la fin du texte (s'il y en a).
Retour en début de page  

Types de géométrie

Les types de géométrie permettent de manipuler les composantes spatiales de l'information géographique. On y trouve des types de nature ponctuelles, linéaires et surfaciques avec dans chaque cas un type simple et un type multiple. Chaque type de géométrie possède des fonctions d'initialisation qui lui sont propres. Les fonctions d'usage sont les mêmes pour tous (à une exception près) et sont présentées ensemble à la suite des types.

Line

Géométrie simple de type linéaire.

    Fonctions d'initialisation
  • points(Point p1, ...) : Construit un élément de type Line à partir d'un nombre variable de points fournis en paramètre.
  • points(List<Point> points): Construit un élément de type Line à partir d'une liste de Points fournie en paramètre.

Exemples :

let segment = Line( Point|xy(100d,50d) , Point|xy(320.4, 55d) )

let lp = new List<Point>
lp.add(Point|xy(100.0,100.0))
lp.add(Point|xy(200.0,100.0))
lp.add(Point|xy(100.0,200.0))
let line2 = Line|points(lp)
    Fonction d'usage
  • List<Point> asListOfPoints() : Donne accès à une liste de Points correspondant aux coordonnées qui constituent cet objet linéaire.


MultiLine

Geométrie linéaire multiple. Ce type regroupe plusieurs éléments linéaires dans une même variable.

    Fonctions d'initialisation
  • lines(Line l1, ...) : Construit un élément de type MultiLine à partir d'un nombre variable de Lines fournis en paramètre.
  • lines(List<Line> lines) : Construit un élément de type MultiLine à partir d'une liste de Lines fournie en paramètre.
    Fonction d'usage
  • List<Line> asListOfLines() : Donne accès à une liste de Line représentant le contenu de ce MultiLine.


Point

Géométrie simple ponctuelle.

    Fonctions d'initialisation
  • xy(Double x, Double y) : Contruit un Point à partir des coordonnées fournies en argument.
  • xyz(Double x, Double y, Double z) : Contruit un Point à partir des coordonnées fournies en argument, z représente une altitude.


MultiPoint

Géométrie ponctuelle multiple. Ce type regroupe un ensemble d'éléments ponctuels dans une même variable.

    Fonctions d'initialisation
  • points(Point p1, ...) : Construit un élément de type MultiPoint à partir d'un nombre variable de Points fournis en paramètre.
  • points(List<Point> points) : Construit un élément de type MultiPoint à partir d'une liste de Points fournie en paramètre.
    Fonction d'usage
  • List<Point> asListOfPoints() : Donne accès à une liste de Points qui constituent ce MultiPoint.


Polygon

Géométrie surfacique simple.

    Fonctions d'initialisation
  • points(Point p1, ...) : Construit un élément de type Polygon à partir d'un nombre variable de points fournis en paramètre.
  • points(List<Point> points): Construit un élément de type Polygon à partir d'une liste de Points fournie en paramètre.
    Fonction d'usage
  • List<Point> asListOfPoints() : Donne accès à une liste de Points qui constituent le contour extérieur de ce Polygon.


MultiPolygon

Geométrie surfacique multiple. Ce type regroupe plusieurs éléments surfaciques dans une même variable.

    Fonctions d'initialisation
  • polygons(Polygon l1, ...) : Construit un élément de type MultiPolygon à partir d'un nombre variable de Polygons fournis en paramètre.
  • polygons(List<Polygon> polys) : Construit un élément de type MultiPolygon à partir d'une liste de Polygons fournie en paramètre.
    Fonction d'usage
  • List<Polygon> asListOfPolygons() : Donne accès à une liste des Polygon contenus dans ce MultiPolygon.


Fonctions d'usage communes à tous les types de géométrie

Ces fonctions peuvent être appliquées aux variables de tous les types de géométries. Pour simplifier la description de ces fonctions, nous utilisons Geom pour désigner un type de géométrie de manière générique (ce type Geom ne peut être utilisé dans un programme Ocelet).

  • Geom buffer(Double largeur) : Produit une zone tampon autour de notre objet dont la largeur est fournie en paramètre.
  • Boolean contains(Geom objet) : Teste si notre objet contient entièrement l'objet fourni en paramètre et renvoie true (vrai) si c'est le cas.
  • Boolean disjoint(Geom objet) : Teste si l'objet fourni et le notre sont disjoints et renvoie true (vrai) si c'est le cas.
  • Double distance(Geom objet) : Renvoie la distance entre notre objet et celui qui est passé en paramètre.
  • Double getArea() : Renvoie la surface de notre objet. Bien entendu il n'y a que pour des objets de type surfacique que l'on obtient une valeur supérieure à 0.
  • Line getBoundary() : Retourne le linéaire qui constitue la frontière extérieure de notre objet.
  • Point getCentroid() : Produit un Point situé au barycentre de notre objet. Attention, le centroide d'un polygone ne se trouve pas forcément à l'intérieur de ce polygone.
  • Integer getDimension(): Renvoie la dimension spatiale de la géométrie de notre objet :
    • 0 pour un objet ponctuel
    • 1 pour un objet linéaire
    • 2 pour un objet surfacique
    • 3 si les coordonnées utilisées comportent une indication d'altitude
  • Point getEndPoint() : Renvoie le dernier Point de notre objet.
  • Geom getEnvelope() : Renvoie le rectangle englobant notre objet.
  • Point getInteriorPoint(): Produit un Point situé à l'intérieur de notre objet. Le temps nécessaire pour calculer la position de ce point est plus bien plus important que pour la fonction getCentroid().
  • Integer getNumPoints() : Retourne le nombre de points dont notre objet est constitué.
  • Point getpointN(Integer index): Renvoie le Point situé à la position fournie dans index, selon l'ordre des points dont notre objet est constitué.
  • Point getStartPoint() : Renvoie le premier Point de notre objet.
  • Boolean intersects(Geom objet) : Teste si l'objet fourni est en intersection avec le notre et renvoie true (vrai) si c'est le cas.
  • Boolean isValid() : Teste si la géométrie de notre objet est valide et renvoie true (vrai) si c'est le cas. Ce test n'est pertinent que sur les objets surfaciques. Ils sont valides si :
    • La frontière extérieure est fermée (le premier point et le dernier sont identiques).
    • Il n'y a pas de croisement : la frontière extérieure des éléments qui contituent notre objet ne doit pas se croiser avec elle même.
    • Les éventuels trous doivent être entièrement situés à l'intérieur de l'enveloppe externe de notre objet.
  • Geom intersection(Geom objet) : Renvoie un nouvel objet dont la géométrie est le résultat de l'intersection entre notre objet et l'objet fourni.
  • Geom move(Double dx, Double dy) : Déplace cet objet selon les distances dx et dy passées en arguments. L'objet déplacé à la nouvelle position est renvoyé par la fonction.
  • Geom rotate(Double angle, Double anchorx, Double anchory) : Opère une rotation de cet objet autour d'un point d'ancrage aux coordonnées anchorx,anchory et selon l'angle angle passés en arguments. L'objet résultant de cette rotation est renvoyé par la fonction.
  • Geom scale(Double xfactor, Double yfactor) : Opère une homothétie sur cet objet selon les facteurs xfactor et yfactor passés en argument. L'objet résultant de cette transformation homothétique est renvoyé par la fonction.
  • Geom union(Geom objet) : Renvoie un nouvel objet dont la géométrie est le résultat de l'union entre notre objet et l'objet fourni.
Retour en début de page  

Structure

Il arrive que l'on ait besoin de stocker dans une même variable plusieurs valeurs, éventuellement de natures différentes, que l'on souhaite conserver ensembles. On a besoin de définir son propre type composite. C'est ce que les structures permettent de faire.

Une structure doit être définie dans un modèle, au même niveau qu'une entité, une relation ou un scénario.

Syntaxe de définition d'une nouvelle structure

structure Nom {

définitions des variables composant la structure

}

On peut mettre autant de variables qu'on le souhaite. Chaque variable est définie par :

Type identifiant

Le Type est soit un des types de base d'Ocelet ( Integer, Double, Point, etc. ), soit un type composite défini par vous même sous la forme d'une structure.

Le Nom de la structure et les identifiants des variables qu'elle contient doivent impérativement commencer par une lettre mais peut éventuellement être suivi par des chiffres, et ne pas contenir d'espace ni de caractère spéciaux. Le Nom de la structure doit commencer par une lettre majuscule.

Utilisation dans un scenario

Les définitions de structures se trouvent en dehors de tout scenario. A l'intérieur d'un scenario on fait référence à ces définitions pour créer une ou plusieurs variables qui ont une structure pour type.

On peut ensuite accéder directement aux variables internes d'une structure en séparant le nom de la variable et la variable interne par un ..

Exemple

structure Deplacement {
  Double direction
  Double vitesse
}

scenario MonModele {
  let dep = new Deplacement
  dep.direction = 0.0
  dep.vitesse=2.4
  dep.direction = 0.3    // change de direction
  println("Direction du déplacement :" + dep.direction)
  println("Vitesse du déplacement :" + dep.vitesse)
}

Il est possible d'initialiser toutes ou partie des variables internes à une structure au moment de sa création à l'aide de la syntaxe :

indentifiant = new nom de la structure => [ affectation des variables ]

Le scénario de l'exemple ci-dessus pourrait ainsi être plus court :

scenario MonModele {
  let dep = new Deplacement => [direction=0.0 vitesse=2.4]
  dep.direction = 0.3    // change de direction
  println("Direction du déplacement :" + dep.direction)
  println("Vitesse du déplacement :" + dep.vitesse)
}
Retour en début de page  

Collections

Les collections sont des types offrant la possibilité de stocker ensemble des séries d'éléments qui sont tous de même type. Ces types de collections sont au nombre de trois dans Ocelet : Group, List et KeyMap.

  • Group correspond à la notion d'ensemble : les éléments qu'il contient sont uniques, et il n'y a pas d'ordre particulier entre eux.
  • List correspond à une série ordonnée d'éléments, dans laquelle on peut éventuellement placer plusieurs fois le même élément.
  • KeyMap est un ensemble associatif qui permet de stocker des couples associant une clé à une valeur.

Les collections possèdent toutes des fonctions d'initialisation et des fonctions d'usages qui sont détaillées de manière spécifiques pour chacun des types ci-dessous. Dans cette section de la documentation nous avons noté T le type des éléments stockés dans le groupe, et à l'usage on peut remplacer ce T par n'importe quel type d'Ocelet.


Group

Le type Group correspond à la notion d'ensemble non ordonné, avec unicité des éléments qu'il contient. Tous les éléments présents dans un Group doivent être de même type, celui-ci doit être indiqué au moment où l'on déclare une variable qui va contenir le groupe. Par exemple si l'on veut un groupe de Point on déclarera la variable par :

fix gpts = new Group<Point>
    Fonctions d'initialisation

Nous avons noté T pour représenter le type des éléments stockés dans le groupe.

  • of(T objet1, T objet2, ...) : Ajoute chacun des objets listés dans le groupe. Tous les objets doivent être du même type que celui qui a été déclaré pour ce Group.

Exemple :

fix gint = Group|of(13,67,34,89,1,0,5,6)
fix gpts = Group|of(Point|xy(12.0,45.3),Point|xy(13.5,43.46))
    Fonctions d'usage
  • add(T objet): Ajoute un objet au groupe
  • addAll(List<T> elements) ; addAll(Group<T> elements) : Ces fonctions permettent d'ajouter une série d'éléments provenant respectivement d'une liste ou d'un groupe qui est fourni en paramètre.
  • clear() : efface tout le contenu.
  • Boolean contains(T objet) : Renvoie true (vrai) si le groupe contient l'objet fourni en paramètre.
  • Boolean isEmpty() : Renvoie true (vrai) si le groupe est un ensemble vide.
  • remove(T objet) : Retire l'objet fourni du groupe (si il s'y trouve).
  • Integer size() : Renvoie le nombre d'éléments contenus dans ce groupe.

Bien qu'il ne s'agisse pas directement d'une fonction d'usage, il faut savoir que l'instruction for(..) peut être utilisée pour parcourir tous les éléments d'un Group. :

// i va prendre successivement la valeur de tous les éléments du group gint
for (i:gint) { println("Entier suivant :"+i) }


List

Le type List correspond à une série ordonnée d'éléments, dans laquelle on peut éventuellement placer plusieurs fois le même élément. Tous les éléments présents dans une List doivent être de même type, celui-ci doit être indiqué au moment où l'on déclare une variable qui va contenir la liste. Par exemple si l'on veut une liste de Point on déclarera la variable par :

fix lpts = new List<Point>

Dans cette section de la documentation nous avons noté T le type des éléments stockés dans la liste, et à l'usage on peut remplacer ce T par n'importe quel type d'Ocelet.

    Fonction d'initialisation
  • of(T objet1, T objet2, ...) : Ajoute à la liste chacun des objets donnés en argument. Tous les objets doivent être du même type que celui qui a été déclaré pour ce List.

Exemple :

let jours = List|of("lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche")
    Fonctions d'usage
  • add(T objet) : Ajoute l'objet fourni à la fin de la liste.
  • add(Integer position, T objet) : Ajoute l'objet fourni à la position indiquée dans la liste.
  • addAll(List<T> elements) ; addAll(Group<T> elements) : Ces fonctions permettent d'ajouter une série d'éléments provenant respectivement d'une liste ou d'un groupe qui est fourni en paramètre.
  • addFill(Integer quantite, T valeur) : Ajoute la valeur à la liste autant de fois que la quantité indiquée.
  • addU(T objet) : Ajout conservant l'unicité du contenu. L'objet est ajouté seulement si il ne se trouve pas déjà dans la liste.
  • clear() : efface tout le contenu.
  • Boolean contains(T objet) : Renvoie true (vrai) si la liste contient l'objet fourni en paramètre.
  • Integer frequency(T objet) : Retourne le nombre d'occurences de l'objet fourni.
  • T get(Integer position) : Retourne l'élément qui se trouve à la position fournie en paramètre. Le premier élément se trouve à la position 0.
  • Boolean isEmpty() : Renvoie true (vrai) si la liste est vide.
  • Integer lastIndexOf(T objet) : Renvoie la position de la dernière occurence de l'objet fourni.
  • remove(T objet) : Retire la première occurence de l'objet fourni de la liste (si il s'y trouve).
  • reverse() : Inverse l'ordre des éléments de la liste.
  • rotate(Integer distance): Décale les éléments de la liste de la distance indiquée. Tous les éléments sortant d'un côté sont replacés de l'autre côté. Après l'appel à cette fonction, les élements à l'index i seront les éléments qui étaient précédemment à l'index (i-distance) modulo list.size pour toutes les valeurs de i comprises entre 0 et list.size-1 inclus. Cette fonction ne modifie pas la taille de la liste.
  • set(Integer position, T objet) : Remplace l'élément se trouvant à la position indiquée par l'objet fourni.
  • shuffle() : Réorganise aléatoirement l'ordre des éléments de la liste.
  • Integer size() : Renvoie le nombre d'éléments contenus dans cette liste.
  • swap(Integer i, Integer j) : Echange les éléments se trouvant aux position i et j indiquées.

Bien qu'il ne s'agisse pas directement d'une fonction d'usage, il faut savoir que l'instruction for(..) peut être utilisée pour parcourir tous les éléments d'une List. :

// j va prendre successivement la valeur de tous les éléments de la liste jours
for (j:jours) { println("Jour suivant :"+j) }


KeyMap

Le type est un ensemble associatif qui permet de stocker des couples associant une clé à une valeur. Il n'y a pas de fonction d'initialisation pour KeyMap. On commence par créer une variable de type KeyMap vide, et on y ajoute des couples clé/valeur avec la fonction put(). Au moment de la création d'une variable de type KeyMap il faut indiquer le type des clés et le type des valeurs :

let km = new KeyMap<Integer,String>
km.put(1,"janvier")
km.put(7,"juillet")

Il n'y a pas de fonction d'initialisation pour KeyMap.

    Fonctions d'usage

Dans cette liste de fonctions, nous avons noté K pour représenter le type des clés, et V pour le type des valeurs.

  • clear() : efface tout le contenu (clé et valeurs).
  • V get(K clé) : Renvoie la valeur correspondant à la clé fournie, ou null si cette clé ne se trouve pas dans la KeyMap.
  • put(K clé, V valeur) : Ajoute un couple clé/valeur
  • remove(K clé) : Retire le couple clé/valeur correspondant à la clé fournie.
  • Integer size() : Renvoie le nombre de couples clé / valeur présents dans la variable de type KeyMap.
Parcours des clés et des valeurs

Il est possible de parcourir l'ensemble des clés presentes dans une variable de type KeyMap à l'aide de l'instruction for(...) et de la fonction keySet() de la manière suivante (en reprenant la variable km en exemple ci-dessus):

for(key:km.keySet()) {
  println("Clé suivante : "+key)
}

Résultat :

Clé suivante : 1
Clé suivante : 7


On peut aussi parcourir l'ensemble des valeurs de façon similaire à l'aide de la fonction values() :

for(val:km.values()) {
  println("Valeur suivante : "+val)
}

Résultat :

Valeur suivante : janvier    
Valeur suivante : juillet
Retour en début de page  

Cell

Le type Cell permet de manipuler une représentation spatiale régulière de l'information géographique. Celui-ci est stocké sous forme matricielle. Il existe trois formes permettant de représenter l'espace de manière régulière et qui sont attribués au type Cell : le carré (ou rectangle), le triangle équilatéral, et l'hexagone régulier. Lorsque qu'une entité est caractérisée par un type Cell celle-ci ne peut avoir que des propriétés de type Double, Integer, Float, Byte ou Boolean.

Cell

Cellules régulières recouvrant l'ensemble d'un espace

    Fonctions d'usage
  • getX() : Retourne la position en abscisse de la matrice(ou nombre de colonnes).
  • getY(): Retourne la position en ordonnée de la matrice (ou nombre de lignes).
  • getCentroid(): Retourne un Point spécifiant la coordonnée projeté ou en latitude/longitude du centre de la cellule selon le type de référencement géographique utilisé.
  • toPolygon(): Retourne un Polygon de la forme de la cellule en coordonnées projetées ou en latitude/longitude selon le type de référencement géographique utilisé.
  • distance(Cell cell): Retourne la distance avec une propriété de type Cell.
  • distance(Geometry geom): Retourne la distance avec une propriété de type Geometry.
Retour en début de page