sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1746518 [6/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
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=1746518&r1=1746517&r2=1746518&view=diff
==============================================================================
--- sis/site/trunk/content/book/en/developer-guide.html (original)
+++ sis/site/trunk/content/book/en/developer-guide.html Thu Jun  2 04:57:06 2016
@@ -19,7 +19,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/>
 
@@ -60,7 +60,8 @@
 <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></ul></li>
+<li><a href="#AffineTransform">Affine transform</a></li>
+<li><a href="#AffineTransformAPI">Integration with graphical libraries</a></li></ul></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>
@@ -1375,7 +1376,8 @@ or the use of <code>isWhitespace(…)
 <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></ul></li>
+<li><a href="#AffineTransform">Affine transform</a></li>
+<li><a href="#AffineTransformAPI">Integration with graphical libraries</a></li></ul></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>
@@ -1634,36 +1636,98 @@ while countries elongated along the Nort
 <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>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>
+<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">
@@ -1679,11 +1743,11 @@ can be represented by the following matr
 <mtable>
 <mtr>
 <mtd><msub><mi>S</mi><mrow>λ</mrow></msub></mtd>
-<mtd><msub><mi>H</mi><mrow>λ</mrow></msub></mtd>
+<mtd><mn>0</mn></mtd>
 <mtd><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
 </mtr>
 <mtr>
-<mtd><msub><mi>H</mi><mrow>φ</mrow></msub></mtd>
+<mtd><mn>0</mn></mtd>
 <mtd><msub><mi>S</mi><mrow>φ</mrow></msub></mtd>
 <mtd><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
 </mtr>
@@ -1697,29 +1761,33 @@ can be represented by the following matr
 <mo>×</mo>
 <mfenced close="]" open="[">
 <mtable>
-<mtr><mtd><mi>i</mi></mtd></mtr>
-<mtr><mtd><mi>j</mi></mtd></mtr>
+<mtr><mtd><mi>x</mi></mtd></mtr>
+<mtr><mtd><mi>y</mi></mtd></mtr>
 <mtr><mtd><mn>1</mn></mtd></mtr>
 </mtable>
 </mfenced>
 </math>
-</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>
+</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>Original conversion</th><th/>
-<th>Modified conversion</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">
@@ -1757,8 +1825,7 @@ where
 <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>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
 </mtr>
 <mtr>
 <mtd><mn>0</mn></mtd>
@@ -1780,8 +1847,7 @@ where
 <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>
+<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><mn>0</mn></mtd>
@@ -1794,8 +1860,7 @@ where
 <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>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><msub><mi>φ</mi><mrow>min</mrow></msub></mtd>
@@ -1821,8 +1886,7 @@ where
 <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>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><msub><mi>φ</mi><mrow>max</mrow></msub></mtd>
@@ -1833,8 +1897,7 @@ where
 <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>
+<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><mn>0</mn></mtd>
@@ -1851,11 +1914,51 @@ where
 </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 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>
 
-<p style="color: red">TODO</p>
+<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>
+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 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>

Modified: sis/site/trunk/content/book/fr/developer-guide.html
URL: http://svn.apache.org/viewvc/sis/site/trunk/content/book/fr/developer-guide.html?rev=1746518&r1=1746517&r2=1746518&view=diff
==============================================================================
--- sis/site/trunk/content/book/fr/developer-guide.html [UTF-8] (original)
+++ sis/site/trunk/content/book/fr/developer-guide.html [UTF-8] Thu Jun  2 04:57:06 2016
@@ -60,7 +60,8 @@
 <li><a href="#CRS_UserCode">Ajout de définitions</a></li></ul></li>
 <li><a href="#CoordinateOperation">Opérations sur les coordonnées</a><ul>
 <li><a href="#MathTransform">Exécution de opérations</a><ul>
-<li><a href="#AffineTransform">Les transformations affines</a></li></ul></li>
+<li><a href="#AffineTransform">Les transformations affines</a></li>
+<li><a href="#AffineTransformAPI">Intégration avec les bibliothèques graphiques</a></li></ul></li>
 <li><a href="#TransformDerivative">Dérivées partielles des opérations</a><ul>
 <li><a href="#DerivativeAndEnvelope">Utilité des dérivées pour la reprojection
d’enveloppes</a></li>
 <li><a href="#DerivativeAndRaster">Utilité des dérivées pour la reprojection
d’images</a></li>
@@ -1429,7 +1430,8 @@ de la bibliothèque <abbr>SIS</abbr>.
 <li><a href="#CRS_UserCode">Ajout de définitions</a></li></ul></li>
 <li><a href="#CoordinateOperation">Opérations sur les coordonnées</a><ul>
 <li><a href="#MathTransform">Exécution de opérations</a><ul>
-<li><a href="#AffineTransform">Les transformations affines</a></li></ul></li>
+<li><a href="#AffineTransform">Les transformations affines</a></li>
+<li><a href="#AffineTransformAPI">Intégration avec les bibliothèques graphiques</a></li></ul></li>
 <li><a href="#TransformDerivative">Dérivées partielles des opérations</a><ul>
 <li><a href="#DerivativeAndEnvelope">Utilité des dérivées pour la reprojection
d’enveloppes</a></li>
 <li><a href="#DerivativeAndRaster">Utilité des dérivées pour la reprojection
d’images</a></li>
@@ -1687,36 +1689,102 @@ alors que les pays plutôt allongés dan
 
 <h4 id="AffineTransform"><span class="section-number">3.3.1.1.</span> 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:
-</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>
-</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:
+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>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>
+<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>
+
+
+<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>
+Les équations ci-dessus peuvent être représentées sous forme de matrices comme ci-dessous:
+</p><p>
 
 
 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required"
display="block">
@@ -1732,11 +1800,11 @@ est alors linéaire et peut être repré
 <mtable>
 <mtr>
 <mtd><msub><mi>S</mi><mrow>λ</mrow></msub></mtd>
-<mtd><msub><mi>H</mi><mrow>λ</mrow></msub></mtd>
+<mtd><mn>0</mn></mtd>
 <mtd><msub><mi>T</mi><mrow>λ</mrow></msub></mtd>
 </mtr>
 <mtr>
-<mtd><msub><mi>H</mi><mrow>φ</mrow></msub></mtd>
+<mtd><mn>0</mn></mtd>
 <mtd><msub><mi>S</mi><mrow>φ</mrow></msub></mtd>
 <mtd><msub><mi>T</mi><mrow>φ</mrow></msub></mtd>
 </mtr>
@@ -1750,35 +1818,35 @@ est alors linéaire et peut être repré
 <mo>×</mo>
 <mfenced close="]" open="[">
 <mtable>
-<mtr><mtd><mi>i</mi></mtd></mtr>
-<mtr><mtd><mi>j</mi></mtd></mtr>
+<mtr><mtd><mi>x</mi></mtd></mtr>
+<mtr><mtd><mi>y</mi></mtd></mtr>
 <mtr><mtd><mn>1</mn></mtd></mtr>
 </mtable>
 </mfenced>
 </math>
-</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):
+</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>Changement 1</th><th/>
-<th>Conversion originale</th><th/>
-<th>Conversion modifiée</th>
+<th>Conversion initiale</th><th/>
+<th>Opérations combinées</th>
 </tr><tr>
 <td style="vertical-align: middle">
 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="MathML capable browser required"
display="block">
@@ -1816,8 +1884,7 @@ alors on peut exprimer ces modifications
 <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>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
 </mtr>
 <mtr>
 <mtd><mn>0</mn></mtd>
@@ -1839,8 +1906,7 @@ alors on peut exprimer ces modifications
 <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>
+<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><mn>0</mn></mtd>
@@ -1853,8 +1919,7 @@ alors on peut exprimer ces modifications
 <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>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><msub><mi>φ</mi><mrow>min</mrow></msub></mtd>
@@ -1880,8 +1945,7 @@ alors on peut exprimer ces modifications
 <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>
+<msub><mi>N</mi><mrow><mi>y</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><msub><mi>φ</mi><mrow>max</mrow></msub></mtd>
@@ -1892,8 +1956,7 @@ alors on peut exprimer ces modifications
 <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>
+<msub><mi>N</mi><mrow><mi>x</mi></mrow></msub>
 </mrow>
 </mfrac></mtd>
 <mtd><mn>0</mn></mtd>
@@ -1910,14 +1973,15 @@ alors on peut exprimer ces modifications
 </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 title="Spatial Information System">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>
@@ -2033,6 +2097,47 @@ En résumé, les besoins qui ont amené
 </ul>
 </article>
 
+<h4 id="AffineTransformAPI"><span class="section-number">3.3.1.2.</span>
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 title="Application Programming Interface">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 title="Spatial Information System">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 class="GeoAPI">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><code class="GeoAPI">MathTransform</code> mt = ...;    <code class="comment">//
N’importe quelle instance créée par Apache SIS.
+</code><b>if</b> (mt <b>instanceof</b> AffineTransform) {
+    AffineTransform at = (AffineTransform) mt;
+    <code class="comment">// Utiliser l’API de Java2D API à partir d’ici.
+</code>}</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 class="GeoAPI">MathTransform</code> répond aux conditions qui devrait
permettre un usage de Java2D.
+</p>
+
 <h3 id="TransformDerivative"><span class="section-number">3.3.2.</span>
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