| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- '''
- Python 3.7+
- @author: olivier.massot, sept 2018
- '''
- from dataclasses import dataclass
- from datetime import datetime
- import logging
- import sys
- from path import Path
- import shapefile
- import yaml
- from core import logconf
- 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
- 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 """
- archive, checker = Path(subject), Path(checker)
-
- if archive.isfile():
- # extraire vers un dossier temp
- # dirname = tempdir
- pass
- elif archive.isdir():
- dirname = subject
- else:
- raise IOError(f"Impossible de trouver le fichier ou répertoire: {subject}")
-
- logging.info("***** Traitement de '%s' *****", subject.name)
-
- logging.info("> Controlleur: '%s'", checker.name)
-
- with open(checker, "r") as cf:
- config = yaml.load(cf)
-
- for filename, model in config["files"].items():
- path_ = dirname / filename
- logging.info("* Traitement de %s", path_.name)
-
- try:
- sf = shapefile.Reader(path_)
- except shapefile.ShapefileException:
- logger.error("Fichier SHAPE illisible")
- 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
- records = sf.shapeRecords()
- if not records:
- if not model["can_be_empty"]:
- logger.error("Le fichier shapefile ne contient aucune donnees")
- del sf, records
- continue
- else:
- logger.warning("Le fichier shapefile ne contient aucune donnees")
-
- if not "fields" in model:
- continue
-
- fields = [f[0] for f in sf.fields if f[0] != 'DeletionFlag']
-
- # controle d'éventuels champs inconnus
- for f in fields:
- if f not in model["fields"]:
- logger.warning("Champs inconnu: %s", f)
-
- # parcours et controle des enregistrements
- for i, record in enumerate(records):
-
- logging.info("\n> Enregistrement n°%s\n", i)
- record_data = {field: record.record[i] for i, field in enumerate(fields)}
-
- for fieldname, fieldmodel in model["fields"].items():
-
- try:
- val = record_data[fieldname]
- except KeyError:
- if fieldmodel.get("required", True):
- logger.error("%s - Champs manquant", fieldname)
- continue
-
- type_ = fieldmodel.get("type", "str")
- if type_ == "float":
- try:
- _ = float(val)
- except (TypeError, ValueError):
- logger.error("%s - Valeur invalide, un flottant est attendu ('%s')", fieldname, val)
- continue
- elif type_ == "datetime":
- try:
- _ = datetime.strptime(val, fieldmodel.get("date_format", "%d/%m/%Y"))
- except ValueError:
- logger.error("%s - Valeur invalide, une date est attendu ('%s')", fieldname, val)
- continue
- else:
- if not fieldmodel.get("allow_empty", False) and not val:
- logger.error("%s - Champs vide", fieldname)
- continue
-
- try:
- if not val in fieldmodel["in_list"]:
- logger.error("%s - Valeur invalide, pas dans la liste ('%s')", fieldname, val)
- continue
- except KeyError:
- pass
-
- del sf, records
- if __name__ == "__main__":
- check(subject, checker)
- logger.info("-- Fin --")
|