|
@@ -3,12 +3,11 @@ Python 3.7+
|
|
|
|
|
|
|
|
@author: olivier.massot, sept 2018
|
|
@author: olivier.massot, sept 2018
|
|
|
'''
|
|
'''
|
|
|
-from dataclasses import dataclass
|
|
|
|
|
from datetime import datetime
|
|
from datetime import datetime
|
|
|
import logging
|
|
import logging
|
|
|
-import sys
|
|
|
|
|
|
|
+import zipfile
|
|
|
|
|
|
|
|
-from path import Path
|
|
|
|
|
|
|
+from path import Path, TempDir
|
|
|
import shapefile
|
|
import shapefile
|
|
|
import yaml
|
|
import yaml
|
|
|
|
|
|
|
@@ -16,38 +15,32 @@ from core import logconf
|
|
|
from core.constants import MAIN
|
|
from core.constants import MAIN
|
|
|
|
|
|
|
|
|
|
|
|
|
-logger = logging.getLogger("netgeo_checker")
|
|
|
|
|
-logconf.start("netgeo_checker", logging.INFO)
|
|
|
|
|
-
|
|
|
|
|
-ETUDE, IN_DIR = False, MAIN / "work" / "SCOPELEC_CAP_097AP0_REC_180829_OK"
|
|
|
|
|
-# ETUDE, IN_DIR = True, MAIN / "rsc" / "data_in" / "SCOPELEC_101BP0_APD_180725"
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-subject = MAIN / "work" / "SCOPELEC_CAP_097AP0_REC_180829_OK"
|
|
|
|
|
-checker = MAIN / "resources" / "netgeo_v2-2_doe.yaml"
|
|
|
|
|
-
|
|
|
|
|
-# prendre une archive en entrée
|
|
|
|
|
-# contrôler la presence des 6 fichiers shp
|
|
|
|
|
-# Pour chaque couche, vérifier le type de géometrie, la presence de données, la projection, l'inclusion du bounding rect dans le departement
|
|
|
|
|
-# Charger les modèles
|
|
|
|
|
-# Vérifier enregistrement par enregistrement la validité des données
|
|
|
|
|
-
|
|
|
|
|
|
|
+logger = logging.getLogger("datachecker")
|
|
|
|
|
+logconf.start("datachecker", logging.INFO)
|
|
|
|
|
|
|
|
|
|
+# TODO Vérifier la projection (besoin de GDAL/OGR)
|
|
|
|
|
|
|
|
def check(subject, checker):
|
|
def check(subject, checker):
|
|
|
""" prends un dossier ou une archive en entier et vérifie son contenu selon les règles données par le fichier de config """
|
|
""" prends un dossier ou une archive en entier et vérifie son contenu selon les règles données par le fichier de config """
|
|
|
- archive, checker = Path(subject), Path(checker)
|
|
|
|
|
|
|
+ subject, checker = Path(subject), Path(checker)
|
|
|
|
|
|
|
|
- if archive.isfile():
|
|
|
|
|
- # extraire vers un dossier temp
|
|
|
|
|
- # dirname = tempdir
|
|
|
|
|
- pass
|
|
|
|
|
- elif archive.isdir():
|
|
|
|
|
- dirname = subject
|
|
|
|
|
|
|
+ if subject.isfile():
|
|
|
|
|
+ with TempDir() as dirname:
|
|
|
|
|
+ zip_ref = zipfile.ZipFile(subject, 'r')
|
|
|
|
|
+ zip_ref.extractall(dirname)
|
|
|
|
|
+ zip_ref.close()
|
|
|
|
|
+ print()
|
|
|
|
|
+ if Path(dirname / subject.stem).isdir(): # cas où l'archive contient un dossier qui lui-même contient les fichiers
|
|
|
|
|
+ dirname /= subject.stem
|
|
|
|
|
+ check_folder(dirname, checker)
|
|
|
|
|
+
|
|
|
|
|
+ elif subject.isdir():
|
|
|
|
|
+ check_folder(subject, checker)
|
|
|
else:
|
|
else:
|
|
|
raise IOError(f"Impossible de trouver le fichier ou répertoire: {subject}")
|
|
raise IOError(f"Impossible de trouver le fichier ou répertoire: {subject}")
|
|
|
-
|
|
|
|
|
- logging.info("***** Traitement de '%s' *****", subject.name)
|
|
|
|
|
|
|
+
|
|
|
|
|
+def check_folder(folder, checker):
|
|
|
|
|
+ logging.info("***** Traitement de '%s' *****", folder.name)
|
|
|
|
|
|
|
|
logging.info("> Controlleur: '%s'", checker.name)
|
|
logging.info("> Controlleur: '%s'", checker.name)
|
|
|
|
|
|
|
@@ -55,20 +48,34 @@ def check(subject, checker):
|
|
|
config = yaml.load(cf)
|
|
config = yaml.load(cf)
|
|
|
|
|
|
|
|
for filename, model in config["files"].items():
|
|
for filename, model in config["files"].items():
|
|
|
- path_ = dirname / filename
|
|
|
|
|
|
|
+ path_ = folder / filename
|
|
|
logging.info("* Traitement de %s", path_.name)
|
|
logging.info("* Traitement de %s", path_.name)
|
|
|
|
|
|
|
|
|
|
+ if not path_.isfile():
|
|
|
|
|
+ logger.error("Fichier introuvable")
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
try:
|
|
try:
|
|
|
sf = shapefile.Reader(path_)
|
|
sf = shapefile.Reader(path_)
|
|
|
except shapefile.ShapefileException:
|
|
except shapefile.ShapefileException:
|
|
|
logger.error("Fichier SHAPE illisible")
|
|
logger.error("Fichier SHAPE illisible")
|
|
|
continue
|
|
continue
|
|
|
|
|
|
|
|
- shape_names = {1:"Point", 3:"Polyligne", 5:"Polygone"}
|
|
|
|
|
- if sf.shapeType != model["shape_type"]:
|
|
|
|
|
- logger.error("Le fichier shapefile n'est pas de type %s", shape_names[model["shape_type"]])
|
|
|
|
|
- del sf
|
|
|
|
|
- continue
|
|
|
|
|
|
|
+ if "srid" in config:
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ xmin, xmax, ymin, ymax = (int(config.get("xmin", 0)),
|
|
|
|
|
+ int(config.get("xmax", float("inf"))),
|
|
|
|
|
+ int(config.get("ymin", 0)),
|
|
|
|
|
+ int(config.get("ymax", float("inf")))
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if "shape_type" in model:
|
|
|
|
|
+ shape_names = {1:"Point", 3:"Polyligne", 5:"Polygone"}
|
|
|
|
|
+ if sf.shapeType != model["shape_type"]:
|
|
|
|
|
+ logger.error("Le fichier shapefile n'est pas de type %s", shape_names[model["shape_type"]])
|
|
|
|
|
+ del sf
|
|
|
|
|
+ continue
|
|
|
|
|
|
|
|
records = sf.shapeRecords()
|
|
records = sf.shapeRecords()
|
|
|
if not records:
|
|
if not records:
|
|
@@ -95,6 +102,11 @@ def check(subject, checker):
|
|
|
logging.info("\n> Enregistrement n°%s\n", i)
|
|
logging.info("\n> Enregistrement n°%s\n", i)
|
|
|
record_data = {field: record.record[i] for i, field in enumerate(fields)}
|
|
record_data = {field: record.record[i] for i, field in enumerate(fields)}
|
|
|
|
|
|
|
|
|
|
+ x1, y1, x2, y2 = sf.shapes()[i].bbox
|
|
|
|
|
+ if not xmin <= x1 <= xmax or not xmin <= x2 <= xmax or \
|
|
|
|
|
+ not ymin <= y1 <= ymax or not ymin <= y2 <= ymax:
|
|
|
|
|
+ logger.error("L'élément est situé hors de la zone autorisée")
|
|
|
|
|
+
|
|
|
for fieldname, fieldmodel in model["fields"].items():
|
|
for fieldname, fieldmodel in model["fields"].items():
|
|
|
|
|
|
|
|
try:
|
|
try:
|
|
@@ -133,5 +145,10 @@ def check(subject, checker):
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if __name__ == "__main__":
|
|
|
|
|
+
|
|
|
|
|
+ subject = MAIN / "work" / "SCOPELEC_CAP_097AP0_REC_180829_OK.zip"
|
|
|
|
|
+ checker = MAIN / "resources" / "netgeo_v2-2_doe.yaml"
|
|
|
|
|
+
|
|
|
check(subject, checker)
|
|
check(subject, checker)
|
|
|
|
|
+
|
|
|
logger.info("-- Fin --")
|
|
logger.info("-- Fin --")
|