Skip to content

Commit

Permalink
fix bug: typo shapely function call within gridintersect modflowpy#2342
Browse files Browse the repository at this point in the history
- fix typo in shapely.multilinestrings
- fix issue with np.apply_along_axis
- consider geometry collections when computing overlaps
- add test for vertex mode
- add inactive test for structured mode (not yet working)
  • Loading branch information
dbrakenhoff committed Oct 22, 2024
1 parent 332a310 commit 4f354dd
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 19 deletions.
53 changes: 42 additions & 11 deletions autotest/test_gridintersect.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,28 @@ def test_rect_grid_linestring_starting_on_vertex():
assert result.cellids[0] == (1, 1)


# @requires_pkg("shapely")
# def test_rect_grid_linestring_geomcolletion():
# gr = get_rect_grid()
# ix = GridIntersect(gr, method="structured")
# ls = LineString(
# [
# (20.0, 0.0),
# (5.0, 5.0),
# (15.0, 7.5),
# (10.0, 10.0),
# (5.0, 15.0),
# (10.0, 19.0),
# (10.0, 20.0),
# ]
# )
# result = ix.intersect(ls)
# assert len(result) == 3 # TODO: currently returns 4
# assert np.allclose(
# result.lengths.sum(), ls.length
# ) # TODO: length is 1m longer than ls


# %% test linestring shapely


Expand Down Expand Up @@ -737,6 +759,26 @@ def test_tri_grid_linestring_cell_boundary_return_all_ix_shapely(rtree):
assert len(r) == 3


@requires_pkg("shapely")
def test_rect_vertex_grid_linestring_geomcollection():
gr = get_rect_vertex_grid()
ix = GridIntersect(gr, method="vertex")
ls = LineString(
[
(20.0, 0.0),
(5.0, 5.0),
(15.0, 7.5),
(10.0, 10.0),
(5.0, 15.0),
(10.0, 19.0),
(10.0, 20.0),
]
)
result = ix.intersect(ls)
assert len(result) == 3
assert np.allclose(result.lengths.sum(), ls.length)


# %% test polygon structured


Expand Down Expand Up @@ -1555,14 +1597,3 @@ def test_create_raster_from_array_transform(example_data_path):
or not ((ymax - ymin) / (rymax - rymin)) == 2
):
raise AssertionError("Transform based raster not working properly")


if __name__ == "__main__":
sgr = get_rect_grid(angrot=45.0, xyoffset=10.0)
ls = LineString([(5, 10.0 + np.sqrt(200.0)), (15, 10.0 + np.sqrt(200.0))])
ix = GridIntersect(sgr, method="structured")
result = ix.intersect(ls)
assert len(result) == 2
ix = GridIntersect(sgr, method="structured", local=True)
result = ix.intersect(ls)
assert len(result) == 0
23 changes: 15 additions & 8 deletions flopy/utils/gridintersect.py
Original file line number Diff line number Diff line change
Expand Up @@ -966,27 +966,34 @@ def parse_linestrings_in_geom_collection(gc):
parts = shapely.get_parts(gc)
parts = parts[np.isin(shapely.get_type_id(parts), [1, 5])]
if len(parts) > 1:
p = shapely.multilinestring(parts)
p = shapely.multilinestrings(parts)
elif len(parts) == 0:
p = shapely.LineString()
else:
p = parts[0]
return p

mask_gc = geomtype_ids[~mask_empty & mask_type] == 7
ixresult[mask_gc] = np.apply_along_axis(
parse_linestrings_in_geom_collection,
axis=0,
arr=ixresult[mask_gc],
)
# NOTE: not working for multiple geometry collections, result is reduced
# to a single multilinestring, which causes doubles in the result
# ixresult[mask_gc] = np.apply_along_axis(
# parse_linestrings_in_geom_collection,
# axis=0,
# arr=ixresult[mask_gc],
# )
ixresult[mask_gc] = [
parse_linestrings_in_geom_collection(gc)
for gc in ixresult[mask_gc]
]

if not return_all_intersections:
# intersection with grid cell boundaries
ixbounds = shapely.intersection(
shp, shapely.get_exterior_ring(self.geoms[qcellids])
)
mask_bnds_empty = shapely.is_empty(ixbounds)
mask_bnds_type = np.isin(shapely.get_type_id(ixbounds), [1, 5])
mask_bnds_type = np.isin(shapely.get_type_id(ixbounds), [1, 5, 7])

# get ids of boundary intersections
idxs = np.nonzero(~mask_bnds_empty & mask_bnds_type)[0]

Expand All @@ -1002,7 +1009,7 @@ def parse_linestrings_in_geom_collection(gc):
mask_bnds_empty = shapely.is_empty(
isect
) # select boundary ix result
mask_overlap = np.isin(shapely.get_type_id(isect), [1, 5])
mask_overlap = np.isin(shapely.get_type_id(isect), [1, 5, 7])

# calculate difference between self and overlapping result
diff = shapely.difference(
Expand Down

0 comments on commit 4f354dd

Please sign in to comment.