diff --git a/src/Model/Geometry/Geometry.py b/src/Model/Geometry/Geometry.py deleted file mode 100644 index ce977efa1dfad3f89db070466b241e657ae98b58..0000000000000000000000000000000000000000 --- a/src/Model/Geometry/Geometry.py +++ /dev/null @@ -1,228 +0,0 @@ -# -*- coding: utf-8 -*- - -import numpy as np - -from time import time -from typing import List -from copy import deepcopy -from operator import itemgetter - -from Model.Geometry.PointXYZ import PointXYZ -from Model.Geometry.ProfileXYZ import ProfileXYZ - -# TypeProfileXYZ = List[ProfileXYZ] - - -class Geometry: - """ - Reach geometry - """ - def __init__(self, parent=None): - self.parent = parent - self._list_profiles: List[ProfileXYZ] = [] - self.file_st = "" - self.__list_copied_profiles = [] - - def __repr__(self): - return f"\n===== Début liste des profils ======> {np.array(self._list_profiles)}" \ - f"\n<====== Fin liste des profils =====" - - @property - def number_profiles(self): - """ - Returns: - Number of profiles - """ - return len(self._list_profiles) - - def get_geometry(self) -> List[ProfileXYZ]: - """ - Returns: - The profiles list. - """ - return self._list_profiles - - def get_profile_i(self, i: int) -> ProfileXYZ: - """ - Args: - i: Index - Returns: - The profile at index i. - """ - try: - return self._list_profiles[i] - except IndexError: - raise IndexError(f"Le bief a moins de {i} profil(s)") - - def import_geometry(self, file_path_name: str): - """Import a geometry from file (.ST or .st) - - Args: - file_path_name: The absolute path of geometry file (.ST or .st) to import. - - Returns: - Nothing. - """ - self.file_st = str(file_path_name) - list_profile, list_header = self.read_file_st() - # print(list_profile, "\n", list_header) - if list_profile and list_header: - for ind, profile in enumerate(list_profile): - prof = ProfileXYZ(*list_header[ind]) - prof.import_points(profile) - self._list_profiles.append(prof) - self._update_profile_numbers() - - else: - print("Fichier introuvable ou non conforme !") - - def add(self): - """Add a new profile at the end of profiles list - - Returns: - Nothing. - """ - nb_profile = self.number_profiles - profile = ProfileXYZ() - profile.num = nb_profile + 1 - self._list_profiles.append(profile) - - def _update_profile_numbers(self): - """Update profiles index - - Returns: - Nothing. - """ - for ind, profile in enumerate(self.get_geometry()): - profile.num = ind + 1 - - def insert(self, index: int): - """Insert new profile in list - - Args: - index: The position of the new profile. - - Returns: - Nothing. - """ - profile = ProfileXYZ() - self._list_profiles.insert(index, profile) - self._update_profile_numbers() - - def delete(self, list_index: list): - """Delete some elements in profile list - - Args: - list_index: The list of element index - - Returns: - Nothing. - """ - try: - if list_index: - indices = sorted(list(set(list_index)), reverse=True) - for idx in indices: - # if idx < len(self._list_profiles) : - try: - self._list_profiles.pop(idx) - self._update_profile_numbers() - except IndexError: - print("Liste vide, rien à supprimer !") - except TypeError: - if isinstance(list_index, int): - self._list_profiles.pop(list_index) - self._update_profile_numbers() - print(f"\nSuppression --> attention !!!!\nL'argument {list_index} doit être une liste!\n") - else: - raise TypeError(f"L'argument {list_index} fourni est de type incorrect") - - def _sort(self, is_reversed: bool = False): - self._list_profiles = sorted( - self._list_profiles, - key=lambda profile: profile.pk, - reverse=is_reversed - ) - - def sort_ascending(self): - """Sort profiles by increasing KP - - Returns: - Nothing. - """ - self._sort(is_reversed=False) - - def sort_descending(self): - """Sort profiles by decreasing KP - - Returns: - Nothing. - """ - self._sort(is_reversed=True) - - def copy(self, index_list: List[int]): - self.__list_copied_profiles.clear() - index_list = list(set(index_list)) # delete duplicate index - for index in index_list: - try: - self.__list_copied_profiles.append(deepcopy(self.get_profile_i(index))) - except IndexError: - raise IndexError(f"Echec de la copie, l'indice {index} n'existe pas !") - - def paste(self): - if self.__list_copied_profiles: - for profile in self.__list_copied_profiles: - self._list_profiles.append(profile) - print("self.__list_copied_profiles", self.__list_copied_profiles, "\n *****") - - def read_file_st(self): - """Read the ST file - - Returns: - List of profiles and list of headers. - """ - t0 = time() - line_is_header = True - list_point_profile = [] - list_profile = [] - list_header = [] - stop_code = "999.999" - try: - with open(self.file_st, encoding="utf-8") as file_st: - for line in file_st: - if not (line.startswith("#") or line.startswith("*")): - line = line.split() - if line_is_header: - if len(line) >= 6: - list_header.append(line[:6]) - elif len(line) == 5: - line.append("") - list_header.append(line) - else: - print(f"Point {line} invalide ==> pas pris en compte") - line_is_header = False - else: - # Read until "999.9990 999.9990" as found - if len(line) == 3: - x, y, z = line - if stop_code in x and stop_code in y: - line_is_header = True - list_profile.append(list_point_profile) - list_point_profile = [] - else: - line.append("") - list_point_profile.append(line) - elif len(line) == 4: - x, y, z, ld = line - if stop_code in x and stop_code in y: - list_profile.append(list_point_profile) - list_point_profile = [] - line_is_header = True - else: - list_point_profile.append(line) - else: - pass - - except FileNotFoundError: - print(f"\n \n %%%%%% Fichier : {self.file_st} introuvable !! %%%%%%") - print("****** Fichier {} lu et traité en {} secondes *******".format(self.file_st, time() - t0)) - return list_profile, list_header diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index 26a26426c1c6df0bc7c16b0403acbac0ecfe5c1d..7036750ab887bf15cab587e903057da059358c41 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -73,7 +73,7 @@ class ProfileXYZ(Profile): Returns: Profile header. """ - return np.array([self._num, self._code1, self._code2, self._nb_points, self.kp, self._name]) + return np.array([self._num, self._code1, self._code2, self._nb_points, self._kp, self._name]) def import_points(self, list_points: list): """Import a list of points to profile diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py index 7fe06ce5318bced623331de884aa66318c90e891..bceab6cd4b1af918b2e3ede2c406b30977f27d43 100644 --- a/src/Model/Geometry/Reach.py +++ b/src/Model/Geometry/Reach.py @@ -1,33 +1,219 @@ # -*- coding: utf-8 -*- -from Model.Geometry.Geometry import Geometry +import numpy as np + +from time import time +from typing import List +from copy import deepcopy +from operator import itemgetter + +from Model.Geometry.Profile import Profile +from Model.Geometry.ProfileXYZ import ProfileXYZ class Reach: - def __init__(self, name: str = "", - upstream_node: str = None, - downstream_node: str = None, - parent=None): - self._name = name - self._name_upstream_node = name_upstream_node - self._name_downstream_node = name_downstream_node - self.parent = parent - self._geometry = Geometry(parent=self) + def __init__(self, edge): + self._edge = edge + self._list_profiles: List[Profile] = [] def __repr__(self): - return f"Bief : {self._name}\n Nb de sections : {self._geometry.number_profiles}" + return f"\n===== Début liste des profils ======> {np.array(self._list_profiles)}" \ + f"\n<====== Fin liste des profils =====" @property - def name(self): - return self._name + def number_profiles(self): + """ + Returns: + Number of profiles + """ + return len(self._list_profiles) - @property - def name_upstream_node(self): - return self._name_upstream_node + def get_geometry(self) -> List[Profile]: + """ + Returns: + The profiles list. + """ + return self._list_profiles - @property - def name_downstream_node(self): - return self._name_downstream_node + def get_profile_i(self, i: int) -> Profile: + """ + Args: + i: Index - @property - def geometry(self): - return self._geometry + Returns: + The profile at index i. + """ + try: + return self._list_profiles[i] + except IndexError: + raise IndexError(f"Le bief a moins de {i} profil(s)") + + def add_XYZ(self): + """Add a new profile at the end of profiles list + + Returns: + Nothing. + """ + nb_profile = self.number_profiles + profile = ProfileXYZ() + profile.num = nb_profile + 1 + self._list_profiles.append(profile) + + def _update_profile_numbers(self): + """Update profiles index + + Returns: + Nothing. + """ + for ind, profile in enumerate(self.get_geometry()): + profile.num = ind + 1 + + def insert(self, index: int): + """Insert new profile in list + + Args: + index: The position of the new profile. + + Returns: + Nothing. + """ + profile = ProfileXYZ() + self._list_profiles.insert(index, profile) + self._update_profile_numbers() + + def delete(self, list_index: list): + """Delete some elements in profile list + + Args: + list_index: The list of element index + + Returns: + Nothing. + """ + try: + if list_index: + indices = sorted(list(set(list_index)), reverse=True) + for idx in indices: + # if idx < len(self._list_profiles) : + try: + self._list_profiles.pop(idx) + self._update_profile_numbers() + except IndexError: + print("Liste vide, rien à supprimer !") + except TypeError: + if isinstance(list_index, int): + self._list_profiles.pop(list_index) + self._update_profile_numbers() + print(f"\nSuppression --> attention !!!!\nL'argument {list_index} doit être une liste!\n") + else: + raise TypeError(f"L'argument {list_index} fourni est de type incorrect") + + def _sort(self, is_reversed: bool = False): + self._list_profiles = sorted( + self._list_profiles, + key=lambda profile: profile.kp(), + reverse=is_reversed + ) + + def sort_ascending(self): + """Sort profiles by increasing KP + + Returns: + Nothing. + """ + self._sort(is_reversed=False) + + def sort_descending(self): + """Sort profiles by decreasing KP + + Returns: + Nothing. + """ + self._sort(is_reversed=True) + + def copy(self, index_list: List[int]): + self.__list_copied_profiles.clear() + index_list = list(set(index_list)) # delete duplicate index + for index in index_list: + try: + self.__list_copied_profiles.append(deepcopy(self.get_profile_i(index))) + except IndexError: + raise IndexError(f"Echec de la copie, l'indice {index} n'existe pas !") + + def paste(self): + if self.__list_copied_profiles: + for profile in self.__list_copied_profiles: + self._list_profiles.append(profile) + print("self.__list_copied_profiles", self.__list_copied_profiles, "\n *****") + + def import_geometry(self, file_path_name: str): + """Import a geometry from file (.ST or .st) + + Args: + file_path_name: The absolute path of geometry file (.ST or .st) to import. + + Returns: + Nothing. + """ + list_profile, list_header = self.read_file_st(str(file_path_name)) + + if list_profile and list_header: + for ind, profile in enumerate(list_profile): + prof = ProfileXYZ(*list_header[ind]) + prof.import_points(profile) + self._list_profiles.append(prof) + self._update_profile_numbers() + else: + print("Fichier introuvable ou non conforme !") + + def read_file_st(self): + """Read the ST file + + Returns: + List of profiles and list of headers. + """ + t0 = time() + line_is_header = True + list_point_profile = [] + list_profile = [] + list_header = [] + stop_code = "999.999" + try: + with open(self.file_st, encoding="utf-8") as file_st: + for line in file_st: + if not (line.startswith("#") or line.startswith("*")): + line = line.split() + if line_is_header: + if len(line) >= 6: + list_header.append(line[:6]) + elif len(line) == 5: + line.append("") + list_header.append(line) + else: + print(f"Point {line} invalide ==> pas pris en compte") + line_is_header = False + else: + # Read until "999.9990 999.9990" as found + if len(line) == 3: + x, y, z = line + if stop_code in x and stop_code in y: + line_is_header = True + list_profile.append(list_point_profile) + list_point_profile = [] + else: + line.append("") + list_point_profile.append(line) + elif len(line) == 4: + x, y, z, ld = line + if stop_code in x and stop_code in y: + list_profile.append(list_point_profile) + list_point_profile = [] + line_is_header = True + else: + list_point_profile.append(line) + else: + pass + + except FileNotFoundError: + print(f"\n \n %%%%%% Fichier : {self.file_st} introuvable !! %%%%%%") + print("****** Fichier {} lu et traité en {} secondes *******".format(self.file_st, time() - t0)) + return list_profile, list_header