GeotoolKit - Géoréférencement

Johann Sorel

Cet article explique comment manipuler les projections avec la librairie GeotoolKit. Un zip contenant tous les exemples se trouve à la fin.
Commentez ?

- Titre : GeotoolKit - Géoréférencement

- Auteur : Johann Sorel

- Parution : 11 mai 2010

- Licence :

Sommaire

- I. le B.A-BA

- II. WKT (Well Knowned Text)

- III. Stockage des projections

- III-A. Derby/JavaDB (pour tout usage)

- III-B. HSQL (pour tout usage)

- III-C. Microsoft Access (Windows uniquement)

- III-D. PostgreSQL (pour serveur ou usage concurrent)

- III-E. Fichier de propriétés (pour applet ou microapplication)

- IV. Cas d'utilisations

- IV-A. Récupérer une projection à partir d'un identifiant

- IV-B. Récupérer une transformation entre deux projections

- IV-C. Pour SIGiste chevronné

- V. Ressources

- VI. Remerciements

I - le B.A-BA

Le cœur de la programmation SIG réside dans cette compréhension. Comprendre ce qu'est une projection et savoir quand on peut se permettre de faire des opérations ou non dans certaines zones de celle-ci.
La Terre n'est pas plate contrairement à ce que montrent toutes les cartes. Une carte affiche une projection de la Terre (nuance). Une projection est la description mathématique de comment on doit transformer un point sur la Terre en un point sur la carte.

Exemple de projections :

Il existe des milliers de projections, aucune n'est correcte à l'échelle de la planète. Chaque projection est, en général, associée à une zone de validité dans laquelle on peut se permettre de faire des calculs avec les coordonnées sans que les erreurs dues à la déformation soient trop grandes.
Actuellement, il existe une autorité qui maintient une liste de ces projections, connue sous le nom de EPSG (European Petroleum Survey Group).
Les plus connues étant :
EPSG:4326 et EPSG:3395

II - WKT (Well Knowned Text)

Le format WKT est la façon la plus répandue d'écrire une projection.
Exemple :

PROJCS[
"WGS 84 / World Mercator",
GEOGCS["WGS 84",
DATUM["World Geodetic System 1984",
SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],
UNIT["degree", 0.017453292519943295],
AXIS["Geodetic latitude", NORTH],
AXIS["Geodetic longitude", EAST],
AUTHORITY["EPSG","4326"]],
PROJECTION["Mercator (1SP)", AUTHORITY["EPSG","9804"]],
PARAMETER["latitude_of_origin", 0.0],
PARAMETER["central_meridian", 0.0],
PARAMETER["scale_factor", 1.0],
PARAMETER["false_easting", 0.0],
PARAMETER["false_northing", 0.0],
UNIT["metre", 1.0],
AXIS["Easting", EAST],
AXIS["Northing", NORTH],
AUTHORITY["EPSG","3395"]
]

On trouve en général la projection dans un fichier *.prj comme c'est le cas pour les fichiers vectoriels shapefiles ou encore les fichiers rasters world-image.

Lecture et écriture de WKT

//Lecture
String wkt = ...;
CoordinateReferenceSystem crs = CRS.parseWKT(wkt);

//Écriture
String backToWkt = crs.toWKT();

Lecture et écriture de PRJ

//Lecture
InputStream stream = ...;
CoordinateReferenceSystem crs = PrjFiles.read(stream,true);

//Écriture
File output = new File("sortie.prj");
PrjFiles.write(crs, output);

III - Stockage des projections

Comme indiqué précédemment il existe des milliers de projections. GeotoolKit doit donc pouvoir stocker une liste de celles-ci ainsi que leurs descriptions détaillées.

III-A - Derby/JavaDB (pour tout usage)

Par défaut GeotoolKit tentera d'utiliser une base de données Derby/JavaDB à condition d'avoir les .jar : geotk-epsg et derby dans le projet.

Si la base de données est inexistante, celui-ci la créera automatiquement. Elle sera placée à l'endroit suivant :
Linux = /home/utilisateur/.geotoolkit.org/EPSG/version
Mac = /Users/utilisateur/Library/GeotoolKit.org/EPSG/version
Windows = C:\Documents and Settings\utilisateur\Application Data\Geotoolkit.org\EPSG\version
Cette base de données n'est accessible qu'à une seule application à la fois.
Donc si vous avez plus d'une application utilisant GeotoolKit en même temps il vous faudra utiliser une des solutions qui suivent.

III-B - HSQL (pour tout usage)

De la même façon que pour Derby/JavaDB, GeotoolKit se chargera de créer automatiquement la base de données dans le même répertoire à condition d'avoir les .jar geotk-epsg et hsql dans le projet.
Attention, dans ce cas, à ne pas avoir le jar de derby présent auquel cas celui-ci sera utilisé en premier.

III-C - Microsoft Access (Windows uniquement)

Il faut inclure les jars odbc et jdbc-odbc bridge dans votre projet.

1- Téléchargez la base Access EPSG depuis http://www.epsg.org et copiez-la où vous le souhaitez.
2- Ouvrez le panneau de contrôle ODBC de Windows.
3- Cliquez sur Ajouter et sélectionnez : Microsoft Access Driver (*.mdb).
4- Nommez la source : EPSG.
5- Cliquez sur sélectionner et indiquez votre base EPSG_version.mdb.
6- Créez ou modifiez le fichier : C:\Documents and Settings\utilisateur\Application Data\Geotoolkit.org\EPSG\DataSource.properties pour qu'il contienne :

DataSource.properties

#
# Connection parameters to the EPSG database.
#
URL = jdbc:odbc:EPSG

III-D - PostgreSQL (pour serveur ou usage concurrent)

Cette solution est dédiée au serveur ou à tout réseau afin d'avoir une base commune ou quand de multiples connections simultanées sont nécessaires.
Il faut inclure les .jar postgresql et geotk-epsg dans le projet.

1- Créer une base de données postgresql vide. Les lignes suivantes créent un rôle « Geotoolkit » et une base de données « Referencing » en UTF-8 sur votre machine locale.
(À adapter selon vos besoins)

createuser --createdb Geotoolkit
createdb --username=Geotoolkit --host=localhost --encoding=UTF-8 Referencing "CRS definitions"
createlang plpgsql --dbname=Referencing --username=Geotoolkit

2- Lancer le jar geotk-epsg comme suit :

java -jar geotk-epsg.jar create jdbc:postgresql://localhost/Referencing Geotoolkit --schema=epsg

3- Nettoyage de la base :

vacuumdb --full --analyze --username Geotoolkit --host localhost Referencing
psql -c 'ALTER USER \"Geotoolkit\" WITH NOCREATEDB' Referencing

4- Créer ou modifier le fichier DataSource.properties situé : Linux = /home/utilisateur/.geotoolkit.org/EPSG/DataSource.properties
Mac = /Users/utilisateur/Library/GeotoolKit.org/EPSG/DataSource.properties
Windows = C:\Documents and Settings\utilisateur\Application Data\Geotoolkit.org\EPSG\DataSource.properties

DataSource.properties

#
# Connection parameters to the EPSG database.
#
URL  = jdbc:postgresql://localhost/Referencing
user = Geotoolkit
password = *****

III-E - Fichier de propriétés (pour applet ou microapplication)

Pour diverses raisons il peut être intéressant d'avoir une version embarquée plus compacte :
- pas d'accès disque ;
- que quelques projections nécessaires ;
- réduire le nombre de fichiers jar ;
- pour les applets java et javafx.

Cette fois, il est nécessaire de renseigner toutes les projections dont on aura besoin dans un fichier nommé epsg.properties.
Placez ensuite celui-ci dans votre projet au chemin suivant :
org\geotoolkit\referencing\factory\epsg\epsg.properties.
Chaque projection doit être sur une seule ligne :

4326=GEOGCS["WGS 84", ... AUTHORITY["EPSG","4326"]]
3395=PROJCS["WGS 84 / World Mercator", ... AUTHORITY["EPSG","3395"]]

IV - Cas d'utilisations

IV-A - Récupérer une projection à partir d'un identifiant

La majeure partie du temps, la projection sera lue automatiquement avec les différents fichiers SIG. Mais il arrive de vouloir obtenir une projection directement, souvent à partir d'un code du type EPSG:XXXX.
Voici comment procéder :

CoordinateReferenceSystem crs = CRS.decode("EPSG:27582");

IV-B - Récupérer une transformation entre deux projections

Bien souvent les données sont des projections différentes, il faut donc en reprojeter l'une ou l'autre pour faire notre travail sereinement. Voici comment faire pour obtenir cette transformation mathématique et l'utiliser :

CoordinateReferenceSystem inCRS = CRS.decode("EPSG:4326");
CoordinateReferenceSystem outCRS = CRS.decode("EPSG:27582");

MathTransform trs = CRS.findMathTransform(inCRS, outCRS);

DirectPosition d1 = new DirectPosition2D(inCRS, 45, 56);
System.out.println("FROM EPSG:4326 = " + d1);

DirectPosition d2 = trs.transform(d1, null);
System.out.println("TO EPSG:27582 = " + d2);

Cette opération demande à GeotoolKit de disposer d'énormément d'informations ainsi que dans certains cas de grilles de transformations. Deux types d'erreurs surviennent régulièrement.

Type : EPSG:XXX Not found…
Erreur classique quand vous avez mal configuré votre source de données pour les projections.
Type : Missing Bursa Wolf… Les paramètres Bursa-Wolf sont des valeurs permettant de définir la transformation vers un système neutre. Il est possible de forcer à trouver une transformation au prix d'une perte de précision plus ou moins conséquente, pour cela il faut exécuter le code suivant au démarrage de votre application :

Hints.putSystemDefault(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);

IV-C - Pour SIGiste chevronné

Contrairement à la librairie Proj4, GeotoolKit va beaucoup plus loin dans la définition et l'exactitude de celle-ci. Mais surtout elle ne se limite pas à deux dimensions.

Vous pouvez construire des projections avec autant d'axes que vous voulez. Voici par exemple une projection à quatre dimensions :

CoordinateReferenceSystem crs2D = CRS.decode("EPSG:27582");
TemporalCRS temporalAxis = DefaultTemporalCRS.JULIAN;
VerticalCRS verticalAxis = DefaultVerticalCRS.GEOIDAL_HEIGHT;
CompoundCRS crs4D = new DefaultCompoundCRS("MyCRS4D", crs2D, temporalAxis, verticalAxis);

Ainsi que quelques méthodes utilitaires :

verticalAxis = CRS.getVerticalCRS(crs4D);
temporalAxis = CRS.getTemporalCRS(crs4D);

Je vous invite à explorer la javadoc pour ceux qui veulent aller plus loin encore et créer de toutes pièces les projections et formules mathématiques.

V - Ressources

Fichier ZIP contenant trois projets maven :
- Stokage-Derby, exemple de projet sur base Derby ;
- Stokage-Properties, exemple de projet sur fichier de propriétés espg ;
- Referencing-Exemple, les divers exemples de cet article.

geotk-referencing-exemple.zip

Site du projet GeotoolKit

Section Système d'information Géographique du forum.

VI - Remerciements

Martin Desruisseaux : pour sa JavaDoc toujours parfaite.
Hédhili Jaïdane : relecture orthographique.