Pour importer un projet existant, voir (Documentation / Plateforme de modélisation / Importer un projet). Si vous le souhaitez, vous pouvez utiliser cet exemple (bellecombe.zip). Une fois l'archive sauvée sur votre disque et importée dans l'OMP, le projet apparaît dans l'explorateur (panneau de gauche).
Naviguez dans l'explorateur pour arriver au modèle "Bellecombe.oclt" (1). En cliquant dessus, le code du modèle apparaît dans la fenêtre centrale, et son aperçu dans celle de droite.
Pour lancer la simulation (2), cliquez sur le bouton .
Vous pouvez suivre l'avancée des simulations dans la fenêtre Console. Une fois le message indiquant la fin de la simulation est affichée (3), le fichier résultat apparaît dans le répertoire output du projet. Pour actualiser le contenu d'un projet faites F5
.
Double-cliquez sur le fichier kml crée (4) pour l'ouvrir dans Google Earth.
Ce petit modèle de changement d'occupation du sol vous permet de voir comment utiliser quelques fonctionnalités de base d'Ocelet. Comme souvent, on procède par étapes de manière incrémentale. A chaque étape intermédiaire, on a un modèle incomplet mais qui tourne.
Créez un nouveau projet (e.g. Fournaise) avec le bouton . Un nouveau répertoire (Fournaise) est créé dans le répertoire "workspace". On aura besoin d'un shapefile qu'il faudra placer dans "..\workspace\Fournaise\data" après avoir dézippé ce fichier (AgPlots_Fournaise.zip).
Définir l'entité "Parcelle"
On va d'abord définir le type d'entités utilisé dans le modèle : PlotAg (Parcelle).
Cette définition se fait dans le fichier "Fournaise.oclt" dans "..\workspace\Fournaise\oclt", avant ou après (mais pas dans) la définition du scénario :
scenario Fournaise {
println("Model Fournaise ready to run")
}
// Define the agricultural plot entity.
entity PlotAg {
property MultiPolygon geom
property Integer id
property Integer lct // land cover type
property Integer surf // surface area in m²
}
A noter que l'entité PlotAg
a été définie avec plusieurs property
, dont une contenant la géometrie.
Définir les datafacer Shapefile et Kml
Ensuite, il faut définir comment accéder au Shapefile à partir duquel les entités PlotAg
(Parcelles) vont être lues, et le fichier Kml dans lequel elles vont être écrites.
// Define a datafacer to read shapefile of plots
datafacer ShpAg {
data Shapefile("data/AgPlots_Fournaise.shp","EPSG:32740") // WGS84 UTM40S
match PlotAg {
geom : "geom"
id : "PID"
lct : "CCULTURE"
surf : "SURF"
}
}
// Define a datafacer for Kml export kml - Land cover
datafacer Kml_LC {
data KmlExport("output/Fournaise_LandCover.kml")
}
A noter que le chemin vers le Shapefile est accompagné d'un code EPSG qui définit la référence spatiale, et que la partie match PlotAg
définit comment les données attributaires du Shapefile sont lues dans les property
des entités.
Utiliser les entités et les datafacers dans un scénario
Il faut maintenant ajouter un service à la définition de l'entité PlotAg
pour pouvoir écrire dans le Kml,
// Define the agricultural plot entity.
entity PlotAg {
property MultiPolygon geom
property Integer id
property Integer lct // land cover type
property Integer surf // surface area in m²
service outputKml (Integer year, KmlExport kml){
let id = "Plot" + id + "_" + year
let style="st" + lct
let deb = year+"-01-01"
let fin = ""+(year+1)+"-01-01"
kml.addGeometry (style,id, deb, fin, geom, style,0)
}
}
et modifier le scénario pour instancier les datafacer, lire les entités parcelles à partir du datafacer Shapefile, définir les styles d'affichage pour le Kml, écrire dans le Kml, et sauver le Kml.
scenario Fournaise {
println("Model Fournaise ready to run")
// Init
// read Plots from Shapefile
let plotShpAg = new ShpAg
let lplotAg = plotShpAg.readAll() // returns a list of PlotAg
// Initialize kml file for output
let kmln = new Kml_LC
let plt = colorRange(8,"dem") // get list of colors from predefined palette "dem"
kmln.defStyleRange("st",1.0,plt,-0.2) // prefix, line thickness, list of colors , darken line color a little
// End Init
// Write land cover state in kml file
let year = 2014
for (p:lplotAg) {
p.outputKml(year, kmln) // write to Kml for each PlotAg of the list
}
// Saving kml file
println("")
println("Saving kml file...")
kmln.saveAsKml()
println("Done.")
}
Dans "..\workspace\Fournaise\output" vous trouverez le Kml résultant : Fournaise_LandCover.kml
On peut maintenant inclure un processus de changement d'occupation du sol. En s'inspirant du jeu de la vie, l'occupation du sol d'une parcelle est modifiée en fonction de celles de ses voisines.
Définir une relation de voisinage entre parcelles
La relation voisinage neighbourhood
définie ci-dessous contient un filtre, une fonction d'interaction et un opérateur d'aggrégation.
La fonction filtre near
avec un paramètre d'entrée dist
ne va retenir que les arcs reliant des parcelles dont les géométries sont distantes de moins de dist
, comme décrit par la condition (p1.geom.distance(p2.geom)< dist
où p1
and p2
sont les deux parcelles connectées par l'arc. La première condition p1.geom.envelope.distance(p2.geom.envelope) < dist
est plus rapide et sert à éliminer du test les cas où les enveloppes des géométries ne sont pas suffisamment proches.
relation Neighbourhood<PlotAg p1, PlotAg p2> {
filter near(Integer dist){
return (p1.geom.envelope.distance(p2.geom.envelope) < dist) &&
(p1.geom.distance(p2.geom) < dist)
}
interaction changeLC() {
// the land cover type of a plot is changed according to the lct of its neighbours
p1.lct = p2.lct // a plot receives the lct of the neighbouring plot
p2.lct = p1.lct
} agg {
p1.lct << Majority // a plot has many neighbours, therefore an aggregation function is applied
p2.lct << Majority // default functions (Mean, Min, Max, Sum ...) or user defined (here Majority)
}
}
La fonction d'interaction de changement d'occupation du sol changeLC
va s'appliquer sur chacun des arcs du graph. Une parcelle prend alors le type d'occupation du sol de sa voisine. Comme une parcelle a plusieurs voisines, un opérateur d'aggrégation est nécessaire pour décider quelle valeur de lct
a être affectée à cette propriété de la parcelle. Ici, une fonction Majority
définie par l'utilisateur va choisir la valeur de lct la plus fréquente parmi les voisines. Mais si cette valeur est trop fréquente, une valeur aléatoire est choisie à la place.
La relation de voisinage peut ensuite être utilisée dans le scénario. Un graphe gN
est instancié avec toutes les parcelles incluses mais non connectées.
gN.complete.near(20).connect()
Dans l'instruction c-dessus, la fonction filtre near
est appliquée au graphe complet complete
, et seulement les parcelles agricoles voisines éloignées de moins de 20
m sont connectées.
La fonction changeLC
va aussi s'appliquer dans le scénario, à chaque pas de temps, une fois les états des parcelles sont écrites dans les fichiers de sortie.
for (year : 2014..2024) {
println(year)
// Write land cover state in kml file
for (p:lplotAg) {
p.outputKml(year, kmln) // write to Kml for each PlotAg of the list
}
// Change land cover according to neighbourhood
gN.changeLC()
}
Dans le scénario ci-dessus on peut voir comment les états des parcelles sont envoyés dans un fichier kml à chaque pas de temps, afin de pouvoir visualiser les changements d'occupation du sol avec Google Earth.
Une autre possibilité d'afficher des cartes animées est avec QGIS une fois le plugin time manager installé. Des attributs temps doivent être ajoutés aux parcelles avant d'être envoyées au shapefile en sortie.
// Define the agricultural plot entity.
entity PlotAg {
property MultiPolygon geom
property Integer id
property Integer lct // land cover type
property Integer surf // surface area in m²
property String date_begin // for use with time manager plugin
property String date_end // in QGIS
}
Un datafacer de sortie shapefile peut être défini comme suit :
datafacer ShpAgOut {
data Shapefile("output/Fournaise_Landcover.shp","EPSG:32740")
match PlotAg {
geom : "the_geom"
id : "gid"
lct : "lct"
date_begin : "begin"
date_end : "end"
}
}
Dans le scénario, des attributs date peuvent être mis à jour à chaque pas de temps, et les parcelles ajoutées à une liste qui sera envoyée au shapefile de sortie.
// simulation
for (year : 2014..2024) {
println(year)
// Initialise list of plots to be added to output shapefile
let lplotAgOut = new List<PlotAg>
// Write land cover state in kml file and shapefile
for (p:lplotAg) {
p.outputKml(year, kmln) // write to Kml for each PlotAg of the list
p.date_begin = ""+ year +"-01-01"
p.date_end = ""+ year +"-12-31"
lplotAgOut.add(p) // add plot to list of plots for shapefile output
}
// output to shapefile
shpout.append(lplotAgOut)
// Change land cover according to neighbourhood
gN.changeLC()
}
A la fin, le datafacer de sortie shapefile doit être fermé afin pour que le fichier soit écrit sur le disque.
// Saving shapefile
print("Saving shp ... ")
shpout.close()
println("ok.")
Voici un code possible de l'exercice ici, et le modèle Fournaise complet avec ses sorties kml et shapefile.