Parmi les sortes d’opérations qu’un SIG doit effectuer sur les coordonnées spatiales, les transformations affines sont à la fois relativement simples et très fréquentes. Les transformations affines peuvent représenter n’importe quelle combinaison d’échelles, de cisaillements, de retournements, de rotations ou de translations, qui sont toutes des opérations linéaires. Les transformations affines ne peuvent pas effectuer des opérations non-linéaires telles que les projections cartographiques, mais couvrent néanmoins de nombreux autres cas:
.tfw
qui accompagnent certaines images TIFF.Les transformations affines peuvent se combiner efficacement. Peu importe le nombre de transformations affines que l’on enchaîne, le résultat sera exprimable par une seule transformation affine. Cette propriété est plus facilement visible lorsque les transformations affines sont exprimées sous forme de matrices: pour combiner les opérations, il suffit de multiplier les matrices. Le cas des conversions des coordonnées pixels en coordonnées géographiques ci-dessous donne un exemple.
Exemple: supposons que nous disposons d’une image dont les coordonnées des pixels sont représentées par (x,y). Supposons aussi que les contraintes suivantes sont respectées:
Alors la conversion des coordonnées pixels (x,y) vers les coordonnées géographiques (λ,φ) peut être représentée par les équations suivantes, où Nx est la largeur et Ny la hauteur de l’image en nombre de pixels.
Les équations ci-dessus peuvent être représentées sous forme de matrices comme ci-dessous:
Dans ce cas particulier, les facteurs d’échelles S correspondent à la taille des pixels en degrés et les termes de translations T correspondent aux coordonnées géographiques d’un coin de l’image (pas nécessairement le coin inférieur gauche si certains axes ont été retournés). Cette interprétation directe n’est possible que lorsque les contraintes énumérées plus haut sont respectées. Les coefficients des matrices deviennent plus complexes si l’image a un cisaillement ou une rotation, ou si les coordonnées des pixels ne commencent pas à (0,0). Toutefois il n’est pas nécessaire d’utiliser des équations plus complexes pour gérer des cas plus génériques. L’exemple ci-dessous prend comme point de départ la matrice d’une « conversion initiale » dans laquelle les coefficients S et T sont les valeurs relativement simples données ci-dessus. Ensuite la direction de l’axe des y est inversée de manière à correspondre à la convention habituelle des systèmes de coordonnées des images (changement 1), et les axes sont intervertis de manière à avoir la latitude avant la longitude (changement 2). Notez que les concaténations de transformations affines écrites sous forme de multiplications matricielles se lisent de droite à gauche: A×B×C est équivalent à d’abord appliquer l’opération C, suivit de l’opération B et finalement l’opération A.
Un principe clé est qu’il n’y a pas besoin d’écrire un code dédié à ce type d’opérations sur les axes. Ces opérations, et bien d’autres, sont prises en compte naturellement par l’algèbre matricielle. On y gagne en généricité du code et en performance. Apache SIS suit ce principe en utilisant les tranformations affine pour toutes les opérations où elles peuvent s’appliquer. Il n’y a par exemple aucun code dédié au changement de l’ordre des ordonnées dans une coordonnée.
A peu près toutes les bibliothèques graphiques supportent une forme de transformation de coordonnées, souvent les transformations affines ou une légère généralisation. Chaque bibliothèque défini son propre API. Quelques exemples sont:
Bibliothèque | Implementation de la transformation | Dimensions |
---|---|---|
Java2D | java.awt.geom.AffineTransform | 2 |
Java3D | javax.media.j3d.Transform3D | 3 |
JavaFX | javafx.scene.transform.Affine | 2 ou 3 |
Java Advanced Imaging (JAI) | javax.media.jai.PerspectiveTransform | 2 |
Android | android.graphics.Matrix | 2 |
Toutefois dans plusieurs cas, les transformations affines sont les seuls types d’opérations supportées par la bibliothèque graphique.
Apache SIS a besoin de gérer un plus grand nombre de type d’opérations,
parmi lesquelles les transformations affines ne sont que des cas particuliers.
Les projections cartographiques et les changements de référentiels notamment,
ne peuvent pas être représentés par des transformations affines.
SIS a aussi besoin de transformer des points ayant un nombre arbitraire de dimensions,
alors que les API cités ci-haut restreignent leur usage à un nombre fixe de dimensions.
Pour ces raisons, SIS ne peut pas utiliser directement ces API.
SIS utilise plutôt une interface plus abstraite, org.opengis.referencing.transform.MathTransform
.
Mais dans le cas particulier où la transformation est réellement affine, SIS peut essayer d’utiliser
une implémentation existante, surtout Java2D.
Par exemple le code suivant peut être utilisé dans les situations où un objet Java2D est désiré:
MathTransform mt = ...; // N’importe quelle instance créée par Apache SIS.
if (mt instanceof AffineTransform) {
AffineTransform at = (AffineTransform) mt;
// Utiliser l’API de Java2D API à partir d’ici.
}
Toutefois SIS n’utilisera Java2D que sur une base opportuniste.
Le forçage de type ci-haut n’est pas garantit de réussir, même si l’instance de
MathTransform
répond aux conditions qui devrait permettre un usage de Java2D.