Skip to content

Commit 8df1cc3

Browse files
stub cutting
1 parent 7c226d5 commit 8df1cc3

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

threedigrid_builder/grid/grid.py

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from osgeo import osr
77
from pyproj import CRS
88
from pyproj.exceptions import CRSError
9+
from shapely.ops import split
910

1011
import threedigrid_builder
1112
from threedigrid_builder.base import (
@@ -881,10 +882,51 @@ def sort(self):
881882
if self.surface_maps is not None:
882883
self.surface_maps.cci[:] = np.take(new_node_ids, self.surface_maps.cci)
883884

884-
def apply_cutlines(self, obstacles):
885-
"""Treat obstacles as cutlines"""
886-
887-
pass
885+
def apply_cutlines(self, cutlines):
886+
"""Treat obstacles as cutlines for now"""
887+
# TODO: add unit test for multiline cutting
888+
889+
# Map of node idx to fragment list
890+
node_fragment = {}
891+
892+
for node_idx in range(len(self.nodes)):
893+
# create the geometry of the corresponding cell
894+
node_polygon = shapely.box(
895+
self.nodes.bounds[node_idx][0],
896+
self.nodes.bounds[node_idx][1],
897+
self.nodes.bounds[node_idx][2],
898+
self.nodes.bounds[node_idx][3],
899+
ccw=False,
900+
)
901+
assert node_polygon.is_valid
902+
903+
# check for intersection with cutlines
904+
fragment_collection = [
905+
node_polygon
906+
] # list of all fragments of the cell (each cutline can cause new fragments), initially the cell itself
907+
908+
for cutline_linestring in cutlines.the_geom:
909+
new_fragments = [] # List of fragments that have been recut
910+
# iterate over the fragments
911+
for fragment in fragment_collection:
912+
intermediate_fragments = split(fragment, cutline_linestring)
913+
914+
# According to docs: If the splitter does not split the geometry, a collection with a single geometry equal to the input geometry is returned.
915+
# Note that the original input geometry does not need to be returned, we'll explicitely add that one again.
916+
if len(intermediate_fragments.geoms) == 1:
917+
assert intermediate_fragments.geoms[0].equals(fragment)
918+
new_fragments.append(fragment)
919+
elif len(intermediate_fragments.geoms) > 1:
920+
for intermediate_fragment in intermediate_fragments.geoms:
921+
assert intermediate_fragment.geom_type == "Polygon"
922+
new_fragments.append(intermediate_fragment)
923+
else:
924+
raise RuntimeError("No resulting geometry")
925+
926+
# set new fragment collection and move to the next cutline
927+
fragment_collection = new_fragments
928+
929+
node_fragment[node_idx] = fragment_collection
888930

889931
def finalize(self):
890932
"""Finalize the Grid, computing and setting derived attributes"""

0 commit comments

Comments
 (0)