Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Grid(projection) to be None #34

Merged
merged 1 commit into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ jobs:
- name: Run tests with optional packages
run: |
pip install -e .[optional]
# Avoid: Matplotlib is building the font cache; this may take a moment
python -c "import matplotlib; matplotlib.get_cachedir()"
pytest -n2 -v --cov

- name: Run doctest
Expand Down
9 changes: 7 additions & 2 deletions gridit/array_from.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,14 @@ def __init__(self, grid, fname, layer, attribute=None):
grid_crs = grid.projection
do_transform = False
if not grid_crs:
self.logger.info("assuming same projection: %s", shorten(grid_crs, 60))
self.logger.info("geometries not transformed: grid has no projection")
elif not ds_crs:
self.logger.info("geometries not transformed: vector has no projection")
elif is_same_crs(grid_crs, ds_crs):
self.logger.info("same projection: %s", shorten(grid_crs, 60))
self.logger.info(
"geometries not transformed: same projection: %s",
shorten(grid_crs, 60),
)
else:
do_transform = True
self.logger.info(
Expand Down
9 changes: 6 additions & 3 deletions gridit/classmethods.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Grid from_* classmethods."""

from math import ceil, floor
from typing import Optional

from gridit.logger import get_logger

Expand Down Expand Up @@ -51,7 +52,7 @@ def from_bbox(
maxy: float,
resolution: float,
buffer: float = 0.0,
projection: str = "",
projection: Optional[str] = None,
logger=None,
):
"""Create grid information from a bounding box and resolution.
Expand All @@ -68,7 +69,7 @@ def from_bbox(
A grid resolution, e.g. 250.0 for 250m x 250m
buffer : float, default 0.0
Add buffer to extents of bounding box.
projection : str, default ""
projection : optional str, default None
Coordinate reference system described as a string either as (e.g.)
EPSG:2193 or a WKT string.
logger : logging.Logger, optional
Expand Down Expand Up @@ -138,10 +139,12 @@ def from_raster(
if logger is None:
logger = get_logger(cls.__name__)
logger.info("creating from raster: %s", fname)
projection = None
with rasterio.open(fname, "r") as ds:
t = ds.transform
shape = ds.shape
projection = ds.crs.to_wkt()
if ds.crs:
projection = ds.crs.to_wkt()
if t.e != -t.a:
logger.error("expected e == -a, but %r != %r", t.e, t.a)
if t.b != 0 or t.d != 0:
Expand Down
5 changes: 1 addition & 4 deletions gridit/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,7 @@ def error_msg(msg: str, name: str = ""):
if ":" in model and (split := model.rindex(":")) > 1:
model = args.grid_from_modflow[:split]
model_name = args.grid_from_modflow[(1 + split) :]
if args.projection == "":
projection = None
else:
projection = args.projection
projection = args.projection if args.projection else None
grid = Grid.from_modflow(model, model_name, projection=projection)
mask = grid.mask_from_modflow(model, model_name=model_name)
else:
Expand Down
5 changes: 4 additions & 1 deletion gridit/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ def print_array(ar, logger=None):
else:
im -= im.min()
im /= im.max()
msk = ndimage.zoom(ar.mask, zf, order=0, cval=True)
if ar.mask.shape:
msk = ndimage.zoom(ar.mask, zf, order=0, cval=True)
else:
msk = np.full(im.shape, ar.mask)
col = ".;-:!>7?8CO$QHNM"
string = ""
height, width = im.shape
Expand Down
8 changes: 5 additions & 3 deletions gridit/grid.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Grid class and spatial tools to read array datasets."""

from typing import Optional

__all__ = ["Grid"]
mask_cache = {}

Expand All @@ -15,7 +17,7 @@ class Grid:
2D array shape (nrow, ncol).
top_left : tuple, default (0.0, 0.0)
Top left corner coordinate.
projection : str, default ""
projection : optional str, default None
WKT coordinate reference system string.
logger : logging.Logger, optional
Logger to show messages.
Expand Down Expand Up @@ -44,7 +46,7 @@ def __init__(
resolution: float,
shape: tuple,
top_left: tuple = (0.0, 0.0),
projection: str = "",
projection: Optional[str] = None,
logger=None,
):
if logger is None:
Expand All @@ -60,7 +62,7 @@ def __init__(
if len(top_left) != 2:
raise ValueError("expected top_left to contain two values")
self.top_left = tuple(float(v) for v in top_left)
self.projection = str(projection)
self.projection = str(projection) if projection else None

def __iter__(self):
"""Return object datasets with an iterator."""
Expand Down
2 changes: 1 addition & 1 deletion gridit/spatial.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
]


def is_same_crs(wkt1, wkt2):
def is_same_crs(wkt1: str, wkt2: str) -> bool:
"""Determine if two CRS strings (as WKT) are nearly the same.

First try to compare simple EPSG codes. Otherwise, use
Expand Down
Binary file added tests/data/nocrs.tif
Binary file not shown.
4 changes: 4 additions & 0 deletions tests/data/points.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
wkt,elevation
POINT(1749679 5450940),105.74257
POINT(1748906 5449151),77.4631
POINT(1750155 5449639),11.318376
15 changes: 13 additions & 2 deletions tests/test_array_from.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
mana_hk_nan_path = datadir / "Mana_hk_nan.tif"
lines_path = datadir / "waitaku2_lines.shp"
points_path = datadir / "waitaku2_points.shp"
nocrs_path = datadir / "nocrs.tif"


@requires_pkg("rasterio")
Expand Down Expand Up @@ -577,12 +578,22 @@ def test_array_from_vector_lines(caplog, attribute, refine, all_touched):
@requires_pkg("rasterio")
def test_array_from_raster_no_projection():
grid = Grid.from_bbox(1748762.8, 5448908.9, 1749509, 5449749, 25)
assert grid.projection == ""
assert grid.projection is None
ar = grid.array_from_raster(mana_dem_path)
assert ar.shape == (34, 31)
assert ar.mask.sum() == 160


@requires_pkg("rasterio")
def test_array_from_raster_without_projection():
grid = Grid.from_raster(nocrs_path)
assert grid.projection is None
ar = grid.array_from_raster(nocrs_path)
assert ar.shape == (2, 3)
assert ar.mask.sum() == 0
np.testing.assert_array_equal(ar, np.arange(6).reshape(2, 3))


@requires_pkg("rasterio")
def test_array_from_raster_same_projection():
grid = Grid.from_bbox(
Expand All @@ -608,7 +619,7 @@ def test_array_from_raster_different_projection():
@requires_pkg("fiona", "rasterio")
def test_array_from_vector_no_projection():
grid = Grid.from_bbox(1748762.8, 5448908.9, 1749509, 5449749, 25)
assert grid.projection == ""
assert grid.projection is None
ar = grid.array_from_vector(mana_polygons_path, attribute="K_m_d", refine=1)
assert ar.shape == (34, 31)
assert ar.mask.sum() == 146
Expand Down
19 changes: 19 additions & 0 deletions tests/test_classmethods.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
mana_polygons_path = datadir / "Mana_polygons.shp"
lines_path = datadir / "waitaku2_lines.shp"
points_path = datadir / "waitaku2_points.shp"
nocrs_path = datadir / "nocrs.tif"
nocrspoints_path = datadir / "points.csv"


def test_grid_from_bbox():
Expand Down Expand Up @@ -61,6 +63,14 @@ def test_grid_from_raster_buffer():
assert grid == expected


@requires_pkg("rasterio")
def test_grid_from_raster_nocrs():
grid = Grid.from_raster(nocrs_path)
expected = Grid(10.0, (2, 3), (1749700.0, 5449800.0))
assert grid == expected
assert grid.projection is None


@requires_pkg("fiona")
def test_grid_from_vector_point():
# all
Expand All @@ -83,6 +93,15 @@ def test_grid_from_vector_point():
assert grid == expected


@requires_pkg("fiona")
def test_grid_from_vector_nocrs():
# all
grid = Grid.from_vector(nocrspoints_path, 250)
expected = Grid(250.0, (8, 6), (1748750.0, 5451000.0))
assert grid == expected
assert grid.projection is None


@requires_pkg("fiona")
def test_grid_from_vector_polygon():
# all
Expand Down
4 changes: 2 additions & 2 deletions tests/test_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_grid_basic(grid_basic):
assert grid.resolution == 10.0
assert grid.shape == (20, 30)
assert grid.top_left == (1000.0, 2000.0)
assert grid.projection == ""
assert grid.projection is None


def test_grid_dict(grid_basic):
Expand All @@ -25,7 +25,7 @@ def test_grid_dict(grid_basic):
assert grid_d["resolution"] == 10.0
assert grid_d["shape"] == (20, 30)
assert grid_d["top_left"] == (1000.0, 2000.0)
assert grid_d["projection"] == ""
assert grid_d["projection"] is None


def test_grid_repr(grid_basic):
Expand Down
6 changes: 3 additions & 3 deletions tests/test_modflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_grid_from_modflow_6(caplog):
grid = Grid.from_modflow(modflow_dir / "mfsim.nam", "h6")
assert len(caplog.messages) == 0
assert grid == expected
assert grid.projection == ""
assert grid.projection is None

grid = Grid.from_modflow(modflow_dir / "mfsim.nam", "h6", "EPSG:2193")
# assert grid == expected
Expand All @@ -67,7 +67,7 @@ def test_grid_from_modflow_6(caplog):
grid = Grid.from_modflow(modflow_dir / "mfsim.nam")
assert "a model name should be specified" in caplog.messages[-1]
assert grid == expected
assert grid.projection == ""
assert grid.projection is None

# also rasises logger warning
grid = Grid.from_modflow(modflow_dir)
Expand All @@ -77,7 +77,7 @@ def test_grid_from_modflow_6(caplog):
with pytest.warns(UserWarning, match="model name should be specified"):
model = get_modflow_model(modflow_dir / "mfsim.nam")
grid = Grid.from_modflow(model.modelgrid)
assert grid.projection == ""
assert grid.projection is None
assert grid.shape == (18, 17)
assert grid.resolution == 1000.0

Expand Down