Ocelet

Pour démarrer


Dans cette page, découvrez comment utiliser un modèle développé par quelqu'un d'autre [1]. Vous pourrez aussi voir comment développer un premier modèle [2] et de visualiser ses sorties de simulations [3].


1. Lancer la simulation d'un projet importé

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.

Retour en début de page  

2. Développer un premier modèle

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).

Lire les entités à partir d'un Shapefile et les écrire dans un fichier kml


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

Ajouter un processus de changement d'occupation du sol et le simuler sur une période de 10 ans

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)< distp1 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() 
    }
Retour en début de page  

3. Visualiser les sorties du modèle

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.

Retour en début de page