mirror of https://gitlab.com/pamhyr/pamhyr2
geometry: "merge" geomerty and reach.
parent
9a165d59d0
commit
81fdb9827b
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue