Skip to content

Commit 9b0f36b

Browse files
committed
Update grid intersect notebook
1 parent 2efa446 commit 9b0f36b

1 file changed

Lines changed: 56 additions & 53 deletions

File tree

.docs/Notebooks/grid_intersection_example.py

Lines changed: 56 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
# The important methods in the GridIntersect object are:
8989
#
9090
# - `intersects()`: returns cellids for gridcells that intersect a shape (accepts
91-
# shapely geometry objects, arrays of shapely geometry object, flopy geometry object,
91+
# shapely geometry objects, arrays of shapely geometry objects, flopy geometry object,
9292
# shapefile.Shape objects, and geojson objects).
9393
# - `intersect()`: for intersecting the modelgrid with point, linestrings, and
9494
# polygon geometries (accepts shapely geometry objects, flopy geometry object,
@@ -130,31 +130,35 @@
130130

131131
# %%
132132
# Create the GridIntersect class for our modelgrid.
133-
ix = GridIntersect(sgr)
133+
gi = GridIntersect(sgr)
134134

135135
# %% [markdown]
136136
# Do the intersect operation for a polygon
137137

138138
# %%
139-
result = ix.intersect(p)
139+
result = gi.intersect(p, geo_dataframe=False)
140140

141141
# %% [markdown]
142-
# The results are returned as a numpy.recarray containing several fields based on the intersection performed. An explanation of the data in each of the possible fields is given below:
143-
# - **cellids**: contains the cell ids of the intersected grid cells
144-
# - **areas**: contains the area of the polygon in that grid cell (only for polygons)
145-
# - **lengths**: contains the length of the linestring in that grid cell (only for linestrings)
146-
# - **ixshapes**: contains the shapely object representing the intersected shape (useful for plotting the result)
142+
# The results are returned as a geopandas.GeoDataFrame or numpy.recarray containing several fields based on the intersection performed. An explanation of the data in each of the possible columns is given below:
143+
# - `cellid`: contains the cell ids of the intersected grid cells
144+
# - `row`: contains the row index of the intersected grid cells (only for structured grids)
145+
# - `col`: contains the column index of the intersected grid cells (only for structured grids)
146+
# - `areas`: contains the area of the polygon in that grid cell (only for polygons)
147+
# - `lengths`: contains the length of the linestring in that grid cell (only for linestrings)
148+
# - `ixshapes`/`geometry`: contains the shapely object representing the intersected shape (useful for plotting the result)
149+
#
150+
# __Note__: The `cellids` column is deprecated since flopy 3.11 but still included in the result for backward compatibility. It contains (row, column) tuples for structured grids and cellids for vertex grids.
147151
#
148152
# Looking at the first few entries of the results of the polygon intersection. Note that you can convert the result to a GeoDataFrame (if geopandas is installed) with `geo_dataframe=True`.
149153

150154
# %%
151-
ix.intersect(p, geo_dataframe=True).head()
155+
gi.intersect(p, geo_dataframe=True).head()
152156

153157
# %% [markdown]
154-
# The cellids can be easily obtained
158+
# The rows and columns can be easily obtained.
155159

156160
# %%
157-
result.cellids
161+
result.row, result.col
158162

159163
# %% [markdown]
160164
# Or the areas
@@ -168,13 +172,14 @@
168172
# method. This method works for all types of shapely geometries including arrays of
169173
# shapely geometries.
170174
#
171-
# This method returns `shp_ids` and `cellids` fields. The `shp_ids` field contains the
175+
# This method returns `shp_id` and `cellid` columns. The `shp_id` column contains the
172176
# index of the geometry in the original input shape provided by the user. This is useful
173177
# when the input is an array of shapely geometries. In this case we have only one polygon,
174-
# so the `shp_id` is always equal to 0.
178+
# so the `shp_id` is always equal to 0. For structured grids the row and column indices
179+
# are returned in the `row` and `col` columns.
175180

176181
# %%
177-
ix.intersects(p)
182+
gi.intersects(p, dataframe=True)
178183

179184
# %% [markdown]
180185
# The results of an intersection can be visualized with the `GridIntersect.plot_intersection_result()` method.
@@ -184,10 +189,10 @@
184189
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
185190

186191
# the intersection object contains some helpful plotting commands
187-
ix.plot_intersection_result(result, ax=ax)
192+
gi.plot_intersection_result(result, ax=ax)
188193

189194
# add black x at cell centers
190-
for irow, icol in result.cellids:
195+
for irow, icol in zip(result.row, result.col):
191196
(h2,) = ax.plot(
192197
sgr.xcellcenters[0, icol],
193198
sgr.ycellcenters[irow, 0],
@@ -210,13 +215,13 @@
210215
# %%
211216
# contains_centroid example
212217

213-
result2 = ix.intersect(p, contains_centroid=True)
218+
result2 = gi.intersect(p, contains_centroid=True, geo_dataframe=True)
214219

215220
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
216-
ix.plot_intersection_result(result2, ax=ax)
221+
gi.plot_intersection_result(result2, ax=ax)
217222

218223
# add black x at cell centers
219-
for irow, icol in result2.cellids:
224+
for irow, icol in zip(result2.row, result2.col):
220225
(h2,) = ax.plot(
221226
sgr.xcellcenters[0, icol],
222227
sgr.ycellcenters[irow, 0],
@@ -232,13 +237,13 @@
232237
# %%
233238
# min_area_threshold example
234239

235-
result3 = ix.intersect(p, min_area_fraction=0.35)
240+
result3 = gi.intersect(p, min_area_fraction=0.35)
236241

237242
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
238-
ix.plot_intersection_result(result3, ax=ax)
243+
gi.plot_intersection_result(result3, ax=ax)
239244

240245
# add black x at cell centers
241-
for irow, icol in result3.cellids:
246+
for irow, icol in zip(result3.row, result3.col):
242247
(h2,) = ax.plot(
243248
sgr.xcellcenters[0, icol],
244249
sgr.ycellcenters[irow, 0],
@@ -258,17 +263,17 @@
258263
mls = MultiLineString(lines=[ls1, ls2, ls3])
259264

260265
# %%
261-
result = ix.intersect(mls)
266+
result = gi.intersect(mls, geo_dataframe=True)
262267

263268
# %% [markdown]
264269
# Plot the result
265270

266271
# %%
267272
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
268273
sgr.plot(ax=ax)
269-
ix.plot_intersection_result(result, ax=ax, cmap="viridis")
274+
gi.plot_intersection_result(result, ax=ax, cmap="tab20")
270275

271-
for irow, icol in result.cellids:
276+
for irow, icol in zip(result.row, result.col):
272277
(h2,) = ax.plot(
273278
sgr.xcellcenters[0, icol],
274279
sgr.ycellcenters[irow, 0],
@@ -291,16 +296,16 @@
291296
# For points and linestrings there is a keyword argument `return_all_intersections` which will return multiple intersection results for points or (parts of) linestrings on cell boundaries. As an example, the difference is shown with the MultiPoint intersection. Note the number of red "+" symbols indicating the centroids of intersected cells, in the bottom left case, there are 4 results because the point lies exactly on the intersection between 4 grid cells.
292297

293298
# %%
294-
result = ix.intersect(mp)
295-
result_all = ix.intersect(mp, return_all_intersections=True)
299+
result = gi.intersect(mp, geo_dataframe=True)
300+
result_all = gi.intersect(mp, return_all_intersections=True, geo_dataframe=True)
296301

297302
# %%
298303
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
299304
sgr.plot(ax=ax)
300-
ix.plot_point(result.ixshapes, ax=ax, ms=10, color="C0")
301-
ix.plot_point(result_all.ixshapes, ax=ax, ms=10, marker=".", color="C3")
305+
gi.plot_point(result.geometry, ax=ax, ms=10, color="C0")
306+
gi.plot_point(result_all.geometry, ax=ax, ms=10, marker=".", color="C3")
302307

303-
for irow, icol in result.cellids:
308+
for irow, icol in zip(result.row, result.col):
304309
(h2,) = ax.plot(
305310
sgr.xcellcenters[0, icol],
306311
sgr.ycellcenters[irow, 0],
@@ -309,7 +314,7 @@
309314
label="centroids of intersected cells",
310315
)
311316

312-
for irow, icol in result_all.cellids:
317+
for irow, icol in zip(result_all.row, result_all.col):
313318
(h3,) = ax.plot(
314319
sgr.xcellcenters[0, icol],
315320
sgr.ycellcenters[irow, 0],
@@ -337,15 +342,13 @@
337342
# for each point. In case a point is on the boundary between multiple cells, it will
338343
# return the cell with the lowest cellid.
339344
#
340-
#
341-
# In this example we're returning the result as a
342-
# node number to easily select the grid cells for our plot. But by default this method
343-
# returns (row, col) for structured grids.
345+
# **Note:** in `points_to_cellids()` the `row`, `column` and `cellid` columns have datatype float to allow
346+
# for NaNs in the results when points lie outside the model grid. In order to use these results as indices
347+
# they need to be converted to integers.
344348

345349
# %%
346-
# return cellid as node numbers: so (node,) instead of (row, col)
347-
# this makes it easier to select the grid cells to highlight in the plot
348-
result = ix.points_to_cellids(random_points, return_nodenumbers=True)
350+
result = gi.points_to_cellids(random_points)
351+
result
349352

350353
# %% [markdown]
351354
# Plot the result
@@ -354,14 +357,14 @@
354357
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
355358
sgr.plot(ax=ax)
356359
ax.plot(x_coords, y_coords, "ro", ms=5, label="random points")
357-
ix.plot_polygon(
358-
ix.geoms[result.cellids.astype(int)], ax=ax, fc="yellow", edgecolor="k", zorder=5
360+
gi.plot_polygon(
361+
gi.geoms[result.cellid.astype(int)], ax=ax, fc="yellow", edgecolor="k", zorder=5
359362
)
360363
# %% [markdown]
361364
# Note that `points_to_cellids()` returns NaNs for points that lie outside the model grid.
362365

363366
# %%
364-
ix.points_to_cellids(shapely.points([50, 110], [55, 50]), dataframe=True)
367+
gi.points_to_cellids(shapely.points([50, 110], [55, 50]))
365368

366369
# %% [markdown]
367370
# ## <a id="trigrid"></a>[Vertex Grid](#top)
@@ -398,17 +401,17 @@
398401
# ### <a id="trigrid.1"></a>[Polygon with triangular grid](#top)
399402

400403
# %%
401-
ix2 = GridIntersect(tgr)
404+
gi2 = GridIntersect(tgr)
402405

403406
# %%
404-
result = ix2.intersect(p)
407+
result = gi2.intersect(p, geo_dataframe=True)
405408

406409
# %%
407410
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
408-
ix.plot_intersection_result(result, ax=ax)
411+
gi2.plot_intersection_result(result, ax=ax)
409412

410413
# only cells that intersect with shape
411-
for cellid in result.cellids:
414+
for cellid in result.cellid:
412415
(h2,) = ax.plot(
413416
tgr.xcellcenters[cellid],
414417
tgr.ycellcenters[cellid],
@@ -421,13 +424,13 @@
421424
# ### <a id="trigrid.2"></a>[LineString with triangular grid](#top)
422425

423426
# %%
424-
result = ix2.intersect(mls)
427+
result = gi2.intersect(mls, geo_dataframe=True)
425428

426429
# %%
427430
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
428-
ix2.plot_intersection_result(result, ax=ax, lw=3)
431+
gi2.plot_intersection_result(result, ax=ax, lw=3)
429432

430-
for cellid in result.cellids:
433+
for cellid in result.cellid:
431434
(h2,) = ax.plot(
432435
tgr.xcellcenters[cellid],
433436
tgr.ycellcenters[cellid],
@@ -440,22 +443,22 @@
440443
# ### <a id="trigrid.3"></a>[MultiPoint with triangular grid](#top)
441444

442445
# %%
443-
result = ix2.intersect(mp)
444-
result_all = ix2.intersect(mp, return_all_intersections=True)
446+
result = gi2.intersect(mp, geo_dataframe=True)
447+
result_all = gi2.intersect(mp, return_all_intersections=True, geo_dataframe=True)
445448

446449
# %%
447450
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
448-
ix2.plot_intersection_result(result, ax=ax, color="k", zorder=5, ms=10)
451+
gi2.plot_intersection_result(result, ax=ax, color="k", zorder=5, ms=10)
449452

450-
for cellid in result.cellids:
453+
for cellid in result.cellid:
451454
(h2,) = ax.plot(
452455
tgr.xcellcenters[cellid],
453456
tgr.ycellcenters[cellid],
454457
"kx",
455458
ms=15,
456459
label="centroids of intersected cells",
457460
)
458-
for cellid in result_all.cellids:
461+
for cellid in result_all.cellid:
459462
(h3,) = ax.plot(
460463
tgr.xcellcenters[cellid],
461464
tgr.ycellcenters[cellid],

0 commit comments

Comments
 (0)