diff --git a/src/Model/Geometry/Profile.py b/src/Model/Geometry/Profile.py index 3f55eb495e55c1724973e0c741a54493e9eedf06..b24e2eb94da10ed0fa1301fa61fda2d9a5a68432 100644 --- a/src/Model/Geometry/Profile.py +++ b/src/Model/Geometry/Profile.py @@ -356,3 +356,9 @@ class Profile(object): def wet_area(self, z): raise NotImplementedMethodeError(self, self.wet_area) + + def wet_radius(self, z): + raise NotImplementedMethodeError(self, self.wet_radius) + + def get_nb_wet_areas(self, z): + raise NotImplementedMethodeError(self, self.get_nb_wet_areas) diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index ee765c22d09a678bef3be2311eaa8795ca0c2f36..bcbd42e93659645d36c172ef49bbc6cf61cf305d 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -402,19 +402,28 @@ class ProfileXYZ(Profile, SQLSubModel): return abs(rg.dist(rd)) def wet_perimeter(self, z): - line = self.wet_line(z) + lines = self.wet_lines(z) - if line is None: + if lines is None: return 0 - return line.length + length = 0.0 + for line in lines: + length += line.length + return length def wet_area(self, z): - poly = self.wet_polygon(z) + lines = self.wet_lines(z) - if poly is None: + if lines is None: return 0 + area = 0.0 + for line in lines: + poly = geometry.Polygon(line) + area += poly.area + return area + return poly.area def wet_radius(self, z): @@ -431,21 +440,57 @@ class ProfileXYZ(Profile, SQLSubModel): if len(points) < 3: return None - z = map(lambda p: p.z, points) + zz = map(lambda p: p.z, points) station = self._get_station(points) - line = geometry.LineString(list(zip(station, z))) + line = geometry.LineString(list(zip(station, zz))) return line + def wet_lines(self, z): + points = self._points + if len(points) < 3: + return None + + lines = [] + + zz = list(map(lambda p: p.z, points)) + station = self._get_station(points) + + line = [] + for i in range(self.number_points-1): + + if zz[i] >= z and zz[i+1] < z: + y = np.interp( + z, + [zz[i], zz[i+1]], + [station[i], station[i+1]] + ) + line.append([y,z]) + + if zz[i] < z: + line.append([station[i],zz[i]]) + + if zz[i] <= z and zz[i+1] > z: + y = np.interp( + z, + [zz[i], zz[i+1]], + [station[i], station[i+1]] + ) + line.append([y,z]) + lines.append(geometry.LineString(line)) + line = [] + + return lines + def wet_polygon(self, z): points = self.wet_points(z) if len(points) < 3: return None - z = map(lambda p: p.z, points) + zz = map(lambda p: p.z, points) station = self._get_station(points) - poly = geometry.Polygon(list(zip(station, z))) + poly = geometry.Polygon(list(zip(station, zz))) return poly def wet_points(self, z): @@ -457,6 +502,19 @@ class ProfileXYZ(Profile, SQLSubModel): return points + def get_nb_wet_areas(self, z): + + n_zones = 0 + points = self._points + if points[0].z <= z: + n_zones += 1 + + for i in range(self.number_points-1): + if points[i].z > z and points[i+1].z <= z: + n_zones += 1 + + return n_zones + def get_water_limits(self, z): """ Determine left and right limits of water elevation.