Artifact [d58fb3a802]
Not logged in

Artifact d58fb3a802e01efc38cef7d978be63a4b3361a63:

Wiki page [Affine Transform] by sandro 2015-05-02 14:42:19.
D 2015-05-02T14:42:19.983
L Affine\sTransform
P ab5eedca812bd461b6aebe3d0fd1ca4149c767dd
U sandro
W 14832
<a href="https://www.gaia-gis.it/fossil/libspatialite/wiki?name=4.2.0-doc">back</a>
<h2>Affine Transformations</h2>
Starting since version <b>4.3.0</b> SpatiaLite supports several new SQL functions based on <a href="http://en.wikipedia.org/wiki/Affine_transformation">affine transformations</a>; understanding all the underlaying mathematics could easily be a rather difficult task, more notably if you have absolutely no familiarity with this kind of operations.<br>
So we'll start smoothly by introducing first a very simple practical example based on kind of a joke about the geography of Italy and Sicily.
<h2>Fancy Geograpy and amusing Math</h2>
<table border="1" cellspacing="4" cellpadding="8">
<tr><td>
<h3>Preface</h3>
Looking to a map of Italy it appears obvious at first glance that Sicily is located in a very inconvenient position:
<ol>
<li>Sicicly is placed too far South and too much close to North Africa; this implies an unpleasant torrid summer, and in turn this poses severe limitations to agricoltural activities.</li>
<li>The <a href="http://en.wikipedia.org/wiki/Strait_of_Messina">Strait of Messina</a> is exaggeratedly narrow, thus posing severe security risks to the navigation of capital ships and supertankers.<br>
Even worst, from time to time some crazy politician strongly advocates the very stupid idea to build an incredibly costly <a href="http://en.wikipedia.org/wiki/Strait_of_Messina_Bridge">bridge crossing the Strait</a>, completely overlooking the very high seismical risk of this district and purposely forgetting to remember that in 1908 both towns of <a href="http://en.wikipedia.org/wiki/1908_Messina_earthquake">Messina and Reggio Calabria</a> were completely destroyed by an earthquake followed by a tsunami.<br>
More than 100,000 peoples lost their lives, and it was one of the most frightening natural disasters registered in Europe during modern times.</li>
</ol>
So we'll immediately start a case study intended to identify a possible alternative location for Sicily.<br>
Incidentally we'll use the new SQL functions based on Affine Transformations for this task.<br>
Let's go on.  
</td><td>
<img src="https://www.gaia-gis.it/gaia-sins/affine-pics/sicily_0.png" alt="wfs-1" border="1">
</td></tr>
<tr><td>
<h3>Step #1: translating Sicily into a more convenient position</h3>
There is plenty of free room in the lower Tyrrhenian Sea, so we'll start by applying a <a href="http://en.wikipedia.org/wiki/Translation_%28geometry%29">translation</a>: this practically means adding (or subctracting) a constant value to the coordinates on both <b>x</b> and <b>y</b> axes.<br>
After a very quick examination moving Sicily <b>150 km</b> (i.e. <b>150,000 m</b>) westwards and <b>150 km</b> northwards seems to be an absolutely reasonable choice.<br>
So using the Affine Transformation SQL functions we'll write the following SQL statement:
<verbatim>
CREATE TABLE sicilia_1 AS
SELECT cod_reg, 
   ATM_Transform(geometry,
      ATM_CreateTranslate(-150000, 150000)) AS geom
FROM sicilia_0;
SELECT RecoverGeometryColumn('sicilia_1', 'geom', 32632, 'MULTIPOLYGON', 'XY');
</verbatim> 
<b>Remarks</b>:
<ul>
<li>all affine transformation related SQL function names start with an <b>ATM_</b> prefix: this simply stands for <i><b><u>A</u></b>ffine <b><u>T</u></b>ransformation <b><u>M</u></b>atrix</i>.</li>
<li><b>ATM_Transform()</b> is very similar to <b>ST_Transform()</b>; the most obvious difference is in that all transformation arguments are now expected to be passed under the form of an appropriate <b>BLOB-serialized</b> Affine Transformation Matrix.</li>
<li><b>ATM_CreateTranslate()</b> simply is an SQL function returning a <b>BLOB-serialized</b> Affine Transformation Matrix.<br>
The BLOB-Matrix will be initialized so to represent a simple <b>2D Translate</b> accordingly to <b>(tx, ty)</b> arguments.<br>
You could eventually define a complete <b>3D Translate</b> by passing <b>(tx, ty, tz)</b> arguments, but this isn't strictly required in our current example.
</ul>
</td><td>
<img src="https://www.gaia-gis.it/gaia-sins/affine-pics/sicily_1.png" alt="wfs-1" border="1">
</td></tr>
<tr><td>
<h3>Step #2: rotating Sicily so to get a nice horizontal alignement</h3>
Aligning the southern shores of Sicily to an almost horizontal line will surely lead to a more nicely ordered layout: so we have now to apply a <a href="http://en.wikipedia.org/wiki/Rotation_%28mathematics%29">counterclockwise rotation</a> of about <b>25.0 degrees</b>.<br>
Thanks to Affine Transformations, we can combine both the previous translation and the current rotation into a single movement (a so called <b>rototranslation</b>).<br>
We simply have to execute the following SQL statement:
<verbatim>CREATE TABLE sicilia_2 AS
SELECT cod_reg, 
   ATM_Transform(geometry,
      ATM_Translate(-150000, 150000,
         ATM_Translate(cx, cy,
            ATM_Rotate(25,
               ATM_CreateTranslate(-cx, -cy))))) AS geom
FROM (SELECT cod_reg, ST_X(centroid) AS cx, ST_Y(centroid) AS cy, geometry
      FROM (SELECT cod_reg, ST_Centroid(geometry) AS centroid, geometry 
            FROM sicilia_0) AS g1
) AS g2;
SELECT RecoverGeometryColumn('sicilia_2', 'geom', 32632, 'MULTIPOLYGON', 'XY');
</verbatim>  
<b>Remarks</b>:
<ul>
<li>correctly handling Rotation is rather complex.
Any rotation will always imply a <b>fixed center point</b>, and by default this is exactly placed at the coordinates origin: <b>(0, 0)</b> (in the <b>2D</b> case) or <b>(0, 0, 0)</b> (in the <b>3D</b> case).</li>
<li>so a very naive attempt to directly invoke <b>ATM_Rotate(25)</b> will simply relocate Sicily in Southern Spain, and this absolutely isn't our intention.</li>
<li>what we really need is a more complex sequence of chained transformations:
<ol>
<li>we'll start first by creating a new <b>BLOB-Matix</b> intended to relocate Sicily's <a href="http://en.wikipedia.org/wiki/Centroid">centroid</a> exactly on the coordinates origin: <b>ATM_CreateTranslate(-cx, -cy)</b></li> 
<li>now we can safely chain the intended Rotation into the overall transformation stack: <b>ATM_Rotate(25, atm-blob)</b></li>
<li>after applying the Rotation we now have to relocate Sicily in its initial position: <b>ATM_Translate(cx, cy, atm-blob)</b></li>
<li>and finally we'll apply the Translation intended to reposition Sicily westwards and nothwards: <b>ATM_Translate(-150000, 150000, atm-blob)</b><br>
<i>we've used two separate translations simply for didactic clarity: we could easily merge both them into a single translation:<br> ATM_Translate(cx - 150000, cy + 150000, atm-blob)</i></li>
<li>this way <b>ATM_Transform()</b> will receive the final <b>BLOB-Matrix</b> resulting by chaining all the above transformation steps in the correct sequence.</li>
</ol></li>
<li><b><u>Very important notice</u></b>: Affine Transformations <u>are not commutative</u>: the relative order of subsequent operations in a complex transformation chain should always be very carefully considered.</li>
<li>all the <b>FROM (SELECT ... FROM (SELECT ...) AS g1) AS g2</b> stuff simply is a rather trivial SQL trick based on two nested sub-queries.<br>
it's indented scope simply is avoiding to call too many times ST_Centroid(), ST_X() and ST_Y() in order to get the centroid coordinates.</li>
</ul>
</td><td>
<img src="https://www.gaia-gis.it/gaia-sins/affine-pics/sicily_2.png" alt="wfs-1" border="1">
</td></tr>
<tr><td>
<h3>Step #3: inflating and reshaping Sicily</h3>
An increased surface is surely welcome, because it automatically implies more agricultural lands: on the other hand shortening a little bit the length of the southern coastline will surely facilitate mobility and communications.<br>
So we'll now apply a <a href="http://en.wikipedia.org/wiki/Scaling_%28geometry%29">scaling</a> transformation using two different values: <b>sx=0.9</b> and <b>sy=1.3</b>.<br>
Once again, Affine Transformations enable us to combine altogether both translate, rotate and scale into a single transformation.<br>
This is the corresponding SQL statement:
<verbatim>
CREATE TABLE sicilia_3 AS
SELECT cod_reg, 
   ATM_Transform(geometry,
      ATM_Translate(-150000, 150000,
         ATM_Translate(cx, cy,
            ATM_Scale(0.9, 1.3,
               ATM_Rotate(25,
                  ATM_CreateTranslate(-cx, -cy)))))) AS geom
FROM (SELECT cod_reg, ST_X(centroid) AS cx, ST_Y(centroid) AS cy, geometry
      FROM (SELECT cod_reg, ST_Centroid(geometry) AS centroid, geometry 
            FROM sicilia_0) AS g1
) AS g2;
SELECT RecoverGeometryColumn('sicilia_3', 'geom', 32632, 'MULTIPOLYGON', 'XY');
</verbatim> 
<b>Remarks</b>:
<ul>
<li>there is nothing really new in this: we'll simply chain yet another transformation in the appropriate sequence order.</li>
<li><b>ATM_Scale(sx, sy)</b> is intended for the simpler <b>2D</b> case.</li>
<li>in the more general <b>3D</b> case you can invoke <b>ATM_Scale(sx, sy, sz)</b></li>
</ul>
</td><td>
<img src="https://www.gaia-gis.it/gaia-sins/affine-pics/sicily_3.png" alt="wfs-1" border="1">
</td></tr>
<tr><td>
<h3>Step #4: final touch: reflecting Sicily</h3>
A reflected Sicily presents many interesting advantages: we'll examine all them in full detail in our study conclusions.<br>
So we'll now apply a final <a href=http://en.wikipedia.org/wiki/Reflection_%28mathematics%29">reflection</a> transformation; this simply corresponds to a <b>180 degrees</b> rotation around the <b>Y axis</b>.<br>
And the following is the final SQL statement applying all the above transformations in a single shot:
<verbatim>CREATE TABLE sicilia_2 AS
CREATE TABLE sicilia_4 AS
SELECT cod_reg, 
   ATM_Transform(geometry,
      ATM_Translate(-150000, 150000,
         ATM_Translate(cx, cy,
            ATM_YRoll(180,
               ATM_Scale(0.9, 1.3,
                  ATM_Rotate(25,
                     ATM_CreateTranslate(-cx, -cy))))))) AS geom
FROM (SELECT cod_reg, ST_X(centroid) AS cx, ST_Y(centroid) AS cy, geometry
      FROM (SELECT cod_reg, ST_Centroid(geometry) AS centroid, geometry 
            FROM sicilia_0) AS g1
) AS g2;
SELECT RecoverGeometryColumn('sicilia_4', 'geom', 32632, 'MULTIPOLYGON', 'XY');
</verbatim> 
<b>Remarks</b>:
<ul>
<li>there are several possible rotations supported by Affine Transformation:
<ol>
<li><b>ATM_Rotate()</b> always intends a <b>2D</b> rotation, i.e. a rotation centered around the <b>Z axis</b></li>
<li>In the more general <b>3D</b> case there are three possible rotations, one for each axis.</li>
<li>the corresponding SQL functions are: <b>ATM_XRoll(angle)</b>, <b>ATM_YRoll(angle)</b> and <b>ATM_ZRoll(angle)</b></li>
<li><i><u>Note</u>: ATM_ZRoll() and ATM_Rotate() simply are two different alias-names for the same identical SQL function</i>.</li>
</ol></li>
</ul>
</td><td>
<img src="https://www.gaia-gis.it/gaia-sins/affine-pics/sicily_4.png" alt="wfs-1" border="1">
</td></tr>
<tr><td>
<h3>Final considerations</h3>
<ol>
<li><b>Agriculture</b>: after its relocation Sicily will gain much more agricultural land and will enjoy a more favourable climate: still sunny and warm but much less arid.<br>
This will certainly start a noticeable development of many economic activities, both direct and indirectly derived.</li>
<li><b>Transportation systems</b>: the suggested new layout for the Lower Tyrrhenian Sea strongly facilitates the development of maritime transports. Sicily could new become the central hub of a highly efficient network of high-speed and high-frequency ferry connections:
<ul>
<li>Palermo will now directly face Naples; Civitavecchia (Rome) seems to be a second obvious terminal for direct connections leading to Central Italy.</li>
<li>Messina will acquire a decisive strategic role, and will become the terminal for ferry connections leading to Civitavecchia, Leghorn and Genoa.</li>
<li>A less relevant (but anyway interesting) ferry link will join Trapani and Reggio Calabria.</li>
<li>Sardinia will strongly benefit from the new layout; Cagliari will be directly connected to Syracuse (or may be Augusta), and Olbia to Messina.<br>This means definitely breaking the secular insulation of Sardinia, that will now start enjoying a stronger integration with all others regions of Southern Italy.</li> 
<li>Last but not least: at a more strategic level it's absolutely obvious that now supertankers and big container ships can freely circumnavigate Sicily in any direction under uncompromised safety conditions.<br>
All Tyrrhenian harbors will now be directly conneted both to Eastern and Western Mediterranean, and this will surely induce a growth in the volumes of international traffics they could potentially attract.</li> 
</ul></li> 
<li><b>Heavy industry</b>: the new transportation system strongly centered around maritime communications will surely induce an active rebirth of shipyards, a fluorishing traditional excellence of many southern regions in past times but nowadays a perishing and declining industrial branch.</li>
<li><b>Tourism</b>: the suggested new layout will certainly promote a strong development of international tourism.<br>
It's worth noting that the new layout will give birth to a wonderful island group extending between Sicily to Campania; several of these islands actually are active volcanoes, and this island chain will ideally join Mount Etna and Mount Vesuvius.<br>
This area could be considered the most impressive volcanic field of Europe and will certainly become a strong touristic attraction.
</li>
<li><b>Internal commerce</b>: we can easily forecast a strong growth in volume of internal exchanges thank to the better connectivity based on maritime transports..<br> 
Just a single example: Sardinia should now be able to export its finest sheep-cheese on the Calabrian markets whilst Calabria could freely export its renown red hot chilly peppers to Sardinia, and both regions will widely befit from increased exchange volumes.</li>
<li><b>Practical realization</b>: the present study clearly demonstrates that there are no adverse factors in Mathematics, Geometry and Geography potentially forbidding the practical realization of the suggested idea.<br>
Unhappily the current state of the art in Geology poses many puzzling questions not yet fully resolved in a completely satisfying way.<br>
Anway we are hopefully expecting that future advancements in Tectonics (and more specifically a deeper comprehension of the micro-plaques mechanics) will surely allow to overcome any remaining issue.
</ol>
</td><td>
<img src="https://www.gaia-gis.it/gaia-sins/affine-pics/italy-2.0.png" alt="wfs-1" border="1">
</td></tr>
</table>

<hr><br>
<a href="https://www.gaia-gis.it/fossil/libspatialite/wiki?name=4.2.0-doc">back</a>
Z 9d7db366e11c637e54c6dc494d94e43e