|
|
@@ -192,7 +192,9 @@ class Mn1Checker(BaseChecker):
|
|
|
super().__init__()
|
|
|
|
|
|
def test_load_layers(self):
|
|
|
- """ Chargement des données """
|
|
|
+ """ Chargement des données
|
|
|
+ Contrôle la présence des couches attendues
|
|
|
+ """
|
|
|
|
|
|
self.dataset = {}
|
|
|
|
|
|
@@ -221,7 +223,9 @@ class Mn1Checker(BaseChecker):
|
|
|
self.zapbos = self.dataset.get(Zapbo, [])
|
|
|
|
|
|
def test_scr(self):
|
|
|
- """ Contrôle des projections """
|
|
|
+ """ Contrôle des projections
|
|
|
+ Vérifie que les couches ont le bon sytème de projection
|
|
|
+ """
|
|
|
for model in models:
|
|
|
if model.layer.crs().authid() != model.crs:
|
|
|
self.log_error(f"Mauvaise projection (attendu: {model.crs})", model=model)
|
|
|
@@ -237,38 +241,58 @@ class Mn1Checker(BaseChecker):
|
|
|
self.log_error(f"{field} : {_translate_messages(err)}", item=item)
|
|
|
|
|
|
def test_structure_arteres(self):
|
|
|
- """ Structure des données: Artères """
|
|
|
+ """ Structure des données: Artères
|
|
|
+ Contrôle les données attributaires de la couche ARTERE_GEO:
|
|
|
+ présence, format, valeurs autorisées...
|
|
|
+ """
|
|
|
self._validate_structure(Artere, self.arteres)
|
|
|
|
|
|
def test_structure_cables(self):
|
|
|
- """ Structure des données: Cables """
|
|
|
+ """ Structure des données: Cables
|
|
|
+ Contrôle les données attributaires de la couche CABLE_GEO:
|
|
|
+ présence, format, valeurs autorisées...
|
|
|
+ """
|
|
|
self._validate_structure(Cable, self.cables)
|
|
|
|
|
|
def test_structure_equipements(self):
|
|
|
- """ Structure des données: Equipements """
|
|
|
+ """ Structure des données: Equipements
|
|
|
+ Contrôle les données attributaires de la couche EQUIPEMENT_GEO:
|
|
|
+ présence, format, valeurs autorisées...
|
|
|
+ """
|
|
|
self._validate_structure(Equipement, self.equipements)
|
|
|
|
|
|
def test_structure_noeuds(self):
|
|
|
- """ Structure des données: Noeuds """
|
|
|
+ """ Structure des données: Noeuds
|
|
|
+ Contrôle les données attributaires de la couche NOEUD_GEO:
|
|
|
+ présence, format, valeurs autorisées...
|
|
|
+ """
|
|
|
self._validate_structure(Noeud, self.noeuds)
|
|
|
|
|
|
def test_structure_tranchees(self):
|
|
|
- """ Structure des données: Tranchées """
|
|
|
+ """ Structure des données: Tranchées
|
|
|
+ Contrôle les données attributaires de la couche TRANCHEE_GEO:
|
|
|
+ présence, format, valeurs autorisées...
|
|
|
+ """
|
|
|
self._validate_structure(Tranchee, self.tranchees)
|
|
|
|
|
|
def test_structure_zapbos(self):
|
|
|
- """ Structure des données: Zapbos """
|
|
|
+ """ Structure des données: Zapbos
|
|
|
+ Contrôle les données attributaires de la couche ZAPBO_GEO:
|
|
|
+ présence, format, valeurs autorisées...
|
|
|
+ """
|
|
|
self._validate_structure(Zapbo, self.zapbos)
|
|
|
|
|
|
def test_geometry_validity(self):
|
|
|
- """ Contrôle de la validité des géométries """
|
|
|
+ """ Contrôle de la validité des géométries
|
|
|
+ """
|
|
|
for model in models:
|
|
|
for item in self.dataset[model]:
|
|
|
if not item.is_geometry_valid():
|
|
|
self.log_error("La géométrie de l'objet est invalide", item=item)
|
|
|
|
|
|
def test_geometry_type(self):
|
|
|
- """ Contrôle des types de géométries """
|
|
|
+ """ Contrôle des types de géométries
|
|
|
+ """
|
|
|
for model in models:
|
|
|
for item in self.dataset[model]:
|
|
|
geom_type = item.get_geom_type()
|
|
|
@@ -276,7 +300,9 @@ class Mn1Checker(BaseChecker):
|
|
|
self.log_error(f"Type de géométrie invalide (attendu: {QgsModel.GEOM_NAMES[geom_type]})", item=item)
|
|
|
|
|
|
def test_bounding_box(self):
|
|
|
- """ Contrôle des emprises """
|
|
|
+ """ Contrôle des emprises
|
|
|
+ Vérifie que les objets sont dans le périmètre attendu
|
|
|
+ """
|
|
|
|
|
|
for model in models:
|
|
|
xmin, ymin, xmax, ymax = model.bounding_box
|
|
|
@@ -290,7 +316,9 @@ class Mn1Checker(BaseChecker):
|
|
|
self.log_error("Hors de l'emprise autorisée", item=item)
|
|
|
|
|
|
def test_duplicates(self):
|
|
|
- """ Recherche de doublons """
|
|
|
+ """ Recherche de doublons
|
|
|
+ Recherche d'éventuels doublons dans des champs qui supposent l'unicité
|
|
|
+ """
|
|
|
|
|
|
tmp = []
|
|
|
for noeud in self.noeuds:
|
|
|
@@ -321,57 +349,62 @@ class Mn1Checker(BaseChecker):
|
|
|
|
|
|
|
|
|
def test_constraints_arteres_noeuds(self):
|
|
|
- """ Les noeuds attachés aux artères existent """
|
|
|
+ """ Application des contraintes: Artères / Noeuds
|
|
|
+ Vérifie que les noeuds attachés aux artères existent
|
|
|
+ """
|
|
|
|
|
|
for artere in self.arteres:
|
|
|
try:
|
|
|
artere.noeud_a = next((n for n in self.noeuds if n.NO_NOM == artere.AR_NOEUD_A))
|
|
|
except StopIteration:
|
|
|
artere.noeud_a = None
|
|
|
- self.log_error(f"Le noeud '{artere.AR_NOEUD_A}' n'existe pas", item=artere)
|
|
|
+ self.log_error(f"Le noeud lié '{artere.AR_NOEUD_A}' n'existe pas", item=artere)
|
|
|
|
|
|
try:
|
|
|
artere.noeud_b = next((n for n in self.noeuds if n.NO_NOM == artere.AR_NOEUD_B))
|
|
|
except StopIteration:
|
|
|
artere.noeud_b = None
|
|
|
- self.log_error(f"Le noeud '{artere.AR_NOEUD_B}' n'existe pas", item=artere)
|
|
|
+ self.log_error(f"Le noeud lié '{artere.AR_NOEUD_B}' n'existe pas", item=artere)
|
|
|
|
|
|
def test_constraints_cables_equipements(self):
|
|
|
- """ Les équipements attachés aux cables existent """
|
|
|
+ """ Application des contraintes: Equipements / Cables
|
|
|
+ Vérifie que les équipements attachés aux cables existent """
|
|
|
|
|
|
for cable in self.cables:
|
|
|
try:
|
|
|
cable.equipement_a = next((e for e in self.equipements if e.EQ_NOM == cable.CA_EQ_A))
|
|
|
except StopIteration:
|
|
|
cable.equipement_a = None
|
|
|
- self.log_error(f"L'équipement '{cable.CA_EQ_A}' n'existe pas", item=cable)
|
|
|
+ self.log_error(f"L'équipement lié '{cable.CA_EQ_A}' n'existe pas", item=cable)
|
|
|
|
|
|
try:
|
|
|
cable.equipement_b = next((e for e in self.equipements if e.EQ_NOM == cable.CA_EQ_B))
|
|
|
except StopIteration:
|
|
|
cable.equipement_b = None
|
|
|
- self.log_error(f"L'équipement '{cable.CA_EQ_B}' n'existe pas", item=cable)
|
|
|
+ self.log_error(f"L'équipement lié '{cable.CA_EQ_B}' n'existe pas", item=cable)
|
|
|
|
|
|
def test_constraints_cables_equipements_b(self):
|
|
|
- """ Tous les équipements sont l'équipement B d'au moins un cable """
|
|
|
+ """ Application des contraintes: Equipements B
|
|
|
+ Vérifie que tous les équipements sont l'équipement B d'au moins un cable """
|
|
|
|
|
|
equipements_b = [cable.CA_EQ_B for cable in self.cables]
|
|
|
for equipement in self.equipements:
|
|
|
if equipement.EQ_TYPE == "BAI":
|
|
|
continue
|
|
|
if not equipement.EQ_NOM in equipements_b:
|
|
|
- self.log_error(f"L'equipement '{equipement.EQ_NOM}' n'est l'équipement B d'aucun cable", item=equipement)
|
|
|
+ self.log_error(f"L'equipement lié '{equipement.EQ_NOM}' n'est l'équipement B d'aucun cable", item=equipement)
|
|
|
|
|
|
|
|
|
def test_constraints_equipements_noeuds(self):
|
|
|
- """ Les noeuds attachés aux équipements existent """
|
|
|
-
|
|
|
+ """ Application des contraintes: Noeuds / Equipements
|
|
|
+ Vérifie que les noeuds attachés aux équipements existent
|
|
|
+ """
|
|
|
for equipement in self.equipements:
|
|
|
try:
|
|
|
equipement.noeud = next((n for n in self.noeuds if n.NO_NOM == equipement.EQ_NOM_NOE))
|
|
|
except StopIteration:
|
|
|
equipement.noeud = None
|
|
|
- self.log_error(f"Le noeud '{equipement.EQ_NOM_NOE}' n'existe pas", item=equipement)
|
|
|
+ self.log_error(f"Le noeud lié '{equipement.EQ_NOM_NOE}' n'existe pas", item=equipement)
|
|
|
|
|
|
|
|
|
def test_graphic_duplicates(self):
|
|
|
@@ -403,7 +436,9 @@ class Mn1Checker(BaseChecker):
|
|
|
self.log_error("Une entité graphique est dupliquée", item=zapbo)
|
|
|
|
|
|
def test_positions_noeuds(self):
|
|
|
- """ Contrôle de la position des noeuds """
|
|
|
+ """ Topologie: Noeuds / Artères
|
|
|
+ Compare la géométrie des noeuds à celle des artères
|
|
|
+ """
|
|
|
|
|
|
for artere in self.arteres:
|
|
|
if not artere.noeud_a or not artere.noeud_b:
|
|
|
@@ -420,7 +455,8 @@ class Mn1Checker(BaseChecker):
|
|
|
self.log_error("Pas de noeud aux coordonnées attendues", item=artere)
|
|
|
|
|
|
def test_positions_equipements(self):
|
|
|
- """ Contrôle de la position des équipements """
|
|
|
+ """ Topologie: Equipements / Cables
|
|
|
+ Compare la géométrie des équipements à celle des cables """
|
|
|
|
|
|
for cable in self.cables:
|
|
|
if not cable.equipement_a or not cable.equipement_b or not cable.is_geometry_valid() or not cable.equipement_a.noeud or not cable.equipement_b.noeud:
|
|
|
@@ -436,10 +472,11 @@ class Mn1Checker(BaseChecker):
|
|
|
(cable_points[0].distanceSquared(equip_b_point) <= TOLERANCE and \
|
|
|
cable_points[-1].distanceSquared(equip_a_point) <= TOLERANCE))):
|
|
|
|
|
|
- self.log_error("Pas d'equipement aux coordonnées attendues", item=cable)
|
|
|
+ self.log_error("Pas d'équipement aux coordonnées attendues", item=cable)
|
|
|
|
|
|
def test_tranchee_artere(self):
|
|
|
- """ Chaque tranchée a au moins une artère """
|
|
|
+ """ Topologie: Tranchées / Artères
|
|
|
+ Compare la géométrie des tranchées à celle des artères """
|
|
|
|
|
|
arteres_full_buffer = QgsGeometry().unaryUnion([a.geom for a in self.arteres]).buffer(TOLERANCE, 100)
|
|
|
|
|
|
@@ -448,7 +485,8 @@ class Mn1Checker(BaseChecker):
|
|
|
self.log_error("Tranchée ou portion de tranchée sans artère", item=tranchee)
|
|
|
|
|
|
def test_cable_artere(self):
|
|
|
- """ Chaque cable a au moins une artère (sauf baguettes) """
|
|
|
+ """ Topologie: Cables / Artères
|
|
|
+ Compare la géométrie des cables à celle des artères """
|
|
|
|
|
|
arteres_full_buffer = QgsGeometry().unaryUnion([a.geom for a in self.arteres]).buffer(TOLERANCE, 100)
|
|
|
|
|
|
@@ -459,9 +497,6 @@ class Mn1Checker(BaseChecker):
|
|
|
if not arteres_full_buffer.contains(cable.geom):
|
|
|
self.log_error("Cable ou portion de cable sans artère", item=cable)
|
|
|
|
|
|
- def test_artere_cable(self):
|
|
|
- """ Chaque artère a au moins une cable (sauf cas spécifiques) """
|
|
|
-
|
|
|
# Verifie que chaque artère a au moins un cable (sauf si commentaire contient un de ces mots 'racco client adductio attente bus 'sans cable'')
|
|
|
cables_full_buffer = QgsGeometry().unaryUnion([c.geom for c in self.cables]).buffer(TOLERANCE, 100)
|
|
|
|
|
|
@@ -472,7 +507,8 @@ class Mn1Checker(BaseChecker):
|
|
|
self.log_error("Artère ou portion d'artère sans cable", item=artere)
|
|
|
|
|
|
def test_dimensions_fourreaux(self):
|
|
|
- """ Nombres de fourreaux cohérents """
|
|
|
+ """ Dimensions logiques: fourreaux
|
|
|
+ Vérifie que les nombres de fourreaux renseignés sont cohérents """
|
|
|
|
|
|
for artere in self.arteres:
|
|
|
try:
|
|
|
@@ -491,7 +527,9 @@ class Mn1Checker(BaseChecker):
|
|
|
pass
|
|
|
|
|
|
def test_pbos(self):
|
|
|
- """ PBO / ZAPBO """
|
|
|
+ """ Topologie: PBO / ZAPBO
|
|
|
+ Compare la géométrie et le nom des équipements de type PBO à celle des ZAPBO
|
|
|
+ """
|
|
|
|
|
|
# Verifier que chaque equipement de type PBO est contenu dans une zapbo, et que le nom de la zapbo contient le nom de l'equipement
|
|
|
for equipement in self.equipements:
|
|
|
@@ -513,11 +551,11 @@ class Mn1Checker(BaseChecker):
|
|
|
try:
|
|
|
equipement.zapbo = next((z for z in candidates if equipement.EQ_NOM in z.ID_ZAPBO))
|
|
|
except StopIteration:
|
|
|
- self.log_error("Le nom du PBO ne coincide avec le nom d'aucune des ZAPBO qui le contient", item=equipement)
|
|
|
+ self.log_error("Le nom du PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent", item=equipement)
|
|
|
break
|
|
|
|
|
|
|
|
|
- # a venir
|
|
|
+ # a venir (webservice?)
|
|
|
def __test_pbo_dimension(self):
|
|
|
""" Dimensionnement des PBO """
|
|
|
for equipement in self.equipements:
|