Introduction à Geotoolkit.org


Table of Contents

1. Introduction
2. Ressources
Sources
Récupérer et tenir à jour les sources
Précompilé
Compilation locale
3. Données
Coverage
Vecteur
Client
Vectoriel
Structure et manipulation
Filtres et expressions
Formats
Datastore
Geometry-JTS
FeatureType
Feature
Filter-expression
filter-cql
Formats
Coverage
Manipulation par lots
Manipulation par Reader/Writer
CoverageStore
CoverageReader
Client
Sécurité
Clients
ServerStore
Service CSW
Service IGN RM
Service OpenStreetMap Tiled Maps Service
Sensor Observation Service
Web Map Server
4. Map
MapContext
Structure
Création
Symbology
Spécification
Règles de style
Symboles
Création
Cas spéciaux
Engine
Spécification
Etapes du rendu
2D engine
Service-portrayal
Service-glyph
Service-report
Service-legend
Custom Graphic Objects
Custom Graphic Builder
Custom decoration
Custom Symbolizer
5. Process
Qu'est ce qu'un process ?
Créer son processus
La registry
La description
Le traitement
Utilisation des processus
Trouver un processus
Exécution d'un processus
Outils
Process Quartz
Process Shell
Process XOffice
6. ObjectConverter
ObjectConverter
Création d'un Converter.
Utilisation d'un converteur
7. Composants Swing
Composants de carte
JMap2D
JContextTree
JNavigationBar
JInformationBar
JSelectionBar
JEditionBar
JCoordinateBar
JConfigBar
JMap2DFrame
Autres composants

List of Figures

1. GeoToolkit.org
2. Architecture de GeoToolkit.org
3.1. Structure des datastores
3.2. Requête sur un datastore
3.3. Architecture des interfaces
3.4. Classe FeatureType
3.5. Structure des filtres
3.6. Opérateurs spatiaux des filtres
3.7. Expressions des filtres
4.1. Classes relatives aux maps
4.2. Classes relatives à la symbologie
4.3. Classes relatives aux styles
4.4. Pipeline image par défaut
4.5. Pipeline pour les images standard (png,jpg,tiff ... : habituellement 3 ou 4 bandes couleurs)
4.6. Pipeline pour les images type scientifique ( 1 bande )
4.7. Sélection de bande - un seul canal
4.8. Sélection de bande - Vert/bleu inversé
4.9. ColorMap - Interpolation
4.10. ColorMap - Catégorisation
4.11. Ajustement de contraste - aucun
4.12. Ajustement de contraste - Gamma
4.13. Ajustement de contraste - Histogramme
4.14. Ajustement de contraste - Normalisation
4.15. Contours
4.16. Effet de relief
4.17. Classes relatives au moteur de rendu 2D
4.18. Etapes de rendu
4.19. Accueil de iReport 3.7.4
4.20. Champs source
4.21. Champs de définition de classe
4.22. Fenêtre de propriétés du champs
4.23. Propriétés du champs
4.24. Exemples de décorations :
5.1. Classes et interfaces de description de paramètres
5.2. Classes et interfaces de valeurs de paramètres
5.3. Activation du JRE pour OpenOffice
5.4. Installation du module geotk pour OpenOffice
7.1. Affichage d'une carte via JMap2D
7.2. Affichage des propriétés d'affichage via JContextTree
7.3. Barre de navigation
7.4. Barre d'information
7.5. Barre de sélection
7.6. Barre d'édition
7.7. Barre des coordonnées
7.8. Barre des élévations
7.9. Barre temporelle
7.10. Barre de configuration
7.11. Boussole
7.12. Panneau d'information
7.13. Affichage d'un JMap2DFrame
7.14. Fenêtre d'édition des attributs
7.15. Fenêtre d'édition de style

List of Tables

3.1. Coverages : formats supportés
3.2. Données vecteur : formats de fichier supportés
3.3. Données vecteur : base de données supportées
3.4. Services supportés
5.1. XOffice : paquets nécessaires
5.2. XOffice : logiciels requis

List of Examples

3.1. Lister les différentes fabriques de DataStore
3.2. Création d'un Datastore en mémoire
3.3. Création de géometrie JTS
3.4. Associer un SRID à une geometrie :
3.5. Création de FeatureType
3.6. Création et manipulation de feature
3.7. Création de filtre standard et Javascript
3.8. Utilisation du CQL
3.9. CQL vers Filter
3.10. Filter vers CQL
3.11. Lecture d'un fichier GPX
3.12. Lecture d'un fichier GPX
3.13. Connexion à une base PostGIS
3.14. Lecture d'un fichier shapefile
3.15. Lister les différentes fabriques de coverage
3.16. Utilisation d'un CoverageReader
3.17. Lister les différentes fabriques de connexion distante
3.18. Code source complet :
3.19. Connexion aux services IGN
3.20. Code de connexion à un service IGN
3.21. Connexion a un service de tuile OpenStreetMap
3.22. Code de connexion a un service OSMTMS
3.23. Connexion à un serveur SOS
3.24. Connexion à un server SOS
3.25. Connexion à un serveur WMS
3.26. Connexion à un server WMS
4.1. Création d'un MapContext
4.2. Création d'un MapContext
4.3. Style avec plusieurs règles
4.4. Divers examples de symbologie
4.5. Génération d'image
4.6. Création et affichage d'une carte-image
4.7. Génération de glyphe
4.8. Création et affichage d'une glyphe
4.9. Génération de rapport avec JasperReport
4.10. Génération de légende
4.11. Création et affichage d'une légende
4.12. Object graphic simple
4.13. Object GraphicBuilder sur mesure
4.14. Object graphic sur mesure
4.15. Création d'un symbolizer sur mesure
5.1. Code complet de création d'une registry
5.2. Identification d'une Registry
5.3. Identification d'une Registry
5.4. Identification d'une Registry
5.5. Code complet de création d'un ProcessDescriptor pour une Addition
5.6. Description des entrées
5.7. Description d'une entrée avec bundle de traduction
5.8. Description des entrées
5.9. Code complet du Process Addition
5.10. Code d'exécution du Process addition
5.11. Méthodes de récupération des valeurs en entrées et d'injection des valeurs en sorties.
5.12. Exemple de traitement long avec mise à jours de la progression
5.13. Exemple d'implementation d'arrêt d'un processus
5.14. Exemple 1 : Trouver un processus.
5.15. Exemple 2 : Exécution d'un processus simple.
5.16. Exemple 3 : Exécution d'un processus complex
5.17. Récupération de la liste des ProcessingRegistry et des ProcessDescriptor
5.18. Récupération d'un ProcessDescriptor en particulier
5.19. Registry méthodes
5.20. Création des paramètres d'entrées
5.21. Remplissage des paramètres d'entrées.
5.22. Création du processus.
5.23. Exécution et récupération de la sortie du processus.
5.24. Utilisation de processus dans Quartz
5.25. Création du sheduler
5.26. Création du process
5.27. Lancement des tâches
5.28. CRS EPSG:27573
5.29. CRS transform EPSG:27573 EPSG:4326
5.30. Execution de process en ligne de commande
6.1. Code complet de création d'un converter d'une String en Geometry JTS.
6.2. Conversion d'un WKT en Geometry
6.3. Demo d'utilisation de la ConverterRegistry et d'un converter en particulier.
6.4. Conversion d'un WKT en Geometry
7.1. Demo regroupant les différents widgets

Figure 1. GeoToolkit.org

GeoToolkit.org

Figure 2. Architecture de GeoToolkit.org

Architecture de Geotoolkit.org

Geotookit est une librairie dédiée à la cartographie, toutefois ce domaine recoupe beaucoup d'autre domaines. Y sont inclus la manipulation des images, des métadonnées, des géometries, les méchanismes de retroingénierie sur les bases de données, la sécurisation de connexion ou encore les interfaces utilisateurs.

Aujourd'hui le projet compte plus d'une centaine de modules.

Différentes ressources sont utilisées au travers de ces tutoriels, les informations communes sont regroupées ici.

La compilation requiert :

Une fois ceux ci installés, la compilation se fait avec la commande :

            mvn clean install -DskipTests
        

Le temps de compilation varie selon la machine utilisée et votre connexion internet. La première compilation est plus longue pour récupérer les différents paquets dont elle a besoin. Comptez une trentaine de minute pour la première compilation.

Les jars de GeotoolKit sont dans le sous-dossier target.

GeotoolKit implémente la norme OGC et GeoAPI 3 .

De ce fait, la manipulation des images et des données vecteurs se fait avec des modèles respectifs qui seront les mêmes quelle que soit la source de données utilisée. On parle alors de :

  • Coverage / Coveragestore pour les images/rasters
  • Feature / Datastore pour les données vecteurs et attributaires.
  • Client / Server pour les connexions distantes

Tous les formats ne sont pas toujours normalisés ou n'entre pas exactement dans l'un ou l'autre modèle. En particulier l'usage des services distants qui peuvent être normalisés mais ne fournissent pas toujours un résultat sous forme de coverage ou de feature. On trouvera donc des servers qui peuvent implementer Datastore ou CoverageStore. GeotoolKit s'occupe de gérer le nécessaire pour communiquer avec ces services, fournissant l'authentification, l'envoi de requête et le traitement des réponses.

Résumé des formats supportés.

???
???
CSV
DBF
KML
GML
CityGML
WFS
OSM
???

Dès lors que l'on peut créer des FeatureTypes et des Features on est à même de manipuler les éléments un par un.

Pour aller plus loin et pouvoir faire des requêtes particulières pour traiter des ensembles de Features, on utilise un Datastore. Celui-ci va nous permettre de faire des requêtes ainsi que de gérer un système de session/transactions pour s'occuper d'enregistrer les changements.

Il n'y a actuellement aucune norme OGC ou ISO qui définisse comment accéder aux données. Les normes OGC Geographic Markup Language (GML) et OGC Web Feature Service (WFS) définissent le concept de collection de feature (FeatureCollection) mais ce n'est pas suffisant.

Plutôt que de concevoir une nouvelle API, nous avons cherché un modèle déjà existant et largement utilisé. En explorant les CMS (Content Management System), nous avons trouvé une spécification Java nommée : Java Content Repository. Cette JSR dispose d'un grand nombre de companies et est utilisée dans plusieurs grand projets, JackRabbit, Exoplatform ou encore Liferay. C'est aussi une API mature qui en est à sa seconde version. (version 1 : JSR-170 et version 2 : JSR-283)

JCR a été conçu pour l’interopérabilité entre des sources de données complétements différentes, des bases de données aux systèmes de gestion de version et aux systèmes de fichiers. Il est intéressant de noter que celle-ci dispose d'une structure équivalente aux FeatureType et Feature qui sont nommés Node et NodeType. (Les données SIG sont elles si différentes des autres ?)

Le modèle JCR réduit tout en type primitif dans les object Node, ce qui serait pénible en SIG avec les géométries ou les projections. Nous avons donc conçu un modèle qui copie 1 pour 1 celui de JCR mais en remplaçant les classes Node et NodeType par leurs équivalents SIG Feature et FeatureType.


JTS est une API java pour la manipulation des géométries.

La documentation complète peut être trouvée sur leur site web :

Documentation : http://www.vividsolutions.com/jts/jtshome.htm
Téléchargement : http://sourceforge.net/projects/jts-topo-suite

Malheureusement il n'y pas d'alternative pour le moment, nous espérons proposer une implémentation des géométries multidimensionnelles basée sur ISO 19107 à l'avenir.


JTS comme GeoAPI travaille avec des fabriques.


                    import com.vividsolutions.jts.geom.GeometryFactory

                    final GeometryFactory gf = new GeometryFactory();

            

Les géométries sont relativement simples a créer.


                    //creating a point
                    final Point point = gf.createPoint(new Coordinate(56, 45));


                    //creating a multipoint
                    final MultiPoint mp = gf.createMultiPoint(new Coordinate[]{
                    new Coordinate(23, 78),
                    new Coordinate(-10, 43),
                    new Coordinate(12, 94)});


                    //creating a linestring
                    final LineString ls = gf.createLineString(new Coordinate[]{
                    new Coordinate(23, 78),
                    new Coordinate(-10, 43),
                    new Coordinate(12, 94)});


                    //creating a multilinestring
                    final LineString ls1 = gf.createLineString(new Coordinate[]{
                    new Coordinate(30, 45),new Coordinate(56, 29)});
                    final LineString ls2 = gf.createLineString(new Coordinate[]{
                    new Coordinate(98,12),new Coordinate(19, 87)});
                    final MultiLineString mls = gf.createMultiLineString(new LineString[]{
                    ls1,ls2});


                    //creating a polygon
                    final LinearRing ring = gf.createLinearRing(new Coordinate[]{
                    new Coordinate(23, 78),
                    new Coordinate(-10, 43),
                    new Coordinate(12, 94),
                    new Coordinate(23, 78)});
                    final Polygon polygon = gf.createPolygon(ring, new LinearRing[0]);


                    //creating a multipolygon
                    final MultiPolygon mpolygon = gf.createMultiPolygon(new Polygon[]{polygon});

            

Comme JTS ne permet pas de stocker la projection, GeotoolKit contient une classe utilitaire SRIDGenerator qui peut être utilisée pour transformer un CRS en entier.

Cela n'est valide que pour les projections des l'autorité EPSG et CRS.


                    final CoordinateReferenceSystem crs = CRS.forCode("EPSG:3395");
                    //converting the CRS to an integer
                    final int srid = SRIDGenerator.toSRID(crs, SRIDGenerator.Version.V1);
                    //srid back to CRS
                    final CoordinateReferenceSystem backcrs = CRS.forCode(SRIDGenerator.toSRS(srid, SRIDGenerator.Version.V1));

            

Il est aussi possible d'utiliser la classe utilitaire JTS pour faire ces affectations.


                    Point pt = new GeometryFactory().createPoint(new Coordinate(10, 50));
                    //set crs on a geometry
                    JTS.setCRS(pt, crs);
                    //extract crs from geometry srid or user map
                    backcrs = JTS.findCoordinateReferenceSystem(pt);

            

La norme à laquelle se rapporte les Feature est ISO 19109 "Rules for application schemas".

Un FeatureType est la définition d'un modèle. Tout comme on définit une table dans une base de données ou les colonnes dans un tableur. Le feature type va donc nous fournir des métadonnées sur ce que l'on manipule, nous donnant le nombre de propriétés, leurs noms, leurs quantités et leurs contraintes.

Un Feature est un enregistrement, il est toujours associé à un FeatureType qui le définit.

En comparaison, un feature dans une base de données correspond à une ligne dans une table et le FeatureType serait la définition de la table.

La norme permet d'avoir des FeatureType abstraits, par exemple on peut avoir un type Voiture abstrait et des sous-types Voiture de course, Utilitaire, ... De la même façon que pour l’héritage objet en programmation, les sous-types peuvent avoir de nouveaux "attributes". Toutefois, dans les formats actuels, les héritages sont très rares.



Un FeatureType se compose de PropertyDescriptor , chacun définissant le nom et les différents paramètres d'une propriété.

Il existe 4 types de propriété :

  • Attribute : c'est le plus simple, il définit un attribut simple qui contient une valeur primitive, une chaine de caractère, un nombre, une date ...
  • Geometrie : similaire au AttributeDescriptor mais limité aux géométries et disposant d'informations complémentaires comme le CRS
  • Operation : peu utilisé cela peut faire référence à une valeur calculée ou à des fonctionnalités
  • Association : permet de faire un lien vers d'autre Feature pour exprimer une relation.

On entend souvent parler de SimpleFeature. La quasi-totalité des librairies et applications existantes ne sont capables de ne traiter que ce modèle. Un SimpleFeature est une simplification du modèle avec les contraintes suivantes :

  • Toutes les propriétés doivent être des "attributes"
  • Toutes les propriétés doivent avoir un minimum et un maximum de 1

On peut classer les formats CSV, shapefile comme des types simples et GPX ou OpenStreetMap comme complexes.


La manière par défaut de procéder pour créer un FeatureType est d'utiliser une FeatureTypeFactory toutefois ceci est très verbeux.

Afin de simplifier ce travail, une classe utilitaire FeatureTypeBuilder a été ajoutée évitant ainsi quantité d'erreur de déclaration, celui ci se charge de créer les types correctes avec les informations fournies.

On procède par ajout, en spécifiant le nom de l'attribut que l'on souhaite, son type et éventuellement dans le cas de geometrie, la projection.


                    final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
                    ftb.setName("Fish");
                    ftb.add("name", String.class);
                    ftb.add("length", Integer.class);
                    ftb.add("lastPosition", LineString.class, CRS.forCode("EPSG:3395"));
                    ftb.add("lastPositionDate", Date.class);
                    ftb.add("direction", Float.class);
                    ftb.setDefaultGeometry("lastPosition");
                    final SimpleFeatureType sft = ftb.buildSimpleFeatureType();

            

Une attention particulière a été portée sur les différentes méthodes toString() afin de simplifier le debuggage.


                    DefaultSimpleFeatureType Fish identified extends Feature
                    ╔══════════════════╤══════╤══════╤═══════════╤════════════╤═══════════╤═══════════╗
                    ║ name             │  min │  max │  nillable │  type      │  CRS      │  UserData ║
                    ╟──────────────────┼──────┼──────┼───────────┼────────────┼───────────┼───────────╢
                    ║ name             │ 1    │ 1    │ true      │ String     │           │           ║
                    ║ length           │ 1    │ 1    │ true      │ Integer    │           │           ║
                    ║ lastPosition     │ 1    │ 1    │ true      │ LineString │ EPSG:3395 │           ║
                    ║ lastPositionDate │ 1    │ 1    │ true      │ Date       │           │           ║
                    ║ direction        │ 1    │ 1    │ true      │ Float      │           │           ║
                    ╚══════════════════╧══════╧══════╧═══════════╧════════════╧═══════════╧═══════════╝
                    crs=EPSG:WGS 84 / World Mercator


            

Un exemple de création d'un type complexe est aussi présent dans le code source complet.


Il existe trois façons des créer des Features.

  • FeatureFactory
  • SimpleFeatureBuilder
  • FeatureUtilities


Le format GPX est utilisé comme format de sortie pour les GPS.

C'est un format XML décrivant trois featuretupe complexe.

  • Track
    
                    DefaultFeatureType {http://www.topografix.com}Track identified extends GPXEntity
                    ╔══════════════════════════════════════════════════╤══════╤════════════╤═══════════╤═════════════════╤════════╤═══════════╗
                    ║ name                                             │  min │        max │  nillable │            type │    CRS │  UserData ║
                    ╟──────────────────────────────────────────────────┼──────┼────────────┼───────────┼─────────────────┼────────┼───────────╢
                    ║ {http://www.topografix.com}index                 │ 1    │ 1          │ false     │ Integer         │        │           ║
                    ║ {http://www.topografix.com}geometry              │ 1    │ 1          │ false     │ MultiLineString │ CRS:84 │           ║
                    ║ {http://www.topografix.com}name                  │ 0    │ 1          │ true      │ String          │        │           ║
                    ║ {http://www.topografix.com}cmt                   │ 0    │ 1          │ true      │ String          │        │           ║
                    ║ {http://www.topografix.com}desc                  │ 0    │ 1          │ true      │ String          │        │           ║
                    ║ {http://www.topografix.com}src                   │ 0    │ 1          │ true      │ String          │        │           ║
                    ║ {http://www.topografix.com}link                  │ 0    │ 2147483647 │ true      │ URI             │        │           ║
                    ║ {http://www.topografix.com}number                │ 0    │ 1          │ true      │ Integer         │        │           ║
                    ║ {http://www.topografix.com}type                  │ 0    │ 1          │ true      │ String          │        │           ║
                    ║ {http://www.topografix.com}trkseg                │ 0    │ 2147483647 │ true      │ CX:TrackSegment │        │           ║
                    ║   ├─{http://www.topografix.com}index             │ 1    │ 1          │ false     │ Integer         │        │           ║
                    ║   ├─{http://www.topografix.com}geometry          │ 1    │ 1          │ false     │ LineString      │ CRS:84 │           ║
                    ║   └─{http://www.topografix.com}trkpt             │ 0    │ 2147483647 │ true      │ CX:WayPoint     │        │           ║
                    ║       ├─{http://www.topografix.com}index         │ 1    │ 1          │ false     │ Integer         │        │           ║
                    ║       ├─{http://www.topografix.com}geometry      │ 1    │ 1          │ false     │ Point           │ CRS:84 │           ║
                    ║       ├─{http://www.topografix.com}ele           │ 0    │ 1          │ true      │ Double          │        │           ║
                    ║       ├─{http://www.topografix.com}time          │ 0    │ 1          │ true      │ Date            │        │           ║
                    ║       ├─{http://www.topografix.com}magvar        │ 0    │ 1          │ true      │ Double          │        │           ║
                    ║       ├─{http://www.topografix.com}geoidheight   │ 0    │ 1          │ true      │ Double          │        │           ║
                    ║       ├─{http://www.topografix.com}name          │ 0    │ 1          │ true      │ String          │        │           ║
                    ║       ├─{http://www.topografix.com}cmt           │ 0    │ 1          │ true      │ String          │        │           ║
                    ║       ├─{http://www.topografix.com}desc          │ 0    │ 1          │ true      │ String          │        │           ║
                    ║       ├─{http://www.topografix.com}src           │ 0    │ 1          │ true      │ String          │        │           ║
                    ║       ├─{http://www.topografix.com}link          │ 0    │ 2147483647 │ true      │ URI             │        │           ║
                    ║       ├─{http://www.topografix.com}sym           │ 0    │ 1          │ true      │ String          │        │           ║
                    ║       ├─{http://www.topografix.com}type          │ 0    │ 1          │ true      │ String          │        │           ║
                    ║       ├─{http://www.topografix.com}fix           │ 0    │ 1          │ true      │ String          │        │           ║
                    ║       ├─{http://www.topografix.com}sat           │ 0    │ 1          │ true      │ Integer         │        │           ║
                    ║       ├─{http://www.topografix.com}hdop          │ 0    │ 1          │ true      │ Double          │        │           ║
                    ║       ├─{http://www.topografix.com}vdop          │ 0    │ 1          │ true      │ Double          │        │           ║
                    ║       ├─{http://www.topografix.com}pdop          │ 0    │ 1          │ true      │ Double          │        │           ║
                    ║       ├─{http://www.topografix.com}ageofdgpsdata │ 0    │ 1          │ true      │ Double          │        │           ║
                    ║       └─{http://www.topografix.com}dgpsid        │ 0    │ 1          │ true      │ Integer         │        │           ║
                    ╚══════════════════════════════════════════════════╧══════╧════════════╧═══════════╧═════════════════╧════════╧═══════════╝
                    crs=WGS84(DD)
                
  • WayPoint
    
                    DefaultFeatureType {http://www.topografix.com}WayPoint identified extends GPXEntity
                    ╔══════════════════════════════════════════╤══════╤════════════╤═══════════╤═════════╤════════╤═══════════╗
                    ║ name                                     │ min  │ max        │ nillable  │ type    │ CRS    │ UserData  ║
                    ╟──────────────────────────────────────────┼──────┼────────────┼───────────┼─────────┼────────┼───────────╢
                    ║ {http://www.topografix.com}index         │ 1    │ 1          │ false     │ Integer │        │           ║
                    ║ {http://www.topografix.com}geometry      │ 1    │ 1          │ false     │ Point   │ CRS:84 │           ║
                    ║ {http://www.topografix.com}ele           │ 0    │ 1          │ true      │ Double  │        │           ║
                    ║ {http://www.topografix.com}time          │ 0    │ 1          │ true      │ Date    │        │           ║
                    ║ {http://www.topografix.com}magvar        │ 0    │ 1          │ true      │ Double  │        │           ║
                    ║ {http://www.topografix.com}geoidheight   │ 0    │ 1          │ true      │ Double  │        │           ║
                    ║ {http://www.topografix.com}name          │ 0    │ 1          │ true      │ String  │        │           ║
                    ║ {http://www.topografix.com}cmt           │ 0    │ 1          │ true      │ String  │        │           ║
                    ║ {http://www.topografix.com}desc          │ 0    │ 1          │ true      │ String  │        │           ║
                    ║ {http://www.topografix.com}src           │ 0    │ 1          │ true      │ String  │        │           ║
                    ║ {http://www.topografix.com}link          │ 0    │ 2147483647 │ true      │ URI     │        │           ║
                    ║ {http://www.topografix.com}sym           │ 0    │ 1          │ true      │ String  │        │           ║
                    ║ {http://www.topografix.com}type          │ 0    │ 1          │ true      │ String  │        │           ║
                    ║ {http://www.topografix.com}fix           │ 0    │ 1          │ true      │ String  │        │           ║
                    ║ {http://www.topografix.com}sat           │ 0    │ 1          │ true      │ Integer │        │           ║
                    ║ {http://www.topografix.com}hdop          │ 0    │ 1          │ true      │ Double  │        │           ║
                    ║ {http://www.topografix.com}vdop          │ 0    │ 1          │ true      │ Double  │        │           ║
                    ║ {http://www.topografix.com}pdop          │ 0    │ 1          │ true      │ Double  │        │           ║
                    ║ {http://www.topografix.com}ageofdgpsdata │ 0    │ 1          │ true      │ Double  │        │           ║
                    ║ {http://www.topografix.com}dgpsid        │ 0    │ 1          │ true      │ Integer │        │           ║
                    ╚══════════════════════════════════════════╧══════╧════════════╧═══════════╧═════════╧════════╧═══════════╝
                    crs=WGS84(DD)
                
  • Routes
    
                    DefaultFeatureType {http://www.topografix.com}Route identified extends GPXEntity
                    ╔══════════════════════════════════════════════╤══════╤════════════╤═══════════╤═════════════╤════════╤═══════════╗
                    ║ name                                         │ min  │ max        │ nillable  │ type        │ CRS    │ UserData  ║
                    ╟──────────────────────────────────────────────┼──────┼────────────┼───────────┼─────────────┼────────┼───────────╢
                    ║ {http://www.topografix.com}index             │ 1    │ 1          │ false     │ Integer     │        │           ║
                    ║ {http://www.topografix.com}geometry          │ 1    │ 1          │ false     │ LineString  │ CRS:84 │           ║
                    ║ {http://www.topografix.com}name              │ 0    │ 1          │ true      │ String      │        │           ║
                    ║ {http://www.topografix.com}cmt               │ 0    │ 1          │ true      │ String      │        │           ║
                    ║ {http://www.topografix.com}desc              │ 0    │ 1          │ true      │ String      │        │           ║
                    ║ {http://www.topografix.com}src               │ 0    │ 1          │ true      │ String      │        │           ║
                    ║ {http://www.topografix.com}link              │ 0    │ 2147483647 │ true      │ URI         │        │           ║
                    ║ {http://www.topografix.com}number            │ 0    │ 1          │ true      │ Integer     │        │           ║
                    ║ {http://www.topografix.com}type              │ 0    │ 1          │ true      │ String      │        │           ║
                    ║ {http://www.topografix.com}rtept             │ 0    │ 2147483647 │ true      │ CX:WayPoint │        │           ║
                    ║   ├─{http://www.topografix.com}index         │ 1    │ 1          │ false     │ Integer     │        │           ║
                    ║   ├─{http://www.topografix.com}geometry      │ 1    │ 1          │ false     │ Point       │ CRS:84 │           ║
                    ║   ├─{http://www.topografix.com}ele           │ 0    │ 1          │ true      │ Double      │        │           ║
                    ║   ├─{http://www.topografix.com}time          │ 0    │ 1          │ true      │ Date        │        │           ║
                    ║   ├─{http://www.topografix.com}magvar        │ 0    │ 1          │ true      │ Double      │        │           ║
                    ║   ├─{http://www.topografix.com}geoidheight   │ 0    │ 1          │ true      │ Double      │        │           ║
                    ║   ├─{http://www.topografix.com}name          │ 0    │ 1          │ true      │ String      │        │           ║
                    ║   ├─{http://www.topografix.com}cmt           │ 0    │ 1          │ true      │ String      │        │           ║
                    ║   ├─{http://www.topografix.com}desc          │ 0    │ 1          │ true      │ String      │        │           ║
                    ║   ├─{http://www.topografix.com}src           │ 0    │ 1          │ true      │ String      │        │           ║
                    ║   ├─{http://www.topografix.com}link          │ 0    │ 2147483647 │ true      │ URI         │        │           ║
                    ║   ├─{http://www.topografix.com}sym           │ 0    │ 1          │ true      │ String      │        │           ║
                    ║   ├─{http://www.topografix.com}type          │ 0    │ 1          │ true      │ String      │        │           ║
                    ║   ├─{http://www.topografix.com}fix           │ 0    │ 1          │ true      │ String      │        │           ║
                    ║   ├─{http://www.topografix.com}sat           │ 0    │ 1          │ true      │ Integer     │        │           ║
                    ║   ├─{http://www.topografix.com}hdop          │ 0    │ 1          │ true      │ Double      │        │           ║
                    ║   ├─{http://www.topografix.com}vdop          │ 0    │ 1          │ true      │ Double      │        │           ║
                    ║   ├─{http://www.topografix.com}pdop          │ 0    │ 1          │ true      │ Double      │        │           ║
                    ║   ├─{http://www.topografix.com}ageofdgpsdata │ 0    │ 1          │ true      │ Double      │        │           ║
                    ║   └─{http://www.topografix.com}dgpsid        │ 0    │ 1          │ true      │ Integer     │        │           ║
                    ╚══════════════════════════════════════════════╧══════╧════════════╧═══════════╧═════════════╧════════╧═══════════╝
                    crs=WGS84(DD)
                


PostGIS est l'extension spatiale de PostgreSQL.

C'est aussi le mode de stockage SIG en base de données le plus utilisé.


                final ParameterValueGroup parameters = PostgisNGDataStoreFactory.PARAMETERS_DESCRIPTOR.createValue();
                Parameters.getOrCreate(PostgisNGDataStoreFactory.HOST, parameters).setValue("hote");
                Parameters.getOrCreate(PostgisNGDataStoreFactory.PORT, parameters).setValue(5432);
                Parameters.getOrCreate(PostgisNGDataStoreFactory.DATABASE, parameters).setValue("base");
                Parameters.getOrCreate(PostgisNGDataStoreFactory.USER, parameters).setValue("user");
                Parameters.getOrCreate(PostgisNGDataStoreFactory.PASSWD, parameters).setValue("secret");

                final DataStore store = DataStoreFinder.getDataStore(parameters);

        

GeotoolKit traite les images en s'appuyant sur l'api standard du java. L'image décrit le modèle de stockage ainsi que le modèle de couleur. Le coverage est une surcouche qui vient ajouter l'aspect georéférencement et métadonnée.

GeotoolKit traite les images en s'appuyant sur l'api standard du java. L'image décrit le modèle de stockage, le modèle de couleur. Le coverage est une surcouche qui vient ajouter l'aspect georéférencement et métadonnée.


Afin d'obtenir un coverage, on passe par un CoverageReader qui va permettre d'améliorer le contrôle sur la lecture de l'image, en limitant la zone à lire ou la résolution. Pour un fichier image (netcdf, geotiff, world image, ...) on utilise la classe utilitaire CoverageIO.
            final File input = new File("data/clouds.jpg");
            final GridCoverageReader reader = CoverageIO.createSimpleReader(input);
        

Une fois que l'on dispose d'un CoverageReader on peut demander à avoir ses metadonnées.

            //print the iso 19115 metadata
            final Metadata metadata = reader.getMetadata();
            System.out.println(metadata);
        

L'objet Metadata est la représentation java du modèle de métadonnée ISO 19115-2. Pour faire des opérations on aura besoin d'un objet Coverage :

            //read a piece of coverage
            final GridCoverageReadParam param = new GridCoverageReadParam();
            param.setResolution(1,1);
            param.setEnvelope(new Rectangle2D.Double(0, 0, 100, 100), DefaultGeographicCRS.WGS84);

            final GridCoverage2D coverage = (GridCoverage2D) reader.read(0, param);
            coverage.show();
        

L'objet GridCoverageReadParam va permettre de préciser ce qui nous intéresse à la lecture afin d'éviter de la lecture inutile. Le coverage (ou coveragereader) peut aussi être utilisé pour créer un CoverageMapLayer.

            //create a mapcontext
            final MapContext context = MapBuilder.createContext();
            final CoverageMapLayer cl = MapBuilder.createCoverageLayer(reader, SF.style(StyleConstants.DEFAULT_RASTER_SYMBOLIZER), "raster");
            context.layers().add(cl);

            //display it
            JMap2DFrame.show(context);
        

GeotoolKit contient plus d'une dizaine de modules permettant de se connecter à différents services distants.

Chaque client s'appuie sur une classe implémentant Server. On trouvera dans cette classe :

CSW
OSM
OSM-TMS
SOS
WCS
WFS
WMS
WMS-C
ncWMS
WMTS
WPS
IGN RM
Google Static Maps

Il existe une grande quantité de server différents, avec des objectifs souvent différents allant de l'affichage de cartes, aux traitements ou à l'administration. Geotoolkit regroupe tout ce qui est distant dans le terme de Server. Un object de type server seul n'a pas grand interet et n'expose aucune fonctionnalité, cela est du à la vaste étendue d'opérations qu'ils peuvent proposer. C'est pourquoi une instance de server implémente en général une autre interface plus complète.

Par exemple les implémentations :


Catalog Web Server (CSW) est un service de l'OGC fait pour renvoyer des métadonnées.

Norme complète : http://www.opengeospatial.org/standards/specifications/catalog

                final MarshallerPool pool = CSWMarshallerPool.getInstance();
                Unmarshaller um = null;

                try {
                um = pool.acquireUnmarshaller();

                // build a new CSW client
                final CatalogServicesServer cswServer = new CatalogServicesServer(new URL("http://demo.geomatys.com/mdweb-demo/WS/csw/default?"), "2.0.2");


                /**
                * make a getCapabilities request
                */
                final GetCapabilitiesRequest getCapa = cswServer.createGetCapabilities();

                InputStream is = getCapa.getResponseStream();

                // unmarshall the response
                Capabilities capabilities = (Capabilities) um.unmarshal(is);

                // print the title of the server
                System.out.println(capabilities.getServiceIdentification().getTitle());


                /**
                * make a getRecords request
                */
                final GetRecordsRequest getRecords = cswServer.createGetRecords();
                getRecords.setTypeNames("gmd:MD_Metadata");
                getRecords.setConstraintLanguage("CQL");
                getRecords.setConstraintLanguageVersion("1.1.0");
                getRecords.setConstraint("Title like '%'");
                is = getRecords.getResponseStream();

                // unmarshall the response
                GetRecordsResponseType response = ((JAXBElement
                <GetRecordsResponseType>) um.unmarshal(is)).getValue();

                // print the number of result matching the request
                System.out.println(response.getSearchResults().getNumberOfRecordsMatched());


                /**
                * retrieve results in dublin core
                */
                getRecords.setResultType(ResultType.RESULTS);

                is = getRecords.getResponseStream();

                // unmarshall the response
                response = ((JAXBElement
                    <GetRecordsResponseType>) um.unmarshal(is)).getValue();

                // print the first result (Dublin core)
                AbstractRecord record = response.getSearchResults().getAbstractRecord().get(0);
                System.out.println(record);


                /**
                * retrieve results in ISO 19139
                */
                getRecords.setOutputSchema("http://www.isotc211.org/2005/gmd");

                is = getRecords.getResponseStream();

                // unmarshall the response
                response = ((JAXBElement
                        <GetRecordsResponseType>) um.unmarshal(is)).getValue();

                // print the first result (ISO 19139)
                Metadata meta = (Metadata) response.getSearchResults().getAny().get(0);
                System.out.println(meta);

                final String identifier = meta.getFileIdentifier();


                /**
                * make a getRecordById request
                */
                final GetRecordByIdRequest getRecordById = cswServer.createGetRecordById();
                getRecordById.setOutputSchema("http://www.isotc211.org/2005/gmd");
                getRecordById.setIds(identifier);

                is = getRecordById.getResponseStream();

                // unmarshall the response
                GetRecordByIdResponse responseBi = ((JAXBElement
                            <GetRecordByIdResponse>) um.unmarshal(is)).getValue();

                // print the result (same as getRecords first result)
                meta = (Metadata) responseBi.getAny().get(0);
                System.out.println(meta);

                } finally {
                if (um != null) {
                pool.release(um);
                }
        

Sensor Observation Service (SOS) est un service de l'OGC pour renvoyer des données de capteurs.

Norme complète : http://www.opengeospatial.org/standards/sos

Exemple 3.24. Connexion à un server SOS


                final MarshallerPool pool = SOSMarshallerPool.getInstance();
                Unmarshaller um = null;

                try {
                um = pool.acquireUnmarshaller();

                // build a new SOS client
                final SensorObservationServiceServer sosServer = new SensorObservationServiceServer(new URL("http://test.geomatys.com/swe_TS/WS/sos?"), "1.0.0");

                /**
                * make a getCapabilities request
                */
                final GetCapabilitiesRequest getCapa = sosServer.createGetCapabilities();

                InputStream is = getCapa.getResponseStream();

                // unmarshall the response
                Capabilities capabilities = (Capabilities) um.unmarshal(is);

                // print the title of the server
                System.out.println(capabilities.getServiceIdentification().getTitle());

                // extract a sensorML identifier and outputFormat to make a describeSensor request
                Operation describeSensorOperation = capabilities.getOperationsMetadata().getOperation("DescribeSensor");

                String sensorID = ((ValueType) describeSensorOperation.getParameter("procedure").getAllowedValues().getValueOrRange().get(0)).getValue();
                String outputFormat = ((ValueType) describeSensorOperation.getParameter("outputFormat").getAllowedValues().getValueOrRange().get(0)).getValue();

                // extract a all the parameters necessary to make a getObservation request
                Operation getObservationOperation = capabilities.getOperationsMetadata().getOperation("GetObservation");

                String offering = ((ValueType) getObservationOperation.getParameter("offering").getAllowedValues().getValueOrRange().get(0)).getValue();
                String responseFormat = ((ValueType) getObservationOperation.getParameter("responseFormat").getAllowedValues().getValueOrRange().get(0)).getValue();
                String phenomenon = ((ValueType) getObservationOperation.getParameter("observedProperty").getAllowedValues().getValueOrRange().get(0)).getValue();
                String procedure = ((ValueType) getObservationOperation.getParameter("procedure").getAllowedValues().getValueOrRange().get(0)).getValue();
                String featureOfInterest = ((ValueType) getObservationOperation.getParameter("featureOfInterest").getAllowedValues().getValueOrRange().get(0)).getValue();

                /**
                * make a DescribeSensor request
                */
                final DescribeSensorRequest descSensor = sosServer.createDescribeSensor();
                descSensor.setSensorId(sensorID);
                descSensor.setOutputFormat(outputFormat);

                is = descSensor.getResponseStream();

                // unmarshall the response
                AbstractSensorML sensorMLResponse = (AbstractSensorML) um.unmarshal(is);

                System.out.println(sensorMLResponse);

                /**
                * make a GetObservation request
                */
                final GetObservationRequest getObs = sosServer.createGetObservation();
                getObs.setOffering(offering);
                getObs.setObservedProperties(phenomenon);
                getObs.setProcedures(procedure);
                getObs.setResponseFormat(responseFormat);
                getObs.setFeatureOfInterest(new FeatureOfInterest(Arrays.asList(featureOfInterest)));

                is = getObs.getResponseStream();

                // unmarshall the response
                ObservationCollectionType getObsResponse = (ObservationCollectionType) um.unmarshal(is);

                System.out.println(getObsResponse);



                } finally {
                if (um != null) {
                pool.release(um);
                }

        


A l'exception des couches spécifiques, MapContext, FeatureMapLayer et CoverageMapLayer sont créés en utilisant la classe MapBuilder.

Voici un exemple de création d'un MapContext avec différents types de couches :


                    //create a map context
                    final MapContext context = MapBuilder.createContext();

                    //create a feature layer
                    final FeatureCollection features = openShapeFile();
                    final MutableStyle featureStyle = styleFactory.style(StyleConstants.DEFAULT_LINE_SYMBOLIZER);
                    final FeatureMapLayer featureLayer = MapBuilder.createFeatureLayer(features, featureStyle);

                    //create a coverage layer
                    final GridCoverageReader reader = openWorldFile();
                    final MutableStyle coverageStyle = styleFactory.style(StyleConstants.DEFAULT_RASTER_SYMBOLIZER);
                    final CoverageMapLayer coverageLayer = MapBuilder.createCoverageLayer(reader, coverageStyle,"background");

                    //create a WMS layer
                    final WebMapServer server = new WebMapServer(new URL("http://demo.geomatys.com/constellation/WS/wms"), WMSVersion.v130);
                    final WMSMapLayer wmsLayer = new WMSMapLayer(server, "BlueMarble");

                    //add all layers in the context
                    context.layers().add(wmsLayer);
                    context.layers().add(coverageLayer);
                    context.layers().add(featureLayer);

                    //check the result
                    JMap2DFrame.show(context);

            

Il est aussi possible de créer une arborescence plutot qu'une liste. Les éléments utilisés pour symbolizer des noeuds sont des MapItem.



GeotoolKit utilise des fabriques pour créer les objets de style.

Il y en a trois :

  • MutableStyleFactory
  • FilterFactory
  • MutableSLDFactory

Vous vous demandez peut-être ce que vient faire ce 'Mutable' ici ?

En fait, toutes les interfaces de styles sont définies dans GeoAPI mais elles sont immutables. C'est pourquoi dans GeotoolKit on trouve ces mêmes interfaces précédées de 'Mutable' ainsi que des méthodes 'setter' sur les propriétés.

Ce ne sont pas strictement toutes les classes qui sont mutables, les filtres, expressions et symbols eux sont immutables pour des raisons de concurrence.

Quand vous créerez des styles, par moment il est préférable d'utiliser les valeurs par défaut pour certaines propriétés, ces valeurs sont accessibles comme des constantes sur la classe : org.geotoolkit.style.StyleConstants.

GeotoolKit contient un moteur de rendu par défaut nommée GO2.

Ce moteur, à l'origine limité aux données cartographiques et aux normes de styles en vigueur, s'est progressivement élargi pour devenir un véritable scénographe. Ses capacités sont limités à du rendu 2 dimensions mais ne se limite pas qu'aux données cartographiques. Il est possible de définir de nouveau symboles, de nouveau procédés de dessin, des éléments graphiques dynamiques et plus encore.


Une seule classe est utilisée pour cette tâche : DefaultPortrayalService qui dispose de deux méthodes :

  • portray : va générer un BufferedImage ou écrire l'image dans le flux/fichier donné.
  • visit : va chercher les éléments qui touche la zone demandée, utilisé pour les opérations de sélection principalement.

La définition de ce qui est à dessiner et comment est divisée en quatre groupes :

  • CanvasDef : définit la taille de la zone de dessin ainsi que la couleur de fond.
  • SceneDef : définit le MapContext ainsi que les éléments de la scène a dessiner.
  • ViewDef : définit la zone géographique a dessiner ainsi qu'un azimuth (rotation).
  • OutputDef : définit le flux de sortie (flux,fichier,uri,...).


Pour générer des rapports ou des atlas, GeotoolKit utilise l'api JasperReports. JasperReports est l'api Java la plus complète pour la génération de rapports et dispose d'un éditeur dédié nommé IReport. Comme nous allons devoir dessiner des éléments spéciaux pour les cartes, légendes, barre d'échelle ... il va être nécessaire de créer un rapport spécifique.

IReport peut être téléchargé ici : http://jasperforge.org/projects/ireport

Aperçu de l'application :


Si vous n'êtes pas familier avec JasperReports ou IReport, la documentation est accessible ici.

Lors de la création d'un rapport, deux type d'informations seront utilisés lors de la génération :

Lorsque l'on aura fini d'établir notre rapport, les paramètres seront donnés avec un objet Map, et les champs seront transformés en FeatureType .


seront transformés dans le FeatureType :


                    ╔═════════════╤══════╤══════╤═══════════╤═══════════════╤══════╤════════════╗
                    ║ name        │  min │  max │  nillable │  type         │  CRS │  UserData  ║
                    ╟─────────────┼──────┼──────┼───────────┼───────────────┼──────┼────────────╢
                    ║ CNTRY_NAME  │ 1    │ 1    │ true      │ String        │      │            ║
                    ║ POP_CNTRY   │ 1    │ 1    │ true      │ Integer       │      │            ║
                    ║ map3        │ 1    │ 1    │ true      │ MapDef        │      │            ║
                    ║ chart4      │ 1    │ 1    │ true      │ ChartDef      │      │            ║
                    ║ legend5     │ 1    │ 1    │ true      │ LegendDef     │      │ map=map3   ║
                    ║ scalebar6   │ 1    │ 1    │ true      │ ScaleBarDef   │      │ map=map3   ║
                    ║ northarrow7 │ 1    │ 1    │ true      │ NorthArrowDef │      │ map=map3   ║
                    ║ table8      │ 1    │ 1    │ true      │ JRDataSource  │      │            ║
                    ║ minimap     │ 1    │ 1    │ true      │ MapDef        │      │            ║
                    ╚═════════════╧══════╧══════╧═══════════╧═══════════════╧══════╧════════════╝
                

Si l'on regarde les binding du FeatureType, on voit MapDef, ChartDef, LegendDef ...

Ce sont des types de champ que GeotoolKit peut reconnaître.

Pour définir ces types, on doit éditer la classe du champ dans IReport :


La liste des champs reconnus est :

  • org.geotoolkit.report.graphic.map.MapDef
  • org.geotoolkit.report.graphic.chart.ChartDef
  • org.geotoolkit.report.graphic.legend.LegendDef
  • org.geotoolkit.report.graphic.scalebar.ScaleBarDef
  • org.geotoolkit.report.graphic.northarrow.NorthArrowDef

Pour les types legend, scalebar et north arrow, il est nécessaire d'indiquer à quelle carte le type se rapporte. Cette information se définit dans les propriétés du champ :



resources/data/report/complexReport.jrxml

  1. Parser le template
    
                            final File template = ...
                            final Entry<JasperReport,FeatureType> entry = JasperReportService.prepareTemplate(template);
                            final JasperReport report = entry.getKey();
                            final FeatureType type = entry.getValue();
                        

    Cette étape va générer le FeatureType associé au template.

  2. Préparer les données

    Cette partie dépend entièrement de votre template.

    L'objectif est de générer une FeatureCollection avec le featuretype fourni, cette étape dépend entièrement du template et des données que vous avez en entrée.

    Le featuretype peut ne pas être rigoureusement identique, les propriétés manquantes seront remplacées par des null .

    Dans IReport vous pouvez spécifier le comportement lors d'une valeur nulle.

  3. Générer le rapport
    
                            final OutputDef output = new OutputDef(JasperReportService.MIME_PDF, new File("atlas.pdf"));
                            JasperReportService.generateReport(report, featureCollection, parameters, output);
                        

    Cette étape peut être plus ou moins longue et utiliser plus ou de mémoire en fonction de la complexité du rapport et la quantité de donnée a traiter.


Une seule classe est utilisée pour cette tâche : DefaultLegendService avec deux méthodes :

  • portray : va dessiner la légende dans un flux ou sur un BufferedImage.
  • legendPreferredSize :va explorer le style et trouver la taille optimale de la légende.

Pour créer la légende, un object LegendTemplate est aussi nécessaire. Cet objet définit les informations générales comme les espacements, couleurs, polices de caractère...




Pour créer nouveau traitement il faut implémenter trois choses :

Les registry sont utilisés dans le module processing de Geotoolkit pour organiser les processus réalisant le même type de traitement. Par exemple, la registry "math" contient uniquement des processus de calcul, la registry vector des processus travaillant sur des couches vectorielles ... etc.

Chaque registry contient donc une liste d'instance de description des processus qu'elle possede. On peut ainsi récupérer la description d'un process précis facilement.


Pour créer sa propre factory, il suffit d'étendre la classe AbstractProcessingRegistry et de redéfinir la méthode getIdentification() permetant d'identifier de manière unique notre registry. L'idenification d'une regisry ce faire par le biais d'un objet Identification comme dans l'exemple suivant.


Il faut ensuite initialiser notre Registry avec la liste des traitements (processus) qu'elle contient. Ce doit être une liste d'instance des descripteur de chaque processus. Le moyen le plus simple étant que chaque descripteur implémente le design pattern singleton. Et lors de l'ajout d'un process, on ajoute son descripteur à l'initialisation de la registry. L'exemple suivant montre ce principe.


On peux également rendre cette initialisation dynamique en listant les processus disponible dans un fichier META-INF/service et un Iterateur donné par la class ServiceRegistry sur l'interface ProcessDescriptor comme dans l'exemple suivant. Il faut pour cela que les constructeurs des descripteur soit publique.


Pour finir avec la création de notre registry, il faut la déclarer notre classe dans un fichier org.geotoolkit.process.ProcessingRegistry dans un dossier resources/META-INF/service de notre module. Ceci permet à la classe utilitaire ProcessFinder de retrouver notre Registry et tous les processus qu'elle contient.

La création d'un process passe par sa définition ou description. Cette description doit contenir l'ensemble des entrées / sorties de notre processus, ainsi que son nom et quelque phrase décrivant sont travail. Il doit aussi permettre d'instancier le traitement en lui même en lui passant les paramètres d'entrées.


Pour la gestion des entrées et des sorties, on utilise dans Geotoolkit les GeneralParameterDescriptor qui est a l'origine un élément de la norme ISO_19111.

La description des entrées et des sorties ce fait par la création de ParameterDescriptorGroup qui regroupe un ensemble de GeneralParameterDescriptor. Ces même GeneralParameterDesciptor peuvent être des sous ParameterDescriptorGroup ou des ParameterDescriptor décrivant un paramètre simple.

Le pseudo diagramme de classe suivante montre la hiérarchie des classes et des interfaces qui définisent les GeneralParameterDescriptor.


Pour créer des ParameterDescriptor ou des ParameterDescriptorGroup, on utilise les implémentations par défaut de Geotoolkit DefaultParameterDescriptor et DefaultParameterDescriptorgourp.

Dans l'exemple suivant, on créer les paramètres d'entrée d'un processus simple réalisant l'addition de deux nombres. Il y a donc deux ParameterDescriptor correspondant à chaque nombre en entrée et un ParameterDescriptorGroup pour les regroupers en tant qu'entrée (INPUT).


DefaultParameterDescriptor possede plusieurs constructeur suivant les informations sur le paramètre voulu. Dans l'exemple précedent, on construit nos nombre en leurs donnant dans l'ordre :

  • Un nom unique. "first"
  • Un description "Fisrt number"
  • Leurs classe de binding. "Double.class"
  • Leur valeur par defaut. "null"
  • Un Boolean disant si le paramètre est opionnel. "Double.class"

Mais on peux également, donner la multipicité pour chaque paramètres, des alias, leurs unités ou la liste des valeurs autorisées. Pour plus d'information ce référer à la Javadoc de DefaultParameterDescriptor et DefaultParameterDescriptorgourp. Ces informations sont utilisées lors de la création des paramètres d'entrer pour vérifier les valeurs inserer.

On peux aussi avoir des traductions pour les descriptions de parametres et la desciption du process comme sur la démo. Pour cela il faut créer des bundles et dans le dossier resources, et créer des objets ResourceInternationalString avec la clé définie par une traduction. Dans le cas des parametres, il faut construire une Map de "properties" comme dans l'exemple suivant.


Par la suite lorsqu'on voudra créer les valeurs des paramètres d'entrer pour les donner à notre processus, il suffira de d'appeler la méthode createValue() sur le ParameterDescriptorGroup représentant les entrées du processus. Cette méthode retournera alors un ParameterValueGroup construit à partir des ParameterDescriptor.


Il ne reste plus pour finir le descripteur qu'à implémenter le constructeur avec l'identification et la description du process ainsi que ses entrées/sorties et redéfinir la méhode createProcess() comme dans l'exemple suivant.



Pour finir il ne reste plus qu'à implémener le processus en lui même réalisant le traitement des données en entrées. Pour cela il faut créer une classe étendant AbstractProcess . Il y a alors une seule méthode à définir, la méthode execute(). C'est cette méthode qui fait le traitement des données après avoir récupérer les paramètres d'entrée et qui retourne les resultats des traitements dans les paramètres de sortie du processus.

Le code suivant contient le traitement effectuer par le process Addition de démonstration.


La récupéation et l'injection des données depuis les paramètres d'entrées/sorties peux ce faire plus simplement grâce aux méthode utilitaires contenu dans la classe Parameters .


Sur un objet Process, on a accès à plusieurs méthodes permetant d'attacher des écouteurs à celui-ci, qui permettent de donner des informations sur le déroulement de du traitement. Ces écouteurs doivent implémenter l'interface ProcessListener qui définit quatres méthodes avec en paramètre ProcessEvent :

  • started(ProcessEvent event) : démarrage du processus
  • progressing(ProcessEvent event) : évolution du traitement (10%, 50%, ...)
  • completed(ProcessEvent event) : traitement fini
  • failed(ProcessEvent event) : erreur lors du traitement

Les événements started et completed sont lancés automatiquement lors de l'appel à la méthode call() (Voir the section called “Exécution d'un processus”). L'événement failed est lui aussi lancé automatiquement lorsque la méhode execute d'un process lance une exception. L'événement progressing est quand à lui à la charge du développeur et doit être lancé par le biai de la méthode fireProgressing() lorsqu'une progression peux être calculé. On peux également fournir des résultats intermédiaire lors du lancement de l'énévement progressing. Cette énévement n'est pas obligatoire, mais il est préféable de l'implémenter pour les traitements longs.


Les exceptions lancés par les différents traitements d'un processus doivent être encapsulé dans des ProcessException pour être remonté dans l'appel de la méthode call() mais aussi pour lancer l'événement processFailed(). Sauf pour les CancellationException qui sont utilisées pour l'arrêt d'un processus.

Dans cette partie nous verrons comment trouver et exécuter un processus simple puis un plus complexe comme Union. Ci-dessous les liens vois les différentes demos utiliser dans cette partie.




Pour exécuter un processus, il faut au préalable recupérer sa description. Pour cela, geotoolkit possede la classe utilitaire ProcessFinder contenant un ensemble de methodes statiques. Cette classe permet de récupérer l'ensemble des ProcessingRegistry définis dans les fichiers resources/META-INF/services/org.geotoolkit.process.ProcessingRegistry. Et pour chaque ProcessFactory, l'ensemble de descriptions des process qu'elle contient.

Dans l'exemple suivant on voit la récupération de la liste des ProcessingRegistry puis pour chaque registry la liste des ProcessDesciptor qu'elle contient.


On peux également récupérer plus rapidement un process en particulier en connaissant son nom et le nom de sa registry. Comme dans l'example suivant.


Une fois que l'on a une registry on peut appeler différentes méthodes dessus :


Une fois que l'on a la description d'un processus, il suffit de passer des valeurs aux paramètres d'entrées. Pour cela, il faut commencer par créer le groupe de paramètres d'entrée ( ParameterValueGroup) à partir de leurs descriptions ( ParameterDescriptorGroup) (définie dans la description complète du processus).

Pour cela on appel la méthode createValue() sur le descripteur du group de paramètre d'entrée. Comme dans l'exemple suivant.


Une fois qu'on a le ParameterValueGroup, il suffit de remplir les paramètres d'entrée avec les valeurs voulus. La récupération d'un parametre en particulier ce fait par son nom définie lors de la description de l'entrée dans le ProcessDescriptor.


Les paramètres d'entrée créer il ne reste plus qu'à créer et à exécuter processus et la récupération de la (des) donnée(s) en sortie. La création du processus ce fait à partir du descripteur avec la méthode createProcess() à laquelle on donne nos paramètres d'entrées.


L'exécution du traitement ce fait simplement par l'appel à la méthode call() sur l'objet process. Lequel retourne dans un ParameterValueGroup le groupe de paramètre de sortie. Il suffit alors de récupérer le paramètre voulu par le biai de son nom et ensuite d'extraire sa valeur.


Geotoolkit possède également plusieurs outils permétant l'exécution et la gestion des process.

Une partie des processus sont exécutables en ligne de commande. Ces outils servent principalement dans les environnements dépourvus d'interface utilisateur, mais peuvent aussi bien être utilisés pour faire du traitement en fond de plan.

Trois outils sont disponibles :

Cette page décrit les outils nécessaires au fonctionnement de l'extension Geotk pour OpenOffice, ainsi que les étapes à suivre pour installer cette extension. La page d'introduction donne un aperçu des fonctionnalités apportées. Le guide de l'utilisateur décrit chacune de ces fonctions.


Avant d'installer l'extension Geotk, il peut être utile de configurer OpenOffice afin que celui-ci sache où se trouve le JRE du Java. Cette configuration s'effectue dans le menu Outils, Options. Dans la boîte de dialogue qui s'affiche, sélectionner Java. Si aucun environnement Java n'apparaît dans la liste, appuyer sur le bouton Ajouter et sélectionner le répertoire où un environnement Java est installé.


Après avoir téléchargé le fichier geotk-openoffice.oxt, lancer le tableur d'Open Office (Calc). Aller dans Outils, Gestionnaire de packages. Sélectionner Mes packages dans la colonne Package et appuyer sur le bouton Ajouter.


Allez dans le répertoire où se trouve le fichier geotk-openoffice.oxt téléchargé et sélectionnez le, puis appuyer sur le bouton Ouvrir. Après que l'extension ait été installé vous pouvez fermer la boite de dialogue Package Manager. À présent l'installation de l'extension Geotk pour OpenOffice est terminée, mais il peut être nécessaire de redémarrer OpenOffice.org pour qu'elle soit prise en compte. Si un icône de démarrage rapide apparaît dans la barre des tâches, il doit être fermé lui aussi avant de relancer OpenOffice.org.

Note

La première fois qu'une des fonctions de Geotk est exécutée dans le tableur d'OpenOffice, un délai de plusieurs secondes peut s'écouler avant que ce dernier ne rende la main. Ce délai est causé par la création d'une copie de la base de données EPSG dans le répertoire utilisateur de la machine cliente. Cette base de données contient les définitions de plus de 3000 systèmes de référence des coordonnées et est indispensable au fonctionnement de l'extension Geotk. Cette opération d'écriture n'est toutefois exécutée qu'une seule fois.

Geotoolkit offre la possiblité de réaliser ses propres conversion d'un type d'objet à un autre. Généralement utilisés pour des conversion simples (StringToFile, StringToURL, URLToFile ...), on peux également les utiliser pour des objets plus complexes. La liste des converteurs basique déjà présent et enregistré dans Geotoolkit ce trouve dans le package package org.geotoolkit.util.converter.

Un converteur ce caractérise par :

Pour créer son propre converter, il faut implémenter la classe ObjectConverter ou étendre la classe abstraite SimpleConverter.

L'exemple suivant montre la création d'un converter réalisant le passage d'une String formatée en WKT geometry JTS.


La principale méthode a implémenter est la méthode T convert(S source) qui réalise la convertion de la classe S vers T. Lors d'erreurs de vérification ou dans le traitement de cette conversion, la méthode convert doit lancer une NonconvertibleObjectException. L'exemple suivant montre la converstion d'une String en Geometry JTS après quelque vérifications.


Les autres méthodes à implémenter servent a récupérer les classes source et cible, et des flags pour savoir si ce converter conserve l'ordre, s'il a des restrictions particuliaires ou s'il inverse l'ordre. Pour plus d'informations, voir la Javadoc de ObjectConverter.

Pour pouvoir utiliser des converters, il faut soit faire sa registry qui contient une liste d'instance de converteur que l'on veux utiliser. Soit enregistrer notre converteur dans la ConverterRegistry par default en utilisant le systeme de ServiceRegistry avec la class ObjectConverter.


GeotoolKit offre une panoplie de composants swing pour la cartographie.