2024-11-26 14:56:34 +01:00

419 lines
15 KiB
Python

# -*- coding: utf-8 -*-
"""
/***************************************************************************
BackinMFU
A QGIS plugin
Permet de créer une nouvelle session d'animation foncière
-------------------
begin : 2015-10-02
git sha : $Format:%H$
copyright : (C) 2015 by CEN Savoie
email : a.lesconnec@cen-savoie.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QAction, QTableWidgetItem
from PyQt5.QtXml import QDomDocument
from qgis.core import *
from qgis.gui import *
# Initialize Qt resources from file resources.py
from pluginsCenSavoie_v3 import resources
# Import the code for the dialog
from pluginsCenSavoie_v3.tools.backinMFU_dialog import BackinMFUDialog
# Import du fichier de configuration
from pluginsCenSavoie_v3.tools.confPython import bd_cen_host, bd_cen_port, bd_cen_name, bd_cen_mdp_1st_cnx
import os.path
import sys
import qgis
import os
import psycopg2
import psycopg2.extras
import base64
import re
from time import localtime, strftime
class BackinMFU:
"""QGIS Plugin Implementation."""
def __init__(self, iface, cenToolbar):
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
application at run time.
:type iface: QgsInterface
"""
# Variable HOTE de l'accès à la base de données
global host
host = bd_cen_host
global port
port = bd_cen_port
global bdd
bdd = bd_cen_name
global mdp_1st_cnx
mdp_1st_cnx = bd_cen_mdp_1st_cnx
global os_user
if sys.platform == 'linux':
os_user = os.environ['USER']
else:
os_user = os.environ['USERNAME']
# Save reference to the QGIS interface
self.iface = iface
self.canvas = self.iface.mapCanvas()
# initialize plugin directory
self.plugin_dir = os.path.dirname(__file__)
# Create the dialog (after translation) and keep reference
self.dlg = BackinMFUDialog()
# Add toolbar button
self.action= QAction(QIcon(":/plugins/pluginsCenSavoie_v3/icons/backinMFU.png"), QCoreApplication.translate('BackinMFU', u'Retour vers la MFU'), self.iface.mainWindow())
self.action.triggered.connect(self.run)
self.action.setEnabled(True)
cenToolbar.addAction(self.action)
def run(self):
"""Run method that performs all the real work"""
# show the dialog
self.dlg.img_logo.setPixmap(QPixmap(":/plugins/pluginsCenSavoie_v3/tools/images/Logo_CEN_Savoie.png"))
self.dlg.lbl_delorean.setPixmap(QPixmap(":/plugins/pluginsCenSavoie_v3/tools/images/delorean.png"))
self.dlg.lbl_fond.setPixmap(QPixmap(":/plugins/pluginsCenSavoie_v3/tools/images/fond_70.png"))
self.dlg.lbl_fond.stackUnder(self.dlg.button_box)
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result:
first_conn = psycopg2.connect("host=" + host + " port=" + port + " dbname=" + bdd + " user=first_cnx password=" + mdp_1st_cnx)
first_cur = first_conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
first_cur.execute("SELECT mdp_cen, usename FROM pg_catalog.pg_user t1, admin_sig.utilisateurs t2 WHERE t2.oid = t1.usesysid AND (utilisateur_id = '" + os_user + "' OR utilisateur_os = '" + os_user + "')")
res_ident = first_cur.fetchone()
mdp = base64.b64decode(str(res_ident[0])).decode('utf-8')
user = res_ident[1]
first_conn.close()
uri = QgsDataSourceUri()
uri.setConnection(host ,port ,bdd ,user ,mdp)
calDate = self.dlg.calSelect.selectedDate().toString('yyyy-MM-dd')
table_name = 'mfu_'+calDate
sql = """
WITH RECURSIVE table_lot AS (
SELECT
site_id,
old_cad_site_id,
new_lot_id,
new_lot_id AS lot_id_origin,
0 AS level,
ARRAY[old_cad_site_id, new_cad_site_id] as tbl_cad_site_id
FROM
foncier_maj.vm_filiation_parcelles
WHERE diff_surf = 0
UNION
SELECT
v.site_id,
v.old_cad_site_id,
v.new_lot_id,
t.lot_id_origin,
t.level + 1,
CASE WHEN v.old_cad_site_id = ANY (t.tbl_cad_site_id) THEN
CASE WHEN v.new_cad_site_id = ANY (t.tbl_cad_site_id) THEN
t.tbl_cad_site_id
ELSE
array_append(t.tbl_cad_site_id, v.new_cad_site_id)
END
ELSE
CASE WHEN v.new_cad_site_id = ANY (t.tbl_cad_site_id) THEN
array_append(t.tbl_cad_site_id, v.old_cad_site_id)
ELSE
array_append(array_append(t.tbl_cad_site_id, v.old_cad_site_id), v.new_cad_site_id)
END
END
FROM
foncier_maj.vm_filiation_parcelles as v
INNER JOIN table_lot as t ON (t.old_cad_site_id = v.new_cad_site_id)
WHERE diff_surf = 0
),
t_max_level AS (
SELECT lot_id_origin, max(level) as level FROM table_lot GROUP BY lot_id_origin
),
t_filiation_lots AS (
SELECT DISTINCT
table_lot.site_id, table_lot.lot_id_origin, table_lot.tbl_cad_site_id
FROM
table_lot
JOIN t_max_level USING (lot_id_origin, level)
LEFT JOIN table_lot as table_lot2 ON (table_lot2.tbl_cad_site_id @> table_lot.tbl_cad_site_id AND table_lot2.tbl_cad_site_id <> table_lot.tbl_cad_site_id AND table_lot2.site_id = table_lot.site_id)
WHERE table_lot2.tbl_cad_site_id IS NULL
),
tprob AS (
SELECT DISTINCT unnest(string_to_array(array_to_string(array_agg(site_id), ','), ',')) AS site_id
FROM (
SELECT DISTINCT site_id FROM alertes.v_prob_mfu_baddata
UNION
SELECT DISTINCT site_id FROM alertes.v_prob_cadastre_cen WHERE statutmfu_id = 1
UNION
SELECT DISTINCT site_id FROM alertes.v_alertes_mu WHERE alerte LIKE 'termin%'
UNION
SELECT DISTINCT substring(v_prob_mfu_sansparc.mfu_id::text, 4, 4) AS site_id FROM alertes.v_prob_mfu_sansparc
) tsousprob
),
t_actes AS (
SELECT
acte,
mfu_id,
COALESCE(date_effet_conv, date_sign_acte) as date_acte_debut,
COALESCE(NULLIF(date_fin_acte, 'N.D.'), COALESCE(last_end, 'infini')) as date_acte_fin
FROM alertes.v_tdb_mfu
WHERE
statutmfu_id NOT IN (0, 3)
),
t_temp_mu AS (
SELECT DISTINCT
cadastre_site.site_id,
par_id,
COALESCE(lot_id_origin, lot_id) AS lot_id,
COALESCE(r_cad_site_mu.surf_mu, dcntlo) as dcntlo,
COALESCE(r_cad_site_mu.geom, parcelles_cen.geom) as geom,
CASE WHEN surf_mu IS NOT NULL THEN 'Convention pour partie' ELSE 'Convention' END AS mfu,
mu_id AS mfu_id,
r_cad_site_mu.date_entree,
r_cad_site_mu.date_sortie,
r_cad_site_mu.motif_entree_id
FROM
cadastre.parcelles_cen
JOIN cadastre.lots_cen USING (par_id)
JOIN cadastre.cadastre_cen USING (lot_id)
JOIN foncier.cadastre_site USING (cad_cen_id)
JOIN foncier.r_cad_site_mu USING (cad_site_id)
JOIN foncier.mu_conventions USING (mu_id)
JOIN foncier.d_typmu USING (typmu_id)
LEFT JOIN t_filiation_lots ON (t_filiation_lots.site_id = cadastre_site.site_id AND cad_site_id = ANY(tbl_cad_site_id))
WHERE d_typmu.mfu = 't'
),
t_synthese_mu AS (
SELECT
site_id,
par_id,
lot_id,
dcntlo as surf_mfu,
geom,
mfu,
mfu_id,
date_acte_debut,
GREATEST(MIN(date_entree), date_acte_debut) as min_date_entree_mu,
LEAST(MAX(date_sortie), date_acte_fin) as max_date_sortie_mu
FROM
t_temp_mu
JOIN t_actes USING (mfu_id)
GROUP BY t_temp_mu.site_id, t_temp_mu.par_id, t_temp_mu.lot_id, t_temp_mu.dcntlo, t_temp_mu.geom, t_temp_mu.mfu, t_temp_mu.mfu_id, t_actes.date_acte_debut, t_actes.date_acte_fin
),
t_temp_mf AS (
SELECT DISTINCT
cadastre_site.site_id,
par_id,
COALESCE(lot_id_origin, lot_id) AS lot_id,
dcntlo,
parcelles_cen.geom,
'Acquisition' AS mfu,
mf_id AS mfu_id,
r_cad_site_mf.date_entree,
r_cad_site_mf.date_sortie
FROM
cadastre.parcelles_cen
JOIN cadastre.lots_cen USING (par_id)
JOIN cadastre.cadastre_cen USING (lot_id)
JOIN foncier.cadastre_site USING (cad_cen_id)
JOIN foncier.r_cad_site_mf USING (cad_site_id)
LEFT JOIN t_filiation_lots ON (t_filiation_lots.site_id = cadastre_site.site_id AND cad_site_id = ANY(tbl_cad_site_id))
),
t_synthese_mf AS (
SELECT
site_id,
par_id,
lot_id,
dcntlo as surf_mfu,
geom,
mfu,
mfu_id,
date_acte_debut,
GREATEST(MIN(date_entree), date_acte_debut) as min_date_entree_mf,
LEAST(MAX(date_sortie), date_acte_fin) as max_date_sortie_mf
FROM
t_temp_mf
JOIN t_actes USING (mfu_id)
GROUP BY t_temp_mf.site_id, t_temp_mf.lot_id, t_temp_mf.par_id, t_temp_mf.dcntlo, t_temp_mf.geom, t_temp_mf.mfu, t_temp_mf.mfu_id, t_actes.date_acte_debut, t_actes.date_acte_fin
),
tmfu AS (
SELECT DISTINCT
site_id,
par_id,
geom,
lot_id,
surf_mfu as surf_acq,
0 as surf_conv,
mfu,
mfu_id as acte_id,
date_acte_debut,
LEFT(min_date_entree_mf, 10) AS min_date_entree_mf,
LEFT(max_date_sortie_mf, 10) AS max_date_sortie_mf,
'3000-01-01' as min_date_entree_mu,
'3000-12-31' as max_date_sortie_mu,
0 AS motif_entree_id_mu,
CASE WHEN tprob.site_id IS NOT NULL THEN 1 ELSE 0 END as etat_bilan
FROM
t_synthese_mf
LEFT JOIN tprob USING (site_id)
UNION
SELECT DISTINCT
t_synthese_mu.site_id,
t_synthese_mu.par_id,
t_synthese_mu.geom,
t_synthese_mu.lot_id,
0 as surf_acq,
surf_mfu as surf_conv,
t_synthese_mu.mfu,
t_synthese_mu.mfu_id as acte_id,
date_acte_debut,
'3000-01-01' as min_date_entree_mf,
'3000-12-31' as max_date_sortie_mf,
LEFT(min_date_entree_mu, 10) AS min_date_entree_mu,
LEFT(max_date_sortie_mu, 10) AS max_date_sortie_mu,
motif_entree_id AS motif_entree_id_mu,
CASE WHEN tprob.site_id IS NOT NULL THEN 1 ELSE 0 END as etat_bilan
FROM
t_synthese_mu
JOIN t_temp_mu ON (t_synthese_mu.site_id = t_temp_mu.site_id AND t_synthese_mu.min_date_entree_mu = t_temp_mu.date_entree AND t_synthese_mu.mfu_id = t_temp_mu.mfu_id AND t_synthese_mu.lot_id = t_temp_mu.lot_id)
LEFT JOIN tprob ON (t_synthese_mu.site_id = tprob.site_id)
),
t_bilan1 AS (
SELECT DISTINCT
site_id, lot_id, par_id, geom, mfu, acte_id, min_date_entree_mf, max_date_sortie_mf, min_date_entree_mu, max_date_sortie_mu,
CASE WHEN mfu = 'Acquisition' AND min_date_entree_mf <= '"""+calDate+"""' AND (max_date_sortie_mf = 'N.D.' OR max_date_sortie_mf >= '"""+calDate+"""') THEN
surf_acq
ELSE
0
END AS surf_acqu,
CASE WHEN mfu LIKE 'Convention%' AND min_date_entree_mu <= '"""+calDate+"""' AND (max_date_sortie_mu = 'N.D.' OR max_date_sortie_mu >= '"""+calDate+"""') THEN
surf_conv
ELSE
0
END AS surf_conv,
etat_bilan
FROM
tmfu
),
tmfu_one_day1 AS (
SELECT tmfu.*, t_bilan1.surf_acqu, t_bilan1.surf_conv
FROM
t_bilan1
JOIN tmfu USING (lot_id)
WHERE
(t_bilan1.surf_acqu > 0 AND t_bilan1.max_date_sortie_mf = '"""+calDate+"""') OR
(t_bilan1.surf_conv > 0 AND t_bilan1.max_date_sortie_mu = '"""+calDate+"""')
),
tmfu_one_day2 AS (
SELECT old_lot_id, array_agg(new_lot_id) as tbl_lot_one_day
FROM
tmfu_one_day1
JOIN foncier_maj.vm_filiation_parcelles ON (lot_id = old_lot_id AND tmfu_one_day1.site_id = vm_filiation_parcelles.site_id)
JOIN tmfu ON (new_lot_id = tmfu.lot_id)
WHERE
(
surf_acqu > 0 AND
tmfu.min_date_entree_mf != 'N.D.' AND tmfu_one_day1.max_date_sortie_mf != 'N.D.' AND
tmfu.min_date_entree_mf::date = tmfu_one_day1.max_date_sortie_mf::date +'1 day'::interval
)
OR
(
tmfu.surf_conv > 0 AND
tmfu.min_date_entree_mu != 'N.D.' AND tmfu_one_day1.max_date_sortie_mu != 'N.D.' AND
tmfu.min_date_entree_mu::date = tmfu_one_day1.max_date_sortie_mu::date +'1 day'::interval
)
GROUP BY old_lot_id
UNION
SELECT new_lot_id, array_agg(old_lot_id) as tbl_lot_one_day
FROM
tmfu_one_day1
JOIN foncier_maj.vm_filiation_parcelles ON (lot_id = new_lot_id AND tmfu_one_day1.site_id = vm_filiation_parcelles.site_id)
JOIN tmfu ON (old_lot_id = tmfu.lot_id)
WHERE
(
surf_acqu > 0 AND
tmfu.max_date_sortie_mf != 'N.D.' AND tmfu_one_day1.min_date_entree_mf != 'N.D.' AND
tmfu.max_date_sortie_mf::date = tmfu_one_day1.min_date_entree_mf::date -'1 day'::interval
)
OR
(
tmfu.surf_conv > 0 AND
tmfu.max_date_sortie_mu != 'N.D.' AND tmfu_one_day1.min_date_entree_mu != 'N.D.' AND
tmfu.max_date_sortie_mu::date = tmfu_one_day1.min_date_entree_mu::date -'1 day'::interval
)
GROUP BY new_lot_id
),
t_bilan2 AS (
SELECT DISTINCT
tmfu.site_id, old_lot_id as lot_id, par_id, geom, mfu, tmfu.acte_id, tmfu.min_date_entree_mf, tmfu.max_date_sortie_mf, tmfu.min_date_entree_mu, tmfu.max_date_sortie_mu,
CASE WHEN tmfu.mfu = 'Acquisition' THEN tmfu.surf_acq ELSE 0 END AS surf_acqu,
CASE WHEN tmfu.mfu LIKE 'Convention%' THEN tmfu.surf_conv ELSE 0 END AS surf_conv,
tmfu.etat_bilan
FROM
tmfu_one_day2
JOIN tmfu ON (tmfu.lot_id = ANY(tbl_lot_one_day))
),
t_bilan3 AS (
SELECT
site_id, par_id, geom, mfu,
COALESCE(SUM(surf_acqu), 0) AS surf_acqu,
COALESCE(SUM(surf_conv), 0) AS surf_conv,
MAX(etat_bilan) AS etat_bilan
FROM (SELECT * FROM t_bilan1 UNION SELECT * FROM t_bilan2) as t
GROUP BY site_id, par_id, geom, mfu
HAVING SUM(surf_acqu) > 0 OR SUM(surf_conv) > 0
),
t_bilan4 AS (
SELECT DISTINCT
t_bilan3.par_id,
sites.site_id,
array_to_string(array_agg(DISTINCT mfu ORDER BY mfu), ' / ') as mfu,
SUM(CASE WHEN surf_acqu > 0 THEN surf_acqu ELSE surf_conv END) as surf_mfu,
MAX(geom) as geom,
etat_bilan
FROM
sites.sites
JOIN t_bilan3 USING (site_id)
GROUP BY t_bilan3.par_id, sites.site_id, t_bilan3.etat_bilan
)
SELECT
row_number() OVER (ORDER BY par_id) AS gid,
t_bilan4.*
FROM
t_bilan4
ORDER BY site_id, par_id """
uri.setDataSource("", u"(%s\n)" % sql, "geometrie", "", "gid")
layer = self.iface.addVectorLayer(uri.uri(), table_name, "postgres")
styleText = layer.getStyleFromDatabase(str(22))[0]
styleDoc = QDomDocument()
styleDoc.setContent(styleText)
layer.importNamedStyle(styleDoc)
self.dlg.close()
self.canvas.refresh()