-
Notifications
You must be signed in to change notification settings - Fork 10
Description
I was a bit confused with the AbstractUgrid.intersect_linestring
method. The docstring mentions it is to "Intersect linestrings" (plural). Looking at the code and the method name, it is to intersect with a single linestring.
I was trying to intersect multiple cross-sections linestrings with a network, and ran into the problem that it returned too much intersections. This is caused by:
xugrid/xugrid/ugrid/ugridbase.py
Line 1222 in 3286ff3
edges = np.stack((xy[:-1], xy[1:]), axis=1) |
which connects all seperate linestring with each other.
This seems to work to create edges where linestrings are not connected:
def intersect_linestring(
self,
obj: Union[xr.DataArray, xr.Dataset],
linestring: "shapely.geometry.LineString", # type: ignore # noqa
) -> Union[xr.DataArray, xr.Dataset]:
...
xys, linesection_ids = shapely.get_coordinates([linestrings], return_index=True)
_, split_ids = np.unique(linesection_ids, return_index=True)
split_xys = np.split(xys, split_ids[1:])
edges = np.concatenate([np.stack((xy[:-1], xy[1:]), axis=1) for xy in split_xys], axis=0)
edge_line_ids = np.delete(linesection_ids, split_ids)
edge_index, core_index, intersections = self.intersect_edges(edges)
# Linestring ids, which can be added to coords
line_ids = edge_line_ids[edge_index]
...
coords, core_index = get_sorted_section_coords(
s, intersection_for_coord, line_ids, dim, core_index, self.name
)
...
I also thought it is useful to keep the linestring ids and add them to coords
:
def get_sorted_section_coords(
s: FloatArray, xy: FloatArray, line_ids: IntArray, dim: str, index: IntArray, name: str
):
order = np.argsort(s)
coords = {
f"{name}_x": (dim, xy[order, 0]),
f"{name}_y": (dim, xy[order, 1]),
f"{name}_s": (dim, s[order]),
f"{name}_line_id": (dim, line_ids[order]),
}
return coords, index[order]
@Huite Let me know if this is within the scope of intersect_linestring
or requires a separate method intersect_linestrings
.