sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1753786 [1/2] - in /sis/site/trunk: book/en/annexes.html book/en/referencing.html book/fr/annexes.html book/fr/referencing.html content/book/en/developer-guide.html content/book/fr/developer-guide.html
Date Fri, 22 Jul 2016 13:07:12 GMT
Author: desruisseaux
Date: Fri Jul 22 13:07:12 2016
New Revision: 1753786

URL: http://svn.apache.org/viewvc?rev=1753786&view=rev
Log:
Moved the chapter about affine transforms to the annexes.

Modified:
    sis/site/trunk/book/en/annexes.html
    sis/site/trunk/book/en/referencing.html
    sis/site/trunk/book/fr/annexes.html
    sis/site/trunk/book/fr/referencing.html
    sis/site/trunk/content/book/en/developer-guide.html
    sis/site/trunk/content/book/fr/developer-guide.html

Modified: sis/site/trunk/book/en/annexes.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/book/en/annexes.html?rev=1753786&r1=1753785&r2=1753786&view=diff
==============================================================================
--- sis/site/trunk/book/en/annexes.html (original)
+++ sis/site/trunk/book/en/annexes.html Fri Jul 22 13:07:12 2016
@@ -372,6 +372,132 @@ public class MyTest extends Parameterize
     <h2 id="DesignNote">Design notes</h2>
     <p>Following chapters explain the rational behind some implementation choices done in Apache <abbr>SIS</abbr>.</p>
 
+
+    <h3 id="AffineTransform">Affine transform</h3>
+    <p>
+      Among the many kinds of operations performed by <abbr>GIS</abbr> softwares on spatial coordinates,
+      <cite>affine transforms</cite>  are both relatively simple and very common.
+      Affine transforms can represent any combination of scales, shears, flips, rotations and translations,
+      which are <em>linear</em> operations.
+      Affine transforms can not handle <em>non-linear</em> operations like map projections,
+      but the affine transform capabilities nevertheless cover many other cases:
+    </p>
+    <ul>
+      <li>Axis order changes,           for example from (<var>latitude</var>, <var>longitude</var>) to (<var>longitude</var>, <var>latitude</var>).</li>
+      <li>Axis direction changes,       for example the <var>y</var> axis oriented toward down in images.</li>
+      <li>Prime meridian rotations,     for example from <cite>Paris</cite> to <cite>Greenwich</cite> prime meridian.</li>
+      <li>Dimensionality changes,       for example from 3-dimensional coordinates to 2-dimensional coordinates by dropping the height.</li>
+      <li>Unit conversion,              for example from feet to metres.</li>
+      <li>Pixel to geodetic coordinate, for example the conversion represented in the <code>.tfw</code> files associated to some <abbr>TIFF</abbr> images.</li>
+      <li>Part of map projections,      for example the <cite>False Easting</cite>, <cite>False Northing</cite> and <cite>Scale factor</cite> parameters.</li>
+    </ul>
+    <p>
+      Affine transforms can be concatenated efficiently.
+      No matter how many affine transforms are chained, the result can be represented by a single affine transform.
+      This property is more easily seen when affine transforms are represented by matrices:
+      in order to concatenate those operations, we only need to multiply those matrices.
+      The “pixel to geographic coordinate conversions” case below gives an example.
+    </p>
+
+    <div class="example">
+      <p><b>Example:</b>
+        given an image with pixel coordinates represented by (<var>x</var>,<var>y</var>) tuples
+        and given the following assumptions:
+      </p>
+      <ul>
+        <li>There is no shear, no rotation and no flip.</li>
+        <li>All pixels have the same width in degrees of longitude.</li>
+        <li>All pixels have the same height in degrees of latitude.</li>
+        <li>Pixel indices are positive integers starting at (0,0) inclusive.</li>
+      </ul>
+      <p>Then conversions from pixel coordinates (<var>x</var>,<var>y</var>)
+        to geographic coordinates (<var>λ</var>,<var>φ</var>) can be represented by the following equations,
+        where <var>N</var><sub><var>x</var></sub> is the image width and
+        <var>N</var><sub><var>y</var></sub> the image height in number of pixels:
+      </p><p>
+        <xi:include href="../math/PixelToGeographicTerms.html"/>
+      </p><p>
+        Above equations can be represented in matrix form as below:
+      </p><p>
+      <xi:include href="../math/PixelToGeographic.html"/>
+      </p><p>
+        In this particular case, scale factors <var>S</var> are the pixel size in degrees
+        and translation terms <var>T</var> are the geographic coordinate of an image corner
+        (not necessarily the lower-left corner if some axes have been flipped).
+        This straightforward interpretation holds because of above-cited assumptions, but
+        matrix coefficients become more complex if the image has shear or rotation
+        or if pixel coordinates do not start at (0,0).
+        However it is not necessary to use more complex equations for supporting more generic cases.
+        The following example starts with an “initial conversion” matrix
+        where the <var>S</var> and <var>T</var> terms are set to the most straightforward values.
+        Then the <var>y</var> axis direction is reversed for matching the most common convention in image coordinate systems (change 1),
+        and axis are swapped resulting in latitude before longitude (change 2).
+        Note that when affine transform concatenations are written as matrix multiplications, operations are ordered from right to left:
+        <var>A</var>×<var>B</var>×<var>C</var> is equivalent to first applying operation <var>C</var>,
+        then operation <var>B</var> and finally operation <var>A</var>.
+      </p>
+      <table class="hidden"><tr>
+        <th>Change 2</th><th></th>
+        <th>Change 1</th><th></th>
+        <th>Initial conversion</th><th></th>
+        <th>Concatenated operation</th>
+      </tr><tr>
+        <td style="vertical-align: middle"><xi:include href="../math/AxisSwapping2D.html"/></td>
+        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
+        <td style="vertical-align: middle"><xi:include href="../math/InverseAxisY.html"/></td>
+        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
+        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicSameAxisDirections.html"/></td>
+        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">=</td>
+        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicReverseOrderAndY.html"/></td>
+      </tr></table>
+      <p>
+        A key principle is that there is no need to write Java code dedicated to above kinds of axis changes.
+        Those operations, and many other, can be handled by matrix algebra.
+        This approach makes easier to write generic code and improves performance.
+        Apache <abbr>SIS</abbr> follows this principle by using affine transforms for every operations
+        that can be performed by such transform.
+        For instance there is no code dedicated to changing order of ordinate values in a coordinate.
+      </p>
+    </div>
+
+    <h4 id="AffineTransformAPI">Integration with graphical libraries</h4>
+    <p>
+      About all graphical libraries support some kind of coordinate operations, usually as <cite>affine transforms</cite>
+      or a slight generalization like <cite>perspective transforms</cite>.
+      Each library defines its own <abbr>API</abbr>. Some examples are listed below:
+    </p>
+    <table>
+      <caption>Affine transform implementations in graphical libraries</caption>
+      <tr><th>Library</th>                                  <th>Transform implementation</th>                          <th>Dimensions</th></tr>
+      <tr><td>Java2D</td>                                   <td><code>java.awt.geom.AffineTransform</code></td>        <td>2</td></tr>
+      <tr><td>Java3D</td>                                   <td><code>javax.media.j3d.Transform3D</code></td>          <td>3</td></tr>
+      <tr><td>JavaFX</td>                                   <td><code>javafx.scene.transform.Affine</code></td>        <td>2 or 3</td></tr>
+      <tr><td>Java Advanced Imaging (<abbr>JAI</abbr>)</td> <td><code>javax.media.jai.PerspectiveTransform</code></td> <td>2</td></tr>
+      <tr><td>Android</td>                                  <td><code>android.graphics.Matrix</code></td>              <td>2</td></tr>
+    </table>
+    <p>
+      However in many cases, affine or perspective transforms are the only kind of coordinate operations supported by the graphical library.
+      Apache <abbr>SIS</abbr> needs to handle a wider range of operations, in which affine transforms are only special cases.
+      In particular most map projections and datum shifts can not be represented by affine transforms.
+      <abbr>SIS</abbr> also needs to support arbitrary number of dimensions,
+      while above-cited <abbr>API</abbr> restrict the use to a fixed number of dimensions.
+      For those reasons <abbr>SIS</abbr> can not use directly the above-cited <abbr>API</abbr>.
+      Instead, <abbr>SIS</abbr> uses the more abstract <code>org.opengis.referencing.transform.MathTransform</code> interface.
+      But in the special case where the transform is actually affine, <abbr>SIS</abbr> may try to use an existing implementation,
+      in particular Java2D. The following Java code can be used in situations where the Java2D object is desired:
+    </p>
+    <pre>MathTransform mt = ...;    // Any math transform created by Apache SIS.
+if (mt instanceof AffineTransform) {
+    AffineTransform at = (AffineTransform) mt;
+    // Use Java2D API from here.
+}</pre>
+    <p>
+      Apache <abbr>SIS</abbr> uses Java2D on a <em>best effort</em> basis only.
+      The above cast is not guaranteed to succeed,
+      even when the <code>MathTransform</code> meets the requirements allowing Java2D usage.
+    </p>
+
+
     <h3 id="MatrixLibrary">Specificities of a matrix library for <abbr>GIS</abbr></h3>
     <p>
       <abbr>GIS</abbr> make an extensive usage of matrices for displaying maps or for transforming coordinates.

Modified: sis/site/trunk/book/en/referencing.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/book/en/referencing.html?rev=1753786&r1=1753785&r2=1753786&view=diff
==============================================================================
--- sis/site/trunk/book/en/referencing.html (original)
+++ sis/site/trunk/book/en/referencing.html Fri Jul 22 13:07:12 2016
@@ -406,130 +406,6 @@ public class MyApp {
 }</pre>
 
 
-    <h4 id="AffineTransform">Affine transform</h4>
-    <p>
-      Among the many kinds of operations performed by <abbr>GIS</abbr> softwares on spatial coordinates,
-      <cite>affine transforms</cite>  are both relatively simple and very common.
-      Affine transforms can represent any combination of scales, shears, flips, rotations and translations,
-      which are <em>linear</em> operations.
-      Affine transforms can not handle <em>non-linear</em> operations like map projections,
-      but the affine transform capabilities nevertheless cover many other cases:
-    </p>
-    <ul>
-      <li>Axis order changes,           for example from (<var>latitude</var>, <var>longitude</var>) to (<var>longitude</var>, <var>latitude</var>).</li>
-      <li>Axis direction changes,       for example the <var>y</var> axis oriented toward down in images.</li>
-      <li>Prime meridian rotations,     for example from <cite>Paris</cite> to <cite>Greenwich</cite> prime meridian.</li>
-      <li>Dimensionality changes,       for example from 3-dimensional coordinates to 2-dimensional coordinates by dropping the height.</li>
-      <li>Unit conversion,              for example from feet to metres.</li>
-      <li>Pixel to geodetic coordinate, for example the conversion represented in the <code>.tfw</code> files associated to some <abbr>TIFF</abbr> images.</li>
-      <li>Part of map projections,      for example the <cite>False Easting</cite>, <cite>False Northing</cite> and <cite>Scale factor</cite> parameters.</li>
-    </ul>
-    <p>
-      Affine transforms can be concatenated efficiently.
-      No matter how many affine transforms are chained, the result can be represented by a single affine transform.
-      This property is more easily seen when affine transforms are represented by matrices:
-      in order to concatenate those operations, we only need to multiply those matrices.
-      The “pixel to geographic coordinate conversions” case below gives an example.
-    </p>
-
-    <div class="example">
-      <p><b>Example:</b>
-        given an image with pixel coordinates represented by (<var>x</var>,<var>y</var>) tuples
-        and given the following assumptions:
-      </p>
-      <ul>
-        <li>There is no shear, no rotation and no flip.</li>
-        <li>All pixels have the same width in degrees of longitude.</li>
-        <li>All pixels have the same height in degrees of latitude.</li>
-        <li>Pixel indices are positive integers starting at (0,0) inclusive.</li>
-      </ul>
-      <p>Then conversions from pixel coordinates (<var>x</var>,<var>y</var>)
-        to geographic coordinates (<var>λ</var>,<var>φ</var>) can be represented by the following equations,
-        where <var>N</var><sub><var>x</var></sub> is the image width and
-        <var>N</var><sub><var>y</var></sub> the image height in number of pixels:
-      </p><p>
-        <xi:include href="../math/PixelToGeographicTerms.html"/>
-      </p><p>
-        Above equations can be represented in matrix form as below:
-      </p><p>
-      <xi:include href="../math/PixelToGeographic.html"/>
-      </p><p>
-        In this particular case, scale factors <var>S</var> are the pixel size in degrees
-        and translation terms <var>T</var> are the geographic coordinate of an image corner
-        (not necessarily the lower-left corner if some axes have been flipped).
-        This straightforward interpretation holds because of above-cited assumptions, but
-        matrix coefficients become more complex if the image has shear or rotation
-        or if pixel coordinates do not start at (0,0).
-        However it is not necessary to use more complex equations for supporting more generic cases.
-        The following example starts with an “initial conversion” matrix
-        where the <var>S</var> and <var>T</var> terms are set to the most straightforward values.
-        Then the <var>y</var> axis direction is reversed for matching the most common convention in image coordinate systems (change 1),
-        and axis are swapped resulting in latitude before longitude (change 2).
-        Note that when affine transform concatenations are written as matrix multiplications, operations are ordered from right to left:
-        <var>A</var>×<var>B</var>×<var>C</var> is equivalent to first applying operation <var>C</var>,
-        then operation <var>B</var> and finally operation <var>A</var>.
-      </p>
-      <table class="hidden"><tr>
-        <th>Change 2</th><th></th>
-        <th>Change 1</th><th></th>
-        <th>Initial conversion</th><th></th>
-        <th>Concatenated operation</th>
-      </tr><tr>
-        <td style="vertical-align: middle"><xi:include href="../math/AxisSwapping2D.html"/></td>
-        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
-        <td style="vertical-align: middle"><xi:include href="../math/InverseAxisY.html"/></td>
-        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
-        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicSameAxisDirections.html"/></td>
-        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">=</td>
-        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicReverseOrderAndY.html"/></td>
-      </tr></table>
-      <p>
-        A key principle is that there is no need to write Java code dedicated to above kinds of axis changes.
-        Those operations, and many other, can be handled by matrix algebra.
-        This approach makes easier to write generic code and improves performance.
-        Apache <abbr>SIS</abbr> follows this principle by using affine transforms for every operations
-        that can be performed by such transform.
-        For instance there is no code dedicated to changing order of ordinate values in a coordinate.
-      </p>
-    </div>
-
-    <h4 id="AffineTransformAPI">Integration with graphical libraries</h4>
-    <p>
-      About all graphical libraries support some kind of coordinate operations, usually as <cite>affine transforms</cite>
-      or a slight generalization like <cite>perspective transforms</cite>.
-      Each library defines its own <abbr>API</abbr>. Some examples are listed below:
-    </p>
-    <table>
-      <caption>Affine transform implementations in graphical libraries</caption>
-      <tr><th>Library</th>                                  <th>Transform implementation</th>                          <th>Dimensions</th></tr>
-      <tr><td>Java2D</td>                                   <td><code>java.awt.geom.AffineTransform</code></td>        <td>2</td></tr>
-      <tr><td>Java3D</td>                                   <td><code>javax.media.j3d.Transform3D</code></td>          <td>3</td></tr>
-      <tr><td>JavaFX</td>                                   <td><code>javafx.scene.transform.Affine</code></td>        <td>2 or 3</td></tr>
-      <tr><td>Java Advanced Imaging (<abbr>JAI</abbr>)</td> <td><code>javax.media.jai.PerspectiveTransform</code></td> <td>2</td></tr>
-      <tr><td>Android</td>                                  <td><code>android.graphics.Matrix</code></td>              <td>2</td></tr>
-    </table>
-    <p>
-      However in many cases, affine or perspective transforms are the only kind of coordinate operations supported by the graphical library.
-      Apache <abbr>SIS</abbr> needs to handle a wider range of operations, in which affine transforms are only special cases.
-      In particular most map projections and datum shifts can not be represented by affine transforms.
-      <abbr>SIS</abbr> also needs to support arbitrary number of dimensions,
-      while above-cited <abbr>API</abbr> restrict the use to a fixed number of dimensions.
-      For those reasons <abbr>SIS</abbr> can not use directly the above-cited <abbr>API</abbr>.
-      Instead, <abbr>SIS</abbr> uses the more abstract <code>org.opengis.referencing.transform.MathTransform</code> interface.
-      But in the special case where the transform is actually affine, <abbr>SIS</abbr> may try to use an existing implementation,
-      in particular Java2D. The following Java code can be used in situations where the Java2D object is desired:
-    </p>
-    <pre>MathTransform mt = ...;    // Any math transform created by Apache SIS.
-if (mt instanceof AffineTransform) {
-    AffineTransform at = (AffineTransform) mt;
-    // Use Java2D API from here.
-}</pre>
-    <p>
-      Apache <abbr>SIS</abbr> uses Java2D on a <em>best effort</em> basis only.
-      The above cast is not guaranteed to succeed,
-      even when the <code>MathTransform</code> meets the requirements allowing Java2D usage.
-    </p>
-
     <h3 id="TransformDerivative">Partial derivatives of coordinate operations</h3>
     <p>
       <span style="color: red">TODO</span>

Modified: sis/site/trunk/book/fr/annexes.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/book/fr/annexes.html?rev=1753786&r1=1753785&r2=1753786&view=diff
==============================================================================
--- sis/site/trunk/book/fr/annexes.html (original)
+++ sis/site/trunk/book/fr/annexes.html Fri Jul 22 13:07:12 2016
@@ -379,6 +379,141 @@ public class MyTest extends Parameterize
     <h2 id="DesignNote">Notes de design</h2>
     <p>Les chapitres suivants expliquent les raisons derrières certains choix d'implémentation de Apache <abbr>SIS</abbr>.</p>
 
+
+    <h3 id="AffineTransform">Utilisation des transformations affines</h3>
+    <p>
+      Parmi les sortes d’opérations qu’un <abbr>SIG</abbr> doit effectuer sur les coordonnées spatiales,
+      les <cite>transformations affines</cite> 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 <cite>opérations linéaires</cite>.
+      Les transformations affines ne peuvent pas effectuer des opérations <cite>non-linéaires</cite>
+      telles que les projections cartographiques, mais couvrent néanmoins de nombreux autres cas:
+    </p>
+    <ul>
+      <li>Changer l’ordre des axes,        par exemple de (<var>latitude</var>, <var>longitude</var>) vers (<var>longitude</var>, <var>latitude</var>).</li>
+      <li>Changer la direction des axes,   par exemple l’axe des <var>y</var> qui pointe habituellement vers le bas dans les images.</li>
+      <li>Changer le méridien d’origine,   par exemple du méridien de <cite>Paris</cite> vers celui de <cite>Greenwich</cite>.</li>
+      <li>Changer le nombre de dimensions, par exemple passer des coordonnées 3D vers 2D en supprimant la hauteur.</li>
+      <li>Convertir des unités de mesures, par exemple convertir des pieds en mètres.</li>
+      <li>Convertir des coordonnées pixels en coordonnées géographiques,
+          par exemple la conversion exprimée dans les fichiers <code>.tfw</code> qui accompagnent certaines images <abbr>TIFF</abbr>.</li>
+      <li>Prendre en charge une petite partie des projections cartographiques,
+          par exemple les paramètres <cite>False Easting</cite>, <cite>False Northing</cite> et <cite>Scale factor</cite>.</li>
+    </ul>
+    <p>
+      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.
+    </p>
+
+    <div class="example">
+      <p><b>Exemple:</b>
+        supposons que nous disposons d’une image dont les coordonnées des pixels sont représentées par (<var>x</var>,<var>y</var>).
+        Supposons aussi que les contraintes suivantes sont respectées:
+      </p>
+      <ul>
+        <li>Il n’y a ni cisaillement, ni rotation, ni retournement de l’image.</li>
+        <li>Tous les pixels ont la même largeur en degrés de longitude.</li>
+        <li>Tous les pixels ont la même hauteur en degrés de latitude.</li>
+        <li>Les coordonnées des pixels commencent à (0,0) inclusivement.</li>
+      </ul>
+      <p>Alors la conversion des coordonnées pixels (<var>x</var>,<var>y</var>)
+        vers les coordonnées géographiques (<var>λ</var>,<var>φ</var>)
+        peut être représentée par les équations suivantes,
+        où <var>N</var><sub><var>x</var></sub> est la largeur
+        et <var>N</var><sub><var>y</var></sub> la hauteur de l’image en nombre de pixels.
+      </p><p>
+        <xi:include href="../math/PixelToGeographicTerms.html"/>
+      </p><p>
+        Les équations ci-dessus peuvent être représentées sous forme de matrices comme ci-dessous:
+      </p><p>
+      <xi:include href="../math/PixelToGeographic.html"/>
+      </p><p>
+        Dans ce cas particulier, les facteurs d’échelles <var>S</var> correspondent à la taille des pixels en degrés
+        et les termes de translations <var>T</var> 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 <var>S</var> et <var>T</var> sont les valeurs relativement simples données ci-dessus.
+        Ensuite la direction de l’axe des <var>y</var> 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:
+        <var>A</var>×<var>B</var>×<var>C</var> est équivalent à d’abord appliquer l’opération <var>C</var>,
+        suivit de l’opération <var>B</var> et finalement l’opération <var>A</var>.
+      </p>
+      <table class="hidden"><tr>
+        <th>Changement 2</th><th></th>
+        <th>Changement 1</th><th></th>
+        <th>Conversion initiale</th><th></th>
+        <th>Opérations combinées</th>
+      </tr><tr>
+        <td style="vertical-align: middle"><xi:include href="../math/AxisSwapping2D.html"/></td>
+        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
+        <td style="vertical-align: middle"><xi:include href="../math/InverseAxisY.html"/></td>
+        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
+        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicSameAxisDirections.html"/></td>
+        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">=</td>
+        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicReverseOrderAndY.html"/></td>
+      </tr></table>
+      <p>
+        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 <abbr>SIS</abbr> 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.
+      </p>
+    </div>
+
+    <h4 id="AffineTransformAPI">Intégration avec les bibliothèques graphiques</h4>
+    <p>
+      A peu près toutes les bibliothèques graphiques supportent une forme de transformation de coordonnées,
+      souvent les <cite>transformations affines</cite> ou une légère généralisation.
+      Chaque bibliothèque défini son propre <abbr>API</abbr>.
+      Quelques exemples sont:
+    </p>
+    <table>
+      <caption>Implémentations des transformations affines dans des bibliothèques graphiques</caption>
+      <tr><th>Bibliothèque</th>                             <th>Implementation de la transformation</th>               <th>Dimensions</th></tr>
+      <tr><td>Java2D</td>                                   <td><code>java.awt.geom.AffineTransform</code></td>        <td>2</td></tr>
+      <tr><td>Java3D</td>                                   <td><code>javax.media.j3d.Transform3D</code></td>          <td>3</td></tr>
+      <tr><td>JavaFX</td>                                   <td><code>javafx.scene.transform.Affine</code></td>        <td>2 ou 3</td></tr>
+      <tr><td>Java Advanced Imaging (<abbr>JAI</abbr>)</td> <td><code>javax.media.jai.PerspectiveTransform</code></td> <td>2</td></tr>
+      <tr><td>Android</td>                                  <td><code>android.graphics.Matrix</code></td>              <td>2</td></tr>
+    </table>
+    <p>
+      Toutefois dans plusieurs cas, les transformations affines sont les seuls types d’opérations supportées par la bibliothèque graphique.
+      Apache <abbr>SIS</abbr> 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.
+      <abbr>SIS</abbr> a aussi besoin de transformer des points ayant un nombre arbitraire de dimensions,
+      alors que les <abbr>API</abbr> cités ci-haut restreignent leur usage à un nombre fixe de dimensions.
+      Pour ces raisons, <abbr>SIS</abbr> ne peut pas utiliser directement ces <abbr>API</abbr>.
+      <abbr>SIS</abbr> utilise plutôt une interface plus abstraite, <code>org.opengis.referencing.transform.MathTransform</code>.
+      Mais dans le cas particulier où la transformation est réellement affine, <abbr>SIS</abbr> 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é:
+    </p>
+    <pre>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.
+}</pre>
+    <p>
+      Toutefois <abbr>SIS</abbr> 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
+      <code>MathTransform</code> répond aux conditions qui devrait permettre un usage de Java2D.
+    </p>
+
+
     <h3 id="MatrixLibrary">Particularités d’une bibliothèque de calculs matriciels pour un <abbr>SIG</abbr></h3>
     <p>
       Les <abbr>SIG</abbr> font un usage intensif de matrices afin d’afficher leurs cartes ou transformer des coordonnées.

Modified: sis/site/trunk/book/fr/referencing.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/book/fr/referencing.html?rev=1753786&r1=1753785&r2=1753786&view=diff
==============================================================================
--- sis/site/trunk/book/fr/referencing.html (original)
+++ sis/site/trunk/book/fr/referencing.html Fri Jul 22 13:07:12 2016
@@ -410,139 +410,6 @@ public class MyApp {
 }</pre>
 
 
-    <h4 id="AffineTransform">Les transformations affines</h4>
-    <p>
-      Parmi les sortes d’opérations qu’un <abbr>SIG</abbr> doit effectuer sur les coordonnées spatiales,
-      les <cite>transformations affines</cite> 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 <cite>opérations linéaires</cite>.
-      Les transformations affines ne peuvent pas effectuer des opérations <cite>non-linéaires</cite>
-      telles que les projections cartographiques, mais couvrent néanmoins de nombreux autres cas:
-    </p>
-    <ul>
-      <li>Changer l’ordre des axes,        par exemple de (<var>latitude</var>, <var>longitude</var>) vers (<var>longitude</var>, <var>latitude</var>).</li>
-      <li>Changer la direction des axes,   par exemple l’axe des <var>y</var> qui pointe habituellement vers le bas dans les images.</li>
-      <li>Changer le méridien d’origine,   par exemple du méridien de <cite>Paris</cite> vers celui de <cite>Greenwich</cite>.</li>
-      <li>Changer le nombre de dimensions, par exemple passer des coordonnées 3D vers 2D en supprimant la hauteur.</li>
-      <li>Convertir des unités de mesures, par exemple convertir des pieds en mètres.</li>
-      <li>Convertir des coordonnées pixels en coordonnées géographiques,
-          par exemple la conversion exprimée dans les fichiers <code>.tfw</code> qui accompagnent certaines images <abbr>TIFF</abbr>.</li>
-      <li>Prendre en charge une petite partie des projections cartographiques,
-          par exemple les paramètres <cite>False Easting</cite>, <cite>False Northing</cite> et <cite>Scale factor</cite>.</li>
-    </ul>
-    <p>
-      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.
-    </p>
-
-    <div class="example">
-      <p><b>Exemple:</b>
-        supposons que nous disposons d’une image dont les coordonnées des pixels sont représentées par (<var>x</var>,<var>y</var>).
-        Supposons aussi que les contraintes suivantes sont respectées:
-      </p>
-      <ul>
-        <li>Il n’y a ni cisaillement, ni rotation, ni retournement de l’image.</li>
-        <li>Tous les pixels ont la même largeur en degrés de longitude.</li>
-        <li>Tous les pixels ont la même hauteur en degrés de latitude.</li>
-        <li>Les coordonnées des pixels commencent à (0,0) inclusivement.</li>
-      </ul>
-      <p>Alors la conversion des coordonnées pixels (<var>x</var>,<var>y</var>)
-        vers les coordonnées géographiques (<var>λ</var>,<var>φ</var>)
-        peut être représentée par les équations suivantes,
-        où <var>N</var><sub><var>x</var></sub> est la largeur
-        et <var>N</var><sub><var>y</var></sub> la hauteur de l’image en nombre de pixels.
-      </p><p>
-        <xi:include href="../math/PixelToGeographicTerms.html"/>
-      </p><p>
-        Les équations ci-dessus peuvent être représentées sous forme de matrices comme ci-dessous:
-      </p><p>
-      <xi:include href="../math/PixelToGeographic.html"/>
-      </p><p>
-        Dans ce cas particulier, les facteurs d’échelles <var>S</var> correspondent à la taille des pixels en degrés
-        et les termes de translations <var>T</var> 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 <var>S</var> et <var>T</var> sont les valeurs relativement simples données ci-dessus.
-        Ensuite la direction de l’axe des <var>y</var> 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:
-        <var>A</var>×<var>B</var>×<var>C</var> est équivalent à d’abord appliquer l’opération <var>C</var>,
-        suivit de l’opération <var>B</var> et finalement l’opération <var>A</var>.
-      </p>
-      <table class="hidden"><tr>
-        <th>Changement 2</th><th></th>
-        <th>Changement 1</th><th></th>
-        <th>Conversion initiale</th><th></th>
-        <th>Opérations combinées</th>
-      </tr><tr>
-        <td style="vertical-align: middle"><xi:include href="../math/AxisSwapping2D.html"/></td>
-        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
-        <td style="vertical-align: middle"><xi:include href="../math/InverseAxisY.html"/></td>
-        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
-        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicSameAxisDirections.html"/></td>
-        <td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">=</td>
-        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicReverseOrderAndY.html"/></td>
-      </tr></table>
-      <p>
-        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 <abbr>SIS</abbr> 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.
-      </p>
-    </div>
-
-    <h4 id="AffineTransformAPI">Intégration avec les bibliothèques graphiques</h4>
-    <p>
-      A peu près toutes les bibliothèques graphiques supportent une forme de transformation de coordonnées,
-      souvent les <cite>transformations affines</cite> ou une légère généralisation.
-      Chaque bibliothèque défini son propre <abbr>API</abbr>.
-      Quelques exemples sont:
-    </p>
-    <table>
-      <caption>Implémentations des transformations affines dans des bibliothèques graphiques</caption>
-      <tr><th>Bibliothèque</th>                             <th>Implementation de la transformation</th>               <th>Dimensions</th></tr>
-      <tr><td>Java2D</td>                                   <td><code>java.awt.geom.AffineTransform</code></td>        <td>2</td></tr>
-      <tr><td>Java3D</td>                                   <td><code>javax.media.j3d.Transform3D</code></td>          <td>3</td></tr>
-      <tr><td>JavaFX</td>                                   <td><code>javafx.scene.transform.Affine</code></td>        <td>2 ou 3</td></tr>
-      <tr><td>Java Advanced Imaging (<abbr>JAI</abbr>)</td> <td><code>javax.media.jai.PerspectiveTransform</code></td> <td>2</td></tr>
-      <tr><td>Android</td>                                  <td><code>android.graphics.Matrix</code></td>              <td>2</td></tr>
-    </table>
-    <p>
-      Toutefois dans plusieurs cas, les transformations affines sont les seuls types d’opérations supportées par la bibliothèque graphique.
-      Apache <abbr>SIS</abbr> 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.
-      <abbr>SIS</abbr> a aussi besoin de transformer des points ayant un nombre arbitraire de dimensions,
-      alors que les <abbr>API</abbr> cités ci-haut restreignent leur usage à un nombre fixe de dimensions.
-      Pour ces raisons, <abbr>SIS</abbr> ne peut pas utiliser directement ces <abbr>API</abbr>.
-      <abbr>SIS</abbr> utilise plutôt une interface plus abstraite, <code>org.opengis.referencing.transform.MathTransform</code>.
-      Mais dans le cas particulier où la transformation est réellement affine, <abbr>SIS</abbr> 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é:
-    </p>
-    <pre>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.
-}</pre>
-    <p>
-      Toutefois <abbr>SIS</abbr> 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
-      <code>MathTransform</code> répond aux conditions qui devrait permettre un usage de Java2D.
-    </p>
-
     <h3 id="TransformDerivative">Dérivées partielles des opérations</h3>
     <p>
       La section précédente indiquait comment calculer les coordonnées d’un point géographique dans une projection au choix.

Modified: sis/site/trunk/content/book/en/developer-guide.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/content/book/en/developer-guide.html?rev=1753786&r1=1753785&r2=1753786&view=diff
==============================================================================
--- sis/site/trunk/content/book/en/developer-guide.html (original)
+++ sis/site/trunk/content/book/en/developer-guide.html Fri Jul 22 13:07:12 2016
@@ -60,9 +60,7 @@ Partially translated by <i>Christina Hou
 <li><a href="#CRSFactory">Constructing programmatically</a></li>
 <li><a href="#CRS_UserCode">Adding new CRS definitions</a></li></ul></li>
 <li><a href="#CoordinateOperation">Coordinate operations</a><ul>
-<li><a href="#MathTransform">Executing an operation on coordinate values</a><ul>
-<li><a href="#AffineTransform">Affine transform</a></li>
-<li><a href="#AffineTransformAPI">Integration with graphical libraries</a></li></ul></li>
+<li><a href="#MathTransform">Executing an operation on coordinate values</a></li>
 <li><a href="#TransformDerivative">Partial derivatives of coordinate operations</a><ul>
 <li><a href="#DerivativeAndEnvelope">Transform derivatives applied to envelopes</a></li>
 <li><a href="#DerivativeAndRaster">Transform derivatives applied to rasters</a></li>
@@ -86,6 +84,8 @@ Partially translated by <i>Christina Hou
 <li><a href="#GeoAPI-validators">Instance validations</a></li>
 <li><a href="#GeoAPI-tests">Executing pre-defined tests</a></li></ul></li>
 <li><a href="#DesignNote">Design notes</a><ul>
+<li><a href="#AffineTransform">Affine transform</a><ul>
+<li><a href="#AffineTransformAPI">Integration with graphical libraries</a></li></ul></li>
 <li><a href="#MatrixLibrary">Specificities of a matrix library for GIS</a><ul>
 <li><a href="#NonSquareMatrix">What to do with non-square matrices (and why)</a></li>
 <li><a href="#MatrixLibrarySummary">Apache SIS matrix library</a></li></ul></li></ul></li></ul></li>
@@ -1381,9 +1381,7 @@ or the use of <code>isWhitespace(…)
 <li><a href="#CRSFactory">Constructing programmatically</a></li>
 <li><a href="#CRS_UserCode">Adding new CRS definitions</a></li></ul></li>
 <li><a href="#CoordinateOperation">Coordinate operations</a><ul>
-<li><a href="#MathTransform">Executing an operation on coordinate values</a><ul>
-<li><a href="#AffineTransform">Affine transform</a></li>
-<li><a href="#AffineTransformAPI">Integration with graphical libraries</a></li></ul></li>
+<li><a href="#MathTransform">Executing an operation on coordinate values</a></li>
 <li><a href="#TransformDerivative">Partial derivatives of coordinate operations</a><ul>
 <li><a href="#DerivativeAndEnvelope">Transform derivatives applied to envelopes</a></li>
 <li><a href="#DerivativeAndRaster">Transform derivatives applied to rasters</a></li>
@@ -1764,408 +1762,81 @@ Note that all geographic coordinates bel
 }</pre>
 
 
-<h4 id="AffineTransform"><span class="section-number">3.3.1.1.</span> Affine transform</h4>
-<p>
-Among the many kinds of operations performed by <abbr>GIS</abbr> softwares on spatial coordinates,
-<cite>affine transforms</cite>  are both relatively simple and very common.
-Affine transforms can represent any combination of scales, shears, flips, rotations and translations,
-which are <em>linear</em> operations.
-Affine transforms can not handle <em>non-linear</em> operations like map projections,
-but the affine transform capabilities nevertheless cover many other cases:
-</p>
-<ul>
-<li>Axis order changes,           for example from (<var>latitude</var>, <var>longitude</var>) to (<var>longitude</var>, <var>latitude</var>).</li>
-<li>Axis direction changes,       for example the <var>y</var> axis oriented toward down in images.</li>
-<li>Prime meridian rotations,     for example from <cite>Paris</cite> to <cite>Greenwich</cite> prime meridian.</li>
-<li>Dimensionality changes,       for example from 3-dimensional coordinates to 2-dimensional coordinates by dropping the height.</li>
-<li>Unit conversion,              for example from feet to metres.</li>
-<li>Pixel to geodetic coordinate, for example the conversion represented in the <code>.tfw</code> files associated to some <abbr>TIFF</abbr> images.</li>
-<li>Part of map projections,      for example the <cite>False Easting</cite>, <cite>False Northing</cite> and <cite>Scale factor</cite> parameters.</li>
-</ul>
+<h3 id="TransformDerivative"><span class="section-number">3.3.2.</span> Partial derivatives of coordinate operations</h3>
 <p>
-Affine transforms can be concatenated efficiently.
-No matter how many affine transforms are chained, the result can be represented by a single affine transform.
-This property is more easily seen when affine transforms are represented by matrices:
-in order to concatenate those operations, we only need to multiply those matrices.
-The “pixel to geographic coordinate conversions” case below gives an example.
-</p>
-
-<div class="example">
-<p><b>Example:</b>
-given an image with pixel coordinates represented by (<var>x</var>,<var>y</var>) tuples
-and given the following assumptions:
+<span style="color: red">TODO</span>
 </p>
-<ul>
-<li>There is no shear, no rotation and no flip.</li>
-<li>All pixels have the same width in degrees of longitude.</li>
-<li>All pixels have the same height in degrees of latitude.</li>
-<li>Pixel indices are positive integers starting at (0,0) inclusive.</li>
-</ul>
-<p>Then conversions from pixel coordinates (<var>x</var>,<var>y</var>)
-to geographic coordinates (<var>λ</var>,<var>φ</var>) can be represented by the following equations,
-where <var>N</var><sub><var>x</var></sub> is the image width and
-<var>N</var><sub><var>y</var></sub> the image height in number of pixels:
-</p><p>
-
 
 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
+<mi>P</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo>
+<mo>=</mo>
+<mfenced close="]" open="[">
 <mtable>
-<mtr>
-<mtd><mo>λ</mo></mtd>
-<mtd><mo>=</mo></mtd>
-<mtd><msub><mi>S</mi><mrow>λ</mrow></msub><mi>x</mi><mo>+</mo><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
-<mtd><mtext>        where        </mtext></mtd>
-<mtd><msub><mi>S</mi><mrow>λ</mrow></msub></mtd>
-<mtd><mo>=</mo></mtd>
-<mtd>
-<mfrac>
-<mrow>
-<msub><mi>λ</mi><mrow>max</mrow></msub><mo>-</mo>
-<msub><mi>λ</mi><mrow>min</mrow></msub>
-</mrow><mrow>
-<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
-</mrow>
-</mfrac>
-</mtd>
-<mtd><mtext>    and    </mtext></mtd>
-<mtd><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
-<mtd><mo>=</mo></mtd>
-<mtd><msub><mi>λ</mi><mrow>min</mrow></msub></mtd>
-</mtr>
-<mtr>
-<mtd><mo>φ</mo></mtd>
-<mtd><mo>=</mo></mtd>
-<mtd><msub><mi>S</mi><mrow>φ</mrow></msub><mi>y</mi><mo>+</mo><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
-<mtd><mtext>        where        </mtext></mtd>
-<mtd><msub><mi>S</mi><mrow>φ</mrow></msub></mtd>
-<mtd><mo>=</mo></mtd>
-<mtd>
-<mfrac>
-<mrow>
-<msub><mi>φ</mi><mrow>max</mrow></msub><mo>-</mo>
-<msub><mi>φ</mi><mrow>min</mrow></msub>
-</mrow><mrow>
-<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
-</mrow>
-</mfrac>
-</mtd>
-<mtd><mtext>    and    </mtext></mtd>
-<mtd><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
-<mtd><mo>=</mo></mtd>
-<mtd><msub><mi>φ</mi><mrow>min</mrow></msub></mtd>
-</mtr>
+<mtr><mtd><mi>x</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mtd></mtr>
+<mtr><mtd><mi>y</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mtd></mtr>
 </mtable>
+</mfenced>
 </math>
-</p><p>
-Above equations can be represented in matrix form as below:
-</p><p>
 
+<p>The map projection partial derivate at this point can be represented by the Jacobian matrix:</p>
 
 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
-<mfenced close="]" open="[">
-<mtable>
-<mtr><mtd><mi>λ</mi></mtd></mtr>
-<mtr><mtd><mi>φ</mi></mtd></mtr>
-<mtr><mtd><mn>1</mn></mtd></mtr>
-</mtable>
-</mfenced>
+<msup><mi>P</mi><mo>′</mo></msup><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo>
+<mo>=</mo>
+<msub><mi>JAC</mi><mrow><mi>P</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow></msub>
 <mo>=</mo>
 <mfenced close="]" open="[">
 <mtable>
 <mtr>
-<mtd><msub><mi>S</mi><mrow>λ</mrow></msub></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
-</mtr>
-<mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><msub><mi>S</mi><mrow>φ</mrow></msub></mtd>
-<mtd><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
+<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
+<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
 </mtr>
 <mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>1</mn></mtd>
+<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
+<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
 </mtr>
 </mtable>
 </mfenced>
-<mo>×</mo>
-<mfenced close="]" open="[">
-<mtable>
-<mtr><mtd><mi>x</mi></mtd></mtr>
-<mtr><mtd><mi>y</mi></mtd></mtr>
-<mtr><mtd><mn>1</mn></mtd></mtr>
-</mtable>
-</mfenced>
 </math>
-</p><p>
-In this particular case, scale factors <var>S</var> are the pixel size in degrees
-and translation terms <var>T</var> are the geographic coordinate of an image corner
-(not necessarily the lower-left corner if some axes have been flipped).
-This straightforward interpretation holds because of above-cited assumptions, but
-matrix coefficients become more complex if the image has shear or rotation
-or if pixel coordinates do not start at (0,0).
-However it is not necessary to use more complex equations for supporting more generic cases.
-The following example starts with an “initial conversion” matrix
-where the <var>S</var> and <var>T</var> terms are set to the most straightforward values.
-Then the <var>y</var> axis direction is reversed for matching the most common convention in image coordinate systems (change 1),
-and axis are swapped resulting in latitude before longitude (change 2).
-Note that when affine transform concatenations are written as matrix multiplications, operations are ordered from right to left:
-<var>A</var>×<var>B</var>×<var>C</var> is equivalent to first applying operation <var>C</var>,
-then operation <var>B</var> and finally operation <var>A</var>.
+
+<p>
+<span style="color: red">TODO</span>
 </p>
+
 <table class="hidden"><tr>
-<th>Change 2</th><th/>
-<th>Change 1</th><th/>
-<th>Initial conversion</th><th/>
-<th>Concatenated operation</th>
-</tr><tr>
-<td style="vertical-align: middle">
+<td><img alt="Exemple de dérivées d’une projection cartographique" src="../images/Derivatives.png" style="border: solid 1px"/></td>
+<td style="padding-left: 30px; vertical-align: middle">
+<p>where vectors are related to the matrix by:</p>
 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
+<mtable><mtr>
+<mtd>
+<mover><mi>U</mi><mo>→</mo></mover><mo>=</mo>
 <mfenced close="]" open="[">
 <mtable>
 <mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>1</mn></mtd>
-<mtd><mn>0</mn></mtd>
-</mtr>
-<mtr>
-<mtd><mn>1</mn></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>0</mn></mtd>
-</mtr>
-<mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>1</mn></mtd>
-</mtr>
-</mtable>
-</mfenced>
-</math>
-</td>
-<td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
-<td style="vertical-align: middle">
-<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
-<mfenced close="]" open="[">
-<mtable>
-<mtr>
-<mtd><mn>1</mn></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>0</mn></mtd>
-</mtr>
-<mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>-1</mn></mtd>
-<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
+<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
 </mtr>
 <mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>1</mn></mtd>
+<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
 </mtr>
 </mtable>
 </mfenced>
-</math>
-</td>
-<td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
-<td style="vertical-align: middle">
-<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
+</mtd>
+<mtd><mtext>et</mtext></mtd>
+<mtd>
+<mover><mi>V</mi><mo>→</mo></mover><mo>=</mo>
 <mfenced close="]" open="[">
 <mtable>
 <mtr>
-<mtd><mfrac>
-<mrow>
-<msub><mi>λ</mi><mrow>max</mrow></msub><mo>-</mo>
-<msub><mi>λ</mi><mrow>min</mrow></msub>
-</mrow><mrow>
-<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
-</mrow>
-</mfrac></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><msub><mi>λ</mi><mrow>min</mrow></msub></mtd>
-</mtr>
-<mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mfrac>
-<mrow>
-<msub><mi>φ</mi><mrow>max</mrow></msub><mo>-</mo>
-<msub><mi>φ</mi><mrow>min</mrow></msub>
-</mrow><mrow>
-<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
-</mrow>
-</mfrac></mtd>
-<mtd><msub><mi>φ</mi><mrow>min</mrow></msub></mtd>
+<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
 </mtr>
 <mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>1</mn></mtd>
+<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
 </mtr>
 </mtable>
 </mfenced>
-</math>
-</td>
-<td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">=</td>
-<td style="vertical-align: middle">
-<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
-<mfenced close="]" open="[">
-<mtable>
-<mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mo>-</mo><mfrac>
-<mrow>
-<msub><mi>φ</mi><mrow>max</mrow></msub><mo>-</mo>
-<msub><mi>φ</mi><mrow>min</mrow></msub>
-</mrow><mrow>
-<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
-</mrow>
-</mfrac></mtd>
-<mtd><msub><mi>φ</mi><mrow>max</mrow></msub></mtd>
-</mtr>
-<mtr>
-<mtd><mfrac>
-<mrow>
-<msub><mi>λ</mi><mrow>max</mrow></msub><mo>-</mo>
-<msub><mi>λ</mi><mrow>min</mrow></msub>
-</mrow><mrow>
-<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
-</mrow>
-</mfrac></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><msub><mi>λ</mi><mrow>min</mrow></msub></mtd>
-</mtr>
-<mtr>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>0</mn></mtd>
-<mtd><mn>1</mn></mtd>
-</mtr>
-</mtable>
-</mfenced>
-</math>
-</td>
-</tr></table>
-<p>
-A key principle is that there is no need to write Java code dedicated to above kinds of axis changes.
-Those operations, and many other, can be handled by matrix algebra.
-This approach makes easier to write generic code and improves performance.
-Apache <abbr title="Spatial Information System">SIS</abbr> follows this principle by using affine transforms for every operations
-that can be performed by such transform.
-For instance there is no code dedicated to changing order of ordinate values in a coordinate.
-</p>
-</div>
-
-<h4 id="AffineTransformAPI"><span class="section-number">3.3.1.2.</span> Integration with graphical libraries</h4>
-<p>
-About all graphical libraries support some kind of coordinate operations, usually as <cite>affine transforms</cite>
-or a slight generalization like <cite>perspective transforms</cite>.
-Each library defines its own <abbr title="Application Programming Interface">API</abbr>. Some examples are listed below:
-</p>
-<table>
-<caption>Affine transform implementations in graphical libraries</caption>
-<tr><th>Library</th>                                  <th>Transform implementation</th>                          <th>Dimensions</th></tr>
-<tr><td>Java2D</td>                                   <td><code>java.awt.geom.AffineTransform</code></td>        <td>2</td></tr>
-<tr><td>Java3D</td>                                   <td><code>javax.media.j3d.Transform3D</code></td>          <td>3</td></tr>
-<tr><td>JavaFX</td>                                   <td><code>javafx.scene.transform.Affine</code></td>        <td>2 or 3</td></tr>
-<tr><td>Java Advanced Imaging (<abbr>JAI</abbr>)</td> <td><code>javax.media.jai.PerspectiveTransform</code></td> <td>2</td></tr>
-<tr><td>Android</td>                                  <td><code>android.graphics.Matrix</code></td>              <td>2</td></tr>
-</table>
-<p>
-However in many cases, affine or perspective transforms are the only kind of coordinate operations supported by the graphical library.
-Apache <abbr title="Spatial Information System">SIS</abbr> needs to handle a wider range of operations, in which affine transforms are only special cases.
-In particular most map projections and datum shifts can not be represented by affine transforms.
-<abbr>SIS</abbr> also needs to support arbitrary number of dimensions,
-while above-cited <abbr>API</abbr> restrict the use to a fixed number of dimensions.
-For those reasons <abbr>SIS</abbr> can not use directly the above-cited <abbr>API</abbr>.
-Instead, <abbr>SIS</abbr> uses the more abstract <code class="GeoAPI">org.opengis.referencing.transform.MathTransform</code> interface.
-But in the special case where the transform is actually affine, <abbr>SIS</abbr> may try to use an existing implementation,
-in particular Java2D. The following Java code can be used in situations where the Java2D object is desired:
-</p>
-<pre><code class="GeoAPI">MathTransform</code> mt = ...;    <code class="comment">// Any math transform created by Apache SIS.
-</code><b>if</b> (mt <b>instanceof</b> AffineTransform) {
-    AffineTransform at = (AffineTransform) mt;
-    <code class="comment">// Use Java2D API from here.
-</code>}</pre>
-<p>
-Apache <abbr>SIS</abbr> uses Java2D on a <em>best effort</em> basis only.
-The above cast is not guaranteed to succeed,
-even when the <code class="GeoAPI">MathTransform</code> meets the requirements allowing Java2D usage.
-</p>
-
-<h3 id="TransformDerivative"><span class="section-number">3.3.2.</span> Partial derivatives of coordinate operations</h3>
-<p>
-<span style="color: red">TODO</span>
-</p>
-
-<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
-<mi>P</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo>
-<mo>=</mo>
-<mfenced close="]" open="[">
-<mtable>
-<mtr><mtd><mi>x</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mtd></mtr>
-<mtr><mtd><mi>y</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mtd></mtr>
-</mtable>
-</mfenced>
-</math>
-
-<p>The map projection partial derivate at this point can be represented by the Jacobian matrix:</p>
-
-<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
-<msup><mi>P</mi><mo>′</mo></msup><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo>
-<mo>=</mo>
-<msub><mi>JAC</mi><mrow><mi>P</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow></msub>
-<mo>=</mo>
-<mfenced close="]" open="[">
-<mtable>
-<mtr>
-<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
-<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
-</mtr>
-<mtr>
-<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
-<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi><mo>(</mo><mi>λ</mi><mo>,</mo><mi>φ</mi><mo>)</mo></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
-</mtr>
-</mtable>
-</mfenced>
-</math>
-
-<p>
-<span style="color: red">TODO</span>
-</p>
-
-<table class="hidden"><tr>
-<td><img alt="Exemple de dérivées d’une projection cartographique" src="../images/Derivatives.png" style="border: solid 1px"/></td>
-<td style="padding-left: 30px; vertical-align: middle">
-<p>where vectors are related to the matrix by:</p>
-<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
-<mtable><mtr>
-<mtd>
-<mover><mi>U</mi><mo>→</mo></mover><mo>=</mo>
-<mfenced close="]" open="[">
-<mtable>
-<mtr>
-<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
-</mtr>
-<mtr>
-<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi></mrow><mrow><mo>∂</mo><mi>λ</mi></mrow></mfrac></mtd>
-</mtr>
-</mtable>
-</mfenced>
-</mtd>
-<mtd><mtext>et</mtext></mtd>
-<mtd>
-<mover><mi>V</mi><mo>→</mo></mover><mo>=</mo>
-<mfenced close="]" open="[">
-<mtable>
-<mtr>
-<mtd><mfrac><mrow><mo>∂</mo><mi>x</mi></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
-</mtr>
-<mtr>
-<mtd><mfrac><mrow><mo>∂</mo><mi>y</mi></mrow><mrow><mo>∂</mo><mi>φ</mi></mrow></mfrac></mtd>
-</mtr>
-</mtable>
-</mfenced>
-</mtd>
-</mtr></mtable>
+</mtd>
+</mtr></mtable>
 </math>
 </td>
 </tr></table>
@@ -2874,6 +2545,8 @@ But when a <code class="OGC">nilReason</
 <li><a href="#GeoAPI-validators">Instance validations</a></li>
 <li><a href="#GeoAPI-tests">Executing pre-defined tests</a></li></ul></li>
 <li><a href="#DesignNote">Design notes</a><ul>
+<li><a href="#AffineTransform">Affine transform</a><ul>
+<li><a href="#AffineTransformAPI">Integration with graphical libraries</a></li></ul></li>
 <li><a href="#MatrixLibrary">Specificities of a matrix library for GIS</a><ul>
 <li><a href="#NonSquareMatrix">What to do with non-square matrices (and why)</a></li>
 <li><a href="#MatrixLibrarySummary">Apache SIS matrix library</a></li></ul></li></ul></li></ul></nav>
@@ -3219,7 +2892,336 @@ However, this example adds a supplementa
 <h2 id="DesignNote"><span class="section-number">7.3.</span> Design notes</h2>
 <p>Following chapters explain the rational behind some implementation choices done in Apache <abbr title="Spatial Information System">SIS</abbr>.</p>
 
-<h3 id="MatrixLibrary"><span class="section-number">7.3.1.</span> Specificities of a matrix library for <abbr>GIS</abbr></h3>
+
+<h3 id="AffineTransform"><span class="section-number">7.3.1.</span> Affine transform</h3>
+<p>
+Among the many kinds of operations performed by <abbr>GIS</abbr> softwares on spatial coordinates,
+<cite>affine transforms</cite>  are both relatively simple and very common.
+Affine transforms can represent any combination of scales, shears, flips, rotations and translations,
+which are <em>linear</em> operations.
+Affine transforms can not handle <em>non-linear</em> operations like map projections,
+but the affine transform capabilities nevertheless cover many other cases:
+</p>
+<ul>
+<li>Axis order changes,           for example from (<var>latitude</var>, <var>longitude</var>) to (<var>longitude</var>, <var>latitude</var>).</li>
+<li>Axis direction changes,       for example the <var>y</var> axis oriented toward down in images.</li>
+<li>Prime meridian rotations,     for example from <cite>Paris</cite> to <cite>Greenwich</cite> prime meridian.</li>
+<li>Dimensionality changes,       for example from 3-dimensional coordinates to 2-dimensional coordinates by dropping the height.</li>
+<li>Unit conversion,              for example from feet to metres.</li>
+<li>Pixel to geodetic coordinate, for example the conversion represented in the <code>.tfw</code> files associated to some <abbr>TIFF</abbr> images.</li>
+<li>Part of map projections,      for example the <cite>False Easting</cite>, <cite>False Northing</cite> and <cite>Scale factor</cite> parameters.</li>
+</ul>
+<p>
+Affine transforms can be concatenated efficiently.
+No matter how many affine transforms are chained, the result can be represented by a single affine transform.
+This property is more easily seen when affine transforms are represented by matrices:
+in order to concatenate those operations, we only need to multiply those matrices.
+The “pixel to geographic coordinate conversions” case below gives an example.
+</p>
+
+<div class="example">
+<p><b>Example:</b>
+given an image with pixel coordinates represented by (<var>x</var>,<var>y</var>) tuples
+and given the following assumptions:
+</p>
+<ul>
+<li>There is no shear, no rotation and no flip.</li>
+<li>All pixels have the same width in degrees of longitude.</li>
+<li>All pixels have the same height in degrees of latitude.</li>
+<li>Pixel indices are positive integers starting at (0,0) inclusive.</li>
+</ul>
+<p>Then conversions from pixel coordinates (<var>x</var>,<var>y</var>)
+to geographic coordinates (<var>λ</var>,<var>φ</var>) can be represented by the following equations,
+where <var>N</var><sub><var>x</var></sub> is the image width and
+<var>N</var><sub><var>y</var></sub> the image height in number of pixels:
+</p><p>
+
+
+<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
+<mtable>
+<mtr>
+<mtd><mo>λ</mo></mtd>
+<mtd><mo>=</mo></mtd>
+<mtd><msub><mi>S</mi><mrow>λ</mrow></msub><mi>x</mi><mo>+</mo><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
+<mtd><mtext>        where        </mtext></mtd>
+<mtd><msub><mi>S</mi><mrow>λ</mrow></msub></mtd>
+<mtd><mo>=</mo></mtd>
+<mtd>
+<mfrac>
+<mrow>
+<msub><mi>λ</mi><mrow>max</mrow></msub><mo>-</mo>
+<msub><mi>λ</mi><mrow>min</mrow></msub>
+</mrow><mrow>
+<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
+</mrow>
+</mfrac>
+</mtd>
+<mtd><mtext>    and    </mtext></mtd>
+<mtd><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
+<mtd><mo>=</mo></mtd>
+<mtd><msub><mi>λ</mi><mrow>min</mrow></msub></mtd>
+</mtr>
+<mtr>
+<mtd><mo>φ</mo></mtd>
+<mtd><mo>=</mo></mtd>
+<mtd><msub><mi>S</mi><mrow>φ</mrow></msub><mi>y</mi><mo>+</mo><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
+<mtd><mtext>        where        </mtext></mtd>
+<mtd><msub><mi>S</mi><mrow>φ</mrow></msub></mtd>
+<mtd><mo>=</mo></mtd>
+<mtd>
+<mfrac>
+<mrow>
+<msub><mi>φ</mi><mrow>max</mrow></msub><mo>-</mo>
+<msub><mi>φ</mi><mrow>min</mrow></msub>
+</mrow><mrow>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
+</mrow>
+</mfrac>
+</mtd>
+<mtd><mtext>    and    </mtext></mtd>
+<mtd><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
+<mtd><mo>=</mo></mtd>
+<mtd><msub><mi>φ</mi><mrow>min</mrow></msub></mtd>
+</mtr>
+</mtable>
+</math>
+</p><p>
+Above equations can be represented in matrix form as below:
+</p><p>
+
+
+<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
+<mfenced close="]" open="[">
+<mtable>
+<mtr><mtd><mi>λ</mi></mtd></mtr>
+<mtr><mtd><mi>φ</mi></mtd></mtr>
+<mtr><mtd><mn>1</mn></mtd></mtr>
+</mtable>
+</mfenced>
+<mo>=</mo>
+<mfenced close="]" open="[">
+<mtable>
+<mtr>
+<mtd><msub><mi>S</mi><mrow>λ</mrow></msub></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><msub><mi>S</mi><mrow>φ</mrow></msub></mtd>
+<mtd><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>1</mn></mtd>
+</mtr>
+</mtable>
+</mfenced>
+<mo>×</mo>
+<mfenced close="]" open="[">
+<mtable>
+<mtr><mtd><mi>x</mi></mtd></mtr>
+<mtr><mtd><mi>y</mi></mtd></mtr>
+<mtr><mtd><mn>1</mn></mtd></mtr>
+</mtable>
+</mfenced>
+</math>
+</p><p>
+In this particular case, scale factors <var>S</var> are the pixel size in degrees
+and translation terms <var>T</var> are the geographic coordinate of an image corner
+(not necessarily the lower-left corner if some axes have been flipped).
+This straightforward interpretation holds because of above-cited assumptions, but
+matrix coefficients become more complex if the image has shear or rotation
+or if pixel coordinates do not start at (0,0).
+However it is not necessary to use more complex equations for supporting more generic cases.
+The following example starts with an “initial conversion” matrix
+where the <var>S</var> and <var>T</var> terms are set to the most straightforward values.
+Then the <var>y</var> axis direction is reversed for matching the most common convention in image coordinate systems (change 1),
+and axis are swapped resulting in latitude before longitude (change 2).
+Note that when affine transform concatenations are written as matrix multiplications, operations are ordered from right to left:
+<var>A</var>×<var>B</var>×<var>C</var> is equivalent to first applying operation <var>C</var>,
+then operation <var>B</var> and finally operation <var>A</var>.
+</p>
+<table class="hidden"><tr>
+<th>Change 2</th><th/>
+<th>Change 1</th><th/>
+<th>Initial conversion</th><th/>
+<th>Concatenated operation</th>
+</tr><tr>
+<td style="vertical-align: middle">
+<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required" display="block">
+<mfenced close="]" open="[">
+<mtable>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>1</mn></mtd>
+<mtd><mn>0</mn></mtd>
+</mtr>
+<mtr>
+<mtd><mn>1</mn></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>0</mn></mtd>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>1</mn></mtd>
+</mtr>
+</mtable>
+</mfenced>
+</math>
+</td>
+<td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
+<td style="vertical-align: middle">
+<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
+<mfenced close="]" open="[">
+<mtable>
+<mtr>
+<mtd><mn>1</mn></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>0</mn></mtd>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>-1</mn></mtd>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>1</mn></mtd>
+</mtr>
+</mtable>
+</mfenced>
+</math>
+</td>
+<td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">×</td>
+<td style="vertical-align: middle">
+<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
+<mfenced close="]" open="[">
+<mtable>
+<mtr>
+<mtd><mfrac>
+<mrow>
+<msub><mi>λ</mi><mrow>max</mrow></msub><mo>-</mo>
+<msub><mi>λ</mi><mrow>min</mrow></msub>
+</mrow><mrow>
+<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
+</mrow>
+</mfrac></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><msub><mi>λ</mi><mrow>min</mrow></msub></mtd>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mfrac>
+<mrow>
+<msub><mi>φ</mi><mrow>max</mrow></msub><mo>-</mo>
+<msub><mi>φ</mi><mrow>min</mrow></msub>
+</mrow><mrow>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
+</mrow>
+</mfrac></mtd>
+<mtd><msub><mi>φ</mi><mrow>min</mrow></msub></mtd>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>1</mn></mtd>
+</mtr>
+</mtable>
+</mfenced>
+</math>
+</td>
+<td style="vertical-align: middle; padding-left: 15px; padding-right: 15px">=</td>
+<td style="vertical-align: middle">
+<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
+<mfenced close="]" open="[">
+<mtable>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mo>-</mo><mfrac>
+<mrow>
+<msub><mi>φ</mi><mrow>max</mrow></msub><mo>-</mo>
+<msub><mi>φ</mi><mrow>min</mrow></msub>
+</mrow><mrow>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
+</mrow>
+</mfrac></mtd>
+<mtd><msub><mi>φ</mi><mrow>max</mrow></msub></mtd>
+</mtr>
+<mtr>
+<mtd><mfrac>
+<mrow>
+<msub><mi>λ</mi><mrow>max</mrow></msub><mo>-</mo>
+<msub><mi>λ</mi><mrow>min</mrow></msub>
+</mrow><mrow>
+<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
+</mrow>
+</mfrac></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><msub><mi>λ</mi><mrow>min</mrow></msub></mtd>
+</mtr>
+<mtr>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>0</mn></mtd>
+<mtd><mn>1</mn></mtd>
+</mtr>
+</mtable>
+</mfenced>
+</math>
+</td>
+</tr></table>
+<p>
+A key principle is that there is no need to write Java code dedicated to above kinds of axis changes.
+Those operations, and many other, can be handled by matrix algebra.
+This approach makes easier to write generic code and improves performance.
+Apache <abbr title="Spatial Information System">SIS</abbr> follows this principle by using affine transforms for every operations
+that can be performed by such transform.
+For instance there is no code dedicated to changing order of ordinate values in a coordinate.
+</p>
+</div>
+
+<h4 id="AffineTransformAPI"><span class="section-number">7.3.1.1.</span> Integration with graphical libraries</h4>
+<p>
+About all graphical libraries support some kind of coordinate operations, usually as <cite>affine transforms</cite>
+or a slight generalization like <cite>perspective transforms</cite>.
+Each library defines its own <abbr title="Application Programming Interface">API</abbr>. Some examples are listed below:
+</p>
+<table>
+<caption>Affine transform implementations in graphical libraries</caption>
+<tr><th>Library</th>                                  <th>Transform implementation</th>                          <th>Dimensions</th></tr>
+<tr><td>Java2D</td>                                   <td><code>java.awt.geom.AffineTransform</code></td>        <td>2</td></tr>
+<tr><td>Java3D</td>                                   <td><code>javax.media.j3d.Transform3D</code></td>          <td>3</td></tr>
+<tr><td>JavaFX</td>                                   <td><code>javafx.scene.transform.Affine</code></td>        <td>2 or 3</td></tr>
+<tr><td>Java Advanced Imaging (<abbr>JAI</abbr>)</td> <td><code>javax.media.jai.PerspectiveTransform</code></td> <td>2</td></tr>
+<tr><td>Android</td>                                  <td><code>android.graphics.Matrix</code></td>              <td>2</td></tr>
+</table>
+<p>
+However in many cases, affine or perspective transforms are the only kind of coordinate operations supported by the graphical library.
+Apache <abbr title="Spatial Information System">SIS</abbr> needs to handle a wider range of operations, in which affine transforms are only special cases.
+In particular most map projections and datum shifts can not be represented by affine transforms.
+<abbr>SIS</abbr> also needs to support arbitrary number of dimensions,
+while above-cited <abbr>API</abbr> restrict the use to a fixed number of dimensions.
+For those reasons <abbr>SIS</abbr> can not use directly the above-cited <abbr>API</abbr>.
+Instead, <abbr>SIS</abbr> uses the more abstract <code class="GeoAPI">org.opengis.referencing.transform.MathTransform</code> interface.
+But in the special case where the transform is actually affine, <abbr>SIS</abbr> may try to use an existing implementation,
+in particular Java2D. The following Java code can be used in situations where the Java2D object is desired:
+</p>
+<pre><code class="GeoAPI">MathTransform</code> mt = ...;    <code class="comment">// Any math transform created by Apache SIS.
+</code><b>if</b> (mt <b>instanceof</b> AffineTransform) {
+    AffineTransform at = (AffineTransform) mt;
+    <code class="comment">// Use Java2D API from here.
+</code>}</pre>
+<p>
+Apache <abbr>SIS</abbr> uses Java2D on a <em>best effort</em> basis only.
+The above cast is not guaranteed to succeed,
+even when the <code class="GeoAPI">MathTransform</code> meets the requirements allowing Java2D usage.
+</p>
+
+
+<h3 id="MatrixLibrary"><span class="section-number">7.3.2.</span> Specificities of a matrix library for <abbr>GIS</abbr></h3>
 <p>
 <abbr>GIS</abbr> make an extensive usage of matrices for displaying maps or for transforming coordinates.
 There is many excellent open source or commercial matrix libraries available.
@@ -3264,7 +3266,7 @@ This implementation addresses the accura
 at the cost of performance in a phase (transform <em>preparation</em>) where performance is not considered critical.
 </p>
 
-<h4 id="NonSquareMatrix"><span class="section-number">7.3.1.1.</span> What to do with non-square matrices (and why)</h4>
+<h4 id="NonSquareMatrix"><span class="section-number">7.3.2.1.</span> What to do with non-square matrices (and why)</h4>
 <p>
 Apache <abbr title="Spatial Information System">SIS</abbr> often needs to inverse matrices, in order to perform a coordinate operation in reverse direction.
 Matrix inversions are typically performed on square matrices, but <abbr>SIS</abbr> also needs to inverse non-square matrices.
@@ -3363,7 +3365,7 @@ Consequently in over-determined systems
 but in case of success the resulting coordinate operation is guaranteed to be exact (ignoring rounding errors).
 </p>
 
-<h4 id="MatrixLibrarySummary"><span class="section-number">7.3.1.2.</span> Apache <abbr title="Spatial Information System">SIS</abbr> matrix library</h4>
+<h4 id="MatrixLibrarySummary"><span class="section-number">7.3.2.2.</span> Apache <abbr title="Spatial Information System">SIS</abbr> matrix library</h4>
 <p>
 In summary, Apache <abbr>SIS</abbr> provides its own matrix library for the following reasons:
 </p>



Mime
View raw message