From 926cade43779fa0ceb29408a1260a63bc5b18fd4 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Tue, 30 Sep 2025 10:25:01 +0200 Subject: [PATCH] River: Add reach split methods. --- src/Model/Geometry/PointXYZ.py | 16 ++++++++++++ src/Model/Geometry/ProfileXYZ.py | 20 ++++++++++++++ src/Model/Geometry/Reach.py | 17 ++++++++++++ src/Model/River.py | 45 ++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+) diff --git a/src/Model/Geometry/PointXYZ.py b/src/Model/Geometry/PointXYZ.py index 3cff1109..e1bea68c 100644 --- a/src/Model/Geometry/PointXYZ.py +++ b/src/Model/Geometry/PointXYZ.py @@ -289,6 +289,22 @@ class PointXYZ(Point): new_p.modified() return new_p + def cloned_for(self, new_profile): + new_p = PointXYZ( + id=-1, + name=self.name, + x=self.x, y=self.y, z=self.z, + profile=new_profile, + status=self._status + ) + if self.is_deleted(): + new_p.set_as_deleted() + + new_p._sl = self.sl + + new_p.modified() + return new_p + def __repr__(self): return f"({self._x}, {self._y}, {self._z}, {self._name})" diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index 29327ee8..2cab60b4 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -402,6 +402,26 @@ class ProfileXYZ(Profile, SQLSubModel): new_p.modified() return new_p + def cloned_for(self, new_reach): + new_p = ProfileXYZ( + id=-1, + name=self.name, + rk=self.rk, + reach=new_reach, + status=self._status + ) + if self.is_deleted(): + new_p.set_as_deleted() + + new_p._sl = self.sl + + for point in self._points: + p = point.cloned_for(new_p) + new_p._points.append(p) + + new_p.modified() + return new_p + def point_from_data(self, header, data): def float_format(s: str): return float( diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py index 57fa875d..8b24437f 100644 --- a/src/Model/Geometry/Reach.py +++ b/src/Model/Geometry/Reach.py @@ -892,3 +892,20 @@ class Reach(SQLSubModel): profile.rk = previous.rk + dist previous = profile + + def _split(self, profile, reach1, reach2): + if profile is None: + return + + nr1 = Reach(status=self._status, parent=reach1) + nr2 = Reach(status=self._status, parent=reach2) + + ind = self.profiles.index(profile) + + nr1_profiles = self.profiles[:ind+1] + nr2_profiles = self.profiles[ind:] + + nr1._profiles = list(map(lambda p: p.cloned_for(nr1), nr1_profiles)) + nr2._profiles = list(map(lambda p: p.cloned_for(nr2), nr2_profiles)) + + return nr1, nr2 diff --git a/src/Model/River.py b/src/Model/River.py index cce5132b..35ece3d9 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -417,6 +417,34 @@ class RiverReach(Edge): def frictions(self): return self._frictions + def _split(self, profile, new_node): + name = self.name + node1 = self.node1 + node2 = self.node2 + + new_reach1 = RiverReach( + id=-1, name=name + "(part 1)", + node1=node1, node2=new_node, + status=self._status, + ) + + new_reach2 = RiverReach( + id=-1, name=name + "(part 2)", + node1=new_node, node2=node2, + status=self._status, + ) + + nr1, nr2 = self._reach._split(profile, new_reach1, new_reach2) + + new_reach1._reach = nr1 + new_reach1._frictions = self._frictions + + new_reach2._reach = nr2 + new_reach2._frictions = self._frictions + + self.disable() + + return new_reach1, new_reach2 class River(Graph): _sub_classes = [ @@ -874,3 +902,20 @@ Last export at: @date.""" @results.setter def results(self, results): self._results = results + + def _split_reach(self, reach, profile): + node1 = reach.node1 + node2 = reach.node2 + + x1, y1 = node1.x, node1.y + x2, y2 = node2.x, node2.y + + center_x = (x1 + x2) / 2 + center_y = (y1 + y2) / 2 + + new_node = self.add_node(center_x, center_y) + + r1, r2 = reach._split(profile, new_node) + + self._add_edge(r1) + self._add_edge(r2)