diff --git a/cenra.png b/cenra.png new file mode 100644 index 00000000..d53a910f Binary files /dev/null and b/cenra.png differ diff --git a/copie.py b/copie.py new file mode 100644 index 00000000..d2d26c83 --- /dev/null +++ b/copie.py @@ -0,0 +1,360 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + Copie + A QGIS plugin + Permet la copie d'une table dans une base PostGis + ------------------- + begin : 2015-04-13 + git sha : $Format:%H$ + copyright : (C) 2015 by Guillaume COSTES - CEN Rhône-Alpes + email : guillaume.costes@espaces-naturels.fr + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 __future__ import absolute_import +#from PyQt4.QtCore import * +#from PyQt4.QtGui import * +from qgis.PyQt.QtCore import QSettings +from qgis.PyQt.QtWidgets import QAction, QMenu, QDialog, QMessageBox +from qgis.PyQt.QtGui import QIcon +from PyQt5.QtCore import * +from PyQt5.QtGui import * +from qgis.core import QgsDataSourceUri +from builtins import str +from builtins import object +from qgis.core import * +from qgis.gui import * +# Initialize Qt resources from file resources.py +from . import resources_rc +# Import the code for the dialog +from .copie_dialog import CopieDialog +import os.path +from .PythonSQL import * +import psycopg2 +import psycopg2.extras +import base64 +#import socket +import os +#import sys + +class Copie(object): + """QGIS Plugin Implementation.""" + + def __init__(self, iface): + """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 + """ + # Save reference to the QGIS interface + self.iface = iface + # initialize plugin directory + self.plugin_dir = os.path.dirname(__file__) + # initialize locale + locale = QSettings().value('locale/userLocale')[0:2] + locale_path = os.path.join( + self.plugin_dir, + 'i18n', + 'Copie_{}.qm'.format(locale)) + + if os.path.exists(locale_path): + self.translator = QTranslator() + self.translator.load(locale_path) + + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(self.translator) + + # Create the dialog (after translation) and keep reference + self.dlg = CopieDialog() + + # Declare instance attributes + self.actions = [] + self.menu = self.tr(u'&Copie') + # TODO: We are going to let the user set this up in a future iteration + self.toolbar = self.iface.addToolBar(u'Copie') + self.toolbar.setObjectName(u'Copie') + + # noinspection PyMethodMayBeStatic + def tr(self, message): + """Get the translation for a string using Qt translation API. + + We implement this ourselves since we do not inherit QObject. + + :param message: String for translation. + :type message: str, QString + + :returns: Translated version of message. + :rtype: QString + """ + # noinspection PyTypeChecker,PyArgumentList,PyCallByClass + return QCoreApplication.translate('Copie', message) + + + def add_action( + self, + icon_path, + text, + callback, + enabled_flag=True, + add_to_menu=True, + add_to_toolbar=True, + status_tip=None, + whats_this=None, + parent=None): + """Add a toolbar icon to the toolbar. + + :param icon_path: Path to the icon for this action. Can be a resource + path (e.g. ':/plugins/foo/bar.png') or a normal file system path. + :type icon_path: str + + :param text: Text that should be shown in menu items for this action. + :type text: str + + :param callback: Function to be called when the action is triggered. + :type callback: function + + :param enabled_flag: A flag indicating if the action should be enabled + by default. Defaults to True. + :type enabled_flag: bool + + :param add_to_menu: Flag indicating whether the action should also + be added to the menu. Defaults to True. + :type add_to_menu: bool + + :param add_to_toolbar: Flag indicating whether the action should also + be added to the toolbar. Defaults to True. + :type add_to_toolbar: bool + + :param status_tip: Optional text to show in a popup when mouse pointer + hovers over the action. + :type status_tip: str + + :param parent: Parent widget for the new action. Defaults None. + :type parent: QWidget + + :param whats_this: Optional text to show in the status bar when the + mouse pointer hovers over the action. + + :returns: The action that was created. Note that the action is also + added to self.actions list. + :rtype: QAction + """ + + icon = QIcon(icon_path) + action = QAction(icon, text, parent) + action.triggered.connect(callback) + action.setEnabled(enabled_flag) + + if status_tip is not None: + action.setStatusTip(status_tip) + + if whats_this is not None: + action.setWhatsThis(whats_this) + + if add_to_toolbar: + self.toolbar.addAction(action) + + if add_to_menu: + self.iface.addPluginToMenu( + self.menu, + action) + + self.actions.append(action) + + return action + + def initGui(self): + """Create the menu entries and toolbar icons inside the QGIS GUI.""" + + icon_path = ':/plugins/Copie/table_copie.png' + self.add_action( + icon_path, + text=self.tr(u'Copie'), + callback=self.run, + parent=self.iface.mainWindow()) + + + def unload(self): + """Removes the plugin menu item and icon from QGIS GUI.""" + for action in self.actions: + self.iface.removePluginMenu( + self.tr(u'&Copie'), + action) + self.iface.removeToolBarIcon(action) + # remove the toolbar + del self.toolbar + + + def run(self): + """Run method that performs all the real work""" + layer = self.iface.activeLayer() + + if layer == None : + #self.iface.messageBar().pushMessage(u"Vous devez sélectionner une table !", level=QgsMessageBar.WARNING, duration=5) + self.iface.messageBar().pushMessage("Ooops", u"Vous devez sélectionner une table !", level=Qgis.Warning, duration=5) + + else : + # Récupération des sources de la couche active + list_sources = layer.source().split(" ") + # dbname + source_db = [s for s in list_sources if "dbname" in s][0].split("'")[1] + # schema + source_schema = [s for s in list_sources if "table" in s][0].split('"')[1] + # tablename + source_tablename = [s for s in list_sources if "table" in s][0].split('"')[3] + + if source_db != sigdb: + #self.iface.messageBar().pushMessage(u"Un référentiel ne peut être copié, utilisez les filtres !", level=QgsMessageBar.CRITICAL, duration=10) + self.iface.messageBar().pushMessage("Ooops", u"Vous ne pouvez copier des couches que dans sigXX", level=Qgis.Critical, duration=5) + + else : + + first_conn = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbname+" user=first_cnx password=" + password) + first_cur = first_conn.cursor(cursor_factory = psycopg2.extras.DictCursor) + first_cur.execute("SELECT mdp_w, login_w FROM pg_catalog.pg_user t1, admin_sig.vm_users_sig t2 WHERE t2.oid = t1.usesysid AND (login_w = '" + os_user + "' OR login_w = '" + os_user + "')") + res_ident = first_cur.fetchone() + mdp = base64.b64decode(str(res_ident[0])).decode('utf-8') + user = res_ident[1] + con = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbname+" user=" + user + " password=" + mdp) + cur = con.cursor(cursor_factory = psycopg2.extras.DictCursor) + first_conn.close() + + # Creation de la liste des schemas de la base de donnees + SQL = """WITH list_schema AS ( + SELECT catalog_name, schema_name + FROM information_schema.schemata + WHERE schema_name <> 'information_schema' + AND schema_name !~ E'^pg_' + ORDER BY schema_name + ) + + SELECT string_agg(schema_name,',') + FROM list_schema + GROUP BY catalog_name""" + + cur.execute(SQL) + + list_brut = str(next(cur)) + + list = list_brut [2:-3] + listItems = list.split(",") + + con.close() + + self.dlg.schema.clear() + self.dlg.schema.addItems(listItems) + self.dlg.schema.setCurrentIndex(-1) # Pour ne pas commencer la liste au premier schema + + + self.dlg.table_source.setText(source_schema + "." + source_tablename) # Affiche le nom de la table source + # show the dialog + self.dlg.show() + # Run the dialog event loop + result = self.dlg.exec_() + # See if OK was pressed + if result: + #******************************debut script********************************* + + + first_conn = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbname+" user=first_cnx password=" + password) + first_cur = first_conn.cursor(cursor_factory = psycopg2.extras.DictCursor) + first_cur.execute("SELECT mdp_w, login_w FROM pg_catalog.pg_user t1, admin_sig.vm_users_sig t2 WHERE t2.oid = t1.usesysid AND (login_w = '" + os_user + "' OR login_w = '" + os_user + "')") + res_ident = first_cur.fetchone() + mdp = base64.b64decode(str(res_ident[0])).decode('utf-8') + user = res_ident[1] + con = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbname+" user=" + user + " password=" + mdp) + cur = con.cursor(cursor_factory = psycopg2.extras.DictCursor) + first_conn.close() + # Récupération de la couche active + layer = self.iface.activeLayer() + + # Récupération des sources de la couche active + list_sources = layer.source().split(" ") + # dbname + source_db = [s for s in list_sources if "dbname" in s][0].split("'")[1] + # schema + source_schema = [s for s in list_sources if "table" in s][0].split('"')[1] + # tablename + source_tablename = [s for s in list_sources if "table" in s][0].split('"')[3] + + if self.dlg.schema.currentIndex() == -1 : + QMessageBox.warning(None, "Oups :", "Veuillez choisir un dossier de destination.") + return + + schema = self.dlg.schema.currentText() + + if self.dlg.table_destination.text() == '' : + QMessageBox.warning(None, "Oups :", "Veuillez choisir un nom de destination.") + return + + if self.dlg.annee.text() == 'aaaa' or self.dlg.annee.text() == '': + tablename = schema + "_" + self.dlg.table_destination.text().lower() + else : + tablename = schema + "_" + self.dlg.table_destination.text().lower() + "_" + self.dlg.annee.text() + + tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis + + if self.dlg.table_vide.isChecked() == 1 : + SQL_table = "CREATE TABLE " + schema + "." + tablename + " AS SELECT * FROM " + source_schema + "." + source_tablename + " LIMIT 0;" + else : + SQL_table = "CREATE TABLE " + schema + "." + tablename + " AS SELECT * FROM " + source_schema + "." + source_tablename + + + SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)" + SQL_sequence_01 = "CREATE SEQUENCE " + schema + "." + tablename + "_gid_seq" + " INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;" + SQL_sequence_02 = "ALTER TABLE " + schema + "." + tablename + " ALTER COLUMN gid SET DEFAULT nextval(\'" + schema + "." + tablename + "_gid_seq\'::regclass);" + SQL_sequence_03 = "SELECT setval(\'" + schema + "." + tablename + "_gid_seq\'::regclass, (SELECT max(gid) AS max_gid FROM " + schema + "." + tablename + "));" + SQL_sequence_04 = "ALTER SEQUENCE " + schema + "." + tablename + "_gid_seq" + " OWNED BY " + schema + "." + tablename + ".gid;" + + SQL_trigger_area_m2 = "CREATE TRIGGER area_m2" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.area_m2();" + SQL_trigger_area_ha = "CREATE TRIGGER area_ha" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.area_ha();" + SQL_trigger_length_m = "CREATE TRIGGER length_m" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.length_m();" + SQL_trigger_length_km = "CREATE TRIGGER length_km" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.length_km();" + SQL_trigger_coordonnees = "CREATE TRIGGER coordonnees" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.coordonnees();" + + cur.execute(SQL_table) + cur.execute(SQL_pkey) + cur.execute(SQL_sequence_01) + cur.execute(SQL_sequence_02) + cur.execute(SQL_sequence_03) + cur.execute(SQL_sequence_04) + + if layer.wkbType() == QgsWkbTypes.PointGeometry : + cur.execute(SQL_trigger_coordonnees) + + if layer.wkbType() == QgsWkbTypes.LineGeometry : + cur.execute(SQL_trigger_length_m) + cur.execute(SQL_trigger_length_km) + + if layer.wkbType() == QgsWkbTypes.PolygonGeometry : + cur.execute(SQL_trigger_area_m2) + cur.execute(SQL_trigger_area_ha) + + con.commit() + + ### Affichage de la table + uri = QgsDataSourceUri() + # set host name, port, database name, username and password + uri.setConnection(host ,port ,dbname ,user ,mdp) + # set database schema, table name, geometry column and optionaly subset (WHERE clause) + uri.setDataSource(schema, tablename, geom) + + layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres") + + con.commit() + con.close() + + #self.iface.messageBar().pushMessage("Table \"" + source_schema + "." + source_tablename + u"\" copiée dans \"" + schema + "." + tablename + "\"." , level=QgsMessageBar.INFO, duration=10) + self.iface.messageBar().pushMessage("Bravo!", "Table \"" + source_schema + "." + source_tablename + u"\" copiée dans \"" + schema + "." + tablename + "\".", level=Qgis.Success, duration=5) + pass diff --git a/copie.py.bak b/copie.py.bak new file mode 100644 index 00000000..057d5db1 --- /dev/null +++ b/copie.py.bak @@ -0,0 +1,360 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + Copie + A QGIS plugin + Permet la copie d'une table dans une base PostGis + ------------------- + begin : 2015-04-13 + git sha : $Format:%H$ + copyright : (C) 2015 by Guillaume COSTES - CEN Rhône-Alpes + email : guillaume.costes@espaces-naturels.fr + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 PyQt4.QtCore import * +#from PyQt4.QtGui import * +from qgis.core import * +from qgis.gui import * +# Initialize Qt resources from file resources.py +import resources_rc +# Import the code for the dialog +from copie_dialog import CopieDialog +import os.path + + +class Copie: + """QGIS Plugin Implementation.""" + + def __init__(self, iface): + """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 + """ + # Save reference to the QGIS interface + self.iface = iface + # initialize plugin directory + self.plugin_dir = os.path.dirname(__file__) + # initialize locale + locale = QSettings().value('locale/userLocale')[0:2] + locale_path = os.path.join( + self.plugin_dir, + 'i18n', + 'Copie_{}.qm'.format(locale)) + + if os.path.exists(locale_path): + self.translator = QTranslator() + self.translator.load(locale_path) + + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(self.translator) + + # Create the dialog (after translation) and keep reference + self.dlg = CopieDialog() + + # Declare instance attributes + self.actions = [] + self.menu = self.tr(u'&Copie') + # TODO: We are going to let the user set this up in a future iteration + self.toolbar = self.iface.addToolBar(u'Copie') + self.toolbar.setObjectName(u'Copie') + + # noinspection PyMethodMayBeStatic + def tr(self, message): + """Get the translation for a string using Qt translation API. + + We implement this ourselves since we do not inherit QObject. + + :param message: String for translation. + :type message: str, QString + + :returns: Translated version of message. + :rtype: QString + """ + # noinspection PyTypeChecker,PyArgumentList,PyCallByClass + return QCoreApplication.translate('Copie', message) + + + def add_action( + self, + icon_path, + text, + callback, + enabled_flag=True, + add_to_menu=True, + add_to_toolbar=True, + status_tip=None, + whats_this=None, + parent=None): + """Add a toolbar icon to the toolbar. + + :param icon_path: Path to the icon for this action. Can be a resource + path (e.g. ':/plugins/foo/bar.png') or a normal file system path. + :type icon_path: str + + :param text: Text that should be shown in menu items for this action. + :type text: str + + :param callback: Function to be called when the action is triggered. + :type callback: function + + :param enabled_flag: A flag indicating if the action should be enabled + by default. Defaults to True. + :type enabled_flag: bool + + :param add_to_menu: Flag indicating whether the action should also + be added to the menu. Defaults to True. + :type add_to_menu: bool + + :param add_to_toolbar: Flag indicating whether the action should also + be added to the toolbar. Defaults to True. + :type add_to_toolbar: bool + + :param status_tip: Optional text to show in a popup when mouse pointer + hovers over the action. + :type status_tip: str + + :param parent: Parent widget for the new action. Defaults None. + :type parent: QWidget + + :param whats_this: Optional text to show in the status bar when the + mouse pointer hovers over the action. + + :returns: The action that was created. Note that the action is also + added to self.actions list. + :rtype: QAction + """ + + icon = QIcon(icon_path) + action = QAction(icon, text, parent) + action.triggered.connect(callback) + action.setEnabled(enabled_flag) + + if status_tip is not None: + action.setStatusTip(status_tip) + + if whats_this is not None: + action.setWhatsThis(whats_this) + + if add_to_toolbar: + self.toolbar.addAction(action) + + if add_to_menu: + self.iface.addPluginToMenu( + self.menu, + action) + + self.actions.append(action) + + return action + + def initGui(self): + """Create the menu entries and toolbar icons inside the QGIS GUI.""" + + icon_path = ':/plugins/Copie/table_copie.png' + self.add_action( + icon_path, + text=self.tr(u'Copie'), + callback=self.run, + parent=self.iface.mainWindow()) + + + def unload(self): + """Removes the plugin menu item and icon from QGIS GUI.""" + for action in self.actions: + self.iface.removePluginMenu( + self.tr(u'&Copie'), + action) + self.iface.removeToolBarIcon(action) + # remove the toolbar + del self.toolbar + + + def run(self): + """Run method that performs all the real work""" + layer = self.iface.activeLayer() + + if layer == None : + self.iface.messageBar().pushMessage(u"Vous devez sélectionner une table !", level=QgsMessageBar.WARNING, duration=5) + + else : + # Récupération des sources de la couche active + list_sources = layer.source().split(" ") + # dbname + source_db = [s for s in list_sources if "dbname" in s][0].split("'")[1] + # schema + source_schema = [s for s in list_sources if "table" in s][0].split('"')[1] + # tablename + source_tablename = [s for s in list_sources if "table" in s][0].split('"')[3] + + if source_db != 'sig4269': + self.iface.messageBar().pushMessage(u"Un référentiel ne peut être copié, utilisez les filtres !", level=QgsMessageBar.CRITICAL, duration=10) + + else : + import psycopg2 + + config = "//100.100.100.100/bd_sig/z_QGIS/config.txt" # Chemin du fichier config + # Fonction de lecture des lignes du fichier config + def readline(n): + with open(config, "r") as f: + for lineno, line in enumerate(f): + if lineno == n: + return line.strip() # Permet d'enlever les retours chariots + + host = readline(10) + port = readline(12) + dbname = readline(14) + user = readline(16) + password = readline(18) + + con = psycopg2.connect("dbname="+ dbname + " user=" + user + " host=" + host + " password=" + password) + cur = con.cursor() + # Creation de la liste des schemas de la base de donnees + SQL = """WITH list_schema AS ( + SELECT catalog_name, schema_name + FROM information_schema.schemata + WHERE schema_name <> 'information_schema' + AND schema_name !~ E'^pg_' + ORDER BY schema_name + ) + + SELECT string_agg(schema_name,',') + FROM list_schema + GROUP BY catalog_name""" + + cur.execute(SQL) + + list_brut = str(cur.next()) + + list = list_brut [3:-3] + listItems = list.split(",") + + con.close() + + self.dlg.schema.clear() + self.dlg.schema.addItems(listItems) + self.dlg.schema.setCurrentIndex(-1) # Pour ne pas commencer la liste au premier schema + + + self.dlg.table_source.setText(source_schema + "." + source_tablename) # Affiche le nom de la table source + # show the dialog + self.dlg.show() + # Run the dialog event loop + result = self.dlg.exec_() + # See if OK was pressed + if result: + #******************************debut script********************************* + ### config.txt + config = "//100.100.100.100/bd_sig/z_QGIS/config.txt" # Chemin du fichier config + + # Fonction de lecture des lignes du fichier config + def readline(n): + with open(config, "r") as f: + for lineno, line in enumerate(f): + if lineno == n: + return line.strip() # Permet d'enlever les retours chariots + + # Recuperation des donnees + host = readline(10) + port = readline(12) + dbname = readline(14) + user = readline(16) + password = readline(18) + + con = psycopg2.connect("dbname="+ dbname + " user=" + user + " host=" + host + " password=" + password) + cur = con.cursor() + + # Récupération de la couche active + layer = self.iface.activeLayer() + + # Récupération des sources de la couche active + list_sources = layer.source().split(" ") + # dbname + source_db = [s for s in list_sources if "dbname" in s][0].split("'")[1] + # schema + source_schema = [s for s in list_sources if "table" in s][0].split('"')[1] + # tablename + source_tablename = [s for s in list_sources if "table" in s][0].split('"')[3] + + if self.dlg.schema.currentIndex() == -1 : + QMessageBox.warning(None, "Oups :", "Veuillez choisir un dossier de destination.") + return + + schema = self.dlg.schema.currentText() + + if self.dlg.table_destination.text() == '' : + QMessageBox.warning(None, "Oups :", "Veuillez choisir un nom de destination.") + return + + if self.dlg.annee.text() == 'aaaa' or self.dlg.annee.text() == '': + tablename = schema + "_" + self.dlg.table_destination.text().lower() + else : + tablename = schema + "_" + self.dlg.table_destination.text().lower() + "_" + self.dlg.annee.text() + + tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis + + geom = readline(6) + + if self.dlg.table_vide.isChecked() == 1 : + SQL_table = "CREATE TABLE " + schema + "." + tablename + " AS SELECT * FROM " + source_schema + "." + source_tablename + " LIMIT 0;" + else : + SQL_table = "CREATE TABLE " + schema + "." + tablename + " AS SELECT * FROM " + source_schema + "." + source_tablename + + + SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)" + SQL_sequence_01 = "CREATE SEQUENCE " + schema + "." + tablename + "_gid_seq" + " INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;" + SQL_sequence_02 = "ALTER TABLE " + schema + "." + tablename + " ALTER COLUMN gid SET DEFAULT nextval(\'" + schema + "." + tablename + "_gid_seq\'::regclass);" + SQL_sequence_03 = "SELECT setval(\'" + schema + "." + tablename + "_gid_seq\'::regclass, (SELECT max(gid) AS max_gid FROM " + schema + "." + tablename + "));" + SQL_sequence_04 = "ALTER SEQUENCE " + schema + "." + tablename + "_gid_seq" + " OWNED BY " + schema + "." + tablename + ".gid;" + + SQL_trigger_area_m2 = "CREATE TRIGGER area_m2" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.area_m2();" + SQL_trigger_area_ha = "CREATE TRIGGER area_ha" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.area_ha();" + SQL_trigger_length_m = "CREATE TRIGGER length_m" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.length_m();" + SQL_trigger_length_km = "CREATE TRIGGER length_km" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.length_km();" + SQL_trigger_coordonnees = "CREATE TRIGGER coordonnees" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.coordonnees();" + + cur.execute(SQL_table) + cur.execute(SQL_pkey) + cur.execute(SQL_sequence_01) + cur.execute(SQL_sequence_02) + cur.execute(SQL_sequence_03) + cur.execute(SQL_sequence_04) + + if layer.wkbType() == QGis.WKBPoint : + cur.execute(SQL_trigger_coordonnees) + + if layer.wkbType() == QGis.WKBMultiLineString : + cur.execute(SQL_trigger_length_m) + cur.execute(SQL_trigger_length_km) + + if layer.wkbType() == QGis.WKBMultiPolygon : + cur.execute(SQL_trigger_area_m2) + cur.execute(SQL_trigger_area_ha) + + con.commit() + + ### Affichage de la table + uri = QgsDataSourceURI() + # set host name, port, database name, username and password + uri.setConnection(host ,port ,dbname ,user ,password) + # set database schema, table name, geometry column and optionaly subset (WHERE clause) + uri.setDataSource(schema, tablename, geom) + + layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres") + + con.commit() + con.close() + + self.iface.messageBar().pushMessage("Table \"" + source_schema + "." + source_tablename + u"\" copiée dans \"" + schema + "." + tablename + "\"." , level=QgsMessageBar.INFO, duration=10) + pass diff --git a/copie_dialog.py b/copie_dialog.py new file mode 100644 index 00000000..95c2d782 --- /dev/null +++ b/copie_dialog.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + CopieDialog + A QGIS plugin + Permet la copie d'une table dans une base PostGis + ------------------- + begin : 2015-04-13 + git sha : $Format:%H$ + copyright : (C) 2015 by Guillaume COSTES - CEN Rhône-Alpes + email : guillaume.costes@espaces-naturels.fr + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +""" + +import os + +from qgis.PyQt import QtCore, QtGui, QtGui, uic +from qgis.PyQt.QtWidgets import QAction, QMenu, QDialog + +FORM_CLASS, _ = uic.loadUiType(os.path.join( + os.path.dirname(__file__), 'copie_dialog_base.ui')) + + +class CopieDialog(QDialog, FORM_CLASS): + def __init__(self, parent=None): + """Constructor.""" + super(CopieDialog, self).__init__(parent) + # Set up the user interface from Designer. + # After setupUI you can access any designer object by doing + # self., and you can use autoconnect slots - see + # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html + # #widgets-and-dialogs-with-auto-connect + self.setupUi(self) diff --git a/copie_dialog.py.bak b/copie_dialog.py.bak new file mode 100644 index 00000000..a951555c --- /dev/null +++ b/copie_dialog.py.bak @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + CopieDialog + A QGIS plugin + Permet la copie d'une table dans une base PostGis + ------------------- + begin : 2015-04-13 + git sha : $Format:%H$ + copyright : (C) 2015 by Guillaume COSTES - CEN Rhône-Alpes + email : guillaume.costes@espaces-naturels.fr + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +""" + +import os + +from PyQt4 import QtGui, uic + +FORM_CLASS, _ = uic.loadUiType(os.path.join( + os.path.dirname(__file__), 'copie_dialog_base.ui')) + + +class CopieDialog(QtGui.QDialog, FORM_CLASS): + def __init__(self, parent=None): + """Constructor.""" + super(CopieDialog, self).__init__(parent) + # Set up the user interface from Designer. + # After setupUI you can access any designer object by doing + # self., and you can use autoconnect slots - see + # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html + # #widgets-and-dialogs-with-auto-connect + self.setupUi(self)