content/developer-guide/coverage/AffineTransform.html (102 lines of code) (raw):

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude" xml:lang="en"> <head> <title>AffineTransform</title> <meta charset="UTF-8"/> <link rel="stylesheet" type="text/css" href="../../book.css"/> </head> <body> <!-- Content below this point is copied in "/asf-staging/book/en/developer-guide.html" file by the `org.apache.sis.buildtools.book` class in `buildSrc`. --> <section> <header> <h3 id="AffineTransform">Affine transform</h3> </header> <p> Among the many kinds of operations performed by <abbr>GIS</abbr> software products on spatial coordinates, <dfn>affine transforms</dfn> 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 cannot 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. Affine transforms are extensively used by Apache <abbr>SIS</abbr> for “grid to <abbr>CRS</abbr>” conversions. 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="../../../layouts/partials/math/PixelToGeographicTerms.html"/> </p><p> Above equations can be represented in matrix form as below: </p><p> <xi:include href="../../../layouts/partials/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> <div style="display:table; margin:auto"> <div style="display:table-row"> <div style="display:table-cell" class="caption">Change 2</div> <div style="display:table-cell" class="caption"> </div> <div style="display:table-cell" class="caption">Change 1</div> <div style="display:table-cell" class="caption"> </div> <div style="display:table-cell" class="caption">Initial conversion</div> <div style="display:table-cell" class="caption"> </div> <div style="display:table-cell" class="caption">Concatenated operation</div> </div> <div style="display:table-row"> <div style="display:table-cell; vertical-align:middle"><xi:include href="../../../layouts/partials/math/AxisSwapping2D.html"/></div> <div style="display:table-cell; vertical-align:middle; padding-left: 15px; padding-right: 15px">×</div> <div style="display:table-cell; vertical-align:middle"><xi:include href="../../../layouts/partials/math/InverseAxisY.html"/></div> <div style="display:table-cell; vertical-align:middle; padding-left: 15px; padding-right: 15px">×</div> <div style="display:table-cell; vertical-align:middle"><xi:include href="../../../layouts/partials/math/PixelToGeographicSameAxisDirections.html"/></div> <div style="display:table-cell; vertical-align:middle; padding-left: 15px; padding-right: 15px">=</div> <div style="display:table-cell; vertical-align:middle"><xi:include href="../../../layouts/partials/math/PixelToGeographicReverseOrderAndY.html"/></div> </div> </div> <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 class="warning"> This section is incomplete. See Javadoc for more details. </div> </section> </body> </html>