retour aux mémos     retour au modèle     back to SimMasto home page   retour à la page d'accueil

Implantation d'un SIG (geography) dans Repast Sim-phony


Objectif : réaliser une simulation basique basée sur un support SIG (fichier shapefile).
Entrée : Un fichier shapefile
Sortie : un display dans le GUI de Repast Simphony
Outils: Repast-Simphony

Création d’une projection

Valable pour RepastSimphony 1.2 :

  1. Rajouter: <projection id="geography" type="geography" />  dans context.xml

G        Normalement un nouvel élément apparaît dans l'arborescence du GUI et s'appelle « geography ».

  1. Vous pouvez le renommer en faisant un clic droit dessus => show properties et en modifiant la ligne « Label »

Attention  A ce stade il est important de choisir une convention pour les noms. Il est préférable qu'ils soient explicites, relativement courts, sans caractère spéciaux et sans espace.

 Il faudra établir la correspondance des éléments de fichier model.score avec le code correspondant par son nom, mais si celui ci est mal écrit, repast n'indiquera pas d'erreur.

Nous avons inscrit une projection dans le contexte, mais elle est seulement déclarée,  il faut la « construire » dans le contexte.

Pour conserver la généricité du code, on va utiliser un « gestionnaire de terrain ». Pour commencer nous allons utiliser un terrain de type geography.

Nous allons donc créer une classe « SIG_Manager » qui va implémenter l'interface « gestionnaire de terrain » (voir Ground_Manager) et qui sera spécialisée dans le traitement de projection de type géographie.

La classe « SIG_Manager » devra donner une implémentation de toutes les méthodes définies dans l'interface.
Mais avant de définir les méthodes de traitement relatives au terrain, nous allons créer le terrain.
Nous allons donc rajouter la méthode « create_ground » qui va recevoir en paramètre le nom du contexte dans lequel on va ajouter la projection « geography »  et la chaîne de caractère qui définir le nom de la projection (il doit être identique à celui mentionné dans le fichier « model.score ».
Une fois que l'on aura ajouté la projection au contexte,on peut renvoyer le contexte modifé.

public class GIS_Manager implements Ground_Manager

{public Context create_ground(Context context,String GeographyName)

      {      }

@Override

      public void add_agents(Context context, int nb_agent) {      }

      @Override

      public ArrayList<Object> find_object(Agent a, double radius) {

           return null;

      }

      @Override

      public Coordinate get_internal_point(Field_Agent fa) {

           return null;

      }

      @Override

      public Coordinate give_object_coordinate(Object o) {

           return null;

      }

      @Override

      public void move_Object(Agent a, Coordinate c) {   

      }

}

Pour créer la géographie, ajoutez le code suivant dans la méthode « create_ground » :

//on crée les paramètres par défaut de la geography

GeographyParameters geoparam = new GeographyParameters();

/*puis on crée la géographie elle même en fonction de son nom, du contexte et des paramètres. On utilise la classe GeographyFactoryFinder pour créé une nouvelle « usine à projection de type géographie» qui va à son tour crée la geography voulu en fonction des paramètres.*/

Geography geo = GeographyFactoryFinder.createGeographyFactory(null).createGeography("Geography",context,geoparam);

 La géographie est créée mais elle est encore vide, on va y ajouter le SIG à partir d'un fichier shp

Importation du shapefile

Repast Simphony comporte plusieurs librairies qui parfois ont des fonctions similaires, il existe plusieurs façon d'importer un shapefile, en particulier en utilisant directement les classes  gérant les shapefiles (ShapefileReader), mais il n'est pas facile par la suite de rattacher les données géométriques des polygones avec leurs attributs associés, on va donc utiliser un objet « Datastore » qui va permettre de regrouper les données du shapefile (données et attributs) dans une variable se comportant comme une base de données. Le principe ressemble à celui utilisé dans PostGIS, on transforme chaque élément en ligne d'attributs.

//on importe le fichier shp en indicant son url

  File file = new File("data_sig/essai_clip.shp");

//on effectue un test pour s'assurer que le fichier est bien chargé

        if ( file == null)

        {System.out.println(" erreur de chargement du fichier");

        }

//on utilise un objet "map" pour enregistrer les paramètres qui pôurront êtres utiles lors de la création de la database, en particulier l'url du fichier shp

        Map<String,Serializable>

        connectParameters = new HashMap<String,Serializable>();

        connectParameters.put("url", file.toURI().toURL());

          connectParameters.put("create spatial index", true );

        //on crée la database.

          ShapefileDataStore dataStore = (ShapefileDataStore) DataStoreFinder.getDataStore(connectParameters);

 L'objet datastore contient toutes les données, du fichier shp et du fichier dbf et conserve leur relation.
Chaque objet du datastore  est appelé « feature », chaque feature contient la geométrie qui lui est associée (polygone) et les attributs correspondants.
Pour pouvoir les incorporer dans le SIG, on va récupérer ces features et effectuer un parcours sur chacun d'entre eux en les associant avec des agents de type terrain que l'on appellera « Agent_Parcelles ».
Avant de faire cette association, on va déclarer et créer le type Agent_Parcelle

  1. Dans le fichier model.score faite un clic droit sur le contexte et créer un nouveau membre agent
  2. Dans les propriétés de l'agent crée, modifiez le label en  « Agent_Parcelle ». (NB: C_SoilCell en 2013)

Une fois que l'agent est créé dans model.score, vous devez rajouter au moins un attribut

  1. Dans les sous éléments de l'agent créé, faites un clic droit sur « Attributes » et choisissez « create_member – scalar attribute ». vous devez alors renseigner le nom de l’attribut, son type et éventuellement une valeur par défaut.

G        Une fois l'agent déclaré, il faut créer la classe correspondante dans les sources.(clic droit sur le package portant le nom du projet dans le dossier src, new => class). Il faut donner le même nom à la classe que celui donné dans model.score.

Attention: Lorsque vous créez un agent, qu'il représente un terrain ou un agent mobile, vous devez impérativement lui donner au moins un attribut dans sa classe java avec les « getters » et « setters » correspondants avec un attribut associé à l'agent dans le fichier model.score. Si vous ne le faites pas vous ne pourrez pas donner de style à vos agents et lorsque vous lancez la compilation vous risquez d'obtenir l'erreur suivante

log4j:WARN No appenders could be found for logger (MessageCenter.INTERNAL.repast.simphony.ui.RSApplication).

log4j:WARN Please initialize the log4j system properly.

 Cette erreur revient régulièrement, elle peut avoir plusieurs origines

§         soit vous avez mal associé les noms (paramètre agent ou projection)  entre le fichier model.score et les classes

§         soit vous avez mal définit les types d'agents lors de la configuration de l'affichage (display)

§         soit vos agents ne possèdent pas d'attributs avec les accesseurs correspondants.

 

Maintenant que les agents Parcelles existent, nous allons les utiliser pour créer les différents éléments du SIG. il faut reprendre la méthode « create_ground » là où nous l'avions laissé :

//on récupère les types de fichier stocké dans la database

        String[] typeNames = dataStore.getTypeNames();

        //on récupère le 1er type ( celui qui nous interesse)

        String typeName = typeNames[0];

        System.out.println("Reading content " + typeName);

//on créé un objet featuresource qui va nous permettre de récupérer les différents éléments du fichier shp (chaque instance de feature va contenir un polygone avec les données qui lui sont associées)

    FeatureSource fs = dataStore.getFeatureSource(typeName);

//on crée une collection pour stocker les "features"

    FeatureCollection collection;

//on crée un objet iterator pour effectuer un parcours sur tous les features

    FeatureIterator iterator ;

    collection = fs.getFeatures();

    iterator = collection.features();

//on enregistre les dimensions de l'enveloppe du shapefile pour pouvoir //délimiter les frontières (on en aura besoin pour placer et contenir les //agents

    Envelope envelope = collection.getBounds();

 

G        Dans cette portion de code, on récupère les dimensions occupées par la collection, ces dimensions sont utilisées pour créer l'enveloppe qui contient le SIG. Ces dimensions peuvent être utiles si l'on veut placer des agents dans le SIG ou les faire se déplacer à l'intérieur sans qu'ils puissent sortir. Mais il faudra effectuer des tests supplémentaires si le shapefile n'a pas une forme rectangulaire.

Une fois qu'on a crée un objet  « itérator », il faut effectuer un parcours pour insérer chaque élément

 while (iterator.hasNext())       {     
 //on récupère un élément du shapefile

      Feature feature = iterator.next();

      //on récupère le polygone qui y est associé

      Geometry geometry = (Geometry) feature.getDefaultGeometry();

      //à ce stade, on peut accéder aux attributs des éléments du
      //shapefile en utilisant les méthodes de feature:      
      //on récupère les attributs qui nous intéressent:   

      int
x =           Integer.parseInt(feature.getAttribute("Catégorie").toString());

//et on construit l'agent correspondant qui aura comme géométrie le //polygone du SIG qui lui est associé et les attributs dont

// nous pouvons nous servir (les caractéristiques de la zones)
      a =
new Agent_Parcelle(x);
      geo.move(a,geometry);

//cette méthode ne déplace pas réellement un agent  

//mais l'associe avec une géométrie qui elle possède des cordonnées.
      }

G        si vous ne connaissez pas les noms des attributs de votre shapefile, vous pouvez utiliser la ligne: System.out.println(feature.toString()). Chaque feature va alors afficher tous ses attributs dans la console.
Cette méthode peut être pratique pour vérifier que les noms des attributs n'ont pas changé. lorsque vous changez de plateforme (Linux vers Windows par exemple) certains caractères ne sont pas bien reconnus, par exemple l'attribut « Catégories » peut devenir « 
Catégorie » et si l'on essaie de récupérer la valeur de l'attribut « Catégorie », celui ci n'existe plus, ce qui provoque une erreur.

Affichage du SIG dans le simulateur

A ce stade, il est normalement possible d'afficher le SIG dans son intégralité

  1.  Cliquez sur la flèche à coté bouton de lancement et sélectionnez 'Run « votreprojet » model'.

G        Au bout de quelques secondes la fenêtre du simulateur doit s'ouvrir.

 

  1. Faites un clic droit sur DataLoaders et utilisez setDataLoaders.
  2. Dans la nouvelle fenêtre sélectionnez « a specific java class » puis le nom de votre constructeur de contexte («  ContextCreator »).
  3. Il faut ensuite configurer l'affichage, faites un clic droit sur « Displays » puis cliquez sur « add display »
  1. Sélectionnez le type d'affichage GIS et faite passer votre geography dans le champ de droite :

  1. cliquez sur suivant

G        ‘Normalement’ dans la colonne à gauche vous devez voir les agents que vous avez crées. Il faut les changer en types polygones.

G        En éditant le styles des agents il est possible de leur donner une échelle de couleur en fonction d'un attribut.

  1. Cliquez sur suivant puis « finish »
  2. Pour vérifier votre model il suffit de l'initialiser en cliquant sur le bouton « initialize run » :

G        Le modèle met un certain temps à se charger en fonction de la taille du projet et du shp.

G        Une fois chargé, le contenu du fichier doit s'afficher.

 


Mémo 15 - Auteur Q.Baduel, adaptation  22.01.13 par jlefur

retour aux mémos     retour au modèle     back to SimMasto home page   retour à la page d'accueil