Source code for stems.gis.tests.test_gis_coords

""" Tests for :py:mod:`stems.gis.coords`
"""
import math

import affine
from rasterio.coords import BoundingBox
import numpy as np
import pytest

from stems.gis import coords


TRANSFORM_1 = affine.Affine(30.0, 0.0, 365385.0,
                            0.0, -30.0, 2916915.0)
TRANSFORM_2 = affine.Affine(0.5, 0.0, -180.0,
                            0.0, -0.5, 90.0)
TRANSFORMS = [TRANSFORM_1, TRANSFORM_2]

SHAPE_1 = (500, 500)
SHAPE_2 = (360, 180)
SHAPES = [SHAPE_1, SHAPE_2]


param_centered = pytest.mark.parametrize('center', [True, False])


# ============================================================================
[docs]@pytest.mark.parametrize(('transform', 'shape', ), zip(TRANSFORMS, SHAPES)) @param_centered def test_transform_to_coords_shape(transform, shape, center): # Run y, x = coords.transform_to_coords(transform, height=shape[1], width=shape[0], center=center) # Check size assert len(y) == shape[1] assert len(x) == shape[0] # Check upper left if center: assert y.max() == transform.f + transform.e / 2 assert x.min() == transform.c + transform.a / 2 else: assert y.max() == transform.f assert x.min() == transform.c # Check spacing assert y[2] - y[1] == transform.e assert x[2] - x[1] == transform.a
[docs]@pytest.mark.parametrize('transform', TRANSFORMS) @pytest.mark.parametrize(('off_y', 'off_x'), [ (10, 5, ), (10.3, 5.7, ) ]) def test_transform_to_coords_bbox(transform, off_y, off_x): left = transform.c + off_x * transform.a top = transform.f + off_y * transform.e right = left + off_x * transform.a bottom = top + off_y * transform.e bbox = BoundingBox(left, bottom, right, top) y, x = coords.transform_to_coords(transform, bbox=bbox, center=False) # Was the bbox evenly offset? if int(off_y) == off_y: assert y.max() == top assert y.min() + transform.e == bottom assert len(y) == off_y # Or was it not aligned to grid set by transform? else: # Should cover extent and have more area assert y.max() > top assert y.min() + transform.e < bottom assert y.max() - y.min() > top - (bottom - transform.e) if int(off_x) == off_x: assert x.max() + transform.a == right assert x.min() == left assert len(x) == off_x else: # Should cover extent and have more area assert x.max() + transform.a > right assert x.min() < left assert x.max() - x.min() > (right - transform.a) - left
[docs]def test_transform_to_coords_error(): transform = TRANSFORMS[0] errmsg = r'Must provide either.*bbox.*height.*width.*' with pytest.raises(ValueError, match=errmsg): y, x = coords.transform_to_coords(transform)
# ============================================================================
[docs]@pytest.mark.parametrize('transform', TRANSFORMS) def test_transform_to_res(transform): res = coords.transform_to_res(transform) assert res == (transform.a, -transform.e)
# ============================================================================
[docs]@pytest.mark.parametrize(('transform', 'shape', ), zip(TRANSFORMS, SHAPES)) def test_transform_to_bounds(transform, shape): bounds = coords.transform_to_bounds(transform, shape[1], shape[0]) assert (bounds.right - bounds.left) / transform.a == shape[0] assert (bounds.bottom - bounds.top) / transform.e == shape[1] assert bounds.left == transform.c assert bounds.top == transform.f
# ============================================================================
[docs]@pytest.mark.parametrize(('dy', 'dx', ), [ [-30, 30], [-1, 1], [-5, 5] ]) @pytest.mark.parametrize(('ul_y', 'ul_x', ), [ [0, 0], [90, -180], [500, 1500] ]) @param_centered @pytest.mark.parametrize('assume_unique', [True, False]) def test_coords_to_transform(dy, dx, ul_y, ul_x, center, assume_unique): y = np.arange(ul_y, ul_y + dy * 7, dy) x = np.arange(ul_x, ul_x + dx * 11, dx) xform = coords.coords_to_transform(y, x, center=center, assume_unique=assume_unique) offset = 0.5 if center else 0.0 assert xform.a == dx assert xform.e == dy assert xform.c == ul_x - dx * offset assert xform.f == ul_y - dy * offset
[docs]def test_coords_to_transform_noneven(): y = np.array([90, 85., 80., 77.5, 75., 72.5, 70.0]) x = np.array([-180., -175., -170., -165.]) with pytest.warns(UserWarning, match=r'"y" coord.*equal spacing'): xform = coords.coords_to_transform(y, x, center=True) with pytest.warns(UserWarning, match=r'"x" coord.*equal spacing'): xform = coords.coords_to_transform(x, y, center=True)
[docs]@pytest.mark.parametrize(('dy', 'dx', ), [ (-10, 15, ), (-30, 30, ) ]) @param_centered def test_coords_to_bounds(dy, dx, center): y = np.arange(115, 10, dy) x = np.arange(-500, -300, dx) bounds = coords.coords_to_bounds(y, x, center=center) if center: assert bounds.left == x.min() - dx / 2 assert bounds.bottom == y.min() + dy / 2 assert bounds.right == x.max() + dx / 2 assert bounds.top == y.max() - dy / 2 else: assert bounds.left == x.min() assert bounds.bottom - dy == y.min() assert bounds.right - dx == x.max() assert bounds.top == y.max()
# ============================================================================
[docs]@pytest.mark.parametrize(('transform', 'shape', ), zip(TRANSFORMS, SHAPES)) @param_centered def test_coord_transform_integration(transform, shape, center): y, x = coords.transform_to_coords(transform, height=shape[1], width=shape[0], center=center) transform_ = coords.coords_to_transform(y, x, center=center) assert transform == transform_