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

View File

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