Geometry: ProfileXYZ: Add 'get_all_water_limits_ac' cache.

opt-result
Pierre-Antoine 2026-06-18 10:09:51 +02:00
parent 1975ed7eaa
commit 181a6c226f
1 changed files with 23 additions and 5 deletions

View File

@ -92,6 +92,7 @@ class ProfileXYZ(Profile, SQLSubModel):
self.station_up_to_date = False self.station_up_to_date = False
self._get_water_limits_cache = {} self._get_water_limits_cache = {}
self._get_water_limits_ac_cache = {}
@classmethod @classmethod
def _db_create(cls, execute, ext=""): def _db_create(cls, execute, ext=""):
@ -621,6 +622,7 @@ class ProfileXYZ(Profile, SQLSubModel):
""" """
return [x for x in lst if not np.isnan(x)] return [x for x in lst if not np.isnan(x)]
@timer
def speed(self, q, z): def speed(self, q, z):
area = self.wet_area(z) area = self.wet_area(z)
@ -672,6 +674,7 @@ class ProfileXYZ(Profile, SQLSubModel):
length += line.length length += line.length
return length return length
@timer
def compute_wet_area(self, z): def compute_wet_area(self, z):
area = 0.0 area = 0.0
if len(self.tab.L) > 0: if len(self.tab.L) > 0:
@ -712,6 +715,7 @@ class ProfileXYZ(Profile, SQLSubModel):
if len(line.coords) > 2: if len(line.coords) > 2:
poly = geometry.Polygon(line) poly = geometry.Polygon(line)
area += poly.area area += poly.area
return area return area
def wet_radius(self, z): def wet_radius(self, z):
@ -734,6 +738,7 @@ class ProfileXYZ(Profile, SQLSubModel):
line = geometry.LineString(list(zip(station, zz))) line = geometry.LineString(list(zip(station, zz)))
return line return line
@timer
def wet_lines(self, z): def wet_lines(self, z):
points = self._points points = self._points
if len(points) < 3: if len(points) < 3:
@ -810,7 +815,6 @@ class ProfileXYZ(Profile, SQLSubModel):
return points return points
def get_nb_wet_areas(self, z): def get_nb_wet_areas(self, z):
n_zones = 0 n_zones = 0
points = self._points points = self._points
if points[0].z <= z: if points[0].z <= z:
@ -822,10 +826,13 @@ class ProfileXYZ(Profile, SQLSubModel):
return n_zones return n_zones
@timer
def get_all_water_limits_ac(self, z): def get_all_water_limits_ac(self, z):
""" """
Determine all water limits for z elevation. Determine all water limits for z elevation.
""" """
if z in self._get_water_limits_ac_cache:
return self._get_water_limits_ac_cache[z]
points = self._points points = self._points
if len(points) < 3: if len(points) < 3:
@ -858,10 +865,19 @@ class ProfileXYZ(Profile, SQLSubModel):
logger.error(f"ERROR in get_all_water_limits_ac") logger.error(f"ERROR in get_all_water_limits_ac")
return [], [] return [], []
return start, list(reversed(end)) res = start, list(reversed(end))
self._get_water_limits_ac_cache[z] = res
return res
@timer @timer
def get_water_limits(self, z): def get_water_limits(self, z):
if z in self._get_water_limits_cache:
return self._get_water_limits_cache[z]
return self.get_water_limits_compute(z)
def get_water_limits_compute(self, z):
""" """
Determine left and right limits of water elevation. Determine left and right limits of water elevation.
""" """
@ -870,9 +886,6 @@ class ProfileXYZ(Profile, SQLSubModel):
i_left = -1 i_left = -1
i_right = -1 i_right = -1
if z in self._get_water_limits_cache:
return self._get_water_limits_cache[z]
for i in range(self.number_points): for i in range(self.number_points):
if self.point(i).z <= z: if self.point(i).z <= z:
i_left = i i_left = i
@ -919,15 +932,20 @@ class ProfileXYZ(Profile, SQLSubModel):
# Create a generator to improve results data reading speed # Create a generator to improve results data reading speed
yield pt_left, pt_right yield pt_left, pt_right
@timer
def compute_tabulation(self): def compute_tabulation(self):
sorted_points = sorted(self._points, key=lambda p: p.z) sorted_points = sorted(self._points, key=lambda p: p.z)
self.tab.z = np.array([p.z for p in sorted_points], np.float64) self.tab.z = np.array([p.z for p in sorted_points], np.float64)
self.tab.L = np.zeros(len(self.tab.z), np.float64) self.tab.L = np.zeros(len(self.tab.z), np.float64)
self.tab.A = np.zeros(len(self.tab.z), np.float64) self.tab.A = np.zeros(len(self.tab.z), np.float64)
for i in range(1, len(self.tab.z)): for i in range(1, len(self.tab.z)):
self.tab.L[i] = self.compute_wet_width(self.tab.z[i]) self.tab.L[i] = self.compute_wet_width(self.tab.z[i])
dx = (self.tab.L[i] + self.tab.L[i-1])/2 dx = (self.tab.L[i] + self.tab.L[i-1])/2
dz = self.tab.z[i] - self.tab.z[i-1] dz = self.tab.z[i] - self.tab.z[i-1]
self.tab.A[i] = self.tab.A[i-1] + dz * dx self.tab.A[i] = self.tab.A[i-1] + dz * dx
self.tab_up_to_date = True self.tab_up_to_date = True