sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1746518 [1/6] - in /sis/site/trunk: book/en/ book/fr/ book/math/ content/book/en/ content/book/fr/
Date Thu, 02 Jun 2016 04:57:06 GMT
Author: desruisseaux
Date: Thu Jun  2 04:57:06 2016
New Revision: 1746518

URL: http://svn.apache.org/viewvc?rev=1746518&view=rev
Log:
Edit and translate the chapter about affine transforms.

Added:
    sis/site/trunk/book/math/AxisSwapping2D.html
      - copied, changed from r1745833, sis/site/trunk/book/fr/referencing.html
    sis/site/trunk/book/math/InverseAxisY.html
      - copied, changed from r1745833, sis/site/trunk/book/fr/referencing.html
    sis/site/trunk/book/math/PixelToGeographicReverseOrderAndY.html
      - copied, changed from r1745833, sis/site/trunk/book/fr/referencing.html
    sis/site/trunk/book/math/PixelToGeographicSameAxisDirections.html
      - copied, changed from r1745833, sis/site/trunk/book/fr/referencing.html
    sis/site/trunk/book/math/PixelToGeographicTerms.html
      - copied, changed from r1745833, sis/site/trunk/book/math/PixelToGeographic.html
Modified:
    sis/site/trunk/book/en/body.html
    sis/site/trunk/book/en/referencing.html
    sis/site/trunk/book/fr/referencing.html
    sis/site/trunk/book/math/PixelToGeographic.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/body.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/book/en/body.html?rev=1746518&r1=1746517&r2=1746518&view=diff
==============================================================================
--- sis/site/trunk/book/en/body.html (original)
+++ sis/site/trunk/book/en/body.html Thu Jun  2 04:57:06 2016
@@ -32,7 +32,7 @@
     <p style="margin-top: 30pt"><span style="font-size: 30pt; font-weight: 900">Introduction
to Apache SIS®</span></p>
     <p style="margin-bottom: 20pt">(English | <a href="../fr/developer-guide.html">Français</a>)</p>
     <p><i>Martin Desruisseaux</i><br/>
-    <i>Christina Hough</i></p>
+    Partially translated by <i>Christina Hough</i></p>
     <p>This work is licensed under the Apache 2 license.</p>
     <hr/>
 

Modified: sis/site/trunk/book/en/referencing.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/book/en/referencing.html?rev=1746518&r1=1746517&r2=1746518&view=diff
==============================================================================
--- sis/site/trunk/book/en/referencing.html (original)
+++ sis/site/trunk/book/en/referencing.html Thu Jun  2 04:57:06 2016
@@ -284,190 +284,126 @@
     <h4 id="AffineTransform">Affine transform</h4>
     <p>
       Among the many kinds of operations performed by <abbr>GIS</abbr> softwares
on spatial coordinates,
-      <cite>linear operations</cite> are both simple and very common.
-      Linear operations are combinations of only additions and some multiplications.
-      Linear operations do not include map projections, which are more complex, but cover
many other cases:
+      <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>Change axis order, for example from (<var>latitude</var>, <var>longitude</var>)
to (<var>longitude</var>, <var>latitude</var>).</li>
-      <li>Change axis direction (for example the <var>y</var> axis in images
is often oriented toward down).</li>
-      <li>Change the prime meridian (for example from <cite>Paris</cite>
to <cite>Greenwich</cite>).</li>
-      <li>Change the number of dimensions (for example from 3-dimensional coordinates
to 2-dimensional coordinates).</li>
-      <li>Convert units of measurement (for example convert feet to metres).</li>
-      <li>Convert pixel coordinates in an image to geodetic coordinates
-          (for example the conversion represented in the <code>.tfw</code> files
associated to some <abbr>TIFF</abbr> images).</li>
-      <li>Handle a small part of map projection task
-          (for example the <cite>False Easting</cite>, <cite>False Northing</cite>
and <cite>Scale factor</cite> parameters).</li>
-      <li>Apply rotations, translations, scales and shears (part of <cite>affines</cite>
transforms).</li>
+      <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>
-      Linear operations can be concatenated efficiently.
-      No matter how many linear operations are chained, the result can be represented by
a single linear operation.
-      This property is more easily seen when linear operations are represented by matrices:
-      in order to concatenate those operations, we only need to multiply the matrices.
+      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>
-      give an image with pixel coordinates represented by (<var>i</var>,<var>j</var>)
coordinates,
-      assuming that all pixels have the same size in longitude and latitude degrees,
-      and assuming there there is no rotation, then conversion from
-      (<var>i</var>,<var>j</var>) pixel coordinates to (<var>λ</var>,<var>φ</var>)
geographic coordinates
-      can be represented by the following matrices:</p>
 
-      <table class="hidden"><tr><td>
-        <xi:include href="../math/PixelToGeographic.html"/>
-      </td><td style="vertical-align: middle; padding-left: 30px">
-        where
-      </td><td style="vertical-align: middle">
-        <ul>
-          <li><var>S</var> is a scale factor which, in this example, is
equals to the pixel size in degrees.</li>
-          <li><var>H</var> is a shear factor, usually equals to zero except
if the image is rotated.</li>
-          <li><var>T</var> is a translation term which, in this example,
is equals to the geographic coordinate of an image corner.</li>
-        </ul>
-      </td></tr></table>
-      <p>
-        <span style="color: red">TODO</span>
+    <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>Original conversion</th><th></th>
-        <th>Modified conversion</th>
+        <th>Initial conversion</th><th></th>
+        <th>Concatenated operation</th>
       </tr><tr>
-        <td style="vertical-align: middle">
-          <math xmlns="http://www.w3.org/1998/Math/MathML" display="block" alttext="MathML
capable browser required">
-            <mfenced open="[" close="]">
-              <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"><xi:include href="../math/AxisSwapping2D.html"/></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 open="[" close="]">
-              <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>
-                  <mtd><mo>(</mo><msub><mi>j</mi><mrow>max</mrow></msub><mo>-</mo>
-                                 <msub><mi>j</mi><mrow>min</mrow></msub><mo>)</mo></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"><xi:include href="../math/InverseAxisY.html"/></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 open="[" close="]">
-              <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>i</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>i</mi><mrow>min</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>j</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>j</mi><mrow>min</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"><xi:include href="../math/PixelToGeographicSameAxisDirections.html"/></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 open="[" close="]">
-              <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>j</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>j</mi><mrow>min</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>i</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>i</mi><mrow>min</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>
+        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicReverseOrderAndY.html"/></td>
       </tr></table>
       <p>
-        <span style="color: red">TODO</span>
+        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>
 
-    <p style="color: red">TODO</p>
+    <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>
+      However <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>

Modified: sis/site/trunk/book/fr/referencing.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/book/fr/referencing.html?rev=1746518&r1=1746517&r2=1746518&view=diff
==============================================================================
--- sis/site/trunk/book/fr/referencing.html (original)
+++ sis/site/trunk/book/fr/referencing.html Thu Jun  2 04:57:06 2016
@@ -283,199 +283,96 @@
 
     <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, il en est une à la fois simple et très fréquente.
-      Ce sont les opérations linéaires, constituées uniquement d’une combinaison
d’additions et de certaines multiplications.
-      Ces opérations n’effectuent pas de projections cartographiques, plus complexes,
mais couvrent de nombreux autres cas:
+      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>
des images pointe souvent vers le bas).</li>
-      <li>Changer de méridien d’origine (par exemple de <cite>Paris</cite>
vers <cite>Greenwich</cite>).</li>
-      <li>Changer le nombre de dimensions (par exemple passer des coordonnées 3D
vers 2D).</li>
-      <li>Convertir des unités de mesures (par exemple convertir des pieds en mètres).</li>
-      <li>Convertir les coordonnées pixels d’une image 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>
-      <li>Appliquer des rotations, translations, échelles ou cisaillements (des
transformations dites <cite>affines</cite>).</li>
+      <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 opérations linéaires peuvent se combiner efficacement:
-      peu importe le nombre d’opérations linéaires que l’on enchaîne,
le résultat sera exprimable par une seule opération linéaire.
-      Cette propriété est plus facilement visible lorsque les opérations linéaires
sont exprimées sous forme de matrices:
+      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>Example:</b>
-      supposons que nous disposons d’une image dont les coordonnées des pixels sont
représentées par (<var>i</var>,<var>j</var>).
-      Supposons que la taille de chaque pixel correspond à un nombre fixe de degrées
de longitude et de latitude
-      dans un système géographique donné et qu’il n’y a pas de rotation.
-      La conversion des coordonnées pixels (<var>i</var>,<var>j</var>)
vers les coordonnées géographiques (<var>λ</var>,<var>φ</var>)
-      est alors linéaire et peut être représentée par la matrice suivante:</p>
 
-      <table class="hidden"><tr><td>
-        <xi:include href="../math/PixelToGeographic.html"/>
-      </td><td style="vertical-align: middle; padding-left: 30px">
-        où
-      </td><td style="vertical-align: middle">
-        <ul>
-          <li><var>S</var> est un facteur d’échelle (<cite>Scale</cite>)
correspondant dans cet exemple à la taille des pixels en degrés.</li>
-          <li><var>H</var> est un terme de cisaillement (<cite>Shear</cite>),
habituellement zéro sauf si l’image a une rotation.</li>
-          <li><var>T</var> est une translation (<cite>Translation</cite>)
correspondant dans cet exemple à la coordonnée géographique d’un coin de l’image.</li>
-        </ul>
-      </td></tr></table>
-      <p>
-        Concentrons notre attention sur la matrice du milieu dans l’équation ci-dessus.
-        Si nous n’interchangeons ni n’inversons la direction d’aucun axe,
alors une conversion des coordonnées pixels vers les coordonnées géographiques
-        pourrait s’exprimer par la matrice « conversion originale » ci-dessous.
-        Mais si l’on veut en outre inverser la direction de l’axe des <var>j</var>
pour se conformer à la convention la plus courante appliquée aux images
-        (« changement 1 ») et interchanger l’ordre des axes pour exprimer
la latitude avant la longitude (« changement 2 »),
-        alors on peut exprimer ces modifications par des multiplications matricielles comme
suit
-        (l’ordre dans laquelle les opérations sont effectuées sur les coordonnées
se lit de droite à gauche):
+    <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 originale</th><th></th>
-        <th>Conversion modifiée</th>
+        <th>Conversion initiale</th><th></th>
+        <th>Opérations combinées</th>
       </tr><tr>
-        <td style="vertical-align: middle">
-          <math xmlns="http://www.w3.org/1998/Math/MathML" display="block" alttext="MathML
capable browser required">
-            <mfenced open="[" close="]">
-              <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"><xi:include href="../math/AxisSwapping2D.html"/></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 open="[" close="]">
-              <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>
-                  <mtd><mo>(</mo><msub><mi>j</mi><mrow>max</mrow></msub><mo>-</mo>
-                                 <msub><mi>j</mi><mrow>min</mrow></msub><mo>)</mo></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"><xi:include href="../math/InverseAxisY.html"/></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 open="[" close="]">
-              <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>i</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>i</mi><mrow>min</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>j</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>j</mi><mrow>min</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"><xi:include href="../math/PixelToGeographicSameAxisDirections.html"/></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 open="[" close="]">
-              <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>j</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>j</mi><mrow>min</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>i</mi><mrow>max</mrow></msub><mo>-</mo>
-                      <msub><mi>i</mi><mrow>min</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>
+        <td style="vertical-align: middle"><xi:include href="../math/PixelToGeographicReverseOrderAndY.html"/></td>
       </tr></table>
       <p>
-        L’idée principale est qu’il n’y a pas besoin d’écrire un
code dédié à l’inversion des axes.
-        Cette opération, et bien d’autres, est prise en compte naturellement par
l’algèbre matricielle.
+        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>
 
-    <p style="color: red">TODO</p>
-
     <article>
       <header>
         <h1>Particularités d’une bibliothèque de calculs matriciels pour
un <abbr>SIG</abbr></h1>
@@ -591,6 +488,47 @@
       </ul>
     </article>
 
+    <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.




Mime
View raw message