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"