Search code examples
pythongisrasterio

Inverse Affine Transform - Rasterio


Is there a build in way in rasterio to compute the inverse affine transform of an rasterio.transform.Affine object?

I'm currently doing the following:

from rasterio.transform import Affine
import numpy as np

transform = Affine(29.976, 0, 5.12e5, 0, -29.976, 6.94e6)

matrix_form_transform = np.vstack(
    [
        np.array(transform.column_vectors).T,
        np.array([0,0,1])
    ]
)

matrix_form_inverse_transform = np.linalg.inv(matrix_form_transform)

inverse_transform = Affine(*matrix_form_inverse_transform[:2, :].ravel())

print(inverse_transform * transform)
# Affine(1.0, 0.0, 0.0,
#        -0.0, 1.0, 0.0)

This is quite clunky and I feel like there should be a builtin way to get to this but I can't find it.


Solution

  • The Affine class is defined in the affine package which is also managed by the rasterio organization. The Affine class implements the __invert__ dunder method. This means that it implements the ability to use the ~ operator. As it happens the implementation for __invert__ finds the inverse Affine object.

    You can do one of the following:

    from rasterio.transform import Affine
    
    transform = Affine(29.976, 0, 5.12e5, 0, -29.976, 6.94e6)
    print(~transform * transform)
    # | 1.00, 0.00, 0.00|
    # | 0.00, 1.00, 0.00|
    # | 0.00, 0.00, 1.00|
    

    or if you want to be more explicit

    from rasterio.transform import Affine
    
    transform = Affine(29.976, 0, 5.12e5, 0, -29.976, 6.94e6)
    print(transform.__invert__() * transform)
    # | 1.00, 0.00, 0.00|
    # | 0.00, 1.00, 0.00|
    # | 0.00, 0.00, 1.00|