Skip to content

Commit 62fb3d0

Browse files
committed
fix(model_attributes_to_shapefile): pass modelgrid
1 parent 228668c commit 62fb3d0

2 files changed

Lines changed: 68 additions & 2 deletions

File tree

autotest/test_shapefile_utils.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import flopy
99
from flopy.discretization import StructuredGrid, UnstructuredGrid, VertexGrid
10+
from flopy.discretization.grid import Grid
1011
from flopy.export.shapefile_utils import model_attributes_to_shapefile, shp2recarray
1112
from flopy.utils.crs import get_shapefile_crs
1213

@@ -49,6 +50,66 @@ def test_model_attributes_to_shapefile(example_data_path, function_tmpdir):
4950
assert shpfile_path.exists()
5051

5152

53+
@requires_pkg("geopandas")
54+
def test_model_attributes_to_shapefile_modelgrid_kwarg(function_tmpdir):
55+
"""Repro https://github.com/modflowpy/flopy/issues/2744
56+
57+
The modelgrid kwarg to model_attributes_to_shapefile should be used as
58+
the geometry source if provided, overriding the model's own modelgrid.
59+
"""
60+
import warnings
61+
62+
nrow, ncol = 3, 4
63+
delr = np.ones(ncol) * 10.0
64+
delc = np.ones(nrow) * 10.0
65+
crs = 26916
66+
67+
# Model without a DIS package: modelgrid is a bare Grid with no geometry.
68+
# Without the fix, this reproduces the reported error:
69+
# TypeError: Grid.to_geodataframe() missing 1 required positional argument: 'features'
70+
sim = flopy.mf6.MFSimulation(sim_name="test", sim_ws=str(function_tmpdir))
71+
gwf = flopy.mf6.ModflowGwf(sim, modelname="test")
72+
mg = StructuredGrid(delr=delr, delc=delc, nlay=1, crs=crs)
73+
shpfile = function_tmpdir / "test_no_dis.shp"
74+
with warnings.catch_warnings():
75+
warnings.simplefilter("ignore", DeprecationWarning)
76+
model_attributes_to_shapefile(shpfile, gwf, modelgrid=mg)
77+
assert shpfile.exists()
78+
79+
# The error in the issue could also have been avoided by retrieving the
80+
# modelgrid after attaching the DIS to the model. Before DIS is added,
81+
# gwf.modelgrid is the bare base Grid class. After DIS is attached, it
82+
# becomes a StructuredGrid whose to_geodataframe() needs no 'features'.
83+
sim1 = flopy.mf6.MFSimulation(sim_name="test_b", sim_ws=str(function_tmpdir))
84+
gwf1 = flopy.mf6.ModflowGwf(sim1, modelname="test_b")
85+
assert isinstance(gwf1.modelgrid, Grid)
86+
flopy.mf6.ModflowGwfdis(gwf1, nlay=1, nrow=nrow, ncol=ncol)
87+
mg1 = gwf1.modelgrid
88+
assert isinstance(mg1, StructuredGrid)
89+
shpfile1 = function_tmpdir / "test_dis_first.shp"
90+
with warnings.catch_warnings():
91+
warnings.simplefilter("ignore", DeprecationWarning)
92+
model_attributes_to_shapefile(
93+
shpfile1, gwf1, package_names=["dis"], modelgrid=mg1
94+
)
95+
assert shpfile1.exists()
96+
97+
# Model with a DIS package but a different modelgrid passed via kwarg:
98+
# the kwarg modelgrid's CRS should take precedence.
99+
sim2 = flopy.mf6.MFSimulation(sim_name="test2", sim_ws=str(function_tmpdir))
100+
gwf2 = flopy.mf6.ModflowGwf(sim2, modelname="test2")
101+
flopy.mf6.ModflowGwfdis(gwf2, nlay=1, nrow=nrow, ncol=ncol)
102+
103+
mg2 = StructuredGrid(delr=delr, delc=delc, nlay=1, crs=crs)
104+
shpfile2 = function_tmpdir / "test_with_dis.shp"
105+
with warnings.catch_warnings():
106+
warnings.simplefilter("ignore", DeprecationWarning)
107+
model_attributes_to_shapefile(
108+
shpfile2, gwf2, package_names=["dis"], modelgrid=mg2
109+
)
110+
assert shpfile2.exists()
111+
112+
52113
@requires_pkg("geopandas")
53114
def test_create_geodataframe(
54115
minimal_unstructured_grid_info, minimal_vertex_grid_info, function_tmpdir

flopy/export/shapefile_utils.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,15 @@ def model_attributes_to_shapefile(
220220
else:
221221
package_names = [pak.name[0] for pak in ml.packagelist]
222222

223-
gdf = ml.to_geodataframe(package_names=package_names, shorten_attr=True)
223+
modelgrid = kwargs.pop("modelgrid", None)
224+
init_gdf = modelgrid.to_geodataframe() if modelgrid is not None else None
225+
gdf = ml.to_geodataframe(
226+
gdf=init_gdf, package_names=package_names, shorten_attr=True
227+
)
224228

225229
if array_dict:
226-
modelgrid = ml.modelgrid
230+
if modelgrid is None:
231+
modelgrid = ml.modelgrid
227232
for name, array in array_dict.items():
228233
if modelgrid.grid_type() == "unstructured":
229234
gdf[name] = array.ravel()

0 commit comments

Comments
 (0)