
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "basic_examples/plot_3d_manipulation.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_basic_examples_plot_3d_manipulation.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_basic_examples_plot_3d_manipulation.py:


3D DEM manipulation
===================

Applying 3D rigid transformations to DEMs is facilitated by the use of several functions, depending on the needs. This can be useful for correcting certain shifts when they are known in advance.

In this page, we will show you how to properly do :
 - a simple translation with translate with :func:`~geoutils.Raster.translate`
 - a simple rotation (with a translation) with :func:`~xdem.coreg.apply_matrix`
 - a complex rotation (with a translation) with :func:`~xdem.coreg.matrix_from_translations_rotations` in :func:`~xdem.coreg.apply_matrix`

.. GENERATED FROM PYTHON SOURCE LINES 13-18

.. code-block:: Python


    import numpy as np

    import xdem








.. GENERATED FROM PYTHON SOURCE LINES 19-20

We load a DEM and crop it.

.. GENERATED FROM PYTHON SOURCE LINES 20-25

.. code-block:: Python


    dem = xdem.DEM(xdem.examples.get_path("longyearbyen_ref_dem"))
    dem = dem.icrop((100, 100, 200, 200))









.. GENERATED FROM PYTHON SOURCE LINES 26-28

### Translation
To translate a DEM by a shift (x, y, z) in CRS unit, we can use the :func:`~geoutils.Raster.translate` function like this :

.. GENERATED FROM PYTHON SOURCE LINES 28-35

.. code-block:: Python


    shift_x, shift_y, shift_z = (3 * dem.res[0], 5 * dem.res[1], 20)
    dem_shifted = dem.translate(shift_x, shift_y) + shift_z

    dem_shifted.plot(cmap="terrain", cbar_title="Elevation (m)")
    dem.get_footprint_projected(dem.crs, densify_points=5000).plot(ec="k", alpha=0.4)




.. image-sg:: /basic_examples/images/sphx_glr_plot_3d_manipulation_001.png
   :alt: plot 3d manipulation
   :srcset: /basic_examples/images/sphx_glr_plot_3d_manipulation_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 36-37

Here the new DEM and the footprint of the original DEM. Note that the translation only updates the geotransform (no resampling is performed).

.. GENERATED FROM PYTHON SOURCE LINES 39-40

### Rotation and translation

.. GENERATED FROM PYTHON SOURCE LINES 42-44

#### With a manually constructed matrix
To perform a rotation, we need a transformation matrix. Here, a rotation of 0.6° in X (across-track) is attempted with the previous rotation.

.. GENERATED FROM PYTHON SOURCE LINES 44-62

.. code-block:: Python


    # Rotation and translation matrix 4*4
    rotation = np.deg2rad(0.6)
    matrix = np.array(
        [
            [1, 0, 0, shift_x],
            [0, np.cos(rotation), -np.sin(rotation), shift_y],
            [0, np.sin(rotation), np.cos(rotation), shift_z],
            [0, 0, 0, 1],
        ]
    )

    # Centroid of the rotation
    centroid = [dem.bounds.left + dem.width / 2, dem.bounds.bottom + dem.height / 2, np.nanmean(dem)]

    # Application
    rotated_dem = xdem.coreg.apply_matrix(dem, matrix=matrix, centroid=centroid)








.. GENERATED FROM PYTHON SOURCE LINES 63-66

We can plot the difference between the original and rotated DEM. Even if a translation is applicated with a rotation, the transform and the footprint are the same before and after.

Keep in mind that depending on the centroid and the value of the rotation, the shift in certain areas of the image can be very significant. Depending on the terrain configuration, some pixels may extend beyond the result "frame".

.. GENERATED FROM PYTHON SOURCE LINES 66-70

.. code-block:: Python


    diff_before = dem - rotated_dem
    diff_before.plot(cmap="RdYlBu", cbar_title="Elevation differences (m)")




.. image-sg:: /basic_examples/images/sphx_glr_plot_3d_manipulation_002.png
   :alt: plot 3d manipulation
   :srcset: /basic_examples/images/sphx_glr_plot_3d_manipulation_002.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 71-75

#### With an automatically constructed matrix
When several rotations and translations are combined, the rotation matrix can be really hard to compute. To do this, you can use the function :func:`~xdem.coreg.matrix_from_translations_rotations`.

Here is an example of a rotation of 0.1 degree in X, 0.2 in Y and 0.3 in Z with the previous shifts `(shift_x, shift_z, shift_z)`.

.. GENERATED FROM PYTHON SOURCE LINES 75-81

.. code-block:: Python


    matrix = xdem.coreg.matrix_from_translations_rotations(
        t1=shift_x, t2=shift_y, t3=shift_z, alpha1=0.1, alpha2=0.2, alpha3=0.3, use_degrees=True
    )
    matrix





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    array([[ 9.99980200e-01, -5.22986361e-03,  3.49973673e-03,
             6.00000000e+01],
           [ 5.23593193e-03,  9.99984801e-01, -1.72702754e-03,
             1.00000000e+02],
           [-3.49065142e-03,  1.74531773e-03,  9.99992385e-01,
             2.00000000e+01],
           [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
             1.00000000e+00]])



.. GENERATED FROM PYTHON SOURCE LINES 82-88

.. code-block:: Python


    rotated_dem = xdem.coreg.apply_matrix(dem, matrix=matrix, centroid=centroid)
    diff_before = dem - rotated_dem
    diff_before.plot(cmap="RdYlBu", cbar_title="Elevation differences (m)")
    rotated_dem.get_footprint_projected(dem.crs, densify_points=5000).plot(ec="k", alpha=0.1)




.. image-sg:: /basic_examples/images/sphx_glr_plot_3d_manipulation_003.png
   :alt: plot 3d manipulation
   :srcset: /basic_examples/images/sphx_glr_plot_3d_manipulation_003.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 89-90

Even if a translation is applicated with a rotation, the transform and the footprint are the same before and after.


.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 1.725 seconds)


.. _sphx_glr_download_basic_examples_plot_3d_manipulation.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_3d_manipulation.ipynb <plot_3d_manipulation.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_3d_manipulation.py <plot_3d_manipulation.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_3d_manipulation.zip <plot_3d_manipulation.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
