Author: desruisseaux Date: Tue Aug 5 10:53:42 2014 New Revision: 1615905 URL: http://svn.apache.org/r1615905 Log: Converted remaining parts from DocBook to HTML 5. Modified: sis/site/trunk/content/book/book.css sis/site/trunk/content/book/fr/developer-guide.html Modified: sis/site/trunk/content/book/book.css URL: http://svn.apache.org/viewvc/sis/site/trunk/content/book/book.css?rev=1615905&r1=1615904&r2=1615905&view=diff ============================================================================== --- sis/site/trunk/content/book/book.css (original) +++ sis/site/trunk/content/book/book.css Tue Aug 5 10:53:42 2014 @@ -19,7 +19,7 @@ * Chapters and sections titles (excluding the book titles). */ h1 { - margin-top: 3cm; + margin-top: 120pt; background-color: #99AAFF; border-top-color: #0000CC; border-bottom-color: #0000CC; @@ -32,17 +32,17 @@ h1 { } h2 { - margin-top: 2cm; + margin-top: 40pt; border-bottom-style: solid; - border-bottom-width: 1pt; + border-bottom-width: 2pt; } h3 { - margin-top: 1.5cm; + margin-top: 24pt; } h4 { - margin-top: 1cm; + margin-top: 15pt; } p { @@ -116,6 +116,29 @@ table tr td.separator { padding-bottom: 3pt; } +table.hidden { + border-style: none; +} + +table.hidden tr { + vertical-align: top; +} + +table.hidden tr th { + border-style: none; + background: none; + color: #0086E0; + font-weight: bold; + padding-top: 9pt; + padding-bottom: 3pt; + padding-left: 0; + padding-right: 0; +} + +table.hidden tr td { + padding: 0; +} + pre { margin-left: 30pt; margin-right: 30pt; Modified: sis/site/trunk/content/book/fr/developer-guide.html URL: http://svn.apache.org/viewvc/sis/site/trunk/content/book/fr/developer-guide.html?rev=1615905&r1=1615904&r2=1615905&view=diff ============================================================================== --- sis/site/trunk/content/book/fr/developer-guide.html (original) +++ sis/site/trunk/content/book/fr/developer-guide.html Tue Aug 5 10:53:42 2014 @@ -22,13 +22,16 @@ - Guide du développeur de Apache SIS + Introduction à Apache SIS -

Introduction

+

Introduction à Apache SIS®

+ + +

Préface

Une communauté d’informations géospatiales est un ensemble de systèmes ou d’individus capables d’échanger leurs données géospatiales grâce à des définitions et des standards communs ainsi qu’une reconnaissance réciproque. @@ -76,7 +79,7 @@ -

À propos de ce document

+

Conventions utilisées dans ce guide

Les éléments définis dans un langage informatique, tels que les classes ou méthodes en Java ainsi que les éléments dans un fichier XML, apparaissent avec une police de caractères mono-espacée. @@ -105,7 +108,7 @@ -

Standards et normes

+

Standards et normes

La majorité des standards utilisés par Apache SIS ont été élaborés par le consortium Open Geospatial (OGC), @@ -146,7 +149,7 @@ -

Processus de standardisation à l’OGC

+

Processus de standardisation à l’OGC

Les travaux de l’OGC se font par courriers électroniques, par conférences téléphoniques et par réunions réelles. @@ -167,7 +170,7 @@ -

Fonctionnement des groupes de travail (SWG)

+

Fonctionnement des groupes de travail (SWG)

Pour être accepté, un projet de standardisation doit être supporté par un nombre minimal de membres appartement à des organisations distinctes. Ces membres fondateurs rédigent une charte définissant les objectifs du SWG, @@ -196,7 +199,7 @@ -

Le conseil d’architecture (OAB) et le comité technique (TC)

+

Le conseil d’architecture (OAB) et le comité technique (TC)

Toute proposition de standard est d’abord examinée par le conseil d’architecture (OGC Architecture Board - OAB). @@ -217,7 +220,7 @@ -

Procédure de soumission de propositions de modifications

+

Procédure de soumission de propositions de modifications

Tout utilisateur, qu’il soit membre ou non du consortium Open Geospatial, peut proposer des modifications à des standards OGC. @@ -235,7 +238,7 @@ -

Les différents types de spécifications

+

Les différents types de spécifications

Les standards OGC sont spécifiés dans plusieurs dizaines de documents. Chaque document élabore un service, par exemple les transformations de coordonnées. @@ -455,7 +458,7 @@ -

Définitions des termes

+

Définitions des termes

Les standards privilégient parfois l’application de certains termes génériques à des contextes particuliers, qui peuvent différer du contexte dans lequel d’autres communautés emploient ces termes. @@ -477,7 +480,7 @@ -

GeoAPI

+

GeoAPI

Le projet GeoAPI offre un ensemble d’interfaces Java pour les applications géo-spatiales. Dans une séries de paquets org.opengis.*, GeoAPI définit des structures représentant des méta-données, @@ -511,52 +514,51 @@

+ -

Historique

-

- En 2001, le consortium Open GIS (l’ancien nom du consortium Open Geospatial) publia la spécification d’implémentation - OGC 01-009: Coordinate Transformation Services. - Cette spécification, élaborée par Computer Aided Development Corporation (Cadcorp), était accompagnée d’interfaces - COM, CORBA et Java. - À cette époque, la vague des services web n’avait pas encore éclipsé les interfaces de programmation classiques. - Les interfaces de l’OGC anticipaient tout de même un monde connecté en réseau, - mais misaient plutôt — dans le cas du Java — sur la technologie RMI (Remote Method Invocation). - Bien que le projet GeoAPI n’existait pas encore, nous désignons rétrospectivement ces interfaces historiques sous le nom de - « GeoAPI 0.1 ». - Ces interfaces utilisaient déjà le nom de paquet org.opengis, qui sera adopté par GeoAPI. -

- En 2002, des développeurs de projets libres ont lancé un appel - à la création d’un API géo-spatial. - La proposition initiale suscita l’intérêt d’au moins cinq projets libres. - Le projet fut créé sur SourceForge, - qui héberge depuis lors le code source dans un dépôt Subversion. - Le projet pris le nom de « GeoAPI » à ce moment là, et utilisa les interfaces de la spécification OGC 01-009 comme point de départ. -

- Quelques mois plus tard, l’OGC lança le projet - GO-1: Geographic Objects, - qui poursuivait des buts similaires à ceux de GeoAPI. - Entre-temps, l’OGC avait abandonné certaines de leur spécifications en faveur des normes ISO. - GeoAPI et GO-1 ont joint leurs efforts pour une refonte des interfaces de GeoAPI en les basant sur ces nouvelles normes ISO. - La première mouture, GeoAPI 1.0, a servit de point de départ - aux premières ébauches de la spécification OGC 03-064 du groupe de travail GO-1. - La version finale de cette spécification est devenue un standard OGC en 2005, et - GeoAPI 2.0 a été publiée à cette occasion. -

- Le projet GO-1 était porté essentiellement par une compagnie nommée Polexis. - Son rachat par Sys Technology et le changement de priorité des nouveaux propriétaires - ont causé l’arrêt des travaux de GO-1, et par ricochet un ralentissement des développements de GeoAPI. - Afin de reprendre les développements, un nouveau groupe de travail « GeoAPI 3.0 » a été créé à l’OGC. - Ce groupe a réduit les ambitions par rapport à GeoAPI 2.0 en se concentrant sur les interfaces les plus stables, - et en plaçant les autres — notamment les géométries — dans un module nommé « pending », - pour considérations futures. GeoAPI 3.0 est devenu un - standard OGC en 2011. - Cette version a été la première à être déployée dans le dépôt central de Maven. -

- - - -

Des spécifications aux interfaces

+

Des spécifications aux interfaces

Les standards de l’OGC étant définis par des moyens bien éprouvés en génie logiciel, il est possible de générer automatiquement des interfaces Java à l’aide d’outils relativement répandus. @@ -675,7 +677,7 @@ -

Correspondances explicitées par l’annotation @UML

+

Correspondances explicitées par l’annotation @UML

Pour chaque classe, méthode et constante définie à partir d’un standard OGC ou ISO, GeoAPI indique sa provenance à l’aide d’annotations @@ -752,7 +754,7 @@ System.out.println("L’interface Geo -

Correspondances implicites avec le JDK standard

+

Correspondances implicites avec le JDK standard

Certaines classes et méthodes n’ont ni annotation @UML, ni entrée dans le fichier class-index.properties. @@ -939,7 +941,7 @@ System.out.println("L’interface Geo -

Obtenir une implémentation des interfaces

+

Obtenir une implémentation des interfaces

GeoAPI définit des fabriques (Factory) permettant de créer des implémentations de ses interfaces. Par exemple DatumFactory fournit des méthodes permettant de créer des instances @@ -974,7 +976,7 @@ System.out.println("L’interface Geo -

Fournir sa propre implémentation

+

Fournir sa propre implémentation

Implémenter soi-même GeoAPI n’est pas si difficile si on se contente de besoins bien précis. Un développeur peut se concentrer sur une poignée d’interfaces parmi les centaines de disponibles, @@ -1040,7 +1042,7 @@ System.out.println("L’interface Geo -

Les modules de GeoAPI

+

Les modules de GeoAPI

Le projet GeoAPI est composé d’une partie standardisée (geoapi) et d’une partie expérimentale (geoapi-pending). Ces deux parties étant @@ -1107,7 +1109,7 @@ System.out.println("L’interface Geo

-

Les modules de définition des interfaces

+

Les modules de définition des interfaces

Les modules geoapi et geoapi-pending fournissent les interfaces dérivées des schémas UML des standards internationaux. @@ -1118,7 +1120,7 @@ System.out.println("L’interface Geo -

Le module de tests de conformité

+

Le module de tests de conformité

Le module geoapi-conformance fournit des validateurs, une suite de tests JUnit et des générateurs de rapports sous forme de pages HTML. @@ -1134,7 +1136,7 @@ System.out.println("L’interface Geo -

Validations des instances

+

Validations des instances

GeoAPI peut valider une instance de ses interfaces en vérifiant que certaines contraintes sont respectées. Ces contraintes, qui ne peuvent pas être exprimées dans la signature de la méthode, sont généralement décrites @@ -1225,7 +1227,7 @@ System.out.println("L’interface Geo -

Exécution des tests pré-définis

+

Exécution des tests pré-définis

Des classes de tests JUnit sont définies dans des sous-paquets de org.opengis.test. Toutes les classes de tests portent un nom se terminant en "Test". @@ -1289,7 +1291,7 @@ System.out.println("L’interface Geo -

Les modules d’exemples

+

Les modules d’exemples

Le module geoapi-examples fournit des exemples d’implémentations simples. Plusieurs de ces classes implémentent plus d’une interface à la fois afin de proposer un modèle conceptuel plus simple. @@ -1318,7 +1320,7 @@ System.out.println("L’interface Geo -

Représentation des objets en XML

+

Représentation des objets en XML

Les objets définis par les standards OGC/ISO @@ -1415,5 +1417,789 @@ System.out.println("L’interface Geo + + +

Représentation des méta-données selon ISO 19139

+

+ Pour chaque classe de méta-donnée, il existe un type XML nommé comme dans la spécification abstraite + (par exemple gmd:MD_Metadata et gmd:CI_Citation). + Tous ces types peuvent être employés comme racine d’un document XML. + Ainsi, il est possible d’écrire un document représentant un objet MD_Metadata complet, + ou d’écrire un document représentant seulement un objet CI_Citation. +

+

+ Le standard ISO 19139 dispose le contenu de ces objets d’une manière inhabituelle: + pour chaque propriété dont le type de la valeur est lui-même une autre classe du standard ISO 19139, + la valeur est enveloppée dans un élément qui représente son type plutôt que d’être écrite directement. + Par exemple dans un objet de type CI_Citation, + la valeur de la propriété citedResponsibleParty + est enveloppée dans un élément CI_Responsibility. + Cette pratique double la profondeur de l’arborescence, en introduisant une duplication + à tous les niveaux pour chaque valeur, comme dans l’exemple suivant: +

+
<MD_Metadata>
+  <identificationInfo>
+    <MD_DataIdentification>
+      <citation>
+        <CI_Citation>
+          <citedResponsibleParty>
+            <CI_Responsibility>
+              <party>
+                <CI_Party>
+                  <contactInfo>
+                    <CI_Contact>
+                      <onlineResource>
+                        <CI_OnlineResource>
+                          <linkage>
+                            <URL>http://www.opengeospatial.org</URL>
+                          </linkage>
+                        </CI_OnlineResource>
+                      </onlineResource>
+                    </CI_Contact>
+                  </contactInfo>
+                </CI_Party>
+              </party>
+            </CI_Responsibility>
+          </citedResponsibleParty>
+        </CI_Citation>
+      </citation>
+    </MD_DataIdentification>
+  </identificationInfo>
+</MD_Metadata>
+ +

+ L’exemple précédent, comme tous les documents conformes à ISO 19139, + est constitué d’une alternance systématique de deux types d’éléments XML. + Il y a d’abord le nom de la propriété, qui commence toujours par une lettre minuscule (en ignorant les préfixes). + Dans les API Java, chaque propriété correspond à une méthode de la classe englobante. + Par exemple dans l’exemple ci-haut, gmd:identificationInfo + correspond à la méthode Metadata.getIdentificationInfo(). + Contrairement aux API Java toutefois, les documents XML + ne placent pas les propriétés filles directement en dessous. + À la place, ces éléments n’acceptent que les informations suivantes: +

+ +

+ Sous chaque propriété se trouve le type de la valeur, sauf si elle a été remplacée par une référence (la sous-section suivante approfondira ce sujet). + Le type de la valeur est un élément XML dont le nom commence toujours par une lettre majuscule, en ignorant les préfixes. + Dans l’exemple ci-haut nous avions MD_DataIdentification, qui correspond à l’interface Java DataIdentification. + C’est cet élément XML qui contient les propriétés filles. Cet élément accepte aussi un groupe d’attributs + (notamment id et uuid) que les schémas XSD + de l’OGC nomment collectivement gco:ObjectIdentification. + Ces attributs n’ont pas de méthodes Java dédiées, mais sont accessibles indirectement via l’interface IdentifiedObject + décrite dans la sous-section suivante. +

+ + + +

+ Afin de réduire la complexité des bibliothèques, GeoAPI et Apache SIS + n’exposent publiquement qu’une vision unifiée de ces deux types d’éléments. + L’API public correspond essentiellement au + deuxième groupe. Toutefois, lors de l’écriture d’un document XML, des éléments du premier groupe + doivent être temporairement recréés. + Les classes qui y correspondent sont définies dans des paquets internes de SIS. + Ces classes peuvent être ignorées, sauf si le développeur souhaite implémenter ses propres + classes dont les instances devront être lus et écrits par JAXB. +

+ + + + +

Identification d’instances déjà définies

+

+ L’élément englobant peut contenir un attribut id, + uuid ou xlink:href. + Si un de ces attributs est présent, l’élément englobé peut être complètement omis; + il sera remplacé au moment de la lecture par l’élément référencé par l’attribut. + Dans l’exemple suivant, la partie gauche définie un élément associé à l’identifiant “mon_id”, + alors que la partie droite référence cet élément: +

+ + + + + + + + + + + + +

+ Le choix de l’attribut à utiliser dépend de la portée de l’élément référencé: +

+ +

+ Dans la bibliothèque SIS, + tous les objets susceptibles d’être identifiés dans un document XML + implémentent l’interface org.apache.sis.xml.IdentifiedObject. + Chaque instance de cette interface fournit une vue de ses identifiants sous forme de Map<Citation,String>, + dans lequel la clé Citation identifie le type d’identifiant et la valeur est l’identifiant lui-même. + Quelques constantes représentant différents types d’identifiants sont énumérées dans IdentifierSpace, + notamment ID, UUID et HREF. + Chacune de ces clés peut être associée à une valeur d’un type différent (habituellement String, + UUID ou URI) selon la clé. + Par exemple le code suivant définit une valeur pour l’attribut uuid: +

+ +
import org.apache.sis.metadata.iso.DefaultMetadata;
+import org.apache.sis.xml.IdentifierSpace;
+import java.util.UUID;
+
+public class MyClass {
+    public void myMethod() {
+        UUID identifier = UUID.randomUUID();
+        DefaultMetadata metadata = new DefaultMetadata();
+        metadata.getIdentifierMap().putSpecialized(IdentifierSpace.UUID, identifier);
+    }
+}
+ +

+ Bien que ce mécanisme aie été définit dans le but de mieux supporter les représentations des + attributs XML du groupe gco:ObjectIdentification, + il permet aussi de manière opportuniste de manipuler d’autres types d’identifiants. + Par exemple les attributs ISBN et ISSN + de Citation peuvent être manipulés de cette manière. + Les méthodes de l’interface IdentifiedObject fournissent donc un endroit unique + où peuvent être manipulés tous types d’identifiants (pas seulement XML) associés à un objet. +

+ + + +

Représentation de valeurs manquantes

+

+ Lorsqu’un attribut n’est pas défini, la méthode correspondante de GeoAPI retourne généralement null. + Toutefois les choses se compliquent lorsque l’attribut manquant est une valeur considérée comme obligatoire par le standard ISO 19115. + Le standard ISO 19139 autorise l’omission d’attributs obligatoires à la condition d’indiquer pourquoi la valeur est manquante. + Les raisons peuvent être que l’attribut ne s’applique pas (inapplicable), + que la valeur existe probablement mais n’est pas connue (unknown), + que la valeur pourrait ne pas exister (missing), + qu’elle ne peut pas être divulguée (withheld), etc. + La transmission de cette information nécessite l’utilisation d’un objet non-nul même lorsque la valeur est manquante. + SIS procède en retournant un objet qui, en plus d’implémenter l’interface GeoAPI attendue, + implémente aussi l’interface org.apache.xml.NilObject. + Cette interface marque les instances dont toutes les méthodes retournent une collection vide, + un tableau vide, null, NaN, 0 ou false, + dans cet ordre de préférence selon ce que les types de retours des méthodes permettent. + Chaque instance implémentant NilObject fournit une méthode + getNilReason() indiquant pourquoi l’objet est nul. +

+

+ Dans l’exemple suivant, la partie gauche montre un élément CI_Citation + contenant un élément CI_Series, alors que dans la partie droite la série est inconnue. + Si l’élément CI_Series avait été complètement omis, + alors la méthode Citation.getSeries() retournerait null en Java. + Mais en présence d’un attribut nilReason, l’implémentation SIS + de getSeries() retournera plutôt un objet implémentant à la fois les interfaces + Series et NilReason, + et dont la méthode getNilReason() retournera la constante UNKNOWN. +

+ + + + + + + + + + + + + + +

Classes et méthodes utilitaires

+

+ Ce chapitre décrit des aspects de Apache SIS qui s’appliquent à l’ensemble de la bibliothèque. + La plupart de ces utilitaires ne sont pas spécifiques aux systèmes d’information spatiales. +

+ +

Modes de comparaisons des objets

+

+ Il existe différentes opinions sur la façon d’implémenter la méthode Object.equals(Object) du Java standard. + Selon certains, il doit être possible de comparer différentes implémentations d’une même interface ou classe de base. + Mais cette politique nécessite que chaque interface ou classe de base définisse entièrement dans sa Javadoc les critères ou calculs + que doivent employer les méthodes equals(Object) et hashCode() dans toutes les implémentations. + Cette approche est choisie notamment par java.util.Collection et ses interfaces filles. + La transposition de cette approche aux centaines d’interfaces de GeoAPI serait toutefois une entreprise ardue, + qui risquerait d’être assez peu suivie par les diverses implémentations. + En outre, elle se fait au détriment de la possibilité de prendre en compte des attributs supplémentaires dans les interfaces filles + si cette possibilité n’a pas été spécifiée dans l’interface parente. + Cette contrainte découle des points suivants du contrat des méthodes equals(Object) et hashCode(): +

+ +

+ Par exemple ces trois contraintes sont violées si A (et éventuellement C) + peuvent contenir des attributs que B ignore. + Pour contourner cette difficulté, une approche alternative consiste à exiger que les objets comparés par la méthode + Object.equals(Object) soient exactement de la même classe, c’est-à-dire que A.getClass() == B.getClass(). + Cette approche est parfois considérée contraire aux principes de la programmation orientée objets. + Dans la pratique, pour des applications relativement complexes, l’importance accordée à ces principes dépend du contexte dans lequel les objets sont comparés: + si les objets sont ajoutés à un HashSet ou utilisés comme clés dans un HashMap, + alors nous avons besoin d’un strict respect du contrat de equals(Object) et hashCode(). + Mais si le développeur compare les objets lui-même, par exemple pour vérifier si des informations qui l’intéresse ont changées, + alors les contraintes de symétrie, transitivité ou de cohérence avec les valeurs de hachages peuvent ne pas être pertinentes pour lui. + Des comparaisons plus permissives peuvent être souhaitables, allant parfois jusqu’à tolérer de légers écarts dans les valeurs numériques. +

+

+ Afin de donner une certaine flexibilité aux développeurs, un grand nombre de classes de la bibliothèque SIS + implémentent l’interface org.apache.sis.util.LenientComparable, qui défini une méthode equals(Object, ComparisonMode). + Les principaux modes de comparaisons sont: +

+ +

+ Le mode par défaut, utilisé par les toutes les méthodes equals(Object) de SIS, + est STRICT. Ce mode est choisi pour une utilisation sécuritaire — notamment avec HashMap — + sans nécessiter de définitions rigoureuses des méthodes equals(Object) et hashCode() dans toutes les interfaces. + Avec ce mode, l’ordre des objets (A.equals(B) ou B.equals(A)) n’a pas d’importance. + C’est toutefois le seul mode à offrir cette garantie. + Dans l’expression A.equals(B), le mode BY_CONTRACT + (et donc par extension tous les autres modes qui en dépendent) ne comparera que les propriétés connues de A, + sans se soucier de savoir si B en connaît davantage. +

+ + + +

Internationalisation

+

+ Dans une architecture où un programme exécuté sur un serveur fournit ses données à plusieurs clients, + les conventions locales du serveur ne sont pas nécessairement les mêmes que celles des clients. + Les conventions peuvent différer par la langue, mais aussi par la façon d’écrire les valeurs numériques + (même entre deux pays parlant la même langue) ainsi que par le fuseau horaire. + Pour produire des messages conformes aux conventions du client, SIS emploie + deux approches qui diffèrent par leur niveau de granularité: au niveau des messages eux-mêmes, + ou au niveau des objets produisant les messages. L’approche utilisée détermine aussi s’il est + possible de partager une même instance d’un objet pour toutes les langues. +

+ +

Chaînes de caractères distinctes pour chaque conventions locales

+

+ Certaines classes ne sont conçues que pour fonctionner selon une convention locale à la fois. + C’est évidemment le cas des implémentations standards de java.text.Format, + puisqu’elles sont entièrement dédiées au travail d’internationalisation. + Mais c’est aussi le cas de d’autres classes moins évidentes comme + javax.imageio.ImageReader/ImageWriter ainsi que les exceptions. + Lorsque une de ces classes est implémentée par SIS, + nous l’identifions en implémentant l’interface org.apache.sis.util.Localized. + La méthode getLocale() de cette interface permet alors de déterminer + selon quelles conventions locales l’instance produira ses messages. +

+

+ Certaines sous-classes de Exception définies par SIS + implémentent aussi l’interface Localized. + Pour ces exceptions, le message d’erreur peut être produit selon deux conventions locales + selon qu’il s’adresse à l’administrateur du système ou au client: + getMessage() retourne le message de l’exception selon les conventions par défaut du système, alors que + getLocalizedMessage() retourne le message de l’exception selon les conventions locales spécifiées par getLocale(). + Ce Locale sera lui-même déterminé par l’objet Localized qui a lancé l’exception. +

+

Exemple: + Supposons que dans un environnement où la langue par défaut serait l’anglais, + un objet AngleFormat est construit pour lire des angles selon les conventions françaises. + Si une ParseException est lancée lors de l’utilisation de ce formateur, + alors getMessage() retournera le message d’erreur en anglais + tandis que getLocalizedMessage() retournera le message d’erreur en français. +

+

+ Les exceptions définies par SIS n’implémentent pas toutes l’interface Localized. + Seules celles dont le message est le plus susceptible d’être montré à l’utilisateur sont ainsi localisées. + Les ParseException sont de bonnes candidates puisqu’elles surviennent souvent + suite à une saisie incorrecte du client. En revanche les NullPointerException + sont généralement la conséquence d’une erreur de programmation; + elles peuvent être localisées dans la langue par défaut du système, mais ça sera généralement tout. +

+

+ La classe utilitaire org.apache.sis.util.Exceptions fournit + des méthodes de commodité pour obtenir des messages selon des conventions locales données + lorsque cette information est disponible. +

+ + + +

Instance unique pour toutes les conventions locales

+

+ Les API définit par SIS + ou hérités de GeoAPI privilégient plutôt l’utilisation du type InternationalString + là où une valeur de type String serait susceptible d’être localisée. + Cette approche permet de différer le processus d’internationalisation au moment d’obtenir + une chaîne de caractères plutôt qu’au moment de construire l’objet qui les contient. + C’est particulièrement utile pour les classes immutables dont les instances existent + en un seul exemplaire indépendamment des conventions locales. +

+

Exemple: + Il existe dans SIS une seule instance de type + OperationMethod représentant la projection de Mercator, quelle que soit la langue du client. + Mais sa méthode getName() fournit (indirectement) + une instance de InternationalString telle que + toString(Locale.ENGLISH) retourne Mercator Projection + alors que toString(Locale.FRENCH) retourne Projection de Mercator. +

+

+ En définissant des objets spatiaux indépendemment des conventions locales, on réduit les risques de sur-coûts de calculs. + Par exemple il est plus facile de détecter que deux cartes emploient la même projection cartographique si cette dernière + est représentée par la même instance de CoordinateOperation, même si la projection + porte différents noms selon les pays. En outre, certain types de CoordinateOperation + peuvent nécessiter des grilles de transformation de coordonnées, ce qui accroît l’intérêt de partager une instance unique + pour des raisons d’économie de mémoire. +

+ + + +

Convention Locale.ROOT

+

+ Toutes les méthodes SIS recevant ou retournant une valeur de type Locale + acceptent la valeur Locale.ROOT. Cette valeur est interprétée comme signifiant de ne pas localiser le texte. + La notion de texte non-localisé est un peu fausse, puisqu’il faut bien choisir une convention de format. + Mais cette convention, bien que très proche de l’anglais, sera généralement légèrement différente. + Par exemple: +

+ + + + +

Traitement des caractères

+

+ Les chaînes de caractères en Java utilisent l’encodage UTF-16. Il existe une correspondance directe + entre les valeurs de type char et la très grande majorité des caractères, ce + qui facilite l’utilisation des chaînes lorsque ces caractères suffisent. + Mais certains caractères Unicode ne sont pas représentables par un seul char. + Ces caractères supplémentaires comprennent certains idéogrammes, + mais aussi des symboles routiers et géographiques dans la plage 1F680 à 1F700. + Le support de ces caractères supplémentaires nécessite des itérations un peu plus complexes + que le cas classique où l’on supposait une correspondance directe. + Ainsi, au lieu de la boucle de gauche ci-dessous, les applications internationales devraient + généralement utiliser la boucle de droite: +

+ + + + + + + + + + + + +

+ SIS supporte les caractères supplémentaires en utilisant la boucle de droite lorsque nécessaire. + Mais la boucle de gauche reste occasionnellement utilisée lorsqu’il est connu que les caractères recherchés ne sont + pas des caractères supplémentaires, même si la chaîne dans laquelle on fait la recherche peut en contenir. +

+ + + +

Interprétation des espaces blancs

+

+ Le Java standard fournit deux méthodes pour déterminer si un caractères est un espace blanc: + Character.isWhitespace(…) et Character.isSpaceChar(…). + Ces deux méthodes diffèrent dans leurs interprétations des espaces insécables, des tabulations et des retours à la ligne. + La première méthode est conforme à l’interprétation couramment utilisée dans des langages telles que le Java, C/C++ et XML, + qui considère les tabulations et retours à la ligne comme des espaces blancs, + alors que les espaces insécables sont interprétés comme des caractères non-blanc. + La seconde méthode — strictement conforme à la définition Unicode — fait l’interprétation inverse. +

+

+ SIS emploie ces deux méthodes dans des contextes différents. + isWhitespace(…) est utilisée pour séparer les éléments d’une liste (nombres, dates, mots, etc.), + tandis que isSpaceChar(…) est utilisée pour ignorer les espaces blancs à l’intérieur d’un seul élément. +

+

Exemple: + Supposons une liste de nombres représentés selon les conventions françaises. + Chaque nombre peut contenir des espace insécables comme séparateurs des milliers, + tandis que les différents nombres de la liste peuvent être séparés par des espaces ordinaires, des tabulations ou des retours à la ligne. + Pendant l’analyse d’un nombre, on veut considérer les espaces insécables comme faisant partie du nombre, + alors qu’une tabulation ou un retour à la ligne indique très probablement une séparation entre ce nombre et le nombre suivant. + On utilisera donc isSpaceChar(…). + Inversement, lors de la séparation des nombres de la liste, on veut considérer les tabulations et + les retours à la ligne comme des séparateurs mais pas les espaces insécables. + On utilisera donc isWhitespace(…). + Le rôle des espaces ordinaires, qui pourraient s’appliquer aux deux cas, doit être décidé en amont. +

+

+ Dans la pratique, cette distinction se traduit pas une utilisation de isSpaceChar(…) + dans les implémentations de java.text.Format, + et une utilisation de isWhitespace(…) dans pratiquement tout le reste + de la bibliothèque SIS. +

+ + + +

Géométries

+

+ Ce chapitre introduit quelques aspects de la norme ISO 19107 (Spatial schema) + et les classes de Apache SIS qui les implémentent. +

+ + + +

Classes de base

+

+ Chaque objet géométrique est considéré comme un ensemble infini de points. + En tant qu’ensemble, leurs opérations les plus fondamentales sont de même nature que les opérations standards des collections du Java. + On pourrait donc voir une géométrie comme une sorte de java.util.Set dont les éléments seraient des points, + à ceci près que le nombre d’éléments contenus dans cet ensemble est infini (à l’exception des géométries représentant un simple point). + Pour mieux représenter ce concept, la norme ISO et GeoAPI définissent une interface TransfiniteSet + que l’on peut voir comme un Set de taille infini. Bien qu’un lien de parenté existe conceptuellement entre ces interfaces, + GeoAPI ne définit pas TransfiniteSet comme une sous-interface de java.util.Collection + car la définition de certaines méthodes telles que size() et iterator() serait problématique. + On y retrouve toutefois des méthodes très similaires telles que contains(…) et intersects(…). +

+

+ La classe parente de toutes les géométries est appelée GM_Object dans la norme ISO 19107. + Les interfaces de GeoAPI utilisent plutôt le nom Geometry, car l’omission du préfixe GM_ + (comme le veut la convention dans GeoAPI) aurait laissé un nom trop proche de la classe Object du Java. + Toutes les géométries sont des spécialisations de TransfiniteSet. +

+ + + +

Points et positions directes

+

+ ISO 19107 définit deux types de structures pour représenter un point: + GM_Point et DirectPosition. + Le premier type est une véritable géométrie et peut donc être relativement lourd, selon les implémentations. + Le second type n’est pas considéré formellement comme une géométrie; + il n’étend ni GM_Object ni TransfiniteSet. + Il ne définit pratiquement pas d’opérations autres que le stockage d’une séquence de nombres représentant une coordonnée. + Il peut donc être un objet plus léger. +

+

+ Afin de permettre à l’API de travailler indifféremment + avec ces deux types de positions, ISO 19107 définit Position comme une union + de DirectPosition et GM_Point. + Il s’agit d’une union au sens du C/C++. Pour le langage Java, GeoAPI obtient le même effet en définissant + Position comme l’interface parente de + DirectPosition et Point. + Dans la pratique, la grande majorité des API + de Apache SIS travaillent sur des + DirectPosition, ou occasionnellement des + Position quand il semble utile d’autoriser aussi des points géométriques. +

+ + + +

Enveloppes

+

+ Les enveloppes stockent les valeurs minimales et maximales des coordonnées d’une géométrie. + Les enveloppes ne sont pas elles-mêmes des géométries; ce ne sont pas des ensembles + infinis de points (TransfiniteSet). Il n’y a aucune garantie + que toutes les positions contenues dans les limites d’une enveloppe soient géographiquement valides. + Il faut voir les enveloppes comme une information sur les valeurs extrêmes que peuvent prendre les + coordonnées d’une géométrie en faisant comme si chaque dimension était indépendante des autres, + rien de plus. Nous assimilons néanmoins les enveloppes à des rectangles, cubes ou hyper-cubes + (selon le nombre de dimensions) afin de faciliter la discussion, mais en gardant à l’esprit leur + nature non-géométrique. +

+

Exemple: + Nous pouvons tester si une position est à l’intérieur des limites de l’enveloppe. + Un résultat positif ne garantie pas que la position est à l’intérieur de la géométrie délimitée par l’enveloppe, + mais un résultat négatif garantie qu’elle est à l’extérieur. De même on peut effectuer des tests d’intersections. + En revanche appliquer une rotation n’a pas beaucoup de sens pour une enveloppe, car le résultat peut être très différent + de celui que nous aurions obtenu en effectuant une rotation de la géométrie originale, puis en recalculant son enveloppe. +

+

+ Une enveloppe peut être représentée par deux positions correspondant à deux coins opposés + d’un rectangle, cube ou hyper-cube. On prend souvent comme premier coin celui dont toutes + les ordonnées ont la valeur minimale (lowerCorner), et comme second + coin celui dont toutes les ordonnées ont la valeur maximale (upperCorner). + Lors d’un affichage utilisant un système de coordonnées classique (valeurs de l’axe des y augmentant vers le haut), + ces deux positions apparaissent respectivement dans le coin inférieur gauche et dans le coin supérieur droit d’un rectangle. + Attention toutefois aux différents systèmes de coordonnées, qui peuvent faire varier les positions de ces coins à l’écran. + Les expressions lower corner et upper corner + doivent être comprises au sens mathématique plutôt que visuel. +

+ + + +

Enveloppes traversant l’antiméridien

+

+ Les minimums et maximums sont les valeurs les plus souvent assignées aux lowerCorner + et upperCorner. Mais les choses se compliquent dans le cas d’une enveloppe traversant + l’antiméridien (-180° ou 180° de longitude). Par exemple, une enveloppe de 10° de largeur peut commencer à 175° de longitude et + se terminer à -175°. Dans ce cas, la valeur de longitude assignée au lowerCorner est + supérieure à celle qui est assignée à l’upperCorner. + Apache SIS emploie donc une définition légèrement différente de ces deux coins: +

+ +

+ Lorsque l’enveloppe ne traverse par l’antiméridien, ces deux définitions sont équivalentes à la sélection + des valeurs minimales et maximales respectivement. C’est le cas du rectangle vert dans la figure ci-dessous. + Lorsque l’enveloppe traverse l’antiméridien, les coins lowerCorner + et upperCorner apparaissent encore en bas et en haut du rectangle + (en supposant un système de coordonnées classique), donc leurs noms restent appropriés d’un point de vue visuel. + Mais les positions gauche et droite sont interchangées. + Ce cas est représenté par le rectangle rouge dans la figure ci-dessous. +

+
+ Exemples d’enveloppes avec et sans croisement de l’antiméridien. +
+

+ Les notions d’inclusion et d’intersection s’interprètent toutefois de manière légèrement différente dans ces deux cas. + Dans le cas habituel où l’on ne traverse par l’antiméridien, le rectangle vert délimite bien une région d’inclusion. + Les régions exclues de ce rectangle se propagent à l’infini dans toutes les directions. + En d’autres mots, la région d’inclusion n’est pas répétée tous les 360°. + Mais dans le cas du rectangle rouge, l’information fournie par l’enveloppe délimite plutôt la région d’exclusion qui + se trouve entre les deux bords du rectangle. La région d’inclusion se propage à l’infini des côtés gauche et droit. + Nous pourrions stipuler que toute longitude inférieure à -180° ou supérieure à 180° est considérée exclue, + mais ça serait une décision arbitraire qui ne serait pas un reflet symétrique du cas habituel (rectangle vert). + Un développeur pourrait vouloir utiliser ces valeurs, par exemple dans une mosaïque où la carte du monde + est répétée plusieurs fois horizontalement sans pour autant les confondre. + Si un développeur souhaite effectuer des opérations comme si les régions d’inclusions ou d’exclusions étaient + répétées tous les 360°, alors il doit lui-même ramener ses valeurs de longitudes entre -180° et 180° au préalable. + Toutes les fonctions add(…), contains(…), + intersect(…), etc. de toutes les enveloppes + définies dans le paquet org.apache.sis.geometry effectuent leurs calculs selon cette convention. +

+ +

+ Pour que les fonctions telles que add(…) fonctionnent correctement, + tous les objets impliqués doivent utiliser le même système de référence des coordonnées, y compris + la même plage de valeurs. Ainsi, une enveloppe exprimant les longitudes dans la plage [-180 … +180]° + n’est pas compatible avec une enveloppe exprimant les longitudes dans la plage [0 … 360]°. + Les conversions, si nécessaires, sont à la charge de l’utilisateur + (la classe Envelopes fournit des méthodes de commodités pour ce faire). + En outre, les coordonnées de l’enveloppe doivent être comprises dans les limites du système de coordonnées, + sauf si le développeur souhaite volontairement considérer (par exemple) 300° de longitude + comme un position distincte de -60°. La classe GeneralEnvelope + fournit une méthode normalize() pour ramener les coordonnées + dans les limites attendues, au prix parfois de valeurs lower + supérieures à la valeur upper. +

+ + + + +

Couvertures de données (Coverages)

+

+ Les images, souvent nommées rasters en anglais, sont des cas particuliers + d’une structure de données appelée coverages. + On pourrait traduire ce terme anglais par « couverture de données ». + Le titre du standard les décrivant, “Coverage geometry and functions” + (ISO 19123), résume bien les deux éléments essentiels des couvertures de données: +

+ +

+ Les caractéristiques du domaine spatial sont définies par le standard ISO 19123, + alors que les caractéristiques du range ne font pas parties du standard. + Le standard mentionne simplement que les ranges peuvent être finis ou infinis, + et ne sont pas nécessairement numériques. + Par exemple les valeurs retournées par une couverture peuvent provenir d’une énumération + (« ceci est une forêt », « ceci est un lac », etc.). + Toutefois, le standard définit deux grands types de couvertures qui ont un impact + sur les types de ranges autorisés: + les couvertures discrètes et les couvertures continues. + Présentées simplement, les couvertures continues sont des fonctions pouvant utiliser des méthodes d’interpolations. + Or, les interpolations n’étant possibles qu’avec des valeurs numériques, les ranges de valeurs + non-numériques ne peuvent être utilisés qu’avec des couvertures de type CV_DiscreteCoverage. + En revanche, les ranges de valeurs numériques peuvent + être utilisés aussi avec des couvertures de type CV_ContinuousCoverage. +

+ + +