diff --git a/.gitignore b/.gitignore index 2545988..ccf295f 100644 --- a/.gitignore +++ b/.gitignore @@ -116,12 +116,10 @@ ENV/ env.bak/ venv.bak/ -# Spyder project settings +# IDE project settings .spyderproject .spyproject - -# Rope project settings -.ropeproject +.vscode/ # mkdocs documentation /site diff --git a/gridit/grid.py b/gridit/grid.py index 073bca5..ee9a079 100644 --- a/gridit/grid.py +++ b/gridit/grid.py @@ -111,6 +111,25 @@ def bounds(self): ymin = ymax - nrow * res return tuple(map(float, (xmin, ymin, xmax, ymax))) + @property + def corner_coords(self): + """Return 4 tuples of (x, y) coordinates to grid corners. + + The order of the corners can be described with this figure: + (x0, y0) (x3, y3) + +---------+ + | | + +---------+ + (x1, y1) (x2, y2) + """ + xmin, ymin, xmax, ymax = self.bounds + return [ + (xmin, ymax), + (xmin, ymin), + (xmax, ymin), + (xmax, ymax), + ] + @property def transform(self): """Return Affine transform; requires affine.""" diff --git a/tests/test_grid.py b/tests/test_grid.py index 63d8e7e..2a24cfe 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -1,3 +1,5 @@ +import pickle + import pytest from gridit import Grid @@ -28,33 +30,56 @@ def test_grid_dict(grid_basic): assert grid_d["projection"] is None -def test_grid_repr(grid_basic): - expected = "" - assert repr(grid_basic) == expected - assert str(grid_basic) == expected +@pytest.mark.parametrize( + "grid, expected_str", + [ + pytest.param( + Grid(10, (20, 30), (1000.0, 2000.0)), + "", + id="without projection", + ), + pytest.param( + Grid(10.0, (20, 30), (1000.0, 2000.0), "EPSG:2193"), + "", + id="with projection", + ), + ], +) +def test_grid_repr(grid, expected_str): + assert repr(grid) == expected_str + assert str(grid) == expected_str def test_grid_eq_hash(): grid1 = Grid(10, (20, 30), (1000.0, 2000.0)) grid2 = Grid(10, (20, 30), (1001.0, 2000.0)) grid3 = Grid(10, (20, 30), (1000.0, 2000.0), "EPSG:2193") - grid4 = Grid(10, (20, 30), (1000.0, 2000.0)) + grid1r = Grid(10, (20, 30), (1000.0, 2000.0)) assert grid1 != grid2 - assert grid1 != grid3 # projection is different - assert grid1 == grid4 + assert grid1 != grid3, "projection is different" + assert grid1 == grid1r hash1 = hash(grid1) hash2 = hash(grid2) hash3 = hash(grid3) - hash4 = hash(grid4) + hash1r = hash(grid1r) assert hash1 != hash2 - assert hash1 != hash3 # projection is different - assert hash1 == hash4 + assert hash1 != hash3, "projection is different" + assert hash1 == hash1r def test_grid_bounds(grid_basic): assert grid_basic.bounds == (1000.0, 1800.0, 1300.0, 2000.0) +def test_grid_corner_coords(grid_basic): + assert grid_basic.corner_coords == [ + (1000.0, 2000.0), + (1000.0, 1800.0), + (1300.0, 1800.0), + (1300.0, 2000.0), + ] + + @requires_pkg("affine") def test_grid_transform(grid_basic): from affine import Affine @@ -62,32 +87,30 @@ def test_grid_transform(grid_basic): assert grid_basic.transform == Affine(10.0, 0.0, 1000.0, 0.0, -10.0, 2000.0) -def test_pickle(): - import pickle - - # Without projection - grid = Grid(25.0, (36, 33), (1748725.0, 5449775.0)) - expected_bytes = ( - b"\x80\x04\x95c\x00\x00\x00\x00\x00\x00\x00\x8c\x0b" - b"gridit.grid\x94\x8c\x04Grid\x94\x93\x94)\x81\x94}\x94(\x8c\n" - b"resolution\x94G@9\x00\x00\x00\x00\x00\x00\x8c\x05" - b"shape\x94K$K!\x86\x94\x8c\x08" - b"top_left\x94GA:\xae\xf5\x00\x00\x00\x00GAT\xca\x0b\xc0\x00\x00\x00\x86" - b"\x94ub." - ) - assert pickle.loads(expected_bytes) == grid, "failed loading previous serialization" - assert pickle.loads(pickle.dumps(grid)) == grid, "failed round-trip" - - # With projection - grid = Grid(25.0, (36, 33), (1748725.0, 5449775.0), "EPSG:2193") - expected_bytes = ( - b"\x80\x04\x95|\x00\x00\x00\x00\x00\x00\x00\x8c\x0b" - b"gridit.grid\x94\x8c\x04Grid\x94\x93\x94)\x81\x94}\x94(\x8c\n" - b"resolution\x94G@9\x00\x00\x00\x00\x00\x00\x8c\x05" - b"shape\x94K$K!\x86\x94\x8c\x08" - b"top_left\x94GA:\xae\xf5\x00\x00\x00\x00GAT\xca\x0b\xc0\x00\x00\x00\x86" - b"\x94\x8c\nprojection\x94\x8c\tEPSG:2193" - b"\x94ub." - ) +@pytest.mark.parametrize( + "grid, expected_bytes", + [ + pytest.param( + Grid(25.0, (36, 33), (1748725.0, 5449775.0)), + b"\x80\x04\x95c\x00\x00\x00\x00\x00\x00\x00\x8c\x0b" + b"gridit.grid\x94\x8c\x04Grid\x94\x93\x94)\x81\x94}\x94(\x8c\n" + b"resolution\x94G@9\x00\x00\x00\x00\x00\x00\x8c\x05" + b"shape\x94K$K!\x86\x94\x8c\x08" + b"top_left\x94GA:\xae\xf5\x00\x00\x00\x00GAT\xca\x0b\xc0\x00\x00\x00\x86\x94ub.", + id="without projection", + ), + pytest.param( + Grid(25.0, (36, 33), (1748725.0, 5449775.0), projection="EPSG:2193"), + b"\x80\x04\x95|\x00\x00\x00\x00\x00\x00\x00\x8c\x0b" + b"gridit.grid\x94\x8c\x04Grid\x94\x93\x94)\x81\x94}\x94(\x8c\n" + b"resolution\x94G@9\x00\x00\x00\x00\x00\x00\x8c\x05" + b"shape\x94K$K!\x86\x94\x8c\x08" + b"top_left\x94GA:\xae\xf5\x00\x00\x00\x00GAT\xca\x0b\xc0\x00\x00\x00\x86" + b"\x94\x8c\nprojection\x94\x8c\tEPSG:2193\x94ub.", + id="with projection", + ), + ], +) +def test_pickle(grid, expected_bytes): assert pickle.loads(expected_bytes) == grid, "failed loading previous serialization" assert pickle.loads(pickle.dumps(grid)) == grid, "failed round-trip"