rasterio/tests/test_transform.py
Vincent Sarago f587fb72ba Gcptransform (#1773)
* add GDALGCPsToGeoTransform

* add method to fall back to gcps geo transform when gcps are found

* add GDALGCPsToGeoTransform output in gcps info

* add GCPS class

* add GCPS in rasterio.control and update tests

* add from_gcps method

* return Affine and revert rio info change

* revert unrelated change

* add & for cython

* fix

* add tests

* Update rasterio/transform.py

Co-Authored-By: Sean Gillies <sean.gillies@gmail.com>

* /gcpslist/gcps/
2019-09-09 16:22:23 -06:00

202 lines
6.5 KiB
Python

from affine import Affine
import pytest
import rasterio
from rasterio import transform
from rasterio.env import GDALVersion
from rasterio.transform import xy, rowcol
from rasterio.windows import Window
gdal_version = GDALVersion.runtime()
def test_window_transform():
with rasterio.open('tests/data/RGB.byte.tif') as src:
assert src.window_transform(((0, None), (0, None))) == src.transform
assert src.window_transform(((None, None), (None, None))) == src.transform
assert src.window_transform(
((1, None), (1, None))).c == src.bounds.left + src.res[0]
assert src.window_transform(
((1, None), (1, None))).f == src.bounds.top - src.res[1]
assert src.window_transform(
((-1, None), (-1, None))).c == src.bounds.left - src.res[0]
assert src.window_transform(
((-1, None), (-1, None))).f == src.bounds.top + src.res[1]
def test_from_origin():
with rasterio.open('tests/data/RGB.byte.tif') as src:
w, n = src.xy(0, 0, offset='ul')
xs, ys = src.res
tr = transform.from_origin(w, n, xs, ys)
assert [round(v, 7) for v in tr] == [round(v, 7) for v in src.transform]
def test_from_bounds():
with rasterio.open('tests/data/RGB.byte.tif') as src:
w, s, e, n = src.bounds
tr = transform.from_bounds(w, s, e, n, src.width, src.height)
assert [round(v, 7) for v in tr] == [round(v, 7) for v in src.transform]
def test_array_bounds():
with rasterio.open('tests/data/RGB.byte.tif') as src:
w, s, e, n = src.bounds
height = src.height
width = src.width
tr = transform.from_bounds(w, s, e, n, src.width, src.height)
assert (w, s, e, n) == transform.array_bounds(height, width, tr)
def test_window_bounds():
with rasterio.open('tests/data/RGB.byte.tif') as src:
rows = src.height
cols = src.width
# Test window for entire DS and each window in the DS
assert src.window_bounds(((0, rows), (0, cols))) == src.bounds
for _, window in src.block_windows():
ds_x_min, ds_y_min, ds_x_max, ds_y_max = src.bounds
w_x_min, w_y_min, w_x_max, w_y_max = src.window_bounds(window)
assert ds_x_min <= w_x_min <= w_x_max <= ds_x_max
assert ds_y_min <= w_y_min <= w_y_max <= ds_y_max
def test_affine_roundtrip(tmpdir):
output = str(tmpdir.join('test.tif'))
out_affine = Affine(2, 0, 0, 0, -2, 0)
with rasterio.open(
output, 'w',
driver='GTiff',
count=1,
dtype=rasterio.uint8,
width=1,
height=1,
transform=out_affine
) as out:
assert out.transform == out_affine
with rasterio.open(output) as out:
assert out.transform == out_affine
@pytest.mark.skipif(
gdal_version.at_least('2.3'),
reason="Test only applicable to GDAL < 2.3")
def test_affine_identity(tmpdir):
"""
Setting a transform with absolute values equivalent to Affine.identity()
should result in a warning (not captured here) and read with
affine that matches Affine.identity().
"""
output = str(tmpdir.join('test.tif'))
out_affine = Affine(1, 0, 0, 0, -1, 0)
with rasterio.open(
output, 'w',
driver='GTiff',
count=1,
dtype=rasterio.uint8,
width=1,
height=1,
transform=out_affine
) as out:
assert out.transform == out_affine
with rasterio.open(output) as out:
assert out.transform == Affine.identity()
def test_from_bounds_two():
width = 80
height = 80
left = -120
top = 70
right = -80.5
bottom = 30.5
tr = transform.from_bounds(left, bottom, right, top, width, height)
# pixelwidth, rotation, ULX, rotation, pixelheight, ULY
expected = Affine(0.49375, 0.0, -120.0, 0.0, -0.49375, 70.0)
assert [round(v, 7) for v in tr] == [round(v, 7) for v in expected]
# Round right and bottom
right = -80
bottom = 30
tr = transform.from_bounds(left, bottom, right, top, width, height)
# pixelwidth, rotation, ULX, rotation, pixelheight, ULY
expected = Affine(0.5, 0.0, -120.0, 0.0, -0.5, 70.0)
assert [round(v, 7) for v in tr] == [round(v, 7) for v in expected]
def test_xy():
aff = Affine(300.0379266750948, 0.0, 101985.0,
0.0, -300.041782729805, 2826915.0)
ul_x, ul_y = aff * (0, 0)
xoff = aff.a
yoff = aff.e
assert xy(aff, 0, 0, offset='ul') == (ul_x, ul_y)
assert xy(aff, 0, 0, offset='ur') == (ul_x + xoff, ul_y)
assert xy(aff, 0, 0, offset='ll') == (ul_x, ul_y + yoff)
expected = (ul_x + xoff, ul_y + yoff)
assert xy(aff, 0, 0, offset='lr') == expected
expected = (ul_x + xoff / 2, ul_y + yoff / 2)
assert xy(aff, 0, 0, offset='center') == expected
assert xy(aff, 0, 0, offset='lr') == \
xy(aff, 0, 1, offset='ll') == \
xy(aff, 1, 1, offset='ul') == \
xy(aff, 1, 0, offset='ur')
def test_bogus_offset():
with pytest.raises(ValueError):
xy(None, 1, 0, offset='bogus')
def test_guard_transform_gdal_TypeError(path_rgb_byte_tif):
"""As part of the 1.0 migration, guard_transform() should raise a TypeError
if a GDAL geotransform is encountered"""
with rasterio.open(path_rgb_byte_tif) as src:
aff = src.transform
with pytest.raises(TypeError):
transform.guard_transform(aff.to_gdal())
def test_tastes_like_gdal_identity():
aff = Affine.identity()
assert not transform.tastes_like_gdal(aff)
assert transform.tastes_like_gdal(aff.to_gdal())
def test_rowcol():
with rasterio.open("tests/data/RGB.byte.tif", 'r') as src:
aff = src.transform
left, bottom, right, top = src.bounds
assert rowcol(aff, left, top) == (0, 0)
assert rowcol(aff, right, top) == (0, src.width)
assert rowcol(aff, right, bottom) == (src.height, src.width)
assert rowcol(aff, left, bottom) == (src.height, 0)
assert rowcol(aff, 101985.0, 2826915.0) == (0, 0)
assert rowcol(aff, 101985.0 + 400.0, 2826915.0) == (0, 1)
def test_xy_rowcol_inverse():
# TODO this is an ideal candiate for
# property-based testing with hypothesis
aff = Affine.identity()
rows_cols = ([0, 0, 10, 10],
[0, 10, 0, 10])
assert rows_cols == rowcol(aff, *xy(aff, *rows_cols))
def test_from_gcps():
with rasterio.open("tests/data/white-gemini-iv.vrt", 'r') as src:
aff = transform.from_gcps(src.gcps[0])
assert not aff == src.transform
assert len(aff) == 9
assert not transform.tastes_like_gdal(aff)