Institut Géographique National Laboratoire COGIT GeOxygene : travaux pratiques Exercices pour la version PostGIS version 1.2 28 février 2007 Eric Grosso Résumé : Ce document a pour but de comprendre GeOxygene au travers de divers exercices et fait suite au document intitulé « GeOxygene : installation pas à pas ». Tous les éléments nécessaires à la réalisation de ces exercices sont fournis avec le CD lors de la formation. GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 1 Exercice 1 : Création d’une structure de données à stocker A FAIRE : Créer une structure d’accueil GeOxygene afin de pouvoir manipuler la classe « Salle » définie comme suit : Cette structure d’accueil doit comprendre la table SALLE (manipulation du SGBD – via SQL), le fichier correspondant au pont relationnel objet « repository_salle.xml » (manipulation de OJB via XML) et enfin la classe « objet » Java (manipulation Java). Tous les composants seront créés manuellement afin de comprendre les différents niveaux d’implémentation de GeOxygene, à savoir PostgreSQL-PostGIS, OJB et Java. Par la suite, notamment lors du prochain exercice, la création se fera de manière automatique. Correction de l’exercice 1 Au niveau du Système de Gestion de Bases de Données : Nous créons tout d’abord la table correspondante à la classe « salle » grâce à la syntaxe SQL suivante : CREATE TABLE salle ( cogitid INTEGER PRIMARY KEY, nom VARCHAR(50), numero INTEGER, superficie DOUBLE PRECISION ); Nous créons ensuite la géométrie associée à cette table via la syntaxe SQL suivante : SELECT AddGeometrycolumn ('','salle','geom','-1','GEOMETRY',3); GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 2 La syntaxe SQL peut s’exécuter depuis pgAdmin (Outils puis Editeurs de requêtes) ou depuis la vue Instant SQL dans la perspective dbEdit (pour plus d’informations, consultez le document « org.eclipse.platform.doc.user_3.0.1.pdf »). Au niveau du langage objet (Java) : Pour plus de détails, se référer au manuel utilisateur page 6. La classe Salle hérite de la classe FT_Feature ; de fait, elle hérite d’un identifiant (id de type « int ») et d’une géométrie (geom de type « GM_Object »). Seuls restent à créer les trois autres attributs relatifs à la classe « Salle », à savoir « nom », « numero » et « superficie ». A partir de la création de ces derniers, on crée soit manuellement soit dynamiquement (cf. « org.eclipse.platform.doc.user_3.0.1.pdf ») les Getters et Setters correspondants. La classe « Salle » s’écrit comme suit : package fr.ign.cogit.geoxygene.user.exercice; import fr.ign.cogit.geoxygene.feature.FT_Feature; public class Salle extends FT_Feature{ protected String nom; public String getNom() {return nom;} public void setNom(String nom) {this.nom = nom;} protected int numero; public int getNumero() {return numero;} public void setNumero(int numero) {this.numero = numero;} protected double superficie; public double getSuperficie() {return superficie;} public void setSuperficie(double superficie) {this.superficie = superficie;} } Au niveau du pont relationnel-objet : Pour plus de détails, se référer au manuel utilisateur page 6. Il reste enfin à créer le pont relationnel-objet, i.e. le fichier de mapping OJB. Pour ce faire, il est nécessaire d’écrire la correspondance entre une classe objet (Java) et une table du SGBD : <class-descriptor class="CheminClasseJava" table="NomTable" > et la correspondence entre chaque attribut de cette classe objet et de cette table en précisant le type de l’attribut (INTEGER, DOUBLE, VARCHAR, etc.) : <field-descriptor name="nomAttributClasseJava" column="nomAttributTable" jdbc-type="TYPE" /> GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 3 Ainsi, dans le présent exemple, « repository_salle.xml » comme suit : nous créons le fichier de mapping <class-descriptor class=" fr.ign.cogit.geoxygene.user.exercice.Salle" table="salle" > <field-descriptor name="id" column="cogitid" jdbc-type="INTEGER" primarykey="true" autoincrement="true"/> <field-descriptor name="nom" column="nom" jdbc-type="VARCHAR" /> <field-descriptor name="numero" column="numero" jdbc-type="INTEGER" /> <field-descriptor name="superficie" column="superficie" jdbc-type="DOUBLE" /> <field-descriptor name="geom" column="GEOM" jdbc-type="STRUCT" conversion="fr.ign.cogit.geoxygene.datatools.ojb.GeomGeOxygene2Dbms" /> </class-descriptor> Remarque : Le type « STRUCT » est utilisé dans le cadre d’un attribut dont le type est défini par l’utilisateur, comme par exemple ici avec la géométrie. Il est de fait nécessaire de fournir en supplément un convertisseur, ici la classe « fr.ign.cogit.geoxygene.datatools.ojb.GeomGeOxygene2Dbms ». Enfin, afin que le système prenne en compte le fichier de mapping repository_salle.xml, il est nécessaire d’ajouter les informations suivantes dans le fichier « repository.xml », fichier qui centralise les informations relatives au pont relationnel-objet. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE descriptor-repository PUBLIC "-//Apache Software Foundation//DTD OJB Repository//EN" "repository.dtd" [ <!ENTITY database SYSTEM "repository_database.xml"> <!ENTITY internal SYSTEM "repository_internal.xml"> <!ENTITY geo SYSTEM "repository_geo.xml"> <!ENTITY dataset SYSTEM "repository_dataset.xml"> <!ENTITY salle SYSTEM "repository_salle.xml"> ]> <descriptor-repository version="1.0" isolation-level="read-uncommitted" proxy-prefetching-limit="50"> <!-- parametres de la connection au SGBD--> &database; <!-- exemple classes geographiques <!-- &geo; --> &salle; --> <!-- jeux de donnees --> &dataset; <!-- fichier de mapping internes a OJB INDISPENSABLE --> &internal; </descriptor-repository> GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 4 Exercice 2 : Chargement de données sous GeOxygene à partir de fichiers au format « SIG » : utilisation de la commande « shp2pgsql » de PostgreSQL-PostGIS et de la console GeOxygene A FAIRE : Charger au sein du SGBD PostgreSQL-PostGIS des données géographiques (comportant une géométrie) contenues dans un fichier au format ESRI Shape, à l’aide de la commande « shp2pgsql » (pour plus de détails, se référer au document « GeOxygene : installation pas à pas »). Information : Le fichier de données géographiques a utilisé est le fichier dep_france_dom.shp contenu dans le dossier « donnees/france » fourni avec le CD de la formation. Le nom utilisé pour la table sera « departements ». Utiliser ensuite la console GeOxygene afin de générer automatiquement les fichiers de mapping et java correspondants. Cet exercice est utile dans la compréhension du chargement de données et de la console GeOxygene. Correction de l’exercice 2 Chargement des données au sein de PostgreSQL-PostGIS : Prérequis : copier le répertoire « donnees » fourni avec le CD dans C:\. On suppose qu’une base nommée « postgres » a été créée dans le SGBD PostgreSQL-PostGIS et que les fonctions liées à PostGIS ont été activées pour cette dernière. Si ce n’est pas le cas, se référer à la partie « Chargement de données au format shape sous PostgreSQL-PostGIS » du document « GeOxygene : installation pas à pas ». Le chargement de données s’effectue comme suit : - ouvrir une console en tant qu’utilisateur postgres (démarrer – Programmes – Accessoires – Invites de commandes -). Pour ce faire, ouvrir une console puis taper : runas /user:postgres cmd taper le mot de passe de l’utilisateur postgres, i.e. postgres. - taper ensuite la commande suivante dans la console ainsi ouverte : shp2pgsql -g geom -D -I C:\donnees\france\dep_france_dom.shp departements | psql postgres Rappel de la commande générique utilisée : shp2pgsql -g geom -D -I shapefile nom_table | psql nom_base_donnees l’option « –g » avec comme arguement « geom » spécifie le nom de la colonne géométrique (par défaut « the_geom »). GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 5 Pour plus d’informations sur les différentes options de la commande « shp2pgsql », taper simplement « shp2pgsql » dans une console. La table « departements » est créée et le rapport suivant apparaît : Utilisation de la console GeOxygene - génération automatique des fichiers de mapping et java correspondants : Le lancement de la console GeOxygene s’effectue depuis la classe Java relative à la console située dans le package fr.ign.cogit.geoxygene.appli, comme illustré cidessous : Information : pour lancer l’application depuis Eclipse, cliquer sur le bouton droit de la souris lorsque le curseur est sur la classe Console.java puis choisir « Run As – Java Application ». GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 6 La console apparaît. Cliquer ensuite sur « SQL to Java » : Sélectionner la table « departements » : que vous voulez charger sous GeOxygene, GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 ici 7 Cliquer sur OK puis remplir de la manière suivante (changer « eric » par votre nom) : Cliquer sur OK. La console retourne ce message : Nous pouvons dors et déjà constater ce qui a été généré par la console : - Fichier de mapping (mapping.ojb1.eric.repository_departements.xml) : GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 8 - Classe Java (fr.ign.cogit.geoxygene.user.exercice.Departements ) : Il faut maintenant faire pointer le fichier central des fichiers de mapping (repository.xml) vers le fichier de mapping que nous avons généré, à savoir « repository_departements.xml » : GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 9 Générer ensuite les identifiants COGIT (COGITID) à partir de la console (Manage Data) en choisissant la table que vous voulez traiter, ici « departements »: Le chargement des données est maintenant terminé. GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 10 Exercice 3 : Visualisation des données A FAIRE : Charger les données de l’exercice précédent et les visualiser tout d’abord avec le visualisateur intégré de GeOxygene puis sous Jump ou OpenJump (via la création d’un menu). Correction de l’exercice 3 Visualisation à l’aide du visualisateur GeOxygene : Créer une classe Java dans le package fr.ign.cogit.appli.exercice.visu que nous nommerons « VisuGeOxygene » : package fr.ign.cogit.geoxygene.user.exercice.visu; import fr.ign.cogit.geoxygene.user.exerice.Departements; import fr.ign.cogit.geoxygene.datatools.Geodatabase; import fr.ign.cogit.geoxygene.datatools.ojb.GeodatabaseOjbFactory; import fr.ign.cogit.geoxygene.feature.FT_FeatureCollection; import fr.ign.cogit.geoxygene.util.viewer.ObjectViewer; /**Classe qui permet la visualisation de la carte des départements français */ public class VisuGeOxygene { /**Méthode qui lance l'application*/ public static void main(String[] args) { //création d’une nouvelle connexion Geodatabase geoDB = GeodatabaseOjbFactory.newInstance(); //chargement des données de la classe donnees.eric.exercice.Departements FT_FeatureCollection ftfc = geoDB.loadAllFeatures(Departements.class); //affichage des données dans le visualisateur GeOxygene ObjectViewer viewer = new ObjectViewer(); viewer.addFeatureCollection(ftfc, "departements francais"); } } Lancer ensuite l’application depuis Eclipse issue de la classe créée (cliquer sur le bouton droit de la souris lorsque le curseur est sur la classe java puis choisir « Run As – Java Application »). S’affiche alors : GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 11 Visualisation à l’aide de JUMP : Créer une classe Java dans le package fr.ign.cogit.appli.exercice.visu que nous nommerons « VisuJump » : package fr.ign.cogit.geoxygene.user.exercice.visu; import java.awt.Color; import com.vividsolutions.jump.workbench.plugin.PlugInContext; import com.vividsolutions.jump.workbench.ui.plugin.FeatureInfoPlugIn; import fr.ign.cogit.geoxygene.user.exercice.Departements; import fr.ign.cogit.appli.commun.interfaceJump.UtilJump; import fr.ign.cogit.geoxygene.datatools.Geodatabase; import fr.ign.cogit.geoxygene.datatools.ojb.GeodatabaseOjbFactory; import fr.ign.cogit.geoxygene.feature.FT_FeatureCollection; public class VisuJump extends extends FeatureInfoPlugIn { /**initialisation de l'interface dans le menu de JUMP : ajout d'un menu * GeOxygene/Departements/Affichage*/ public void initialize (PlugInContext context) throws Exception { context.getFeatureInstaller().addMainMenuItem(this,new String[]{"GeOxygene","Departements"}, "Affichage", false, null, null); } /**partie du code relative à l’exécution*/ public boolean execute(PlugInContext context) throws Exception { //création d’une nouvelle connexion Geodatabase geoDB = GeodatabaseOjbFactory.newInstance(); //chargement des données de la classe donnees.eric.exercice.Departements FT_FeatureCollection ftfc = geoDB.loadAllFeatures(Departements.class); //affichage des données en rose sous Jump UtilJump.afficheCollection(context, ftfc, "France","Départements",Color.pink); return true; } } Nous remarquons que ce fichier se compose de deux parties. La première (« unitialize ») est relative à l’initialisation d’un menu dans JUMP (GeOxygene – Departements – Affichage), la seconde au programme qui sera lancé à l’aide du menu créé. Afin que cette classe soit prise en compte au lancement de JUMP, il est nécessaire d’ajouter la ligne suivante dans le fichier « workbench-properties.xml » relatif à JUMP (répertoire JUMP/bin) : <plug-in>fr.ign.cogit.geoxygene.user.exercice.visu.VisuJump</plug-in> GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 12 Lancer ensuite JUMP et cliquer sur le menu « GeOxygene – Departements – Affichage ». GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 13 Exercice 4 : Création et manipulation de données A FAIRE : Créer un attribut supplémentaire nommé « superficie » pour les départements et remplir cet attribut de manière persistante dans le SGBD. Correction de l’exercice 4 Au niveau du Système de Gestion de Bases de Données : Nous créons tout d’abord la colonne « superficie » correspondant à la table « departements » grâce à la syntaxe SQL suivante : ALTER TABLE departements add superficie DOUBLE PRECISION ; La syntaxe SQL peut s’exécuter depuis pgAdmin (Outils puis Editeurs de requêtes) ou depuis la vue Instant SQL dans la perspective dbEdit (pour plus d’informations, consultez le document « org.eclipse.platform.doc.user_3.0.1.pdf »). Il est également possible de créer cette même colonne à l’aide des outils interactifs proposés par pgAdmin. Pour ce faire, procéder comme suit : - clic droit sur la table « departements » puis « Ajouter un objet – Ajouter une colonne » : GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 14 - l’interface suivante apparaît. Remplir comme ci-dessous puis cliquer sur « OK » : Remarque : Les attributs sont à écrire de préférence en caractère alpha et en minuscules. Au niveau du langage objet (Java) : Il est maintenant nécessaire d’ajouter l’attribut « superficie » au niveau objet. Pour ce faire, ajouter les lignes de code suivantes dans la classe « donnees.user.exercice.Departements ». protected double superficie; public double getSuperficie() {return superficie;} public void setSuperficie(double superficie) {this.superficie = superficie;} Au niveau du pont relationnel-objet : Il reste enfin à ajouter la correspondance dans le fichier de mapping OJB « repository_departements.xml ». Pour ce faire, ajouter la ligne suivante : <field-descriptor name="superficie" column=" superficie " jdbc-type="DOUBLE" /> Dans le cas présent, il est inutile d’ajouter quoique ce soit dans le fichier de mapping « repository.xml » puisque « repository_departements.xml » est déjà pris en compte. GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 15 Remarque importante : Lors de la création de la table « departements », une contrainte sur la géométrie des objets est créée : CONSTRAINT enforce_geotype_geom CHECK (geometrytype(geom) = 'MULTIPOLYGON'::text OR geom IS NULL) Cette contrainte oblige les objets de la table « departements » à avoir une géométrie de type « MULTIPOLYGON » ou une géométrie nulle. Or certains objets créés sont de type « POLYGON » et ne vérifient donc pas la contrainte. Il s’agit d’un bug dans la commande « shp2pgsql ». Ce dernier a été identifié et est en passe d’être résolu dans les prochaines versions. Dès lors que nous voulons modifier la table, il devient obligatoire soit de supprimer cette contrainte, soit de la rendre plus « souple », en donnant la possibilité aux objets d’être soit de type géométrique « MULTIPOLYGON » soit de type « POLYGON ». Nous faisons ici le choix de la seconde solution et de fait, exécutons la requête suivante suivante : ALTER TABLE departements DROP CONSTRAINT enforce_geotype_geom; ALTER TABLE departements ADD CONSTRAINT enforce_geotype_geom CHECK (geometrytype(geom) = 'POLYGON'::text OR geometrytype(geom) = 'MULTIPOLYGON'::text OR geom IS NULL); Créons maintenant une classe permettant de calculer la superficie des départements et de remplir la colonne « superficie » de la table « departements » : package fr.ign.cogit.geoxygene.user.exercice.visu; import java.util.Iterator; import fr.ign.cogit.geoxygene.user.exercice.Departements; import fr.ign.cogit.geoxygene.datatools.Geodatabase; import fr.ign.cogit.geoxygene.datatools.ojb.GeodatabaseOjbFactory; import fr.ign.cogit.geoxygene.feature.FT_FeatureCollection; public class CalculSuperficie { public static void main(String[] args) { //définition des variables Departements departement; //création d’une nouvelle connexion Geodatabase geoDB = GeodatabaseOjbFactory.newInstance(); //ouverture d'une transaction relative à la connexion geoDB.begin(); //chargement des données de la classe donnees.eric.exercice.Departements FT_FeatureCollection ftfc = geoDB.loadAllFeatures(Departements.class); //calcul et instanciation de l'attribut superficie Iterator<Departements> it = ftfc.getElements().iterator(); while(it.hasNext()){ GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 16 departement = it.next(); departement.setSuperficie(departement.getGeom().area()); } //commit et ferme la transaction geoDB.commit(); } } Lancer l’application et constater le résultat en visualisant la table « departements » : GeOxygene : travaux pratiques – Exercices pour la version PostGIS – version 1.2 17