geometry: "merge" geomerty and reach.

mesh
Pierre-Antoine Rouby 2023-03-30 15:55:32 +02:00
parent 9a165d59d0
commit 81fdb9827b
3 changed files with 209 additions and 251 deletions

View File

@ -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

View File

@ -73,7 +73,7 @@ class ProfileXYZ(Profile):
Returns: Returns:
Profile header. 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): def import_points(self, list_points: list):
"""Import a list of points to profile """Import a list of points to profile

View File

@ -1,33 +1,219 @@
# -*- coding: utf-8 -*- # -*- 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: class Reach:
def __init__(self, name: str = "", def __init__(self, edge):
upstream_node: str = None, self._edge = edge
downstream_node: str = None, self._list_profiles: List[Profile] = []
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 __repr__(self): 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 @property
def name(self): def number_profiles(self):
return self._name """
Returns:
Number of profiles
"""
return len(self._list_profiles)
@property def get_geometry(self) -> List[Profile]:
def name_upstream_node(self): """
return self._name_upstream_node Returns:
The profiles list.
"""
return self._list_profiles
@property def get_profile_i(self, i: int) -> Profile:
def name_downstream_node(self): """
return self._name_downstream_node Args:
i: Index
@property Returns:
def geometry(self): The profile at index i.
return self._geometry """
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