|
|
@@ -0,0 +1,195 @@
|
|
|
+"""
|
|
|
+
|
|
|
+ Importe les données géographiques des essais de compactage depuis les fichiers Shapefile
|
|
|
+ recus des exploitants vers la base Postgis de ControlesSig
|
|
|
+
|
|
|
+ - Ajoute de nouveaux chantiers / points de compactage à la base POSTGIS
|
|
|
+ - Les chantiers créés sont issus des dossiers du répertoire 'compactage_dir'
|
|
|
+ - Une fois importés, ces dossiers sont renommés 'XXXXXX' > 'I_XXXXXX'
|
|
|
+ - Les noms complets des chantiers sont récupérés dans la base Controles
|
|
|
+
|
|
|
+@author: olivier.massot, mai 2018
|
|
|
+"""
|
|
|
+import logging
|
|
|
+import re
|
|
|
+import sys
|
|
|
+
|
|
|
+from path import Path
|
|
|
+import shapefile
|
|
|
+
|
|
|
+from core import logconf
|
|
|
+from core.pde import ControlesDb, CSigDb, COMPACTAGE_DIR, QGisChantier, \
|
|
|
+ QGisPoint, SRID
|
|
|
+from core.sqlformatter import SqlFormatter
|
|
|
+
|
|
|
+
|
|
|
+logger = logging.getLogger("qgis_sync_compactage")
|
|
|
+logconf.start("qgis_sync_compactage", logging.DEBUG)
|
|
|
+
|
|
|
+# # POUR TESTER, décommenter les lignes suivantes
|
|
|
+##-----------------------------------------------
|
|
|
+
|
|
|
+ControlesDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\cg67Parc_data.mdb")
|
|
|
+logger.handlers = [h for h in logger.handlers if (type(h) == logging.StreamHandler)]
|
|
|
+logger.warning("<<<<<<<<<<<<<< Mode TEST >>>>>>>>>>>>>>>>>")
|
|
|
+
|
|
|
+##-----------------------------------------------
|
|
|
+
|
|
|
+Sql = SqlFormatter()
|
|
|
+
|
|
|
+# Connexion à ControlesSig (postgres)
|
|
|
+csig_db = CSigDb(autocommit=False)
|
|
|
+
|
|
|
+# Connexion à Controles
|
|
|
+controles_db = ControlesDb(autocommit=False)
|
|
|
+
|
|
|
+# Regex pour parser les noms de repertoires
|
|
|
+rx = re.compile(r"^(I_)?(\d{5,6})(-S?\d{1,2})?[\s_]?(.*)$")
|
|
|
+
|
|
|
+a_importer = [subdir for subdir in COMPACTAGE_DIR.dirs() if rx.search(subdir.name) and not subdir.name[:2] == "I_"]
|
|
|
+
|
|
|
+if a_importer:
|
|
|
+ # !!! Selection des chantiers à importer
|
|
|
+ pass
|
|
|
+
|
|
|
+if not a_importer:
|
|
|
+ logger.info("Aucun nouveau dossier à importer")
|
|
|
+ sys.exit()
|
|
|
+
|
|
|
+chantiers = []
|
|
|
+
|
|
|
+# ** Read the data in the shapefiles and store it in memory **
|
|
|
+for chantier_dir_path in a_importer:
|
|
|
+ logger.info("** %s", chantier_dir_path)
|
|
|
+
|
|
|
+ # instanciate a new Chantier
|
|
|
+ chantier = QGisChantier()
|
|
|
+ chantier.dir_path = chantier_dir_path
|
|
|
+
|
|
|
+ logger.debug("> parse path")
|
|
|
+ parsed = rx.search(chantier_dir_path.name)
|
|
|
+ chantier.number = parsed.group(2)
|
|
|
+ chantier.complement = parsed.group(3)
|
|
|
+ logger.debug("> number: %s, compl: %s", chantier.number, chantier.complement)
|
|
|
+
|
|
|
+ # query for name in ControlesDb
|
|
|
+ logger.debug("> Query ControlesDb for chantier's name")
|
|
|
+ row = controles_db.first("""SELECT tblChantiers.lngChantierId, tblCollectivites.strNom
|
|
|
+ FROM tblChantiers INNER JOIN tblCollectivites
|
|
|
+ ON tblChantiers.strCollectiviteId = tblCollectivites.strCollectiviteId
|
|
|
+ WHERE lngChantierId = {lngChantierId};""".format(lngChantierId=chantier.number))
|
|
|
+
|
|
|
+ chantier.name = "{} {}".format(chantier.number, row.strNom)
|
|
|
+ logger.debug("> {}".format(chantier.name))
|
|
|
+
|
|
|
+ # importe le fichier shape dans une couche temp
|
|
|
+ shp_path = chantier_dir_path / "{}_p_PointCompactage.shp".format(chantier_dir_path.name)
|
|
|
+
|
|
|
+ logger.debug("Read the shapefile: %s", shp_path)
|
|
|
+
|
|
|
+ sf = shapefile.Reader(shp_path)
|
|
|
+
|
|
|
+ # should we check? :
|
|
|
+ if sf.shapeType != 1:
|
|
|
+ logger.error("Le fichier shapefile n'est pas de type POINT")
|
|
|
+ sys.exit(1)
|
|
|
+
|
|
|
+ sh_points = sf.shapeRecords()
|
|
|
+ if not sh_points:
|
|
|
+ logger.error("Le fichier shapefile ne contient aucune donnees")
|
|
|
+ sys.exit(1)
|
|
|
+
|
|
|
+ chantier.points = []
|
|
|
+ for sh_point in sh_points:
|
|
|
+
|
|
|
+ # create the Point instance
|
|
|
+ point = QGisPoint()
|
|
|
+ point.number = sh_point.record[0]
|
|
|
+ point.name = sh_point.record[1]
|
|
|
+ point.x, point.y = sh_point.shape.points[0]
|
|
|
+ logger.debug("> {}".format(point))
|
|
|
+ chantier.points.append(point)
|
|
|
+
|
|
|
+ # compute the chantier's rect coordinates
|
|
|
+ logger.debug("Compute the chantier's rect coordinates")
|
|
|
+ chantier.x0 = min([point.x for point in chantier.points])
|
|
|
+ chantier.x1 = max([point.x for point in chantier.points])
|
|
|
+ chantier.y0 = min([point.y for point in chantier.points])
|
|
|
+ chantier.y1 = max([point.y for point in chantier.points])
|
|
|
+ logger.debug("> ({}, {}, {}, {})".format(chantier.x0, chantier.x1, chantier.y0, chantier.y1))
|
|
|
+
|
|
|
+ chantiers.append(chantier)
|
|
|
+
|
|
|
+# ** Insère les chantiers dans la base **
|
|
|
+
|
|
|
+for chantier in chantiers:
|
|
|
+ logger.debug("** Chantier {}: {} points".format(chantier.name, len(chantier.points)))
|
|
|
+
|
|
|
+ # Contrôle si un chantier portant ce nom n'existe pas déjà dans la base
|
|
|
+ row = csig_db.first(u"SELECT id FROM t_chantiers WHERE nom = '{}';".format(chantier.name))
|
|
|
+ if row:
|
|
|
+ logger.warning("Un chantier portant ce nom existe déjà {} (id {})".format(chantier.name, row.id))
|
|
|
+ if input("Voulez-vous le remplacer? (o/n)") == "o":
|
|
|
+ # delete the old chantier
|
|
|
+ csig_db.execute("""DELETE FROM t_points_compactage
|
|
|
+ WHERE id_chantier = {};""".format(row.id))
|
|
|
+ csig_db.execute("""DELETE FROM t_chantiers
|
|
|
+ WHERE id = {};""".format(row.id))
|
|
|
+ logger.info("> L'ancien chantier a été supprimé".format(chantier.name, row.id))
|
|
|
+ else:
|
|
|
+ logger.warning("Import du chantier annulé")
|
|
|
+ continue
|
|
|
+
|
|
|
+ # Créé le chantier
|
|
|
+ q = csig_db.first("""INSERT INTO t_chantiers(id_type_chantier, numero, nom, geom, archive)
|
|
|
+ VALUES ({chantier_type}, {number}, '{name}', {geom}, {archive})
|
|
|
+ RETURNING id;
|
|
|
+ """.format(
|
|
|
+ chantier_type=2,
|
|
|
+ number=chantier.number,
|
|
|
+ name=chantier.name,
|
|
|
+ geom="ST_GeomFromText('POLYGON(({x0} {y0}, \
|
|
|
+ {x0} {y1}, {x1} {y1}, {x1} {y0}, {x0} {y0}))', {srid})".format(x0=chantier.x0,
|
|
|
+ x1=chantier.x1,
|
|
|
+ y0=chantier.y0,
|
|
|
+ y1=chantier.y1,
|
|
|
+ srid=SRID),
|
|
|
+ archive="FALSE"
|
|
|
+ )
|
|
|
+ )
|
|
|
+
|
|
|
+ # get its postgis ID
|
|
|
+ logger.debug("Getting newly created ID")
|
|
|
+ chantier.pgid = q.id
|
|
|
+ logger.debug("> {}".format(chantier.pgid))
|
|
|
+ q = None
|
|
|
+
|
|
|
+ # create the points
|
|
|
+ for point in chantier.points:
|
|
|
+ csig_db.execute("""INSERT INTO t_points_compactage(numero, nom, id_chantier, geom, archive)
|
|
|
+ VALUES ({number}, '{name}', {chantier_id}, {geom}, {archive});
|
|
|
+ """.format(
|
|
|
+ number=point.number,
|
|
|
+ name=point.name,
|
|
|
+ chantier_id=chantier.pgid,
|
|
|
+ geom="ST_GeomFromText('POINT({x} {y})', {srid})".format(x=point.x, y=point.y, srid=SRID),
|
|
|
+ archive="FALSE"
|
|
|
+ )
|
|
|
+ )
|
|
|
+
|
|
|
+ csig_db.commit()
|
|
|
+
|
|
|
+ # rename the directory to mark it as imported ('I_')
|
|
|
+ new_path = r"{}\I_{}".format(chantier.dir_path.parent, chantier.dir_path.name)
|
|
|
+ logger.debug("Rename {} to {}".format(chantier.dir_path, new_path))
|
|
|
+
|
|
|
+ chantier.dir_path.rename(new_path)
|
|
|
+
|
|
|
+ logger.info("Chantier importé")
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|