mirror of
https://github.com/rasterio/rasterio.git
synced 2025-12-08 17:36:12 +00:00
* initial * add TransformDirection enum, fix cython compiler issues * make RPCTransformWarning more generic * include GDALGCP* in gdal.pxi * add GCPTransformer * typo * move xy and rowcol to TransformerBase * change existing transform methods to use new *Transformer classes * normalize transform direction, update docstrings * update docstrings * make subsubheadings of Coordinate Transform subheading * Add new docs transform topic * add to index * update docstrings * update docstring * Add rasterio.rpc to docs * update georeferencing.rst * update transform.srst * relax isinstance check for RPCTransformer * catch invalid transform input to get_transformer * replace None with identity transform so we test the correct ValueError * update AffineTransformer * add tests * rename method to map singleton coordinate to array-like and validate all coordiantes have same dimensions * update test * add more tests * update docstring of GCPTransformer init * fix copy+paste error * relax check on xy transformed values due to floating point precision * remove unused imports * fix tests and address comments Co-authored-by: Sean Gillies <sean@mapbox.com>
109 lines
4.3 KiB
ReStructuredText
109 lines
4.3 KiB
ReStructuredText
Transforms
|
|
===========
|
|
|
|
Rasterio supports three primary methods for transforming of coordinates from
|
|
image pixel (row, col) to and from geographic/projected (x, y) coordinates.
|
|
The interface for performing these coordinate transformations is available
|
|
in ``rasterio.transforms`` through one of ``AffineTransformer``,
|
|
``GCPTransformer``, or ``RPCTransformer``. The methods ``xy`` and ``rowcol``
|
|
are responsible for converting between (row, col) -> (x, y) and (x, y) ->
|
|
(row, col), respectively.
|
|
|
|
Using Affine transformation matrix
|
|
-----------------------------------
|
|
``rasterio.transform.AffineTransformer`` takes care of coordinate transformations
|
|
given an Affine transformation matrix. For example
|
|
|
|
.. code-block:: python
|
|
|
|
>>> transform = Affine(300.0379266750948, 0.0, 101985.0, 0.0,
|
|
-300.041782729805, 2826915.0)
|
|
>>> transformer = rasterio.transform.AffineTransformer(transform)
|
|
>>> transformer.xy(0, 0)
|
|
(102135.01896333754, 2826764.979108635)
|
|
>>> transformer.rowcol(102135.01896333754, 2826764.979108635)
|
|
(0, 0)
|
|
|
|
This is approximately equivalent to
|
|
|
|
.. code-block:: python
|
|
|
|
>>> transform = Affine(300.0379266750948, 0.0, 101985.0, 0.0,
|
|
-300.041782729805, 2826915.0)
|
|
>>> transform * (0.5, 0.5)
|
|
(102135.01896333754, 2826764.979108635)
|
|
>>> ~transform * (102135.01896333754, 2826764.979108635)
|
|
(0.5, 0.5)
|
|
|
|
The dataset methods ``xy`` and ``index`` use ``rasterio.transform`` under the hood
|
|
|
|
.. code-block:: python
|
|
|
|
>>> with rasterio.open('RGB.byte.tif') as src:
|
|
print(src.xy(0, 0))
|
|
(102135.01896333754, 2826764.979108635)
|
|
|
|
Using Ground Control Points
|
|
----------------------------
|
|
|
|
.. code-block:: python
|
|
|
|
>>> gcps = [GroundControlPoint(row=11521.5, col=0.5, x=-123.6185142817931, y=48.99561141948625, z=89.13533782958984, id='217', info=''),
|
|
GroundControlPoint(row=11521.5, col=7448.5, x=-122.8802747777599, y=48.91210259315549, z=89.13533782958984, id='234', info=''),
|
|
GroundControlPoint(row=0.5, col=0.5, x=-123.4809665720148, y=49.52809729106944, z=89.13533782958984, id='1', info=''),
|
|
GroundControlPoint(row=0.5, col=7448.5, x=-122.7345733674704, y=49.44455878004666, z=89.13533782958984, id='18', info='')]
|
|
>>> transformer = rasterio.transform.GCPTransformer(gcps)
|
|
>>> transformer.xy(0, 0)
|
|
(-123.478928146887, 49.52808986989645)
|
|
|
|
Using Rational Polynomial Coefficients
|
|
---------------------------------------
|
|
For accuracy a height value is typically required when using ``RPCTransformer``. By default,
|
|
a value of 0 is assumed.
|
|
|
|
.. code-block:: python
|
|
|
|
>>> with rasterio.open('RGB.byte.rpc.vrt') as src:
|
|
transformer = rasterio.trasform.RPCTransformer(src.rpcs)
|
|
transformer.xy(0, 0)
|
|
(-123.47959047080701, 49.52794990575094)
|
|
|
|
A first order correction would be to use a mean elevation value for the image
|
|
|
|
.. code-block:: python
|
|
|
|
>>> with rasterio.open('RGB.byte.rpc.vrt') as src:
|
|
transformer = rasterio.trasform.RPCTransformer(src.rpcs)
|
|
transformer.xy(0, 0, zs=src.rpcs.height_off)
|
|
(-123.48096552376548, 49.528097381526386)
|
|
|
|
Better yet is to sample height values from a digital elevation model (DEM).
|
|
``RPCTransformer`` allows for options to be passed to ``GDALCreateRPCTransformer``
|
|
|
|
.. code-block:: python
|
|
|
|
>>> with rasterio.open('RGB.byte.rpc.vrt') as src:
|
|
transformer = rasterio.trasform.RPCTransformer(src.rpcs, rpc_dem='vancouver-dem.tif')
|
|
transformer.xy(0, 0)
|
|
(-123.47954729595642, 49.5279448909449)
|
|
|
|
See https://gdal.org/api/gdal_alg.html?highlight=gdalcreaterpctransformer#_CPPv426GDALCreateRPCTransformerV2PK13GDALRPCInfoV2idPPc
|
|
for more details.
|
|
|
|
Transformer Resources
|
|
----------------------
|
|
The ``AffineTransformer`` is a pure Python class, however ``GCPTransformer``
|
|
and ``RPCTransformer`` make use of C/C++ GDAL objects. Explicit control of
|
|
the transformer object can be achieved by use within a context manager or
|
|
by calling ``close()`` method e.g.
|
|
|
|
.. code-block:: python
|
|
|
|
>>> with rasterio.transform.RPCTransformer(rpcs) as transform:
|
|
transform.xy(0, 0)
|
|
>>> transform.xy(0, 0)
|
|
ValueError: Unexpected NULL transformer
|
|
|
|
.. note::
|
|
If ``RPC_DEM`` is specified in ``rpc_options``, GDAL will maintain an
|
|
open file handle to the DEM until the transformer is closed. |