Compare commits

...
76 Commits
Author SHA1 Message Date
tlaveille 06e259c338 premier commit/push 2024-10-14 13:56:22 +02:00
tlaveille c9954f295d test de commit avec gitignore 2024-10-14 11:50:44 +02:00
tlaveille 60d4051840 test de gitignore 2024-10-14 11:35:00 +02:00
tlaveille f831f2e5a3 Téléverser les fichiers vers "CenRa_Metabase" 2024-10-08 12:15:09 +02:00
tlaveille 839eb525e4 Téléverser les fichiers vers "CenRa_FLUX" 2024-10-07 17:17:27 +02:00
tlaveille 7b6e77d17e Téléverser les fichiers vers "CenRa_Metabase" 2024-10-07 17:16:57 +02:00
tlaveille 8ee1d6d888 Supprimer CenRa_AUTOMAP/tools/mise_en_pages/1. Modèle carto standard (consolidé).qpt 2024-10-07 17:16:16 +02:00
tlaveille 62b3052b04 Téléverser les fichiers vers "CenRa_AUTOMAP/tools/mise_en_pages" 2024-10-07 17:16:05 +02:00
tlaveille f2f1cb6ab1 Téléverser les fichiers vers "CenRa_AUTOMAP/tools/logo_library" 2024-10-07 17:15:47 +02:00
tlaveille 9683e7382c Téléverser les fichiers vers "CenRa_AUTOMAP/tools/font" 2024-10-07 17:14:51 +02:00
tlaveille 8f32acc561 Téléverser les fichiers vers "CenRa_AUTOMAP/tools/ui" 2024-10-07 17:14:25 +02:00
tlaveille 47fa68e1d2 Téléverser les fichiers vers "CenRa_AUTOMAP/tools" 2024-10-07 17:14:01 +02:00
tlaveille 6e159166cc Supprimer CenRa_AUTOMAP/editor.py 2024-10-07 17:13:38 +02:00
tlaveille d382770688 Téléverser les fichiers vers "CenRa_AUTOMAP" 2024-10-07 17:13:31 +02:00
tlaveille 82cce4a0f1 Téléverser les fichiers vers "CenRa_AUTOMAP/tools/ui" 2024-09-26 16:52:21 +02:00
tlaveille 3b44e6b59a Téléverser les fichiers vers "CenRa_AUTOMAP/tools/mise_en_pages" 2024-09-26 16:52:01 +02:00
tlaveille 450dc2fe68 Téléverser les fichiers vers "CenRa_AUTOMAP/tools/icons" 2024-09-26 16:51:39 +02:00
tlaveille 317f47cd11 Téléverser les fichiers vers "CenRa_AUTOMAP/tools/bg" 2024-09-26 16:51:23 +02:00
tlaveille d932dd0e74 Téléverser les fichiers vers "CenRa_AUTOMAP/tools" 2024-09-26 16:51:07 +02:00
tlaveille 5cf9380367 Téléverser les fichiers vers "CenRa_AUTOMAP" 2024-09-26 16:50:38 +02:00
tlaveille 055b9cc69d Téléverser les fichiers vers "CenRa_AUTOMAP" 2024-09-26 16:50:26 +02:00
tlaveille bace581f5c Supprimer issues.py 2024-09-26 16:49:57 +02:00
tlaveille f29df89ba0 Supprimer icon.png 2024-09-26 16:49:53 +02:00
tlaveille 8335b25ddd Supprimer editor.py 2024-09-26 16:49:49 +02:00
tlaveille 54585175ed Supprimer about_form.py 2024-09-26 16:49:44 +02:00
tlaveille 5a2ee3b1c0 Actualiser CenRa_AUTOMAP/CenRa_AutoMap.py 2024-09-26 16:49:35 +02:00
tlaveille 30a58ad9fd Téléverser les fichiers vers "/" 2024-09-26 16:49:07 +02:00
tlaveille 5f40aaea88 Actualiser plugins.xml 2024-08-26 15:51:43 +02:00
tlaveille 87f51f8084 Actualiser plugins.xml 2024-08-02 11:03:15 +02:00
tlaveille 76bcc9148d Actualiser CenRa_COPIE/README.md 2024-08-02 10:58:54 +02:00
tlaveille 5b6b96f134 Actualiser CenRa_COPIE/README.md 2024-08-02 10:46:50 +02:00
tlaveille 1a221bcbe2 Téléverser les fichiers vers "CenRa_SICEN" 2024-08-02 10:46:27 +02:00
tlaveille de1c84bf6d Téléverser les fichiers vers "CenRa_SICEN" 2024-08-02 10:46:19 +02:00
tlaveille babf387f37 Téléverser les fichiers vers "CenRa_SICEN/tools" 2024-08-02 10:45:53 +02:00
tlaveille 7775b9e0f7 Actualiser CenRa_SICEN/README.md 2024-08-02 10:45:34 +02:00
tlaveille 518a95d6fa Téléverser les fichiers vers "CenRa_SICEN" 2024-08-02 10:45:18 +02:00
tlaveille 299b2b01ea Actualiser CenRa_POSTGIS/README.md 2024-08-02 10:43:36 +02:00
tlaveille 94b5e1776f Téléverser les fichiers vers "CenRa_Metabase" 2024-08-02 10:43:02 +02:00
tlaveille 710304eb28 Téléverser les fichiers vers "CenRa_Metabase/resources" 2024-08-02 10:41:28 +02:00
tlaveille 6d39a11a39 Téléverser les fichiers vers "CenRa_POSTGIS" 2024-08-02 10:41:12 +02:00
tlaveille 29ef2053a1 Téléverser les fichiers vers "CenRa_FLUX/tools" 2024-08-02 10:40:49 +02:00
tlaveille 6f57119c09 Téléverser les fichiers vers "CenRa_COPIE/tools" 2024-08-02 10:40:12 +02:00
tlaveille 8f3512aaa2 Téléverser les fichiers vers "CenRa_Metabase/resources" 2024-08-02 10:39:55 +02:00
tlaveille 4c62cef083 Supprimer CenRa_COPIE/PythonSQL.py 2024-08-02 10:35:46 +02:00
tlaveille 8fdd6c2853 Téléverser les fichiers vers "CenRa_COPIE" 2024-08-02 10:35:37 +02:00
tlaveille 775e6b176e Téléverser les fichiers vers "CenRa_COPIE/tools" 2024-08-02 10:35:20 +02:00
tlaveille 7858e7f149 Téléverser les fichiers vers "CenRa_POSTGIS/tools" 2024-08-02 10:29:23 +02:00
tlaveille 5612948aa7 Téléverser les fichiers vers "CenRa_POSTGIS" 2024-08-02 10:28:54 +02:00
tlaveille bb454b0b4b Téléverser les fichiers vers "CenRa_POSTGIS" 2024-08-02 10:27:10 +02:00
tlaveille f4a21491f9 Téléverser les fichiers vers "CenRa_POSTGIS" 2024-08-02 10:26:27 +02:00
tlaveille d2cc6f16b5 Téléverser les fichiers vers "CenRa_POSTGIS" 2024-08-02 10:25:19 +02:00
tlaveille d666ae2a65 Téléverser les fichiers vers "CenRa_Metabase/i18n" 2024-08-02 10:24:14 +02:00
tlaveille 7c23016672 Téléverser les fichiers vers "CenRa_Metabase/resources/css" 2024-08-02 10:23:25 +02:00
tlaveille 496089bdd3 Téléverser les fichiers vers "CenRa_Metabase/resources/icons" 2024-08-02 10:22:55 +02:00
tlaveille f1f34160f1 Téléverser les fichiers vers "CenRa_Metabase/resources/ui" 2024-08-02 10:22:15 +02:00
tlaveille f4ab19ddcc Téléverser les fichiers vers "CenRa_Metabase/resources/xml" 2024-08-02 10:21:56 +02:00
tlaveille 653f14b3ff Téléverser les fichiers vers "CenRa_Metabase/resources" 2024-08-02 10:21:41 +02:00
tlaveille b1d2a2f9b5 Téléverser les fichiers vers "CenRa_Metabase" 2024-08-02 10:21:03 +02:00
tlaveille 812412c6f9 Téléverser les fichiers vers "CenRa_Metabase" 2024-08-02 10:20:26 +02:00
tlaveille 0d9fcd8de9 Téléverser les fichiers vers "CenRa_FLUX" 2024-08-02 10:19:08 +02:00
tlaveille cbccca397b Téléverser les fichiers vers "CenRa_FLUX" 2024-08-02 10:18:59 +02:00
tlaveille 543e94c861 Supprimer CenRa_FLUX/tools/resources.cpython-312.pyc 2024-08-02 10:17:56 +02:00
tlaveille 38a969d714 Supprimer CenRa_FLUX/tools/PythonSQL.cpython-312.pyc 2024-08-02 10:17:51 +02:00
tlaveille 3320ba1dd9 Téléverser les fichiers vers "CenRa_FLUX/tools" 2024-08-02 10:17:20 +02:00
tlaveille b7cfeb2484 Téléverser les fichiers vers "CenRa_FLUX" 2024-08-02 10:16:37 +02:00
tlaveille 7c0188b9a5 Téléverser les fichiers vers "CenRa_FLUX" 2024-08-02 10:15:52 +02:00
tlaveille 80bcd3de55 Téléverser les fichiers vers "/" 2024-08-01 15:40:30 +02:00
tlaveille 8c5691c77b Actualiser CenRa_COPIE/README.md 2024-08-01 15:18:17 +02:00
tlaveille b3f4f1ffa1 Téléverser les fichiers vers "CenRa_COPIE" 2024-08-01 15:17:53 +02:00
tlaveille c8966c7316 Téléverser les fichiers vers "CenRa_COPIE" 2024-08-01 15:17:32 +02:00
tlaveille 6aa35a2620 Supprimer copie_dialog.py 2024-08-01 14:43:37 +02:00
tlaveille 227aacb5d1 Supprimer copie.py.bak 2024-08-01 14:43:31 +02:00
tlaveille 5ec3a216b8 Supprimer copie.py 2024-08-01 14:43:27 +02:00
tlaveille de4d120f67 Supprimer copie_dialog.py.bak 2024-08-01 14:43:22 +02:00
tlaveille 1f91f96bac Supprimer cenra.png 2024-08-01 14:43:16 +02:00
tlaveille 997b1147af Merge pull request 'Téléverser les fichiers vers "/"' (#1) from dev into main
Reviewed-on: #1
2024-08-01 14:42:50 +02:00
95 changed files with 21568 additions and 376 deletions
+15
View File
@@ -0,0 +1,15 @@
#Ignores gitignore
.gitignore
#Ignores all folders
/*
#Except Plugin folders
!/CenRa_COPIE/*
!/CenRa_FLUX/*
!/CenRa_METABASE/*
!/CenRa_POSTGIS/*
!/CenRa_SICEN/*
!/CenRa_AUTOMAP/*
*__pycache__*
+142
View File
@@ -0,0 +1,142 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
from qgis.core import QgsApplication
from qgis.PyQt.QtCore import QCoreApplication, Qt, QTranslator, QUrl
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtWidgets import QAction, QMessageBox
from qgis.utils import iface
import qgis
#include <QSettings>
'''
from pg_metadata.connection_manager import (
store_connections,
validate_connections_names,
)
from pg_metadata.locator import LocatorFilter
from pg_metadata.processing.provider import PgMetadataProvider
from pg_metadata.qgis_plugin_tools.tools.custom_logging import setup_logger
'''
import os
from .tools.resources import (
plugin_path,
resources_path,
maj_verif,
)
from .canvas_editor import AutoMap_Editor
from .about_form import AutoMapAboutDialog
from PyQt5.QtCore import *
class PgAutoMap:
def __init__(self):
""" Constructor. """
self.canvas_editor = None
# self.issues = None
self.provider = None
self.locator_filter = None
self.dock_action = None
self.help_action = None
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\')+1
global NAME
NAME = plugin_dir[end_find:]
maj_verif(NAME)
# Display About window on first use
version = qgis.utils.pluginMetadata('CenRa_AUTOMAP','version')
s = QSettings()
versionUse = s.value("automap/version", 1, type=str)
if str(versionUse) != str(version) :
s.setValue("automap/version", str(version))
print(versionUse,version)
self.open_about_dialog()
def initGui(self):
""" Build the plugin GUI. """
self.toolBar = iface.addToolBar("CenRa_AutoMap")
self.toolBar.setObjectName("CenRa_AutoMap")
icon = QIcon(resources_path('icons', 'icon.png'))
# Open the online help
self.help_action = QAction(icon, 'CenRa_AutoMap', iface.mainWindow())
iface.pluginHelpMenu().addAction(self.help_action)
self.help_action.triggered.connect(self.open_help)
if not self.canvas_editor:
self.canvas_editor = AutoMap_Editor()
self.automap_action = QAction(icon, 'CenRa_AutoMap',None)
self.toolBar.addAction(self.automap_action)
self.automap_action.triggered.connect(self.open_editor)
'''
if not self.locator_filter:
self.locator_filter = LocatorFilter(iface)
iface.registerLocatorFilter(self.locator_filter)
@staticmethod
def check_invalid_connection_names():
""" Check for invalid connection names in the QgsSettings. """
valid, invalid = validate_connections_names()
n_invalid = len(invalid)
if n_invalid == 0:
return
invalid_text = ', '.join(invalid)
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setWindowTitle(tr('PgMetadata: Database connection(s) not available'))
msg.setText(tr(
f'{n_invalid} connection(s) listed in PgMetadata’s settings are invalid or '
f'no longer available: {invalid_text}'))
msg.setInformativeText(tr(
'Do you want to remove these connection(s) from the PgMetadata settings? '
'(You can also do this later with the “Set Connections” tool.)'))
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
clicked = msg.exec()
if clicked == QMessageBox.Yes:
iface.messageBar().pushSuccess('PgMetadata', tr(f'{n_invalid} invalid connection(s) removed.'))
store_connections(valid)
if clicked == QMessageBox.No:
iface.messageBar().pushInfo('PgMetadata', tr(f'Keeping {n_invalid} invalid connections.'))
'''
def open_about_dialog(self):
"""
About dialog
"""
dialog = AutoMapAboutDialog(iface)
dialog.exec_()
def open_help():
""" Open the online help. """
QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
def open_editor(self):
self.canvas_editor.show()
self.canvas_editor.raise_()
def unload(self):
""" Unload the plugin. """
if self.canvas_editor:
iface.removePluginMenu('CenRa_AutoMap',self.automap_action)
if self.provider:
QgsApplication.processingRegistry().removeProvider(self.provider)
del self.provider
if self.locator_filter:
iface.deregisterLocatorFilter(self.locator_filter)
del self.locator_filter
if self.help_action:
iface.pluginHelpMenu().removeAction(self.help_action)
del self.help_action
+1
View File
@@ -0,0 +1 @@
# CenRa_AutoMap
+10
View File
@@ -0,0 +1,10 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
# noinspection PyPep8Naming
def classFactory(iface): # pylint: disable=invalid-name
_ = iface
from CenRa_AUTOMAP.CenRa_AutoMap import PgAutoMap
return PgAutoMap()
+46
View File
@@ -0,0 +1,46 @@
import os.path
from pathlib import Path
from qgis.PyQt import uic
from qgis.PyQt.QtGui import QPixmap
from qgis.PyQt.QtWidgets import QDialog
from .tools.resources import devlog
ABOUT_FORM_CLASS, _ = uic.loadUiType(
os.path.join(
str(Path(__file__).resolve().parent),
'tools/ui',
'CenRa_AutoMap_about_form.ui'
)
)
class AutoMapAboutDialog(QDialog, ABOUT_FORM_CLASS):
""" About - Let the user display the about dialog. """
def __init__(self, iface, parent=None):
super().__init__(parent)
self.iface = iface
self.setupUi(self)
self.viewer.setHtml(devlog('CenRa_AUTOMAP'))
self.rejected.connect(self.onReject)
self.buttonBox.rejected.connect(self.onReject)
self.buttonBox.accepted.connect(self.onAccept)
def onAccept(self):
"""
Save options when pressing OK button
"""
self.accept()
def onReject(self):
"""
Run some actions when
the user closes the dialog
"""
self.close()
+737
View File
@@ -0,0 +1,737 @@
import logging
import os
from PyQt5.QtCore import QSettings
from collections import namedtuple
from enum import Enum
from functools import partial
from pathlib import Path
from xml.dom.minidom import parseString
from qgis.gui import *
import qgis
from qgis.core import (
NULL,
QgsApplication,
QgsScaleBarSettings,
QgsDataSourceUri,
QgsProject,
QgsProviderConnectionException,
QgsProviderRegistry,
QgsRasterLayer,
QgsSettings,
QgsVectorLayer,
QgsGeometry,
QgsPrintLayout,
QgsReadWriteContext,
QgsLayoutItemMap,
QgsLayoutItemPage,
QgsLayoutSize,
QgsUnitTypes,
QgsLayoutPoint,
QgsLayoutItemLabel,
QgsLayoutItemPicture,
QgsLayoutItemLegend,
QgsLegendStyle,
QgsLayoutItemScaleBar,
QgsLayerTreeGroup,
QgsCoordinateReferenceSystem,
QgsCoordinateTransform,
QgsLayerTree,
QgsLayoutTableColumn,
QgsRectangle,
QgsLayoutItemMapOverviewStack,
)
from qgis.PyQt.QtCore import QLocale, QUrl, QDateTime, Qt
from qgis.PyQt.QtGui import QDesktopServices, QIcon, QColor, QFont, QMovie
from qgis.PyQt.QtPrintSupport import QPrinter
from qgis.PyQt.QtWebKitWidgets import QWebPage
from qgis.PyQt.QtWidgets import (
QDialog,
QAction,
QDockWidget,
QFileDialog,
QInputDialog,
QMenu,
QToolButton,
QTableWidget,
QTableWidgetItem,
QVBoxLayout,
)
from qgis.PyQt.QtXml import QDomDocument
from qgis.utils import iface
import glob
from .tools.resources import (
load_ui,
resources_path,
login_base,
send_issues,
)
from .tools.mises_en_pages.canvas import (fletch_canvas)
from .issues import CenRa_Issues
from datetime import date
EDITOR_CLASS = load_ui('CenRa_AutoMap_base.ui')
LOGGER = logging.getLogger('CenRa_AutoMap')
url_osm = 'https://osm.datagrandest.fr/mapcache/?crs=EPSG:2154&featureCount=10&format=image/png&layers=pure&maxHeight=256&maxWidth=256&styles=&url=https://osm.datagrandest.fr/mapcache'
url_ortho = 'http://tiles.craig.fr/ortho/service/?crs=EPSG:2154&featureCount=10&format=image/jpeg&layers=ortho&maxHeight=256&maxWidth=256&styles=&url=http://tiles.craig.fr/ortho/service'
url_mnt = 'http://tiles.craig.fr/mnt/crs=EPSG:2154&featureCount=10&format=image/png&layers=relief&maxHeight=256&maxWidth=256&styles=&url=http://tiles.craig.fr/mnt'
url_pente = 'http://tiles.craig.fr/mnt/crs=EPSG:2154&featureCount=10&format=image/png&layers=pente&maxHeight=256&maxWidth=256&styles=&url=http://tiles.craig.fr/mnt'
data_source = [
'CENRA',
'IGN',
'CRAIG',
'OpenStreetMap',
'Sandre',
'BRGM',
'MUSÉUM NATIONAL D’HISTOIRE NATURELLE',
"Muséum national d'Histoire naturelle",
'ONF',
'20xx LPO',
'ofb.gouv.fr',
'Stamen Design',
'MTES',
'MTES',
'FEDER',
'DREAL Auvergne-Rhône-Alpes',
'INSEE',
'DGFiP',
'Fédération des Conservatoires d’espaces naturels',
'Plan cadastral informatisé - Etalab - juillet 202X',
'Parcellaire Express - IGN - 202X',
]
class AutoMap_Editor(QDialog, EDITOR_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
self.s = QSettings()
path = ''
ix = 0
plugin_dir = str(os.path.dirname(os.path.abspath(__file__))).split(os.sep)
for i in plugin_dir[1:]:
ix = ix+1
path = path+'/'+i
self.tabWidget.setStyleSheet('background-image: url('+path+'/tools/bg/Capture.png);')
self.commandLinkButton.clicked.connect(self.chargement_qpt)
self.radioButton_9.clicked.connect(self.statu_atlas)
self.radioButton_10.clicked.connect(self.statu_source)
self.radioButton_11.clicked.connect(self.statu_map)
self.radioButton_13.clicked.connect(self.statu_titre)
self.comboBox_2.currentIndexChanged.connect(self.field_list)
self.comboBox_7.currentIndexChanged.connect(self.update_subtitle)
self.commandLinkButton_2.clicked.connect(self.load_ortho)
self.commandLinkButton_3.clicked.connect(self.load_osm)
self.CustomeLogo.clicked.connect(self.deflogoteck)
## On ajoute le nom des templates à la liste déroulante de l'onglet "mises en page" :
mises_en_page = []
for filename in glob.glob(resources_path("mises_en_pages","*.qpt")):
mises_en_page.append(filename)
for i, filename in enumerate(mises_en_page):
nom_fichier = os.path.basename(filename)
self.comboBox.addItem(nom_fichier)
self.comboBox.setCurrentIndex(1)
self.template_parameters = {
'map_size': None,
'map_position' : None,
'position_map_size' : None,
'position_map_position' : None,
'title_position': None,
'title_size': None,
'subtitle_position': None,
'subtitle_size': None,
'logo_position': None,
'logo_size': None,
'legend_position': None,
'legend_size': None,
'scalebarnumeric_position':None,
'scalebarnumeric_size':None,
'scalebar_position': None,
'scalebar_size': None,
'north_position': None,
'north_size': None,
'credit_text_position': None,
'credit_text_size': None,
'credit_text2_position': None,
'credit_text2_size': None,
# Add more variables as needed
}
self.update_logo_library()
self.mComboBox_3.addItems(sorted(data_source))
self.hide_map()
self.hide_titre()
self.hide_source()
self.hide_atlas()
def update_logo_library(self):
self.mComboBox_4.clear()
logo_library = []
custome_bibliotech = glob.glob(self.s.value("automap/logoteck", 1, type=str)+'*.*')
for l,logo_x in enumerate(custome_bibliotech):
logo_library.append(' '+os.path.basename(logo_x))
bibliotech = glob.glob(resources_path("logo_library","*.png"))
for l,logo_x in enumerate(bibliotech):
logo_library.append(os.path.basename(logo_x))
self.mComboBox_4.addItems(sorted(logo_library))
def select_file(self):
options = QFileDialog.Options()
options |= QFileDialog.ShowDirsOnly
folder = QFileDialog.getExistingDirectory(self, "Sélection du dossier parent", options=options)
return folder+'/'
def deflogoteck(self):
folder = self.select_file()
logopath = folder
self.s.setValue("automap/logoteck", str(logopath))
self.update_logo_library()
def update_subtitle(self):
project_subtitle = QgsProject.instance()
if self.radioButton_13.isChecked() == 1:
if self.comboBox_7.currentText() != "":
try:
layout_subtitle = project_subtitle.layoutManager().layoutByName(self.comboBox_7.currentText())
self.lineEdit_3.setText(layout_subtitle.itemById("SubTitle").text())
except:
print("")
def load_ortho(self):
global myGroup,last_group
runing = False
try: myGroup
except NameError: runing = True
try: last_group
except NameError: last_group = ''
if runing or (last_group != '' and last_group != 'ortho'):
layername = False
layerAll = QgsProject.instance().layerTreeRoot().children()
xl = 0
for layeritem in layerAll:
if layeritem.name() == 'SuperFont':
myGroup = layerAll[xl]
layername = True
xl = xl+1
if layername:
(QgsProject.instance().layerTreeRoot()).removeChildNode(myGroup)
runing = True
if runing or last_group != 'ortho':
myGroup = (QgsProject.instance().layerTreeRoot()).addGroup("SuperFont")
last_group = 'ortho'
#OSM_RASTER = QgsRasterLayer(url_osm, 'OpenStreetMap Backgound', 'wms')
ORTHO_RASTER = QgsRasterLayer(url_ortho, 'Orthophoto AURA', 'wms')
MNT_RASTER = QgsRasterLayer(url_mnt, 'MNT RGE Alti (<= 1:100000)', 'wms')
PENTE_RASTER = QgsRasterLayer(url_pente, 'Pente RGE Alti 0 à 90°(<= 1:100000)', 'wms')
#OSM_RASTER.loadNamedStyle(resources_path("font","osm_background.qml"))
ORTHO_RASTER.loadNamedStyle(resources_path("font","ortho_aura.qml"))
MNT_RASTER.loadNamedStyle(resources_path("font","mnt_alti.qml"))
#QgsProject.instance().addMapLayer(OSM_RASTER,False)
QgsProject.instance().addMapLayer(ORTHO_RASTER,False)
QgsProject.instance().addMapLayer(MNT_RASTER,False)
QgsProject.instance().addMapLayer(PENTE_RASTER,False)
#myGroup.addLayer(OSM_RASTER)
myGroup.addLayer(ORTHO_RASTER)
myGroup.addLayer(MNT_RASTER)
myGroup.addLayer(PENTE_RASTER)
def load_osm(self):
global myGroup,last_group
runing = False
try: myGroup
except NameError: runing = True
try: last_group
except NameError: last_group = ''
if runing or (last_group != '' and last_group != 'osm'):
layername = False
layerAll = QgsProject.instance().layerTreeRoot().children()
xl = 0
for layeritem in layerAll:
if layeritem.name() == 'SuperFont':
myGroup = layerAll[xl]
layername = True
xl = xl+1
if layername:
(QgsProject.instance().layerTreeRoot()).removeChildNode(myGroup)
runing = True
if runing or last_group != 'osm':
myGroup = (QgsProject.instance().layerTreeRoot()).addGroup("SuperFont")
last_group = 'osm'
OSM_RASTER = QgsRasterLayer(url_osm, 'OpenStreetMap Backgound', 'wms')
#ORTHO_RASTER = QgsRasterLayer(url_ortho, 'Orthophoto AURA', 'wms')
MNT_RASTER = QgsRasterLayer(url_mnt, 'MNT RGE Alti (<= 1:100000)', 'wms')
PENTE_RASTER = QgsRasterLayer(url_pente, 'Pente RGE Alti 0 à 90°(<= 1:100000)', 'wms')
OSM_RASTER.loadNamedStyle(resources_path("font","osm_background.qml"))
#ORTHO_RASTER.loadNamedStyle(resources_path("font","ortho_aura.qml"))
MNT_RASTER.loadNamedStyle(resources_path("font","mnt_alti.qml"))
QgsProject.instance().addMapLayer(OSM_RASTER,False)
#QgsProject.instance().addMapLayer(ORTHO_RASTER,False)
QgsProject.instance().addMapLayer(MNT_RASTER,False)
QgsProject.instance().addMapLayer(PENTE_RASTER,False)
myGroup.addLayer(OSM_RASTER)
#myGroup.addLayer(ORTHO_RASTER)
myGroup.addLayer(MNT_RASTER)
myGroup.addLayer(PENTE_RASTER)
def raise_(self):
self.activateWindow()
self.mComboBox_2.clear()
self.comboBox_2.clear()
self.comboBox_3.clear()
self.comboBox_4.clear()
self.comboBox_5.clear()
self.comboBox_6.clear()
self.comboBox_7.clear()
couches = []
couche_vecteur = ['']
mapThemes = ['']
titrePage = ['']
for lyr in QgsProject.instance().mapLayers().values():
if isinstance(lyr, QgsVectorLayer):
couche_vecteur.append(lyr.name())
couches.append(lyr.name())
for mapThemesCollection in (QgsProject.instance().mapThemeCollection()).mapThemes():
mapThemes.append(mapThemesCollection)
for layoutTitre in (QgsProject.instance().layoutManager().layouts()):
titrePage.append(layoutTitre.name())
self.comboBox_2.addItems(sorted(couche_vecteur))
self.mComboBox_2.addItems(sorted(couches))
self.comboBox_5.addItems(sorted(mapThemes))
self.comboBox_6.addItems(sorted(mapThemes))
self.comboBox_7.addItems(sorted(titrePage))
def statu_map(self):
if self.radioButton_11.isChecked() == 1:
self.show_map()
else:
self.hide_map()
def show_map(self):
self.groupBox_3.setEnabled(True)
self.groupBox_3.show()
def hide_map(self):
self.groupBox_3.setEnabled(False)
self.groupBox_3.hide()
def statu_titre(self):
if self.radioButton_13.isChecked() == 1:
self.show_titre()
else:
self.hide_titre()
def show_titre(self):
self.lineEdit_2.setEnabled(False)
self.lineEdit_2.hide()
self.comboBox_7.setEnabled(True)
self.comboBox_7.show()
def hide_titre(self):
self.lineEdit_2.setEnabled(True)
self.lineEdit_2.show()
self.comboBox_7.setEnabled(False)
self.comboBox_7.hide()
def statu_source(self):
if self.radioButton_10.isChecked() == 1:
self.show_source()
else:
self.hide_source()
def show_source(self):
self.lineEdit_4.setEnabled(False)
self.lineEdit_4.hide()
self.mComboBox_3.setEnabled(True)
self.mComboBox_3.show()
def hide_source(self):
self.lineEdit_4.setEnabled(True)
self.lineEdit_4.show()
self.mComboBox_3.setEnabled(False)
self.mComboBox_3.hide()
def statu_atlas(self):
if self.radioButton_9.isChecked() == 1:
self.show_atlas()
else:
self.hide_atlas()
def show_atlas(self):
self.groupBox.setEnabled(True)
self.groupBox.show()
def hide_atlas(self):
self.groupBox.setEnabled(False)
self.groupBox.hide()
def field_list(self):
fields = []
self.comboBox_3.clear()
self.comboBox_4.clear()
if self.comboBox_2.currentText() != '':
layer = QgsProject.instance().mapLayersByName(self.comboBox_2.currentText())[0]
#BUG sur layer.fields() pas défini sur ce qui est pas vecteur
for vfields in layer.fields():
fields.append(vfields.name())
self.comboBox_3.addItems(sorted(fields))
self.comboBox_4.addItems(sorted(fields))
def chargement_qpt(self):
project = QgsProject.instance()
self.manager = project.layoutManager()
if self.radioButton_13.isChecked() == 1:
layout_name = self.comboBox_7.currentText()
else:
layout_name = self.lineEdit_2.text()
layouts_list = self.manager.printLayouts()
for filename in glob.glob(resources_path("mises_en_pages","*.qpt")):
with open(os.path.join(os.getcwd(), filename), 'r') as f:
self.layout = QgsPrintLayout(project)
self.layout.initializeDefaults()
myAtlas=self.layout.atlas()
template_content = f.read()
doc = QDomDocument()
doc.setContent(template_content)
self.layout.loadFromTemplate(doc, QgsReadWriteContext(), True)
self.layout.setName(layout_name)
if True:#os.path.basename(filename) == "1. Modèle carto standard (consolidé).qpt":
self.actualisation_mise_en_page()
## Add map to layout
self.map_modele_test = QgsLayoutItemMap(self.layout)
# Charger une carte vide
self.map_modele_test.setRect(20, 20, 20, 20)
# Mettre le canvas courant comme emprise
self.map_modele_test.setExtent(iface.mapCanvas().extent())
# Position de la carte dans le composeur
self.map_modele_test.attemptMove(self.template_parameters['map_position'])
# on dimensionne le rendu de la carte (pour référence la page totale est une page A4 donc 297*210)
self.map_modele_test.attemptResize(self.template_parameters['map_size'])
self.map_modele_test.setKeepLayerSet(True)
self.map_modele_test.setKeepLayerStyles(True)
if self.radioButton_11.isChecked() == 1:
self.map_modele_test.setKeepLayerSet(False)
self.map_modele_test.setKeepLayerStyles(False)
self.map_modele_test.setFollowVisibilityPreset(True)
self.map_modele_test.setFollowVisibilityPresetName(self.comboBox_5.currentText())
if self.radioButton_12.isChecked() == 1:
self.position_map = QgsLayoutItemMap(self.layout)
self.position_map.setRect(20, 20, 20, 20)
self.position_map.setExtent(QgsRectangle(641552,6647386, 995856,6331104))
self.position_map.setFollowVisibilityPreset(True)
self.position_map.setFollowVisibilityPresetName(self.comboBox_6.currentText())
self.position_map.attemptMove(self.template_parameters['position_map_position'])
self.position_map.attemptResize(self.template_parameters['position_map_size'])
overviewitem = QgsLayoutItemMapOverviewStack(self.position_map)
map_overview = self.position_map.overview()
map_overview.setLinkedMap(self.map_modele_test)
map_overview.setCentered(True)
overviewitem.addOverview(map_overview)
self.position_map.refresh()
self.map_modele_test.setFrameEnabled(True)
self.layout.addLayoutItem(self.position_map)
self.position_map.setId("carte_position")
self.map_modele_test.refresh()
self.map_modele_test.setBackgroundColor(QColor(255, 255, 255, 255))
self.map_modele_test.setFrameEnabled(True)
if self.radioButton_9.isChecked() == 1:
self.map_modele_test.setAtlasDriven(True)
self.layout.addLayoutItem(self.map_modele_test)
self.map_modele_test.setId("carte_principale")
## Ajout d'un titre à la mise en page
title = QgsLayoutItemLabel(self.layout)
self.layout.addLayoutItem(title)
titre = layout_name
title.setText(titre)
title.setFont(QFont("Calibri", 15, QFont.Bold))
title.attemptMove(self.template_parameters['title_position'])
title.attemptResize(self.template_parameters['title_size'])
title.setBackgroundEnabled(True)
title.setBackgroundColor(QColor(255, 255, 255, 130))
self.layout.addItem(title)
# title.adjustSizeToText() on n'utilise plutot setFixedSize pour pouvoir centrer le titre de manière plus optimale ici
title.setHAlign(Qt.AlignHCenter)
title.setVAlign(Qt.AlignVCenter)
## Ajout d'un sous titre à la mise en page
subtitle = QgsLayoutItemLabel(self.layout)
self.layout.addLayoutItem(subtitle)
titre = self.lineEdit_3.text()
if self.radioButton_9.isChecked() == 1:
titre = titre + ' [%' + self.comboBox_4.currentText() + '%]'
subtitle.setText(titre)
subtitle.setFont(QFont("MS Shell Dlg 2", 10))
subtitle.attemptMove(self.template_parameters['subtitle_position'])
subtitle.attemptResize(self.template_parameters['subtitle_size'])
subtitle.setId("SubTitle")
subtitle.setBackgroundEnabled(True)
subtitle.setBackgroundColor(QColor(255, 255, 255, 130))
self.layout.addItem(subtitle)
subtitle.setHAlign(Qt.AlignHCenter)
subtitle.setVAlign(Qt.AlignVCenter)
## Ajout du logo CEN NA en haut à gauche de la page
logo = QgsLayoutItemPicture(self.layout)
logo.setResizeMode(QgsLayoutItemPicture.Zoom)
logo.setMode(QgsLayoutItemPicture.FormatRaster)
logo.attemptMove(self.template_parameters['logo_position'])
logo.setFixedSize(self.template_parameters['logo_size'])
logo.setPicturePath(resources_path("icons","CEN_RA.png"))
logo.setId('logo')
self.layout.addLayoutItem(logo)
## Ajout de la legende :
legend = QgsLayoutItemLegend(self.layout)
legend.setId('legende_model1')
# legend.setTitle('Legende')
legend.adjustBoxSize()
legend.setFrameEnabled(False)
legend.setAutoUpdateModel(False)
legend.setLinkedMap(self.map_modele_test)
checked_items = self.mComboBox_2.checkedItems()
self.layout.addItem(legend)
# group_name = 'Périmètres écologiques' # Name of a group in your legend
layers_to_remove = []
for lyr in project.mapLayers().values():
if lyr.name() not in checked_items:
layers_to_remove.append(lyr.name())
# the layer tree
root = project.layerTreeRoot()
# get legend
legend = [i for i in self.layout.items() if isinstance(i, QgsLayoutItemLegend)][0]
# disable auto-update
legend.setAutoUpdateModel(False)
legend.setLegendFilterByMapEnabled(True)
# legend model
model = legend.model()
# the root legend group
root_group = model.rootGroup()
# loop through layer names
for layer_name in layers_to_remove:
# find layer in project
layer = project.mapLayersByName(layer_name)[0]
# get layer tree layer instance of layer
layertreelayer = root.findLayer(layer.id())
# get the parent of the layer tree layer (layer tree root, or group)
parent = layertreelayer.parent()
# if the parent is a group and has a name, find it and remove the layer
if isinstance(parent, QgsLayerTreeGroup) and parent.name():
group = root_group.findGroup(parent.name())
group.removeLayer(layer)
# remove layers that are not in a group
else:
root_group.removeLayer(layer)
legend.setEqualColumnWidth(True)
legend.setSplitLayer(True)
legend.setColumnSpace(5)
legend.rstyle(QgsLegendStyle.Title).setMargin(1.5) # 1 mm
legend.rstyle(QgsLegendStyle.Group).setMargin(QgsLegendStyle.Top, 3)
legend.rstyle(QgsLegendStyle.Subgroup).setMargin(QgsLegendStyle.Top, 3)
legend.setColumnCount(self.spinBox.value())
legend.adjustBoxSize()
legend.setBackgroundEnabled(True)
legend.setBackgroundColor(QColor(255, 255, 255, 130))
self.layout.refresh()
legend.updateLegend()
legend.attemptMove(self.template_parameters['legend_position'])
## Ajout de l'échelle numeric à la mise en page
self.scalebarnumeric_qpt = QgsLayoutItemScaleBar(self.layout)
self.scalebarnumeric_qpt.setStyle('Numeric')
self.scalebarnumeric_qpt.setLinkedMap(self.map_modele_test)
self.scalebarnumeric_qpt.applyDefaultSize()
# self.scalebarnumeric_qpt.applyDefaultSettings()
self.scalebarnumeric_qpt.setNumberOfSegments(2)
self.scalebarnumeric_qpt.setNumberOfSegmentsLeft(0)
self.scalebarnumeric_qpt.attemptMove(self.template_parameters['scalebarnumeric_position'])
self.scalebarnumeric_qpt.attemptResize(self.template_parameters['scalebarnumeric_size'])
self.scalebarnumeric_qpt.setAlignment(QgsScaleBarSettings.Alignment(1))
self.scalebarnumeric_qpt.setBackgroundEnabled(True)
self.scalebarnumeric_qpt.setBackgroundColor(QColor(255, 255, 255, 130))
self.layout.addLayoutItem(self.scalebarnumeric_qpt)
## Ajout de l'échelle à la mise en page
self.scalebar_qpt = QgsLayoutItemScaleBar(self.layout)
self.scalebar_qpt.setStyle('Single Box')
self.scalebar_qpt.setLinkedMap(self.map_modele_test)
self.scalebar_qpt.applyDefaultSize()
self.scalebar_qpt.applyDefaultSettings()
self.scalebar_qpt.setNumberOfSegments(2)
self.scalebar_qpt.setNumberOfSegmentsLeft(0)
self.scalebar_qpt.attemptMove(self.template_parameters['scalebar_position'])
self.scalebar_qpt.attemptResize(self.template_parameters['scalebar_size'])
self.scalebar_qpt.setAlignment(QgsScaleBarSettings.Alignment(1))
self.scalebar_qpt.setBackgroundEnabled(True)
self.scalebar_qpt.setBackgroundColor(QColor(255, 255, 255, 130))
self.layout.addLayoutItem(self.scalebar_qpt)
# self.scalebar_qpt.setFixedSize(QgsLayoutSize(55, 15))
# ajout de la fleche du Nord
north = QgsLayoutItemPicture(self.layout)
north.setPicturePath(resources_path("mises_en_pages","NorthArrow_02.svg"))
self.layout.addLayoutItem(north)
north.attemptMove(self.template_parameters['north_position'])
north.attemptResize(self.template_parameters['north_size'])
if self.radioButton_10.isChecked() == 1:
info_text = ["Source : " + self.mComboBox_3.currentText()][0]
else:
info_text = ["Source : " + self.lineEdit_4.text()][0]
# ajout note info:
info = ["Réalisation : " + "CEN Rhône-Alpes (" + date.today().strftime(
"%d/%m/%Y") + ")"]
credit_text = QgsLayoutItemLabel(self.layout)
credit_text.setText(info[0])
credit_text.setFont(QFont("Calibri", 9))
credit_text.setHAlign(Qt.AlignRight)
credit_text.setVAlign(Qt.AlignVCenter)
credit_text.setItemRotation(-90)
credit_text2 = QgsLayoutItemLabel(self.layout)
credit_text2.setText(info_text)
credit_text2.setFont(QFont("Calibri", 9))
credit_text2.setHAlign(Qt.AlignRight)
credit_text2.setVAlign(Qt.AlignVCenter)
credit_text.attemptMove(self.template_parameters['credit_text_position'])
credit_text.attemptResize(self.template_parameters['credit_text_size'])
credit_text2.attemptMove(self.template_parameters['credit_text2_position'])
credit_text2.attemptResize(self.template_parameters['credit_text2_size'])
self.layout.addLayoutItem(credit_text)
self.layout.addLayoutItem(credit_text2)
## Ajout du logo credit en bas à droit de la page
for logo_run in self.mComboBox_4.checkedItems():
logo_credit = QgsLayoutItemPicture(self.layout)
logo_credit.setResizeMode(QgsLayoutItemPicture.Zoom)
logo_credit.setMode(QgsLayoutItemPicture.FormatRaster)
cur_x = self.template_parameters['logo_credit_position'].x()
logo_credit.attemptMove(self.template_parameters['logo_credit_position'])
logo_credit.setPictureAnchor(4)
self.template_parameters['logo_credit_position'].setX(cur_x+51)
logo_credit.setFixedSize(self.template_parameters['logo_credit_size'])
if logo_run[0] == ' ':
logo_credit.setPicturePath(self.s.value("automap/logoteck", 1, type=str)+logo_run[1:])
else:
logo_credit.setPicturePath(resources_path("logo_library",logo_run))
logo_credit.setId('logo_'+logo_run)
logo_credit.setBackgroundEnabled(True)
logo_credit.setBackgroundColor(QColor(255, 255, 255, 130))
self.layout.addLayoutItem(logo_credit)
# credit_text.attemptResize(QgsLayoutSize(95, 5, QgsUnitTypes.LayoutMillimeters))
self.bar_echelle_auto(iface.mapCanvas(), self.scalebar_qpt)
existing_layout = project.layoutManager().layoutByName(self.layout.name())
if existing_layout:
if self.radioButton_12.isChecked() != 1:
project.layoutManager().removeLayout(existing_layout)
result = project.layoutManager().addLayout(self.layout)
self.manager.addLayout(self.layout)
if self.radioButton_9.isChecked() == 1:
self.layout.atlas().setEnabled(True)
cover_layer = QgsProject.instance().mapLayersByName(self.comboBox_2.currentText())[0]
self.layout.atlas().setCoverageLayer(cover_layer)
self.layout.atlas().setPageNameExpression(self.comboBox_4.currentText())
fichier_mise_en_page = layout_name
layout_modifie = QgsProject.instance().layoutManager().layoutByName(fichier_mise_en_page)
iface.openLayoutDesigner(layout_modifie)
self.close()
def actualisation_mise_en_page(self):
A4_size = {'Portrait':{'RIGHT':210,'LEFT':0,'TOP':0,'BOTTOM':297},'Landscape':{'RIGHT':297,'LEFT':0,'TOP':0,'BOTTOM':210}}
A3_size = {'Portrait':{'RIGHT':298,'LEFT':0,'TOP':0,'BOTTOM':420},'Landscape':{'RIGHT':420,'LEFT':0,'TOP':0,'BOTTOM':298}}
values_page = self.comboBox.currentText()
if self.radioButton_6.isChecked() and self.radioButton_7.isChecked():
pc = self.layout.pageCollection()
pc.pages()[0].setPageSize('A4', QgsLayoutItemPage.Portrait)
if self.radioButton_6.isChecked() and self.radioButton_8.isChecked():
pc = self.layout.pageCollection()
pc.pages()[0].setPageSize('A4', QgsLayoutItemPage.Landscape)
if self.radioButton_5.isChecked() and self.radioButton_7.isChecked():
pc = self.layout.pageCollection()
pc.pages()[0].setPageSize('A3', QgsLayoutItemPage.Portrait)
if self.radioButton_5.isChecked() and self.radioButton_8.isChecked():
pc = self.layout.pageCollection()
pc.pages()[0].setPageSize('A3', QgsLayoutItemPage.Landscape)
self.template_parameters = fletch_canvas(self,values_page)
def bar_echelle_auto(self, echelle, bar_echelle):
if True:
if echelle.scale() >= 20000:
bar_echelle.setUnits(QgsUnitTypes.DistanceKilometers)
bar_echelle.setUnitLabel("km")
bar_echelle.setUnitsPerSegment(round((echelle.scale()*0.02)/1000))
else:
bar_echelle.setUnits(QgsUnitTypes.DistanceMeters)
bar_echelle.setUnitLabel("m")
bar_echelle.setUnitsPerSegment(round(echelle.scale()*0.02))
bar_echelle.update()

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

+89
View File
@@ -0,0 +1,89 @@
import os
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\')+1
NAME = plugin_dir[end_find:]
#print(NAME)
from qgis.gui import *
from qgis.core import (
NULL,
QgsApplication,
QgsDataSourceUri,
QgsProject,
QgsProviderConnectionException,
QgsProviderRegistry,
QgsRasterLayer,
QgsSettings,
QgsVectorLayer,
QgsGeometry,
)
from qgis.PyQt.QtWidgets import (
QDialog,
QAction,
QDockWidget,
QFileDialog,
QInputDialog,
QMenu,
QToolButton,
QTableWidget,
QTableWidgetItem,
)
from qgis.utils import iface
from .tools.resources import (
load_ui,
resources_path,
send_issues,
)
EDITOR_CLASS = load_ui('CenRa_IssuesSend.ui')
class CenRa_Issues(QDialog, EDITOR_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
#place connect here
self.annuler_button.clicked.connect(self.close)
self.ok_button.clicked.connect(self.run_sendissues)
def run_sendissues(self):
text_titre = self.titre_line.text()
text_message = self.messages_plain.toPlainText()
statu_bug = self.check_bug.isChecked()
statu_aide = self.check_aide.isChecked()
statu_question = self.check_question.isChecked()
statu_amelioration = self.check_amelioration.isChecked()
statu_autre = self.check_autre.isChecked()
statu = []
if statu_bug == True : statu = statu + [1]
if statu_aide == True : statu = statu + [3]
if statu_question == True : statu = statu + [5]
if statu_amelioration == True : statu = statu + [2]
if statu_autre == True : statu = statu + [6]
if len(statu) >= 1:
import qgis
url = qgis.utils.pluginMetadata(NAME,'tracker')
print(text_message)
send_info = send_issues(url,text_titre,text_message,statu)
code = send_info.status_code
print(code)
else:
code = 423
if code == 201:
iface.messageBar().pushMessage("Envoyer :", "Votre messages à bien été envoyer.", level=Qgis.Success, duration=20)
self.close()
elif code == 422:
iface.messageBar().pushMessage("Erreur :", "Erreur dans le contenu du messages.", level=Qgis.Critical, duration=20)
elif code == 423:
iface.messageBar().pushMessage("Erreur :", "Pas de sujet sélectionné.", level=Qgis.Critical, duration=20)
elif code == 404:
iface.messageBar().pushMessage("Missing :", "Le serveur de messagerie est injoignable.", level=Qgis.Warning, duration=20)
+48
View File
@@ -0,0 +1,48 @@
# This file contains metadata for your plugin.
# This file should be included when you package your plugin.# Mandatory items:
[general]
name=CenRa_AutoMap
qgisMinimumVersion=3.0
description=CenRa_AutoMap
version=1.6
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
about=Outils de création de mise en page prédéfinis pour simplifier et organiser cette étape.
repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
homepage=https://plateformesig.cenra-outils.org/
tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues
# End of mandatory metadata
# Recommended items:
hasProcessingProvider=no
# Uncomment the following line and add your changelog:
changelog=<h2>CenRa_AutoMap:</h2></br><p><h3>07/10/2024 - Version 1.6: </h3> - Option de bibliotheque de logo custome.</p></br><p><h3>03/10/2024 - Version 1.5: </h3> - Remonte la fênetre dans la pille.</br> - Gestion du nombre de colonne dans la légend.</br></p></br><p><h3>02/10/2024 - Version 1.4: </h3> - Mise en page plein écrant.</br></p></br><p><h3>01/10/2024 - Version 1.3: </h3> - Récupération du titre et sous-titre pour mise en page existente.</br> - Integration de bibliotheque de logo.</br> - Integration de gestionaire pour les source de donnée.</br> - Mise en place d'une bar d'echelle adaptative. </br></p></br><p><h3>30/09/2024 - Version 1.2: </h3> - Activation du thème. </br> - Ajouter une carte de suivie. </br><p></br><h3>27/09/2024 - Version 1.1: </h3> - Ajout d'une liste déroulante pour les sources de données. </br>- Bouton pour ajouter des fonts de carte customisés. </br>- Fonctionnalité de génération d'atlas. </p></br><p><h3>26/09/2024 - Version 1.0: </h3> - Lancement du plugin CenRa_AutoMap avec une seul mise en page. </p></br>
# Tags are comma separated with spaces allowed
tags=python
category=Plugins
icon=icon.png
# experimental flag
experimental=False
# deprecated flag (applies to the whole plugin, not just a single version)
deprecated=False
# Since QGIS 3.8, a comma separated list of plugins to be installed
# (or upgraded) can be specified.
# Check the documentation for more information.
# plugin_dependencies=
Category of the plugin: Raster, Vector, Database or Web
# category=cenra,mise en page,atlas
# If the plugin can run on QGIS Server.
server=False
+34
View File
@@ -0,0 +1,34 @@
import sys
import socket
import os
IPAddr=socket.gethostbyname(socket.gethostname())
#print(IPAddr)
if IPAddr[0:11] == "100.100.100": #4269
host = "100.100.100.81"
port = "5432"
dbname = "sig4269"
sigdb="sig4269"
refdb="ref_geo4269"
password = "McVities"
if IPAddr[0:9] == "192.168.0": #01
host = "192.168.0.201"
port = "5432"
dbname = "sig01"
sigdb="sig01"
refdb="ref_geo01"
password = "McVities"
if IPAddr[0:9] == "192.168.1": #0726
host = "192.168.1.201"
port = "5432"
dbname = "sig0726"
sigdb="sig0726"
refdb="ref_geo0726"
password = "McVities"
if sys.platform == 'linux':
os_user = os.environ['USER']
else:
os_user = os.environ['USERNAME']
if os_user == 'STAGE':
os_user='stage'
if os_user == 'Administrateur':
os_user='stage'
Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

+143
View File
@@ -0,0 +1,143 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis minScale="1e+08" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" version="3.36.2-Maidenhead" maxScale="0">
<flags>
<Identifiable>1</Identifiable>
<Removable>1</Removable>
<Searchable>1</Searchable>
<Private>0</Private>
</flags>
<temporal enabled="0" fetchMode="0" mode="0">
<fixedRange>
<start></start>
<end></end>
</fixedRange>
</temporal>
<elevation enabled="0" symbology="Line" zscale="1" band="1" zoffset="0">
<data-defined-properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data-defined-properties>
<profileLineSymbol>
<symbol force_rhr="0" frame_rate="10" type="line" alpha="1" is_animated="0" name="" clip_to_extent="1">
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
<layer enabled="1" locked="0" class="SimpleLine" pass="0" id="{7e5fa3f7-eb9e-4791-ba1e-0e77899392ea}">
<Option type="Map">
<Option type="QString" value="0" name="align_dash_pattern"/>
<Option type="QString" value="square" name="capstyle"/>
<Option type="QString" value="5;2" name="customdash"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="customdash_map_unit_scale"/>
<Option type="QString" value="MM" name="customdash_unit"/>
<Option type="QString" value="0" name="dash_pattern_offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="dash_pattern_offset_map_unit_scale"/>
<Option type="QString" value="MM" name="dash_pattern_offset_unit"/>
<Option type="QString" value="0" name="draw_inside_polygon"/>
<Option type="QString" value="bevel" name="joinstyle"/>
<Option type="QString" value="145,82,45,255,rgb:0.56862745098039214,0.32156862745098042,0.17647058823529413,1" name="line_color"/>
<Option type="QString" value="solid" name="line_style"/>
<Option type="QString" value="0.6" name="line_width"/>
<Option type="QString" value="MM" name="line_width_unit"/>
<Option type="QString" value="0" name="offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="offset_map_unit_scale"/>
<Option type="QString" value="MM" name="offset_unit"/>
<Option type="QString" value="0" name="ring_filter"/>
<Option type="QString" value="0" name="trim_distance_end"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="trim_distance_end_map_unit_scale"/>
<Option type="QString" value="MM" name="trim_distance_end_unit"/>
<Option type="QString" value="0" name="trim_distance_start"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="trim_distance_start_map_unit_scale"/>
<Option type="QString" value="MM" name="trim_distance_start_unit"/>
<Option type="QString" value="0" name="tweak_dash_pattern_on_corners"/>
<Option type="QString" value="0" name="use_custom_dash"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="width_map_unit_scale"/>
</Option>
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</profileLineSymbol>
<profileFillSymbol>
<symbol force_rhr="0" frame_rate="10" type="fill" alpha="1" is_animated="0" name="" clip_to_extent="1">
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
<layer enabled="1" locked="0" class="SimpleFill" pass="0" id="{59353ec9-f57a-451f-93dc-24f9ec60d3e1}">
<Option type="Map">
<Option type="QString" value="3x:0,0,0,0,0,0" name="border_width_map_unit_scale"/>
<Option type="QString" value="145,82,45,255,rgb:0.56862745098039214,0.32156862745098042,0.17647058823529413,1" name="color"/>
<Option type="QString" value="bevel" name="joinstyle"/>
<Option type="QString" value="0,0" name="offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="offset_map_unit_scale"/>
<Option type="QString" value="MM" name="offset_unit"/>
<Option type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1" name="outline_color"/>
<Option type="QString" value="no" name="outline_style"/>
<Option type="QString" value="0.26" name="outline_width"/>
<Option type="QString" value="MM" name="outline_width_unit"/>
<Option type="QString" value="solid" name="style"/>
</Option>
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</profileFillSymbol>
</elevation>
<customproperties>
<Option type="Map">
<Option type="bool" value="false" name="WMSBackgroundLayer"/>
<Option type="bool" value="false" name="WMSPublishDataSourceUrl"/>
<Option type="int" value="0" name="embeddedWidgets/count"/>
<Option type="QString" value="Html" name="identify/format"/>
</Option>
</customproperties>
<mapTip enabled="1"></mapTip>
<pipe-data-defined-properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</pipe-data-defined-properties>
<pipe>
<provider>
<resampling enabled="false" zoomedOutResamplingMethod="nearestNeighbour" zoomedInResamplingMethod="nearestNeighbour" maxOversampling="2"/>
</provider>
<rasterrenderer opacity="1" nodataColor="" type="singlebandcolordata" band="1" alphaBand="-1">
<rasterTransparency/>
<minMaxOrigin>
<limits>None</limits>
<extent>WholeRaster</extent>
<statAccuracy>Estimated</statAccuracy>
<cumulativeCutLower>0.02</cumulativeCutLower>
<cumulativeCutUpper>0.98</cumulativeCutUpper>
<stdDevFactor>2</stdDevFactor>
</minMaxOrigin>
</rasterrenderer>
<brightnesscontrast contrast="0" gamma="1" brightness="0"/>
<huesaturation colorizeRed="255" saturation="0" colorizeBlue="128" grayscaleMode="2" colorizeOn="0" colorizeGreen="128" colorizeStrength="100" invertColors="0"/>
<rasterresampler maxOversampling="2"/>
<resamplingStage>resamplingFilter</resamplingStage>
</pipe>
<blendMode>6</blendMode>
</qgis>
+143
View File
@@ -0,0 +1,143 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis minScale="1e+08" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" version="3.36.2-Maidenhead" maxScale="0">
<flags>
<Identifiable>1</Identifiable>
<Removable>1</Removable>
<Searchable>1</Searchable>
<Private>0</Private>
</flags>
<temporal enabled="0" fetchMode="0" mode="0">
<fixedRange>
<start></start>
<end></end>
</fixedRange>
</temporal>
<elevation enabled="0" symbology="Line" zscale="1" band="1" zoffset="0">
<data-defined-properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data-defined-properties>
<profileLineSymbol>
<symbol force_rhr="0" frame_rate="10" type="line" alpha="1" is_animated="0" name="" clip_to_extent="1">
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
<layer enabled="1" locked="0" class="SimpleLine" pass="0" id="{ca7f0ebe-2f98-47c2-b569-3b44bade4d11}">
<Option type="Map">
<Option type="QString" value="0" name="align_dash_pattern"/>
<Option type="QString" value="square" name="capstyle"/>
<Option type="QString" value="5;2" name="customdash"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="customdash_map_unit_scale"/>
<Option type="QString" value="MM" name="customdash_unit"/>
<Option type="QString" value="0" name="dash_pattern_offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="dash_pattern_offset_map_unit_scale"/>
<Option type="QString" value="MM" name="dash_pattern_offset_unit"/>
<Option type="QString" value="0" name="draw_inside_polygon"/>
<Option type="QString" value="bevel" name="joinstyle"/>
<Option type="QString" value="152,125,183,255,rgb:0.59607843137254901,0.49019607843137253,0.71764705882352942,1" name="line_color"/>
<Option type="QString" value="solid" name="line_style"/>
<Option type="QString" value="0.6" name="line_width"/>
<Option type="QString" value="MM" name="line_width_unit"/>
<Option type="QString" value="0" name="offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="offset_map_unit_scale"/>
<Option type="QString" value="MM" name="offset_unit"/>
<Option type="QString" value="0" name="ring_filter"/>
<Option type="QString" value="0" name="trim_distance_end"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="trim_distance_end_map_unit_scale"/>
<Option type="QString" value="MM" name="trim_distance_end_unit"/>
<Option type="QString" value="0" name="trim_distance_start"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="trim_distance_start_map_unit_scale"/>
<Option type="QString" value="MM" name="trim_distance_start_unit"/>
<Option type="QString" value="0" name="tweak_dash_pattern_on_corners"/>
<Option type="QString" value="0" name="use_custom_dash"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="width_map_unit_scale"/>
</Option>
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</profileLineSymbol>
<profileFillSymbol>
<symbol force_rhr="0" frame_rate="10" type="fill" alpha="1" is_animated="0" name="" clip_to_extent="1">
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
<layer enabled="1" locked="0" class="SimpleFill" pass="0" id="{935ae4b1-d4c4-418b-88e0-dfa266fa0167}">
<Option type="Map">
<Option type="QString" value="3x:0,0,0,0,0,0" name="border_width_map_unit_scale"/>
<Option type="QString" value="152,125,183,255,rgb:0.59607843137254901,0.49019607843137253,0.71764705882352942,1" name="color"/>
<Option type="QString" value="bevel" name="joinstyle"/>
<Option type="QString" value="0,0" name="offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="offset_map_unit_scale"/>
<Option type="QString" value="MM" name="offset_unit"/>
<Option type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1" name="outline_color"/>
<Option type="QString" value="no" name="outline_style"/>
<Option type="QString" value="0.26" name="outline_width"/>
<Option type="QString" value="MM" name="outline_width_unit"/>
<Option type="QString" value="solid" name="style"/>
</Option>
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</profileFillSymbol>
</elevation>
<customproperties>
<Option type="Map">
<Option type="bool" value="false" name="WMSBackgroundLayer"/>
<Option type="bool" value="false" name="WMSPublishDataSourceUrl"/>
<Option type="int" value="0" name="embeddedWidgets/count"/>
<Option type="QString" value="Undefined" name="identify/format"/>
</Option>
</customproperties>
<mapTip enabled="1"></mapTip>
<pipe-data-defined-properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</pipe-data-defined-properties>
<pipe>
<provider>
<resampling enabled="false" zoomedOutResamplingMethod="nearestNeighbour" zoomedInResamplingMethod="nearestNeighbour" maxOversampling="2"/>
</provider>
<rasterrenderer opacity="0.8" nodataColor="" type="singlebandcolordata" band="1" alphaBand="-1">
<rasterTransparency/>
<minMaxOrigin>
<limits>None</limits>
<extent>WholeRaster</extent>
<statAccuracy>Estimated</statAccuracy>
<cumulativeCutLower>0.02</cumulativeCutLower>
<cumulativeCutUpper>0.98</cumulativeCutUpper>
<stdDevFactor>2</stdDevFactor>
</minMaxOrigin>
</rasterrenderer>
<brightnesscontrast contrast="20" gamma="0.9" brightness="30"/>
<huesaturation colorizeRed="255" saturation="30" colorizeBlue="255" grayscaleMode="0" colorizeOn="0" colorizeGreen="255" colorizeStrength="0" invertColors="0"/>
<rasterresampler maxOversampling="2"/>
<resamplingStage>resamplingFilter</resamplingStage>
</pipe>
<blendMode>6</blendMode>
</qgis>
+143
View File
@@ -0,0 +1,143 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis minScale="1e+08" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" version="3.36.2-Maidenhead" maxScale="0">
<flags>
<Identifiable>1</Identifiable>
<Removable>1</Removable>
<Searchable>1</Searchable>
<Private>0</Private>
</flags>
<temporal enabled="0" fetchMode="0" mode="0">
<fixedRange>
<start></start>
<end></end>
</fixedRange>
</temporal>
<elevation enabled="0" symbology="Line" zscale="1" band="1" zoffset="0">
<data-defined-properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data-defined-properties>
<profileLineSymbol>
<symbol force_rhr="0" frame_rate="10" type="line" alpha="1" is_animated="0" name="" clip_to_extent="1">
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
<layer enabled="1" locked="0" class="SimpleLine" pass="0" id="{a04c2f3d-4206-4d46-98fa-41458cd1d25d}">
<Option type="Map">
<Option type="QString" value="0" name="align_dash_pattern"/>
<Option type="QString" value="square" name="capstyle"/>
<Option type="QString" value="5;2" name="customdash"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="customdash_map_unit_scale"/>
<Option type="QString" value="MM" name="customdash_unit"/>
<Option type="QString" value="0" name="dash_pattern_offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="dash_pattern_offset_map_unit_scale"/>
<Option type="QString" value="MM" name="dash_pattern_offset_unit"/>
<Option type="QString" value="0" name="draw_inside_polygon"/>
<Option type="QString" value="bevel" name="joinstyle"/>
<Option type="QString" value="213,180,60,255,rgb:0.83529411764705885,0.70588235294117652,0.23529411764705882,1" name="line_color"/>
<Option type="QString" value="solid" name="line_style"/>
<Option type="QString" value="0.6" name="line_width"/>
<Option type="QString" value="MM" name="line_width_unit"/>
<Option type="QString" value="0" name="offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="offset_map_unit_scale"/>
<Option type="QString" value="MM" name="offset_unit"/>
<Option type="QString" value="0" name="ring_filter"/>
<Option type="QString" value="0" name="trim_distance_end"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="trim_distance_end_map_unit_scale"/>
<Option type="QString" value="MM" name="trim_distance_end_unit"/>
<Option type="QString" value="0" name="trim_distance_start"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="trim_distance_start_map_unit_scale"/>
<Option type="QString" value="MM" name="trim_distance_start_unit"/>
<Option type="QString" value="0" name="tweak_dash_pattern_on_corners"/>
<Option type="QString" value="0" name="use_custom_dash"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="width_map_unit_scale"/>
</Option>
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</profileLineSymbol>
<profileFillSymbol>
<symbol force_rhr="0" frame_rate="10" type="fill" alpha="1" is_animated="0" name="" clip_to_extent="1">
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
<layer enabled="1" locked="0" class="SimpleFill" pass="0" id="{56980d1e-41f6-4d14-8389-d5daeb39d97f}">
<Option type="Map">
<Option type="QString" value="3x:0,0,0,0,0,0" name="border_width_map_unit_scale"/>
<Option type="QString" value="213,180,60,255,rgb:0.83529411764705885,0.70588235294117652,0.23529411764705882,1" name="color"/>
<Option type="QString" value="bevel" name="joinstyle"/>
<Option type="QString" value="0,0" name="offset"/>
<Option type="QString" value="3x:0,0,0,0,0,0" name="offset_map_unit_scale"/>
<Option type="QString" value="MM" name="offset_unit"/>
<Option type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1" name="outline_color"/>
<Option type="QString" value="no" name="outline_style"/>
<Option type="QString" value="0.26" name="outline_width"/>
<Option type="QString" value="MM" name="outline_width_unit"/>
<Option type="QString" value="solid" name="style"/>
</Option>
<data_defined_properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</profileFillSymbol>
</elevation>
<customproperties>
<Option type="Map">
<Option type="bool" value="false" name="WMSBackgroundLayer"/>
<Option type="bool" value="false" name="WMSPublishDataSourceUrl"/>
<Option type="int" value="0" name="embeddedWidgets/count"/>
<Option type="QString" value="Undefined" name="identify/format"/>
</Option>
</customproperties>
<mapTip enabled="1"></mapTip>
<pipe-data-defined-properties>
<Option type="Map">
<Option type="QString" value="" name="name"/>
<Option name="properties"/>
<Option type="QString" value="collection" name="type"/>
</Option>
</pipe-data-defined-properties>
<pipe>
<provider>
<resampling enabled="false" zoomedOutResamplingMethod="nearestNeighbour" zoomedInResamplingMethod="nearestNeighbour" maxOversampling="2"/>
</provider>
<rasterrenderer opacity="1" nodataColor="" type="singlebandcolordata" band="1" alphaBand="-1">
<rasterTransparency/>
<minMaxOrigin>
<limits>None</limits>
<extent>WholeRaster</extent>
<statAccuracy>Estimated</statAccuracy>
<cumulativeCutLower>0.02</cumulativeCutLower>
<cumulativeCutUpper>0.98</cumulativeCutUpper>
<stdDevFactor>2</stdDevFactor>
</minMaxOrigin>
</rasterrenderer>
<brightnesscontrast contrast="-10" gamma="1" brightness="40"/>
<huesaturation colorizeRed="255" saturation="10" colorizeBlue="255" grayscaleMode="0" colorizeOn="0" colorizeGreen="255" colorizeStrength="100" invertColors="0"/>
<rasterresampler maxOversampling="2"/>
<resamplingStage>resamplingFilter</resamplingStage>
</pipe>
<blendMode>6</blendMode>
</qgis>
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

+187
View File
@@ -0,0 +1,187 @@
"""Tools to work with resource files."""
import configparser
import shutil
import tempfile
import base64
import psycopg2
import psycopg2.extras
from os.path import abspath, join, pardir, dirname
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt import uic
__copyright__ = "Copyright 2019, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
__revision__ = "$Format:%H$"
def plugin_path(*args):
"""Get the path to plugin root folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the plugin path.
:rtype: str
"""
path = dirname(dirname(__file__))
path = abspath(abspath(join(path, pardir)))
for item in args:
path = abspath(join(path, item))
return path
def plugin_name():
"""Return the plugin name according to metadata.txt.
:return: The plugin name.
:rtype: basestring
"""
metadata = metadata_config()
name = metadata["general"]["name"]
return name
def metadata_config() -> configparser:
"""Get the INI config parser for the metadata file.
:return: The config parser object.
:rtype: ConfigParser
"""
path = plugin_path("metadata.txt")
config = configparser.ConfigParser()
config.read(path, encoding='utf8')
return config
def plugin_test_data_path(*args, copy=False):
"""Get the path to the plugin test data path.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:param copy: If the file must be copied into a temporary directory first.
:type copy: bool
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "test", "data")))
for item in args:
path = abspath(join(path, item))
if copy:
temp = tempfile.mkdtemp()
shutil.copy(path, temp)
return join(temp, args[-1])
else:
return path
def resources_path(*args):
"""Get the path to our resources folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_AUTOMAP\\tools")))
for item in args:
path = abspath(join(path, item))
return path
def load_ui(*args):
"""Get compile UI file.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Compiled UI file.
"""
ui_class, _ = uic.loadUiType(resources_path("ui", *args))
return ui_class
def login_base(take=None):
from CenRa_METABASE.tools.PythonSQL import host,port,dbname,password,os_user
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()
if take:
return cur,con
else:
return cur
def send_issues(url,titre,body,labels):
import requests
import json
import os
import qgis
usr = os.environ['USERNAME']
token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
url=url+'?token='+token
headers = {'Authorization': 'token ' + token,'accept': 'application/json','Content-Type': 'application/json'}
payload = {'title': titre, 'body': body, 'labels': labels}
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
r = ''
if binar:
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r
def maj_verif(NAME):
import qgis
import urllib.request
iface = qgis.utils.iface
from qgis.core import Qgis
url = qgis.utils.pluginMetadata(NAME,'repository')
#URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/releases/plugins.xml'
# print(URL)
version = qgis.utils.pluginMetadata(NAME,'version')
len_version = len(version)
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
if binar:
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>',plugin_num)+9
version_plugin = version_web[valeur_version_web:valeur_version_web+len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
def tr(text, context="@default"):
return QApplication.translate(context, text)
def devlog(NAME):
import qgis
devmaj = '<head><style>* {margin:0; padding:0; }</style></head>'
devmaj = devmaj+qgis.utils.pluginMetadata(NAME,'changelog')
return devmaj
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_Metabase_editorwidget_base</class>
<widget class="QDialog" name="CenRa_Metabase_editorwidget_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>594</height>
</rect>
</property>
<property name="windowTitle">
<string>Metabase</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../../CenRa_Metabase/tools/ui/icon.svg</normaloff>../../CenRa_Metabase/tools/ui/icon.svg</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>453</width>
<height>547</height>
</rect>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>451</width>
<height>541</height>
</rect>
</property>
<property name="title">
<string>DevLog</string>
</property>
<widget class="QWebView" name="viewer" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>431</width>
<height>511</height>
</rect>
</property>
<property name="url" stdset="0">
<url>
<string>about:blank</string>
</url>
</property>
</widget>
</widget>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QWebView</class>
<extends>QWidget</extends>
<header location="global">QtWebKitWidgets/QWebView</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
File diff suppressed because it is too large Load Diff
+332
View File
@@ -0,0 +1,332 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_IssuesSend</class>
<widget class="QDialog" name="CenRa_IssuesSend">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>810</width>
<height>587</height>
</rect>
</property>
<property name="windowTitle">
<string>CEN-RA Metabase</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>icon.svg</normaloff>icon.svg</iconset>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>550</y>
<width>811</width>
<height>31</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="2">
<widget class="QPushButton" name="annuler_button">
<property name="text">
<string>Annuler</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="ok_button">
<property name="text">
<string>Envoyer</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>791</width>
<height>531</height>
</rect>
</property>
<property name="title">
<string>Issues</string>
</property>
<widget class="QLineEdit" name="titre_line">
<property name="geometry">
<rect>
<x>240</x>
<y>40</y>
<width>321</width>
<height>41</height>
</rect>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPlainTextEdit" name="messages_plain">
<property name="geometry">
<rect>
<x>10</x>
<y>101</y>
<width>571</width>
<height>421</height>
</rect>
</property>
</widget>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>589</x>
<y>100</y>
<width>191</width>
<height>431</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>341</width>
<height>411</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property>
<item row="0" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="check_bug">
<property name="text">
<string>Bug</string>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="check_aide">
<property name="text">
<string>Aide</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="check_question">
<property name="text">
<string>Question</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="check_amelioration">
<property name="text">
<string>Amélioration</string>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="check_autre">
<property name="text">
<string>Autre</string>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>250</x>
<y>20</y>
<width>51</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Titre:</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Messages:</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>600</x>
<y>70</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Sujet:</string>
</property>
</widget>
</widget>
</widget>
<tabstops>
<tabstop>ok_button</tabstop>
<tabstop>annuler_button</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
+35
View File
@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
Copie
A QGIS plugin
Permet la copie d'une table dans une base PostGis
-------------------
begin : 2015-04-13
copyright : (C) 2015 by Guillaume COSTES - CEN Rhône-Alpes
email : guillaume.costes@espaces-naturels.fr
git sha : $Format:%H$
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
This script initializes the plugin, making it known to QGIS.
"""
# noinspection PyPep8Naming
def classFactory(iface): # pylint: disable=invalid-name
"""Load Copie class from file Copie.
:param iface: A QGIS interface instance.
:type iface: QgsInterface
"""
#
from .copie import Copie
return Copie(iface)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

+17 -1
View File
@@ -36,9 +36,12 @@ from qgis.gui import *
# Initialize Qt resources from file resources.py # Initialize Qt resources from file resources.py
from . import resources_rc from . import resources_rc
# Import the code for the dialog # Import the code for the dialog
import qgis
from .forms.about_form import CopieAboutDialog
from .copie_dialog import CopieDialog from .copie_dialog import CopieDialog
import os.path import os.path
from .PythonSQL import * from .tools.PythonSQL import *
from .tools.resources import maj_verif
import psycopg2 import psycopg2
import psycopg2.extras import psycopg2.extras
import base64 import base64
@@ -77,6 +80,15 @@ class Copie(object):
# Create the dialog (after translation) and keep reference # Create the dialog (after translation) and keep reference
self.dlg = CopieDialog() self.dlg = CopieDialog()
maj_verif('CenRa_COPIE')
version = qgis.utils.pluginMetadata('CenRa_COPIE','version')
# Display About window on first use
s = QSettings()
versionUse = s.value("copie/version", 1, type=str)
if str(versionUse) != str(version) :
s.setValue("copie/version", str(version))
self.open_about_dialog()
# Declare instance attributes # Declare instance attributes
self.actions = [] self.actions = []
@@ -85,6 +97,10 @@ class Copie(object):
self.toolbar = self.iface.addToolBar(u'Copie') self.toolbar = self.iface.addToolBar(u'Copie')
self.toolbar.setObjectName(u'Copie') self.toolbar.setObjectName(u'Copie')
def open_about_dialog(self):
dialog = CopieAboutDialog(self.iface)
dialog.exec_()
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
def tr(self, message): def tr(self, message):
"""Get the translation for a string using Qt translation API. """Get the translation for a string using Qt translation API.
+107
View File
@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'copie_dialog_base.ui'
#
# Created: Tue Apr 14 11:48:04 2015
# by: PyQt4 UI code generator 4.10.2
#
# WARNING! All changes made in this file will be lost!
from builtins import object
from qgis.PyQt import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_CopieDialogBase(object):
def setupUi(self, CopieDialogBase):
CopieDialogBase.setObjectName(_fromUtf8("CopieDialogBase"))
CopieDialogBase.resize(386, 290)
self.button_box = QtGui.QDialogButtonBox(CopieDialogBase)
self.button_box.setGeometry(QtCore.QRect(100, 250, 161, 32))
self.button_box.setOrientation(QtCore.Qt.Horizontal)
self.button_box.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.button_box.setObjectName(_fromUtf8("button_box"))
self.schema_label = QtGui.QLabel(CopieDialogBase)
self.schema_label.setGeometry(QtCore.QRect(20, 100, 121, 29))
self.schema_label.setMaximumSize(QtCore.QSize(10000, 16777215))
self.schema_label.setObjectName(_fromUtf8("schema_label"))
self.label_nom_table = QtGui.QLabel(CopieDialogBase)
self.label_nom_table.setGeometry(QtCore.QRect(20, 150, 131, 29))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_nom_table.setFont(font)
self.label_nom_table.setObjectName(_fromUtf8("label_nom_table"))
self.schema = QtGui.QComboBox(CopieDialogBase)
self.schema.setGeometry(QtCore.QRect(20, 130, 351, 20))
self.schema.setObjectName(_fromUtf8("schema"))
self.table_destination = QtGui.QLineEdit(CopieDialogBase)
self.table_destination.setGeometry(QtCore.QRect(20, 180, 291, 20))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.table_destination.setFont(font)
self.table_destination.setObjectName(_fromUtf8("table_destination"))
self.annee = QtGui.QLineEdit(CopieDialogBase)
self.annee.setGeometry(QtCore.QRect(320, 180, 50, 20))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee.setFont(font)
self.annee.setAlignment(QtCore.Qt.AlignCenter)
self.annee.setObjectName(_fromUtf8("annee"))
self.table_vide = QtGui.QCheckBox(CopieDialogBase)
self.table_vide.setGeometry(QtCore.QRect(60, 220, 271, 20))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.table_vide.setFont(font)
self.table_vide.setObjectName(_fromUtf8("table_vide"))
self.table_source = QtGui.QLineEdit(CopieDialogBase)
self.table_source.setEnabled(False)
self.table_source.setGeometry(QtCore.QRect(20, 60, 351, 20))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.table_source.setFont(font)
self.table_source.setObjectName(_fromUtf8("table_source"))
self.Titre = QtGui.QLabel(CopieDialogBase)
self.Titre.setGeometry(QtCore.QRect(0, 0, 381, 31))
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.Titre.setFont(font)
self.Titre.setAlignment(QtCore.Qt.AlignCenter)
self.Titre.setObjectName(_fromUtf8("Titre"))
self.table_source_label = QtGui.QLabel(CopieDialogBase)
self.table_source_label.setGeometry(QtCore.QRect(20, 30, 75, 29))
self.table_source_label.setMaximumSize(QtCore.QSize(75, 16777215))
self.table_source_label.setObjectName(_fromUtf8("table_source_label"))
self.retranslateUi(CopieDialogBase)
QtCore.QObject.connect(self.button_box, QtCore.SIGNAL(_fromUtf8("accepted()")), CopieDialogBase.accept)
QtCore.QObject.connect(self.button_box, QtCore.SIGNAL(_fromUtf8("rejected()")), CopieDialogBase.reject)
QtCore.QMetaObject.connectSlotsByName(CopieDialogBase)
def retranslateUi(self, CopieDialogBase):
CopieDialogBase.setWindowTitle(_translate("CopieDialogBase", "Copie", None))
self.schema_label.setText(_translate("CopieDialogBase", "Dossier de destination ", None))
self.label_nom_table.setText(_translate("CopieDialogBase", "Nom de la nouvelle table", None))
self.annee.setText(_translate("CopieDialogBase", "aaaa", None))
self.table_vide.setText(_translate("CopieDialogBase", "Cocher cette case pour vider la table de destination", None))
self.Titre.setText(_translate("CopieDialogBase", "Copie d\'une table", None))
self.table_source_label.setText(_translate("CopieDialogBase", "Table source ", None))
+234
View File
@@ -0,0 +1,234 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CopieDialogBase</class>
<widget class="QDialog" name="CopieDialogBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>386</width>
<height>290</height>
</rect>
</property>
<property name="windowTitle">
<string>Copie</string>
</property>
<widget class="QDialogButtonBox" name="button_box">
<property name="geometry">
<rect>
<x>100</x>
<y>250</y>
<width>161</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="schema_label">
<property name="geometry">
<rect>
<x>20</x>
<y>100</y>
<width>121</width>
<height>29</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>10000</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Dossier de destination </string>
</property>
</widget>
<widget class="QLabel" name="label_nom_table">
<property name="geometry">
<rect>
<x>20</x>
<y>150</y>
<width>131</width>
<height>29</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Nom de la nouvelle table</string>
</property>
</widget>
<widget class="QComboBox" name="schema">
<property name="geometry">
<rect>
<x>20</x>
<y>130</y>
<width>351</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="table_destination">
<property name="geometry">
<rect>
<x>20</x>
<y>180</y>
<width>291</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
</widget>
<widget class="QLineEdit" name="annee">
<property name="geometry">
<rect>
<x>320</x>
<y>180</y>
<width>50</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QCheckBox" name="table_vide">
<property name="geometry">
<rect>
<x>60</x>
<y>220</y>
<width>271</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Cocher cette case pour vider la table de destination</string>
</property>
</widget>
<widget class="QLineEdit" name="table_source">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>351</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
</widget>
<widget class="QLabel" name="Titre">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>381</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Copie d'une table</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLabel" name="table_source_label">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>75</width>
<height>29</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Table source </string>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>button_box</sender>
<signal>accepted()</signal>
<receiver>CopieDialogBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>button_box</sender>
<signal>rejected()</signal>
<receiver>CopieDialogBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+37
View File
@@ -0,0 +1,37 @@
# This file contains metadata for your plugin. Since
# version 2.0 of QGIS this is the proper way to supply
# information about a plugin. The old method of
# embedding metadata in __init__.py will
# is no longer supported since version 2.0.
# This file should be included when you package your plugin.# Mandatory items:
[general]
name=CenRA_COPIE
qgisMinimumVersion=3.0
description=Permet la copie d'une table dans une base PostGis
version=1.5
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
# End of mandatory metadata
# Recommended items:
# Uncomment the following line and add your changelog:
changelog=<h2>CenRa_COPIE:</h2></br><p><h3>13/09/2024 - Version 1.5:</h3>- Ajoute d'un changelog et vérification de mise à jour.</p>
# Tags are comma separated with spaces allowed
tags=cenra, database, table
repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
homepage=https://plateformesig.cenra-outils.org/
category=Plugins
icon=cenra.png
# experimental flag
experimental=True
# deprecated flag (applies to the whole plugin, not just a single version)
deprecated=False
+134
View File
@@ -0,0 +1,134 @@
#!/usr/bin/env python
# coding=utf-8
"""This script uploads a plugin package on the server.
Authors: A. Pasotti, V. Picavet
git sha : $TemplateVCSFormat
"""
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import input
import sys
import getpass
import xmlrpc.client
from optparse import OptionParser
# Configuration
PROTOCOL = 'http'
SERVER = 'plugins.qgis.org'
PORT = '80'
ENDPOINT = '/plugins/RPC2/'
VERBOSE = False
def main(parameters, arguments):
"""Main entry point.
:param parameters: Command line parameters.
:param arguments: Command line arguments.
"""
address = "%s://%s:%s@%s:%s%s" % (
PROTOCOL,
parameters.username,
parameters.password,
parameters.server,
parameters.port,
ENDPOINT)
# fix_print_with_import
# fix_print_with_import
print("Connecting to: %s" % hide_password(address))
server = xmlrpc.client.ServerProxy(address, verbose=VERBOSE)
try:
plugin_id, version_id = server.plugin.upload(
xmlrpc.client.Binary(open(arguments[0]).read()))
# fix_print_with_import
# fix_print_with_import
print("Plugin ID: %s" % plugin_id)
# fix_print_with_import
# fix_print_with_import
print("Version ID: %s" % version_id)
except xmlrpc.client.ProtocolError as err:
# fix_print_with_import
print("A protocol error occurred")
# fix_print_with_import
# fix_print_with_import
print("URL: %s" % hide_password(err.url, 0))
# fix_print_with_import
# fix_print_with_import
print("HTTP/HTTPS headers: %s" % err.headers)
# fix_print_with_import
# fix_print_with_import
print("Error code: %d" % err.errcode)
# fix_print_with_import
# fix_print_with_import
print("Error message: %s" % err.errmsg)
except xmlrpc.client.Fault as err:
# fix_print_with_import
print("A fault occurred")
# fix_print_with_import
# fix_print_with_import
print("Fault code: %d" % err.faultCode)
# fix_print_with_import
# fix_print_with_import
print("Fault string: %s" % err.faultString)
def hide_password(url, start=6):
"""Returns the http url with password part replaced with '*'.
:param url: URL to upload the plugin to.
:type url: str
:param start: Position of start of password.
:type start: int
"""
start_position = url.find(':', start) + 1
end_position = url.find('@')
return "%s%s%s" % (
url[:start_position],
'*' * (end_position - start_position),
url[end_position:])
if __name__ == "__main__":
parser = OptionParser(usage="%prog [options] plugin.zip")
parser.add_option(
"-w", "--password", dest="password",
help="Password for plugin site", metavar="******")
parser.add_option(
"-u", "--username", dest="username",
help="Username of plugin site", metavar="user")
parser.add_option(
"-p", "--port", dest="port",
help="Server port to connect to", metavar="80")
parser.add_option(
"-s", "--server", dest="server",
help="Specify server name", metavar="plugins.qgis.org")
options, args = parser.parse_args()
if len(args) != 1:
# fix_print_with_import
print("Please specify zip file.\n")
parser.print_help()
sys.exit(1)
if not options.server:
options.server = SERVER
if not options.port:
options.port = PORT
if not options.username:
# interactive mode
username = getpass.getuser()
# fix_print_with_import
# fix_print_with_import
print("Please enter user name [%s] :" % username, end=' ')
res = input()
if res != "":
options.username = res
else:
options.username = username
if not options.password:
# interactive mode
options.password = getpass.getpass()
main(options, args)
+21
View File
@@ -0,0 +1,21 @@
from qgis.core import QgsApplication
def gitea():
file_url = QgsApplication.qgisSettingsDirPath()+'QGIS/QGIS3.ini'
recherche_1 = 'plugin_repositories\\github\\url=https://github.com/CEN-Rhone-Alpes/Plugin_QGIS/releases/latest/download/plugins.xml'
replace_1 = 'plugin_repositories\\gitea\\url=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
recherche_2 = 'github'
replace_2 = 'gitea'
# Read in the file
with open(file_url, 'r') as file:
filedata = file.read()
# Replace the target string
filedata = filedata.replace(recherche_1, replace_1)
filedata = filedata.replace(recherche_2, replace_2)
# Write the file out again
with open(file_url, 'w') as file:
file.write(filedata)
+172
View File
@@ -0,0 +1,172 @@
import sys
import socket
import os
IPAddr=socket.gethostbyname(socket.gethostname())
if IPAddr[0:11] == "100.100.100": #4269
host = "100.100.100.11"
port = "5432"
dbname = "sig4269"
sigdb="sig4269"
refdb="ref_geo4269"
password = "McVities"
if IPAddr[0:9] == "192.168.0": #01
host = "192.168.0.201"
port = "5432"
dbname = "sig01"
sigdb="sig01"
refdb="ref_geo01"
password = "McVities"
if IPAddr[0:9] == "192.168.1": #0726
host = "192.168.1.201"
port = "5432"
dbname = "sig0726"
sigdb="sig0726"
refdb="ref_geo0726"
password = "McVities"
if sys.platform == 'linux':
os_user = os.environ['USER']
else:
os_user = os.environ['USERNAME']
if os_user == 'STAGE':
os_user='stage'
geom = "geom"
champ_travaux_prevus_multipolygon="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, surface_m2 double precision, surface_ha double precision, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_travaux_prevus_multilinestring="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, longueur_m double precision, longueur_km double precision, date_creation date, date_maj date, geom geometry(MultiLineString,2154))"""
champ_travaux_prevus_point = """(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, x_wgs84 double precision, y_wgs84 double precision, date_creation date, date_maj date, geom geometry(Point,2154))"""
champ_viergePolygone = """(gid serial NOT NULL, commentaire text, surface_m2 double precision, surface_ha double precision, geom geometry(MultiPolygon,2154))"""
champ_viergeLigne = """(gid serial NOT NULL, commentaire text, longueur_m double precision, longueur_km double precision, geom geometry(MultiLineString,2154))"""
champ_viergePoint = """(gid serial NOT NULL, commentaire text, x_wgs84 double precision, y_wgs84 double precision, geom geometry(Point,2154))"""
champ_habitat = """(gid serial NOT NULL, cd_cb_01 text, lb_cb97_fr_01 text, occupation_01 integer, cd_cb_02 text, lb_cb97_fr_02 text, occupation_02 integer, cd_cb_03 text, lb_cb97_fr_03 text, occupation_03 integer, milieu_code text, milieu_libelle text, surface_m2 double precision, surface_ha double precision, commentaire text, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_contour="""(gid serial NOT NULL, date_creation date, date_maj date, utilisateur character varying, dept character(2), nom character varying, surface_m2 double precision, surface_ha double precision, type_site character varying, type_milieu character varying, date_premier_pg integer, date_debut_pg integer, date_fin_pg integer, referent character varying, gestion_deleguee character varying, terrain_militaire character(3), ens character(3), zh character(3), adapt_pmr character(3), inform character(3), guide character(3), ouverture_public character(3), obs character(3), anim character(3), n2000_anim character(3), contrat_n2000_conseil character(3), n2000_op character(3), contrat_n2000_benef character(3), contrat_agri character(3), bc_habitat integer, bc_amphibien integer, bc_coleoptere integer, bc_crustace integer, bc_mammifere integer, bc_chiroptere integer, bc_mollusque integer, bc_odonate integer, bc_oiseau integer, bc_orthoptere integer, bc_poisson integer, bc_reptile integer, bc_rhopalocere integer, bc_heterocere integer, bc_autre_invertebre integer, bc_flore integer, bc_bryophyte integer, bc_champignon integer, suiv_analyse_sol character(3), suiv_piezo character(3), suiv_climat character(3), suiv_topo character(3), suiv_habitat character(3), suiv_amphibien character(3), suiv_coleoptere character(3), suiv_crustace character(3), suiv_mammifere character(3), suiv_chiroptere character(3), suiv_mollusque character(3), suiv_odonate character(3), suiv_oiseau character(3), suiv_orthoptere character(3), suiv_poisson character(3), suiv_reptile character(3), suiv_rhopalocere character(3), suiv_heterocere character(3), suiv_autre_invertebre character(3), suiv_flore character(3), suiv_bryophyte character(3), suiv_champignon character(3), suiv_analyse_eau character(3), suiv_phenologie character(3), suiv_frequentation character(3), suiv_paysager character(3), suiv_autre character(3), commentaire text, geom geometry(MultiPolygon,2154))
"""
champ_vegethab_point = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(Point,2154)
)
"""
champ_vegethab_multilinestring = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiLineString,2154)
)
"""
champ_vegethab_multipolygon = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiPolygon,2154)
)
"""
+183
View File
@@ -0,0 +1,183 @@
"""Tools to work with resource files."""
import configparser
import shutil
import tempfile
import base64
import psycopg2
import psycopg2.extras
from os.path import abspath, join, pardir, dirname
from qgis.PyQt import uic
__copyright__ = "Copyright 2019, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
__revision__ = "$Format:%H$"
def plugin_path(*args):
"""Get the path to plugin root folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the plugin path.
:rtype: str
"""
path = dirname(dirname(__file__))
path = abspath(abspath(join(path, pardir)))
for item in args:
path = abspath(join(path, item))
return path
def plugin_name():
"""Return the plugin name according to metadata.txt.
:return: The plugin name.
:rtype: basestring
"""
metadata = metadata_config()
name = metadata["general"]["name"]
return name
def metadata_config() -> configparser:
"""Get the INI config parser for the metadata file.
:return: The config parser object.
:rtype: ConfigParser
"""
path = plugin_path("metadata.txt")
config = configparser.ConfigParser()
config.read(path, encoding='utf8')
return config
def plugin_test_data_path(*args, copy=False):
"""Get the path to the plugin test data path.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:param copy: If the file must be copied into a temporary directory first.
:type copy: bool
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "test", "data")))
for item in args:
path = abspath(join(path, item))
if copy:
temp = tempfile.mkdtemp()
shutil.copy(path, temp)
return join(temp, args[-1])
else:
return path
def resources_path(*args):
"""Get the path to our resources folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_Metabase\\resources")))
for item in args:
path = abspath(join(path, item))
return path
def load_ui(*args):
"""Get compile UI file.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Compiled UI file.
"""
ui_class, _ = uic.loadUiType(resources_path("ui", *args))
return ui_class
def login_base(take=None):
from CenRa_Metabase.resources.PythonSQL import host,port,dbname,password,os_user
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()
if take:
return cur,con
else:
return cur
def send_issues(url,titre,body,labels):
import requests
import json
import os
import qgis
usr = os.environ['USERNAME']
token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
url=url+'?token='+token
headers = {'Authorization': 'token ' + token,'accept': 'application/json','Content-Type': 'application/json'}
payload = {'title': titre, 'body': body, 'labels': labels}
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
r = ''
if binar:
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r
def maj_verif(NAME):
import qgis
import urllib.request
iface = qgis.utils.iface
from qgis.core import Qgis
url = qgis.utils.pluginMetadata(NAME,'repository')
#URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/releases/plugins.xml'
# print(URL)
version = qgis.utils.pluginMetadata(NAME,'version')
len_version = len(version)
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
if binar:
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>',plugin_num)+9
version_plugin = version_web[valeur_version_web:valeur_version_web+len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
def devlog(NAME):
import qgis
devmaj = '<head><style>* {margin:0; padding:0; }</style></head>'
devmaj = devmaj+qgis.utils.pluginMetadata(NAME,'changelog')
return devmaj
+940
View File
@@ -0,0 +1,940 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
FluxCEN
A QGIS plugin
Centralisation des flux WFS/WMS utilisés au CEN NA
Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
-------------------
begin : 2022-03-23
git sha : $Format:%H$
copyright : (C) 2022 by Romain MONTILLET
email : r.montillet@cen-na.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 qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt, QUrl
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from PyQt5 import *
# Initialize Qt resources from file resources.py
from .resources import *
# Import the code for the dialog
from .FluxCEN_dialog import FluxCENDialog
import os.path, os, shutil
from qgis.core import *
from qgis.gui import *
from qgis.utils import *
from .forms.about_form import FluxAboutDialog
import qgis
import processing
import psycopg2
import psycopg2.extras
from PyQt5.QtXml import QDomDocument
import csv
import os
import io
import re
import random
# Deal with SSL
import ssl
import urllib
from urllib import request, parse
import socket
import json
import requests
import base64
ssl._create_default_https_context = ssl._create_unverified_context
from .tools.resources import maj_verif
from .tools.PythonSQL import *
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)
#from .HubToTea import gitea
#gitea()
first_conn.close()
'''
# Vérifier la connexion à internet
try:
# Vérifier si l'utilisateur est connecté à internet en ouvrant une connexion avec un site web
host = socket.gethostbyname("www.google.com")
s = socket.create_connection((host, 80), 2)
s.close()
except socket.error:
# Afficher un message si l'utilisateur n'est pas connecté à internet
QMessageBox.warning(None, 'Avertissement',
'Vous n\'êtes actuellement pas connecté à internet. Veuillez vous connecter pour pouvoir utiliser FluxCEN !')
'''
class Flux:
def __init__(self, t, c, nc, l, u, p):
self.type = t
self.category = c
self.nom_commercial = nc
self.layer = l
self.url = u
self.parameters = p
maj_verif('CenRa_FLUX')
class Popup(QWidget):
def __init__(self, parent=None):
super(Popup, self).__init__(parent)
self.plugin_dir = os.path.dirname(__file__)
self.text_edit = QTextBrowser()
fp = urllib.request.urlopen("https://raw.githubusercontent.com/CEN-Nouvelle-Aquitaine/fluxcen/main/info_changelog.html")
mybytes = fp.read()
html_changelog = mybytes.decode("utf8")
fp.close()
self.text_edit.setHtml(html_changelog)
self.text_edit.setFont(QtGui.QFont("Calibri",weight=QtGui.QFont.Bold))
self.text_edit.anchorClicked.connect(QtGui.QDesktopServices.openUrl)
self.text_edit.setOpenLinks(False)
self.text_edit.setWindowTitle("Nouveautés")
self.text_edit.setMinimumSize(600,450)
class FluxCEN:
"""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
#print(QSettings().value('locale/userLocale'))
locale = QSettings().value('locale/userLocale')[0:2]
locale_path = os.path.join(
self.plugin_dir,
'i18n',
'FluxCEN_{}.qm'.format(locale))
version = qgis.utils.pluginMetadata('CenRa_FLUX','version')
# Display About window on first use
s = QSettings()
versionUse = s.value("flux/version", 1, type=str)
if str(versionUse) != str(version) :
s.setValue("flux/version", str(version))
self.open_about_dialog()
if os.path.exists(locale_path):
self.translator = QTranslator()
self.translator.load(locale_path)
QCoreApplication.installTranslator(self.translator)
# Declare instance attributes
self.actions = []
self.menu = self.tr(u'&FluxCEN')
self.dlg = FluxCENDialog()
self.plugin_path = os.path.dirname(__file__)
# Check if plugin was started the first time in current QGIS session
# Must be set in initGui() to survive plugin reloads
self.first_start = None
self.dlg.tableWidget.setSelectionBehavior(QTableWidget.SelectRows)
self.dlg.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.dlg.comboBox_2.addItem("SIG")
self.dlg.comboBox_2.addItem('REF')
# self.dlg.comboBox.addItem('07')
# self.dlg.comboBox.addItem('26')
# self.dlg.comboBox.addItem('42')
# self.dlg.comboBox.addItem('69')
# self.dlg.comboBox.addItem('form')
self.dlg.comboBox.currentIndexChanged.connect(self.initialisation_flux)
self.dlg.commandLinkButton.clicked.connect(self.selection_flux)
self.dlg.tableWidget.itemDoubleClicked.connect(self.selection_flux)
self.dlg.pushButton_2.clicked.connect(self.limite_flux)
self.dlg.commandLinkButton_2.clicked.connect(self.suppression_flux)
self.dlg.tableWidget_2.itemDoubleClicked.connect(self.suppression_flux)
self.dlg.comboBox_2.currentIndexChanged.connect(self.bd_source)
#self.dlg.commandLinkButton_3.clicked.connect(self.option_OSM)
#self.dlg.commandLinkButton_4.clicked.connect(self.option_google_maps)
#self.dlg.commandLinkButton_5.clicked.connect(self.popup)
# iface.mapCanvas().extentsChanged.connect(self.test5)
# url_open = urllib.request.urlopen("https://raw.githubusercontent.com/CEN-Rhone-Alpes/Plugin_QGIS/main/flux.csv")
# colonnes_flux = csv.DictReader(io.TextIOWrapper(url_open, encoding='utf8'), delimiter=';')
#mots_cles = [row["categorie"] for row in colonnes_flux if row["categorie"]]
#categories = list(set(mots_cles))
#categories.sort()
#self.dlg.comboBox.addItems(categories)
layout = QVBoxLayout()
self.dlg.lineEdit.textChanged.connect(self.filtre_dynamique)
layout.addWidget(self.dlg.lineEdit)
self.dlg.lineEdit.mousePressEvent = self._mousePressEvent
metadonnees_plugin = open(self.plugin_path + '/metadata.txt')
infos_metadonnees = metadonnees_plugin.readlines()
# derniere_version = urllib.request.urlopen("https://sig.dsi-cen.org/qgis/downloads/last_version_fluxcen.txt")
# num_last_version = derniere_version.readlines()[0].decode("utf-8")
# Connect the itemClicked signal to the open_url function
#self.dlg.tableWidget.itemClicked.connect(self.open_url)
# version_utilisateur = infos_metadonnees[8].splitlines()
# if infos_metadonnees[8].splitlines() == num_last_version.splitlines():
# iface.messageBar().pushMessage("Plugin à jour", "Votre version de FluxCEN %s est à jour !" %version_utilisateur, level=Qgis.Success, duration=5)
# else:
# iface.messageBar().pushMessage("Information :", "Une nouvelle version de FluxCEN est disponible, veuillez mettre à jour le plugin !", level=Qgis.Info, duration=120)
def open_about_dialog(self):
dialog = FluxAboutDialog(self.iface)
dialog.exec_()
def _mousePressEvent(self, event):
self.dlg.lineEdit.setText("")
self.dlg.lineEdit.mousePressEvent = None
# 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('FluxCEN', message)
def add_action(
self,
icon_path,
text,
callback,
dbtype=None,
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:
# Adds plugin icon to Plugins toolbar
#self.iface.addToolBarIcon(action)
self.toolBar.addAction(action)
if add_to_menu:
self.iface.addPluginToMenu(
self.menu,
action)
self.actions.append(action)
return action
def initGui(self):
self.toolBar = self.iface.addToolBar("FluxCEN")
self.toolBar.setObjectName("FluxCEN")
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
icon_path = ':/plugins/CenRa_FLUX/reficon.png'
self.add_action(
icon_path,
text=self.tr(u'SigCEN'),
callback=self.bd_source,
dbtype='"+dbname+"',
parent=self.iface.mainWindow())
'''
icon_path_2 = ':/plugins/CenRa_FLUX/reficon.png'
self.add_action(
icon_path_2,
text=self.tr(u'RefCEN'),
callback=self.run_ref,
dbtype='ref_geo4269',
parent=self.iface.mainWindow())
'''
# will be set False in run()
self.first_start = False
def unload(self):
"""Removes the plugin menu item and icon from QGIS GUI."""
for action in self.actions:
self.iface.removePluginMenu(
self.tr(u'&SigCEN'),
action)
self.iface.removeToolBarIcon(action)
for action in self.actions:
self.iface.removePluginMenu(
self.tr(u'&RefCEN'),
action)
self.iface.removeToolBarIcon(action)
def bd_source(self):
self.dlg.activateWindow()
bd_origine=self.dlg.comboBox_2.currentText()
if bd_origine == 'REF':
self.run_ref()
if bd_origine == 'SIG':
self.run_sig()
def run_ref(self):
"""Run method that performs all the real work"""
while self.dlg.tableWidget_2.rowCount() > 0:
self.dlg.tableWidget_2.removeRow(self.dlg.tableWidget_2.rowCount()-1)
# print(self.dlg.tableWidget_2.rowCount())
global cur,con,dbtype
dbtype=refdb
con = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbtype+" user=" + user + " password=" + mdp)
cur = con.cursor(cursor_factory = psycopg2.extras.DictCursor)
self.initialisation_flux()
self.combobox_custom()
# Create the dialog with elements (after translation) and keep reference
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
if self.first_start == True:
self.first_start = False
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result:
# Do something useful here - delete the line containing pass and
# substitute with your code.
pass
def run_sig(self):
"""Run method that performs all the real work"""
while self.dlg.tableWidget_2.rowCount() > 0:
self.dlg.tableWidget_2.removeRow(self.dlg.tableWidget_2.rowCount()-1)
global cur,con,dbtype
dbtype=sigdb
con = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbtype+" user=" + user + " password=" + mdp)
cur = con.cursor(cursor_factory = psycopg2.extras.DictCursor)
self.initialisation_flux()
self.combobox_custom()
# Create the dialog with elements (after translation) and keep reference
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
if self.first_start == True:
self.first_start = False
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result:
# Do something useful here - delete the line containing pass and
# substitute with your code.
pass
def suppression_flux(self):
self.dlg.tableWidget_2.removeRow(self.dlg.tableWidget_2.currentRow())
'''
def option_OSM(self):
tms = 'type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png&zmax=19&zmin=0'
layer = QgsRasterLayer(tms, 'OSM', 'wms')
if not QgsProject.instance().mapLayersByName("OSM"):
QgsProject.instance().addMapLayer(layer)
else:
QMessageBox.question(iface.mainWindow(), u"Fond OSM déjà chargé !", "Le fond de carte OSM est déjà chargé", QMessageBox.Ok)
OSM_layer = QgsProject.instance().mapLayersByName("OSM")[0]
root = QgsProject.instance().layerTreeRoot()
# Move Layer
OSM_layer = root.findLayer(OSM_layer.id())
myClone = OSM_layer.clone()
parent = OSM_layer.parent()
parent.insertChildNode(-1, myClone)
parent.removeChildNode(OSM_layer)
def option_google_maps(self):
tms = 'type=xyz&zmin=0&zmax=20&url=https://mt1.google.com/vt/lyrs%3Ds%26x%3D{x}%26y%3D{y}%26z%3D{z}'
layer = QgsRasterLayer(tms, 'Google Satelitte', 'wms')
if not QgsProject.instance().mapLayersByName("Google Satelitte"):
QgsProject.instance().addMapLayer(layer)
else:
QMessageBox.question(iface.mainWindow(), u"Fond Google Sat' déjà chargé !", "Le fond de carte Google Satelitte est déjà chargé", QMessageBox.Ok)
google_layer = QgsProject.instance().mapLayersByName("Google Satelitte")[0]
root = QgsProject.instance().layerTreeRoot()
# Move Layer
google_layer = root.findLayer(google_layer.id())
myClone = google_layer.clone()
parent = google_layer.parent()
parent.insertChildNode(-1, myClone)
parent.removeChildNode(google_layer)
'''
def open_url(self, item):
url = item.data(Qt.UserRole)
#if url:
# Open the URL, you might use QDesktopServices.openUrl for this in a standalone PyQt application
# QDesktopServices.openUrl(QUrl(url))
def initialisation_flux(self):
'''
def csv_import(url):
url_open = urllib.request.urlopen(url)
csvfile = csv.reader(io.TextIOWrapper(url_open, encoding='utf8'), delimiter=';')
#on ne lit pas la première ligne correspondant aux noms des colonnes avec next()
next(csvfile)
return csvfile;
data = []
data2 = []
model = QStandardItemModel()
raw = csv_import(
"https://raw.githubusercontent.com/CEN-Rhone-Alpes/Plugin_QGIS/main/flux.csv")
for row in raw:
data.append(row)
data2.append(row)
data = [k for k in data if self.dlg.comboBox.currentText() in k]
data.sort()
data2.sort()
items = [
QStandardItem(field)
for field in row]
model.appendRow(items)
row=0
data=['a1','a2','a3']
data2=[['b1','c1','d1'],['b2','c2','d2'],['b3','c3','d3']]
if self.dlg.comboBox.currentText() == 'toutes les catégories':
# print(str(data2[0]))
# del data2[0]
# print(str(data2[0]))
nb_row = len(data2)
nb_col = len(data2[0])
print(data2[row][2])
self.dlg.tableWidget.setRowCount(nb_row)
self.dlg.tableWidget.setColumnCount(nb_col)
for row in range(nb_row):
for col in range(nb_col):
item = QTableWidgetItem(str(data2[row][col]))
# Access the value from the 6th column for the current row (style here)
value_from_2nd_column = str(data2[row][2])
# Set tooltip for each row
tooltip = f"Nom du flux: {value_from_2nd_column}"
item.setToolTip(tooltip)
# Check if the current column is the "Résumé des métadonnées" column
if col == 7:
# Set icon for the "Résumé des métadonnées" column
icon_path = self.plugin_path + '/info_metadata.png' # Replace 'path_to_your_icon.png' with the actual path to your icon
icon = QIcon(icon_path)
item.setIcon(icon)
# Store the URL in the item's data for later retrieval
url_from_6th_column = str(data2[row][7]) # Assuming the URL is in the next column
item.setData(Qt.UserRole, url_from_6th_column)'''
if dbtype == sigdb:
if self.dlg.comboBox.currentText() == 'toutes les catégories':
custom_list=schemaname_list
elif self.dlg.comboBox.currentText() == 'travaux':
custom_list="""(SELECT schemaname,tablename from pg_catalog.pg_tables
where schemaname like '"""+ str(self.dlg.comboBox.currentText()) +"""%' order by schemaname,tablename) UNION (SELECT schemaname,matviewname AS tablename FROM pg_catalog.pg_matviews where schemaname like '"""+ str(self.dlg.comboBox.currentText()) +"""%' order by schemaname,tablename) order by schemaname,tablename;"""
else:
custom_list="""(SELECT schemaname,tablename from pg_catalog.pg_tables
where schemaname like '\_"""+ str(self.dlg.comboBox.currentText()) +"""%' order by schemaname,tablename) UNION (SELECT schemaname,matviewname AS tablename FROM pg_catalog.pg_matviews where schemaname like '\_"""+ str(self.dlg.comboBox.currentText()) +"""%' order by schemaname,tablename) order by schemaname,tablename;"""
else:
if self.dlg.comboBox.currentText() == 'toutes les catégories':
custom_list=schemaname_list_ref
else:
custom_list="""SELECT schemaname,tablename from pg_catalog.pg_tables
where schemaname like '"""+ str(self.dlg.comboBox.currentText()) +"""' order by schemaname,tablename;"""
cur.execute(custom_list)
list_schema = cur.fetchall()
self.dlg.tableWidget.setRowCount(len(list_schema))
self.dlg.tableWidget.setColumnCount(3)
i=0
for value in list_schema:
if dbtype == sigdb:
type_val = str(value[0])[1:3]
schema_name=str(value[0])[4:]
table_name=str(value[1])
else:
type_val = ''
schema_name=str(value[0])
table_name=str(value[1])
if type_val == 'fo':
type_val=str(value[0])[1:5]
schema_name=str(value[0])[6:]
table_name=str(value[1])
elif type_val == 'ra':
type_val='travaux'
schema_name=str(value[0])
table_name=str(value[1])
elif type_val != '00' and type_val != '01' and type_val != '07' and type_val != '26' and type_val != '42' and type_val != '69' and type_val != 'ra':
type_val='agregation'
schema_name=str(value[0])
table_name=str(value[1])
item = QTableWidgetItem(type_val)
self.dlg.tableWidget.setItem(i,0,item)
item = QTableWidgetItem(schema_name)
self.dlg.tableWidget.setItem(i,1,item)
item = QTableWidgetItem(table_name)
self.dlg.tableWidget.setItem(i,2,item)
i=i+1
self.dlg.tableWidget.setColumnWidth(0, 20)
self.dlg.tableWidget.setColumnWidth(1, 300)
self.dlg.tableWidget.setColumnWidth(2, 300)
self.dlg.tableWidget.setHorizontalHeaderLabels(["Code","Schema","Table"])
'''
else:
nb_row = len(data)
nb_col = len(data[0])
self.dlg.tableWidget.setRowCount(nb_row)
self.dlg.tableWidget.setColumnCount(nb_col)
for row in range(nb_row):
for col in range(nb_col):
item = QTableWidgetItem(str(data[row][col]))
# Access the value from the 6th column for the current row (style here)
value_from_2nd_column = str(data[row][1])
# Set tooltip for each row
tooltip = f"Nom du flux: {value_from_2nd_column}"
item.setToolTip(tooltip)
# Check if the current column is the "Résumé des métadonnées" column
if col == 7:
# Set icon for the "Résumé des métadonnées" column
icon_path = self.plugin_path + '/metadata.png' # Replace 'path_to_your_icon.png' with the actual path to your icon
icon = QIcon(icon_path)
item.setIcon(icon)
# Store the URL in the item's data for later retrieval
url_from_6th_column = str(data2[row][7]) # Assuming the URL is in the next column
item.setData(Qt.UserRole, url_from_6th_column)
self.dlg.tableWidget.setItem(row, col, item)
self.dlg.tableWidget.setHorizontalHeaderLabels(["Service", "Catégorie", "Flux", "Nom technique", "Url d'accès", "Source", "Style", "Infos"])
self.dlg.tableWidget.setColumnWidth(0, 76)
self.dlg.tableWidget.setColumnWidth(1, 0)
self.dlg.tableWidget.setColumnWidth(2, 610)
self.dlg.tableWidget.setColumnWidth(3, 0)
self.dlg.tableWidget.setColumnWidth(4, 0)
self.dlg.tableWidget.setColumnWidth(5, 88)
self.dlg.tableWidget.setColumnWidth(6, 0)
self.dlg.tableWidget.setColumnWidth(7, 30)
self.dlg.tableWidget.selectRow(0)
'''
def selection_flux(self):
selected_row = 0
selected_items = self.dlg.tableWidget.selectedItems()
# Assuming you want to compare items in the first column for uniqueness
new_item_text = selected_items[2].text()
if not self.item_already_exists(new_item_text):
self.dlg.tableWidget_2.insertRow(selected_row)
for column in range(self.dlg.tableWidget.columnCount()):
cloned_item = selected_items[column].clone()
self.dlg.tableWidget_2.setHorizontalHeaderLabels(["Code","Schema", "Table"])
self.dlg.tableWidget_2.setColumnCount(3)
self.dlg.tableWidget_2.setItem(selected_row, column, cloned_item)
self.dlg.tableWidget_2.setColumnWidth(0, 50)
self.dlg.tableWidget_2.setColumnWidth(1, 300)
self.dlg.tableWidget_2.setColumnWidth(2, 300)
def item_already_exists(self, new_item_text):
# Assuming you want to compare items in the first column for uniqueness
existing_items = self.dlg.tableWidget_2.findItems(new_item_text, QtCore.Qt.MatchExactly)
# Check if there are any existing items with the same text in the first column
return len(existing_items) > 0
def limite_flux(self):
if self.dlg.tableWidget_2.rowCount() > 3:
self.QMBquestion = QMessageBox.question(iface.mainWindow(), u"Attention !",
"Le nombre de flux à charger en une seule fois est limité à 3 pour des questions de performances. Souhaitez vous tout de même charger les " + str(
self.dlg.tableWidget_2.rowCount()) + " flux sélectionnés ? (risque de plantage de QGIS)",
QMessageBox.Yes | QMessageBox.No)
if self.QMBquestion == QMessageBox.Yes:
self.chargement_flux()
if self.QMBquestion == QMessageBox.No:
print("Annulation du chargement des couches")
if self.dlg.tableWidget_2.rowCount() <= 3:
self.chargement_flux()
def chargement_flux(self):
managerAU = QgsApplication.authManager()
k = managerAU.availableAuthMethodConfigs().keys()
def REQUEST(type):
switcher = {
'WFS': "GetFeature",
'WMS': "GetMap",
'WMS+Vecteur': "GetMap",
'WMS+Raster': "GetMap",
'WMTS': "GetMap"
}
return switcher.get(type, "nothing")
def displayOnWindows(type, uri, name):
'''
if type == 'WFS':
vlayer = QgsVectorLayer(uri, name, "WFS")
# vlayer.setScaleBasedVisibility(True)
QgsProject.instance().addMapLayer(vlayer)
layers = QgsProject.instance().mapLayers() # dictionary
# rowCount() This property holds the number of rows in the table
for row in range(self.dlg.tableWidget_2.rowCount()):
# item(row, 0) Returns the item for the given row and column if one has been set; otherwise returns nullptr.
_item = self.dlg.tableWidget_2.item(row, 2).text()
_legend = self.dlg.tableWidget_2.item(row, 6).text()
# print(_item)
# print(_legend)
for layer in layers.values():
if layer.name() == _item:
if len(_legend) > 1:
styles_url = 'https://raw.githubusercontent.com/CEN-Nouvelle-Aquitaine/fluxcen/main/styles_couches/' + _legend + '.qml'
fp = urllib.request.urlopen(styles_url)
mybytes = fp.read()
document = QDomDocument()
document.setContent(mybytes)
res = layer.importNamedStyle(document)
layer.triggerRepaint()
else:
print("Pas de style à charger pour cette couche")
elif type == 'WMS' or type == 'WMS Raster' or type == 'WMS Vecteur' or type == 'WMTS':
rlayer = QgsRasterLayer(uri, name, "WMS")
QgsProject.instance().addMapLayer(rlayer)
else:
print("Unknown datatype !")
'''
p = []
for row in range(0, self.dlg.tableWidget_2.rowCount()):
## supression de la partie de l'url après le point d'interrogation
if dbtype == sigdb:
code = self.dlg.tableWidget_2.item(row,0).text()
schema = '_'+code+'_'+self.dlg.tableWidget_2.item(row,1).text()
if code == 'travaux' or code == 'agregation':
schema = self.dlg.tableWidget_2.item(row,1).text()
table = self.dlg.tableWidget_2.item(row,2).text()#.split("?", 1)[0]
if dbtype == refdb:
# code = self.dlg.tableWidget_2.item(row,0).text()
schema = self.dlg.tableWidget_2.item(row,1).text()
table = self.dlg.tableWidget_2.item(row,2).text()#.split("?", 1)[0]
uri = QgsDataSourceUri()
uri.setConnection(host ,port ,dbtype ,user ,mdp)
# nom du schéma à remplacer: "hydrographie" à supprimer et mettre "couches_collaboratives" lorsqu'on aura regroupé les couches à modifier dans un même schéma
uri.setDataSource(schema, table, "geom")
uri.setKeyColumn('gid')
# Chargement de la couche PostGIS
geom_type ='SELECT right(st_geometrytype(geom),-3) as a FROM '+schema+'.'+table+' GROUP BY a'
cur.execute(geom_type)
list_typegeom = cur.fetchall()
print(len(list_typegeom))
if len(list_typegeom) > 1:
for typegeom in list_typegeom:
if typegeom[0] == 'MultiPolygon':
uri.setWkbType(QgsWkbTypes.MultiPolygon)
elif typegeom[0] == 'MultiLineString':
uri.setWkbType(QgsWkbTypes.MultiLineString)
elif typegeom[0] == 'Point':
uri.setWkbType(QgsWkbTypes.Point)
if typegeom[0] == 'Polygon':
uri.setWkbType(QgsWkbTypes.Polygon)
elif typegeom[0] == 'LineString':
uri.setWkbType(QgsWkbTypes.LineString)
elif typegeom[0] == 'MultiPoint':
uri.setWkbType(QgsWkbTypes.MultiPoint)
if (typegeom[0] != None and typegeom[0] != 'Polygon'):
uri.setSrid('2154')
layer = QgsVectorLayer(uri.uri(), table, "postgres")
# Ajout de la couche au canevas QGIS
QgsProject.instance().addMapLayer(layer)
else:
layer = QgsVectorLayer(uri.uri(), table, "postgres")
# Ajout de la couche au canevas QGIS
QgsProject.instance().addMapLayer(layer)
'''
try:
service = re.search('SERVICE=(.+?)&VERSION', self.dlg.tableWidget_2.item(row,4).text()).group(1)
except:
service = '1.0.0'
try:
version = re.search('VERSION=(.+?)&REQUEST', self.dlg.tableWidget_2.item(row,4).text()).group(1)
except:
version = '1.0.0'
if self.dlg.tableWidget_2.item(row,0).text() == 'WMS' or self.dlg.tableWidget_2.item(row,0).text() == 'WMS Vecteur' or self.dlg.tableWidget_2.item(row,0).text() == 'WMS Raster':
a = Flux(
self.dlg.tableWidget_2.item(row,0).text(),
self.dlg.tableWidget_2.item(row,1).text(),
self.dlg.tableWidget_2.item(row,2).text(),
self.dlg.tableWidget_2.item(row,3).text(),
"url="+url,
{
'service': self.dlg.tableWidget_2.item(row,0).text(),
'version': version,
'crs': "EPSG:2154",
'format' : "image/png",
'layers': self.dlg.tableWidget_2.item(row,3).text()+"&styles"
}
)
p.append(a)
uri = p[row].url + '&' + urllib.parse.unquote(urllib.parse.urlencode(p[row].parameters))
# print(uri)
if not QgsProject.instance().mapLayersByName(p[row].nom_commercial):
displayOnWindows(p[row].type, uri, p[row].nom_commercial)
else:
print("Couche "+p[row].nom_commercial+" déjà chargée")
elif self.dlg.tableWidget_2.item(row,0).text() == 'WFS':
a = Flux(
self.dlg.tableWidget_2.item(row, 0).text(),
self.dlg.tableWidget_2.item(row, 1).text(),
self.dlg.tableWidget_2.item(row, 2).text(),
self.dlg.tableWidget_2.item(row, 3).text(),
url,
{
'VERSION': version,
'TYPENAME': self.dlg.tableWidget_2.item(row, 3).text(),
'request': "GetFeature",
}
)
p.append(a)
uri = p[row].url + '?' + urllib.parse.unquote(urllib.parse.urlencode(p[row].parameters))
try:
response = requests.get(uri)
if response.status_code == 401:
print("Statut de réponse: 401")
if len(list(k)) == 0:
QMessageBox.question(iface.mainWindow(), u"Attention", "Veuillez ajouter une entrée de configuration d'authentification dans QGIS pour accéder aux flux CEN-NA sécurisés par un mot de passe (Flux 'FoncierCEN')", QMessageBox.Ok)
else:
# Add 'authcfg' to the parameters dictionary
p[row].parameters['authcfg'] = list(k)[0]
# Update the URI with the modified parameters
uri = p[row].url + '?' + urllib.parse.unquote(urllib.parse.urlencode(p[row].parameters))
# Make the request again with the updated URI
response = requests.get(uri)
elif response.status_code == 200:
print("Statut de réponse: 200.")
else:
print(f"Statut de réponse: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"problème de requete: {e}")
if not QgsProject.instance().mapLayersByName(p[row].nom_commercial):
displayOnWindows(p[row].type, uri, p[row].nom_commercial)
else:
print("Couche "+p[row].nom_commercial+" déjà chargée")
elif self.dlg.tableWidget_2.item(row, 0).text() == 'PostGIS':
# Connexion à la base de données PostGIS
uri = QgsDataSourceUri()
uri.setConnection("sandbox.cen-nouvelle-aquitaine.dev", "5432", "piezo", "", "")
# nom du schéma à remplacer: "hydrographie" à supprimer et mettre "couches_collaboratives" lorsqu'on aura regroupé les couches à modifier dans un même schéma
uri.setDataSource("collaboratif", self.dlg.tableWidget_2.item(row, 3).text(), "geom")
# Chargement de la couche PostGIS
layer = QgsVectorLayer(uri.uri(), self.dlg.tableWidget_2.item(row, 2).text(), "postgres")
# Ajout de la couche au canevas QGIS
QgsProject.instance().addMapLayer(layer)
else:
print("Les flux WMTS et autres ne sont pas encore gérés par le plugin")
'''
def combobox_custom(self):
if dbtype == sigdb:
self.dlg.comboBox.clear()
self.dlg.comboBox.addItem("toutes les catégories")
self.dlg.comboBox.addItem('00')
self.dlg.comboBox.addItem('01')
self.dlg.comboBox.addItem('07')
self.dlg.comboBox.addItem('26')
self.dlg.comboBox.addItem('42')
self.dlg.comboBox.addItem('69')
self.dlg.comboBox.addItem('agregation')
self.dlg.comboBox.addItem('travaux')
self.dlg.comboBox.addItem('form')
if dbtype == refdb:
custom_list=schemaname_distinct
cur.execute(custom_list)
list_schema = cur.fetchall()
self.dlg.comboBox.clear()
self.dlg.comboBox.addItem("toutes les catégories")
for baxval in list_schema:
self.dlg.comboBox.addItem(baxval[0])
def filtre_dynamique(self, filter_text):
for i in range(self.dlg.tableWidget.rowCount()):
for j in range(self.dlg.tableWidget.columnCount()):
item = self.dlg.tableWidget.item(i, j)
match = filter_text.lower() not in item.text().lower()
self.dlg.tableWidget.setRowHidden(i, match)
if not match:
break
def popup(self):
self.dialog = Popup() # +++ - self
self.dialog.text_edit.show()
# from owslib.wfs import WebFeatureService
# import csv
# wfs = WebFeatureService(url='https://opendata.cen-nouvelle-aquitaine.org/geoserver/agriculture/wfs')
# agriculture = list(wfs.contents)
# with open('C:/Users/Romain/Desktop/test.csv', "a+", encoding="ISO-8859-1", newline='') as f:
# writer = csv.writer(f)
# for row in agriculture:
# writer.writerow(row.split())
#
# from owslib.wms import WebMapService
# wms = WebMapService('https://opendata.cen-nouvelle-aquitaine.org/geoserver/fond_carto/wms')
# fonds_carto = list(wms.contents)
# with open('C:/Users/Romain/Desktop/test.csv', "a+", encoding="ISO-8859-1", newline='') as f:
# writer = csv.writer(f)
# for row in fonds_carto:
# writer.writerow(row.split())
#
# import csv
#
# fluxWMS = ['AGG_TMM', '16-014_Brandes_de_Soyaux_2020-05', '17IMERIS_Bois-Charles_Vallée-du-Larry_2022_01', '17IMERIS_Grand-Champ_2022-01', '19PTOR_MNS_filtre_futurs_travaux_2021-10_L93', '19PTOR_MNS_filtre_travaux_realises_2021-10_L93', '19PTOR_ortho_2021-10_L93', '23CELI_marais_du_chancelier_2022_03_24', '23CLAM_Rocher_de_Clamouzat_2020-11', '23DIAB_lande_du_pont_du_diable_nord_2021-10_L93', '23DIAB_lande_du_pont_du_diable_sud_2021-10_L93', '23LAND_RNN_etang_des_landes_2020-08_L93', '33_Lagune-108-2021-08', '79BLVI_Blanchère-de-Viennay_2021-10', '79VGAT_Vallée-du-Gâteau_Pressigny_2020-02', '79VGAT_Vallée-du-Gâteau_Pressigny_2021-10', '86-001_TMM_CA-CD_2020-07', '86-500_Clain-sud_Etang-du-Pin', '86_AT_Chalandray_2021-10', '87CREN_siege_saint_gence_2021-09', '87GRLA_grandes_landes_2021-09-24', '87SANA_sanadie_2021-09-24', 'a_16_030_Prairies_de_Vouharte_2019_09', 'a_17_474_Estauaire_de_la_Gironde_Les_Pr_s_de_la_Rouille_2019_08', 'a_17_474_Estauaire_de_la_Gironde_Moulin_Rompu_2019_08', 'a_17_474_Estuaire_de_la_Gironde_Zone_Humide_de_la_Motte_Ronde_2021_04', 'a_17_IMERIS_Carriere_du_Planton_2021_08_12', 'a_17_LGV_Ragouillis_2021_08_12', 'a_33_Lagune_058_2021_08', 'a_33_Lagune_070_2021_08', 'a_33_Lagune_094_2021_08', 'a_33_Lagune_162_2021_08', 'a_33_Lagune_165_2021_08', 'a_33_Lagunes_207_208_209_2021_08', 'a_79_001_Clussais_la_Pommeraie_2020_11', 'a_79_008_Landes_de_L_Hopiteau_2019_09', 'a_79_020_Bessines_1_avant_travaux_2019_10', 'a_79_020_Bessines_2_pendant_travaux_2019_11', 'a_79_020_Bessines_3_apres_travaux_2020_12', 'a_79_044_Carriere_des_Landes_2020_09', 'a_79_AT_Vernoux_en_Gatine_2020_09', 'a_79_Sources_de_la_Sevre_Niortaise_Pierre_levee_2020_09', 'a_86_001_TMM_AA_2020_06', 'a_86_001_TMM_AB_2020_06', 'a_86_001_TMM_AC_2020_06', 'a_86_001_TMM_AD_2020_06', 'a_86_001_TMM_AE_2020_06', 'a_86_001_TMM_AF_2020_06', 'a_86_001_TMM_AG_2020_07', 'a_86_001_TMM_BA_2020_06', 'a_86_001_TMM_BB_2020_06', 'a_86_001_TMM_BC_2020_06', 'a_86_001_TMM_BD_2020_06', 'a_86_001_TMM_BE_2020_07', 'a_86_001_TMM_BF_2021_06', 'a_86_001_TMM_CB_2020_07', 'a_86_001_TMM_CC_2020_07', 'a_86_001_TMM_CC_2021_06', 'a_86_001_TMM_CD_2021_06', 'a_86_001_TMM_CE_2020_07', 'a_86_001_TMM_CF_2020_09', 'a_86_001_TMM_DA_2020_07', 'a_86_001_TMM_DB_2020_09', 'a_86_001_TMM_DC_2021_06', 'a_86_001_TMM_EA_2020_06', 'a_86_001_TMM_EB_2020_06', 'a_86_001_TMM_EC_2020_06', 'a_86_001_TMM_FA_2020_06', 'a_86_001_TMM_FB_2020_07', 'a_86_001_TMM_FC_2020_07', 'a_86_001_TMM_FC_2021_06', 'a_86_001_TMM_HA_2020_09', 'a_86_001_TMM_IA_2020_06', 'a_86_001_TMM_IB_2020_06', 'a_86_001_TMM_IC_2020_06', 'a_86_001_TMM_JA_2020_07', 'a_86_001_TMM_JB_2020_07', 'a_86_001_TMM_JC_2020_07', 'a_86_001_TMM_JE_2020_07', 'a_86_001_TMM_KA_2020_07', 'a_86_001_TMM_KB_2020_07', 'a_86_003_Falunieres_de_Moulin_Pochas_2019_09', 'a_86_006_Landes_et_pelouses_de_Lussac_Sillars_2019_08', 'a_86_011_Landes_de_Sainte_Marie_2019_09', 'a_86_025_Marais_des_Ragouillis_2020_11', 'a_86_025_Marais_des_Ragouillis_2021_02', 'a_86_026_Etangs_Baro_2019_09', 'a_86_029_Vallee_de_la_Longere_2019_09', 'a_86_037_Tourbiere_des_Regeasses_2021_06', 'a_86_038_Vallees_de_la_Vienne_et_du_Clain_Persac_2019_09', 'a_86_038_Vallees_de_la_Vienne_et_du_Clain_Persac_2020_12', 'a_86_052_Fontaine_le_Comte_nord_2020_11', 'a_86_052_Fontaine_le_Comte_sud_2020_11', 'a_86_054_Vallee_de_la_Vonne_2020_11', 'a_86_058_Carriere_de_Puy_Herve_2021_02_09', 'a_86_058_Carriere_de_Puy_Herve_2021_02_25', 'a_86_060_Bocage_de_la_Geoffronniere_2020_11', 'a_86_Le_Cormier_2021_05']
#
# with open('C:/Users/Romain/Desktop/test.csv', "a+", encoding="ISO-8859-1", newline='') as f:
# writer = csv.writer(f)
# for row in fluxWMS:
# writer.writerow(row.split())
#### Récupération des métadonnées des couches quand disponibles:
# from owslib.wms import WebMapService
# wms = WebMapService('http://geoservices.brgm.fr/geologie?service=WMS+Raster', version='1.1.1')
# print(list(wms.contents))
#
# print(wms['IDPR'].abstract)
+44
View File
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
FluxCENDialog
A QGIS plugin
Flux IGN etc etc
Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
-------------------
begin : 2022-04-04
git sha : $Format:%H$
copyright : (C) 2022 by Romain Montillet
email : r.montillet@cen-na.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. *
* *
***************************************************************************/
"""
import os
from qgis.PyQt import uic
from qgis.PyQt import QtWidgets
# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'FluxCEN_dialog_base.ui'))
class FluxCENDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(FluxCENDialog, self).__init__(parent)
# Set up the user interface from Designer through FORM_CLASS.
# After self.setupUi() you can access any designer object by doing
# self.<objectname>, 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)
+247
View File
@@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'FluxCEN_dialog_base.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'FluxCEN_dialog_base.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
import resources
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setEnabled(True)
Dialog.resize(910, 800)
Dialog.setMinimumSize(QtCore.QSize(910, 800))
Dialog.setMaximumSize(QtCore.QSize(910, 800))
self.comboBox = QtWidgets.QComboBox(Dialog)
self.comboBox.setGeometry(QtCore.QRect(260, 130, 171, 22))
self.comboBox.setEditable(False)
self.comboBox.setCurrentText("")
self.comboBox.setObjectName("comboBox")
self.comboBox_2 = QtWidgets.QComboBox(Dialog)
self.comboBox_2.setGeometry(QtCore.QRect(370, 80, 171, 22))
self.comboBox_2.setEditable(False)
self.comboBox_2.setCurrentText("")
self.comboBox_2.setObjectName("comboBox_2")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(50, 20, 271, 91))
self.label_3.setText("")
self.label_3.setPixmap(QtGui.QPixmap(":/plugins/CenRa_FLUX/logo.png"))
self.label_3.setScaledContents(True)
self.label_3.setObjectName("label_3")
self.pushButton_2 = QtWidgets.QPushButton(Dialog)
self.pushButton_2.setGeometry(QtCore.QRect(370, 750, 171, 23))
self.pushButton_2.setObjectName("pushButton_2")
self.tableWidget = QtWidgets.QTableWidget(Dialog)
self.tableWidget.setEnabled(True)
self.tableWidget.setGeometry(QtCore.QRect(30, 170, 850, 281))
self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.tableWidget_2 = QtWidgets.QTableWidget(Dialog)
self.tableWidget_2.setGeometry(QtCore.QRect(30, 550, 850, 181))
self.tableWidget_2.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.tableWidget_2.setObjectName("tableWidget_2")
self.tableWidget_2.setColumnCount(0)
self.tableWidget_2.setRowCount(0)
self.commandLinkButton = QtWidgets.QCommandLinkButton(Dialog)
self.commandLinkButton.setGeometry(QtCore.QRect(400, 470, 61, 61))
self.commandLinkButton.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/plugins/CenRa_FLUX/arrow-bottom.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.commandLinkButton.setIcon(icon)
self.commandLinkButton.setIconSize(QtCore.QSize(50, 40))
self.commandLinkButton.setObjectName("commandLinkButton")
self.commandLinkButton_2 = QtWidgets.QCommandLinkButton(Dialog)
self.commandLinkButton_2.setGeometry(QtCore.QRect(460, 470, 61, 61))
self.commandLinkButton_2.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/plugins/CenRa_FLUX/arrow-up.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.commandLinkButton_2.setIcon(icon1)
self.commandLinkButton_2.setIconSize(QtCore.QSize(50, 40))
self.commandLinkButton_2.setObjectName("commandLinkButton_2")
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setEnabled(True)
self.lineEdit.setGeometry(QtCore.QRect(480, 130, 171, 21))
self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
self.lineEdit.setReadOnly(False)
self.lineEdit.setClearButtonEnabled(True)
self.lineEdit.setObjectName("lineEdit")
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(40, 150, 161, 16))
font = QtGui.QFont()
font.setFamily("Calibri")
font.setPointSize(10)
font.setItalic(False)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setGeometry(QtCore.QRect(30, 530, 171, 16))
font = QtGui.QFont()
font.setFamily("Calibri")
font.setPointSize(10)
font.setItalic(False)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "SIG CEN-RA"))
self.pushButton_2.setText(_translate("Dialog", "Charger les couches"))
self.tableWidget.setSortingEnabled(True)
self.lineEdit.setText(_translate("Dialog", "Recherche par mots-clés"))
self.label.setText(_translate("Dialog", "Liste des flux disponibles :"))
self.label_2.setText(_translate("Dialog", "Flux sélectionné(s) à charger :"))
'''
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setEnabled(True)
Dialog.resize(910, 800)
Dialog.setMinimumSize(QtCore.QSize(910, 800))
Dialog.setMaximumSize(QtCore.QSize(910, 800))
self.comboBox = QtWidgets.QComboBox(Dialog)
self.comboBox.setGeometry(QtCore.QRect(260, 130, 171, 22))
self.comboBox.setEditable(False)
self.comboBox.setCurrentText("")
self.comboBox.setObjectName("comboBox")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(350, 20, 221, 71))
self.label_3.setText("")
self.label_3.setPixmap(QtGui.QPixmap(":/plugins/FluxCEN/logo.png"))
self.label_3.setScaledContents(True)
self.label_3.setObjectName("label_3")
self.pushButton_2 = QtWidgets.QPushButton(Dialog)
self.pushButton_2.setGeometry(QtCore.QRect(370, 750, 171, 23))
self.pushButton_2.setObjectName("pushButton_2")
self.tableWidget = QtWidgets.QTableWidget(Dialog)
self.tableWidget.setEnabled(True)
self.tableWidget.setGeometry(QtCore.QRect(30, 170, 850, 281))
self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.tableWidget_2 = QtWidgets.QTableWidget(Dialog)
self.tableWidget_2.setGeometry(QtCore.QRect(30, 550, 850, 181))
self.tableWidget_2.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.tableWidget_2.setObjectName("tableWidget_2")
self.tableWidget_2.setColumnCount(0)
self.tableWidget_2.setRowCount(0)
self.commandLinkButton = QtWidgets.QCommandLinkButton(Dialog)
self.commandLinkButton.setGeometry(QtCore.QRect(400, 470, 61, 61))
self.commandLinkButton.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/plugins/FluxCEN/arrow-bottom.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.commandLinkButton.setIcon(icon)
self.commandLinkButton.setIconSize(QtCore.QSize(50, 40))
self.commandLinkButton.setObjectName("commandLinkButton")
self.commandLinkButton_2 = QtWidgets.QCommandLinkButton(Dialog)
self.commandLinkButton_2.setGeometry(QtCore.QRect(460, 470, 61, 61))
self.commandLinkButton_2.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/plugins/FluxCEN/arrow-up.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.commandLinkButton_2.setIcon(icon1)
self.commandLinkButton_2.setIconSize(QtCore.QSize(50, 40))
self.commandLinkButton_2.setObjectName("commandLinkButton_2")
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setEnabled(True)
self.lineEdit.setGeometry(QtCore.QRect(480, 130, 171, 21))
self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
self.lineEdit.setReadOnly(False)
self.lineEdit.setClearButtonEnabled(True)
self.lineEdit.setObjectName("lineEdit")
self.commandLinkButton_3 = QtWidgets.QCommandLinkButton(Dialog)
self.commandLinkButton_3.setGeometry(QtCore.QRect(690, 20, 201, 41))
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(9)
self.commandLinkButton_3.setFont(font)
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/plugins/FluxCEN/globe.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.commandLinkButton_3.setIcon(icon2)
self.commandLinkButton_3.setIconSize(QtCore.QSize(20, 20))
self.commandLinkButton_3.setObjectName("commandLinkButton_3")
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(40, 150, 161, 16))
font = QtGui.QFont()
font.setFamily("Calibri")
font.setPointSize(10)
font.setItalic(False)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setGeometry(QtCore.QRect(30, 530, 171, 16))
font = QtGui.QFont()
font.setFamily("Calibri")
font.setPointSize(10)
font.setItalic(False)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.commandLinkButton_4 = QtWidgets.QCommandLinkButton(Dialog)
self.commandLinkButton_4.setGeometry(QtCore.QRect(690, 60, 201, 41))
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(9)
self.commandLinkButton_4.setFont(font)
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(":/plugins/FluxCEN/orthos.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.commandLinkButton_4.setIcon(icon3)
self.commandLinkButton_4.setIconSize(QtCore.QSize(20, 20))
self.commandLinkButton_4.setObjectName("commandLinkButton_4")
self.commandLinkButton_5 = QtWidgets.QCommandLinkButton(Dialog)
self.commandLinkButton_5.setGeometry(QtCore.QRect(860, 750, 41, 41))
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(9)
self.commandLinkButton_5.setFont(font)
self.commandLinkButton_5.setText("")
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/plugins/FluxCEN/info.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.commandLinkButton_5.setIcon(icon4)
self.commandLinkButton_5.setIconSize(QtCore.QSize(25, 25))
self.commandLinkButton_5.setObjectName("commandLinkButton_5")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "FluxCEN"))
self.pushButton_2.setText(_translate("Dialog", "Charger les couches"))
self.tableWidget.setSortingEnabled(True)
self.lineEdit.setText(_translate("Dialog", "Recherche par mots-clés"))
self.commandLinkButton_3.setText(_translate("Dialog", " Ajouter fond de carte OSM"))
self.label.setText(_translate("Dialog", "Liste des flux disponibles :"))
self.label_2.setText(_translate("Dialog", "Flux sélectionné(s) à charger :"))
self.commandLinkButton_4.setText(_translate("Dialog", "Ajouter Ortho (Google sat\')"))
'''
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
+242
View File
@@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<resources>
</resources>
<widget class="QDialog" name="Dialog">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>910</width>
<height>800</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>910</width>
<height>800</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>910</width>
<height>800</height>
</size>
</property>
<property name="windowTitle">
<string>SIG CEN-RA</string>
</property>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>260</x>
<y>130</y>
<width>171</width>
<height>22</height>
</rect>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="currentText">
<string notr="true"/>
</property>
</widget>
<widget class="QComboBox" name="comboBox_2">
<property name="geometry">
<rect>
<x>370</x>
<y>80</y>
<width>171</width>
<height>22</height>
</rect>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="currentText">
<string notr="true"/>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>350</x>
<y>20</y>
<width>221</width>
<height>71</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="resources.qrc">:/plugins/CenRa_FLUX/logo.jpg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>370</x>
<y>750</y>
<width>171</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Charger les couches</string>
</property>
</widget>
<widget class="QTableWidget" name="tableWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>170</y>
<width>850</width>
<height>281</height>
</rect>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
<widget class="QTableWidget" name="tableWidget_2">
<property name="geometry">
<rect>
<x>30</x>
<y>550</y>
<width>850</width>
<height>181</height>
</rect>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
</widget>
<widget class="QCommandLinkButton" name="commandLinkButton">
<property name="geometry">
<rect>
<x>400</x>
<y>470</y>
<width>61</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/plugins/CenRa_FLUX/arrow-bottom.png</normaloff>:/plugins/CenRa_FLUX/arrow-bottom.png</iconset>
</property>
<property name="iconSize">
<size>
<width>50</width>
<height>40</height>
</size>
</property>
</widget>
<widget class="QCommandLinkButton" name="commandLinkButton_2">
<property name="geometry">
<rect>
<x>460</x>
<y>470</y>
<width>61</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/plugins/CenRa_FLUX/arrow-up.png</normaloff>:/plugins/CenRa_FLUX/arrow-up.png</iconset>
</property>
<property name="iconSize">
<size>
<width>50</width>
<height>40</height>
</size>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>480</x>
<y>130</y>
<width>171</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Recherche par mots-clés</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>40</x>
<y>150</y>
<width>161</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>Calibri</family>
<pointsize>10</pointsize>
<italic>false</italic>
</font>
</property>
<property name="text">
<string>Liste des flux disponibles :</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>30</x>
<y>530</y>
<width>171</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>Calibri</family>
<pointsize>10</pointsize>
<italic>false</italic>
</font>
</property>
<property name="text">
<string>Flux sélectionné(s) à charger :</string>
</property>
</widget>
</widget>
<connections/>
</ui>
+60
View File
@@ -0,0 +1,60 @@
# <p align="center">FluxCEN</p>
<img align="left" src=https://raw.githubusercontent.com/CEN-Nouvelle-Aquitaine/fluxcen/main/icon.png width="220"/>
<br>
<br>
<br>
Le plugin QGIS FluxCEN permet d'accéder rapidement à un large éventail de flux WFS/WMS organisés par catégories et interrogeables sous forme de mots-clés.
<br>
<br>
Il évite ainsi d'avoir à gérer dans QGIS une multitude de connexions.
<br>
<br>
<br>
## 🧐 Features
- Sélection rapide des ressources par autocomplétion
- Regroupement des flux au sein de catégories
- Gestion des styles par défaut à l'ouverture dans QGIS pour les données WFS
- Centralisation et gestion des flux simplifiée dans un fichier .csv
- Code et ressources attachées gérées directement via le git
- Prise en charge des flux Geoserver et Mapserver
- Lien direct vers la fiche de métadonnées de la ressource
## Composition du fichier .csv
* service : type de service utilisé (WFS ou WMS)
* categorie : categorie de la couche pour affichage et recherche dans le plugin
* Nom_couche_plugin : nom de la couche qui s'affichera dans le plugin
* nom_technique : nom technique de la couche utilisé sur le serveur source (caché dans le plugin)
* url : URL du serveur pour accéder à la couche
* source : Source de la donnée
* style : nom du fichier de style pour affichage à l'ouverture dans QGIS
* metadonnees : URL d'accès à la fiche de métadonnées liée à la resource
Exemple pour accéder à la BD ORTHO® :
| service | categorie | Nom_couche_plugin | nom_technique | url | source | style |
| -------- | -------- | -------- | -------- | -------- |-------- | -------- |
| WMS Raster| Fonds cartos | BD ORTHO® | HR.ORTHOIMAGERY.ORTHOPHOTOS |https://wxs.ign.fr/ortho/geoportail/r/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities| IGN | |
## Style des couches
Le dossier *styles_couches* stocke les styles QGIS au format .qml afin d'appliquer par défaut ce style à l'ouverture de la couche dans QGIS. L'ajout d'un style dans ce dossier nécessite de reporter le nom du fichier .qml dans le champ "style" du csv.
## Accès aux données protégées
Si l'accès à la majorité des ressources reste public, certaines peuvent être protégées par un mot de passe (données métier confidentielles par exemple).
Cette authentification est gérée via le serveur cartographique qui génère les flux.
Pour y accéder, il faut créer en amont une authentification dans QGIS. L'ouverture des données protégées se fera alors à partir de la première authentification enregistrée dans QGIS (pas de gestion multi-authentification pour le moment)
## Interface du plugin:
<img align="center" src=https://raw.githubusercontent.com/CEN-Nouvelle-Aquitaine/fluxcen/main/fluxcen_interface.PNG width="600"/>
+36
View File
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
FluxCEN
A QGIS plugin
Flux IGN etc etc
Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
-------------------
begin : 2022-04-04
copyright : (C) 2022 by Romain Montillet
email : r.montillet@cen-na.org
git sha : $Format:%H$
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
This script initializes the plugin, making it known to QGIS.
"""
# noinspection PyPep8Naming
def classFactory(iface): # pylint: disable=invalid-name
"""Load FluxCEN class from file FluxCEN.
:param iface: A QGIS interface instance.
:type iface: QgsInterface
"""
#
from .FluxCEN import FluxCEN
return FluxCEN(iface)
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

+48
View File
@@ -0,0 +1,48 @@
# This file contains metadata for your plugin.
# This file should be included when you package your plugin.# Mandatory items:
[general]
name=CenRa_FLUX
qgisMinimumVersion=3.0
description=Permet d'ouvrire une table dans la base PostGis
version=1.14
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
#about=
# End of mandatory metadata
# Recommended items:
hasProcessingProvider=no
# Uncomment the following line and add your changelog:
# changelog= correctif de sécurité: envoi du certificat d'authentification seulement pour les couches fonciercen et drone / intégration des styles RPG geoportail / modification des noms de couches pour plus de clarté
# Tags are comma separated with spaces allowed
tags=cenra, postgis, database
repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
homepage=https://plateformesig.cenra-outils.org/
tracker=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
category=Plugins
icon=cenra.png
# experimental flag
experimental=False
changelog=<h1>CenRA_FLUX:</h1></br><p><h3>03/10/2024 - Version 1.14:</h3> - Remonte la fênetre dans la pille.</br></p><p><h3>13/09/2024 - Version 1.13:</h3>- MAJ sur le lien du changelog</br>- Bug-fix: Ouvre MultiPolygone et Polygon séparément.</p></br><p><h3>10/09/2024 - Version 1.11:</h3>- Ouverture de table contenant plusieurs géométries.</p></br><p><h3>26/08/2024 - Version 1.10:</h3>- Ajoute d'un changelog et vérification de mise à jour.</p>
# deprecated flag (applies to the whole plugin, not just a single version)
deprecated=False
# Since QGIS 3.8, a comma separated list of plugins to be installed
# (or upgraded) can be specified.
# Check the documentation for more information.
# plugin_dependencies=
# If the plugin can run on QGIS Server.
server=False
+111
View File
@@ -0,0 +1,111 @@
#!/usr/bin/env python
# coding=utf-8
"""This script uploads a plugin package to the plugin repository.
Authors: A. Pasotti, V. Picavet
git sha : $TemplateVCSFormat
"""
import sys
import getpass
import xmlrpc.client
from optparse import OptionParser
standard_library.install_aliases()
# Configuration
PROTOCOL = 'https'
SERVER = 'plugins.qgis.org'
PORT = '443'
ENDPOINT = '/plugins/RPC2/'
VERBOSE = False
def main(parameters, arguments):
"""Main entry point.
:param parameters: Command line parameters.
:param arguments: Command line arguments.
"""
address = "{protocol}://{username}:{password}@{server}:{port}{endpoint}".format(
protocol=PROTOCOL,
username=parameters.username,
password=parameters.password,
server=parameters.server,
port=parameters.port,
endpoint=ENDPOINT)
print("Connecting to: %s" % hide_password(address))
server = xmlrpc.client.ServerProxy(address, verbose=VERBOSE)
try:
with open(arguments[0], 'rb') as handle:
plugin_id, version_id = server.plugin.upload(
xmlrpc.client.Binary(handle.read()))
print("Plugin ID: %s" % plugin_id)
print("Version ID: %s" % version_id)
except xmlrpc.client.ProtocolError as err:
print("A protocol error occurred")
print("URL: %s" % hide_password(err.url, 0))
print("HTTP/HTTPS headers: %s" % err.headers)
print("Error code: %d" % err.errcode)
print("Error message: %s" % err.errmsg)
except xmlrpc.client.Fault as err:
print("A fault occurred")
print("Fault code: %d" % err.faultCode)
print("Fault string: %s" % err.faultString)
def hide_password(url, start=6):
"""Returns the http url with password part replaced with '*'.
:param url: URL to upload the plugin to.
:type url: str
:param start: Position of start of password.
:type start: int
"""
start_position = url.find(':', start) + 1
end_position = url.find('@')
return "%s%s%s" % (
url[:start_position],
'*' * (end_position - start_position),
url[end_position:])
if __name__ == "__main__":
parser = OptionParser(usage="%prog [options] plugin.zip")
parser.add_option(
"-w", "--password", dest="password",
help="Password for plugin site", metavar="******")
parser.add_option(
"-u", "--username", dest="username",
help="Username of plugin site", metavar="user")
parser.add_option(
"-p", "--port", dest="port",
help="Server port to connect to", metavar="80")
parser.add_option(
"-s", "--server", dest="server",
help="Specify server name", metavar="plugins.qgis.org")
options, args = parser.parse_args()
if len(args) != 1:
print("Please specify zip file.\n")
parser.print_help()
sys.exit(1)
if not options.server:
options.server = SERVER
if not options.port:
options.port = PORT
if not options.username:
# interactive mode
username = getpass.getuser()
print("Please enter user name [%s] :" % username, end=' ')
res = input()
if res != "":
options.username = res
else:
options.username = username
if not options.password:
# interactive mode
options.password = getpass.getpass()
main(options, args)
Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because it is too large Load Diff
+8
View File
@@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/plugins/CenRa_FLUX" >
<file>reficon.png</file>
<file>arrow-up.png</file>
<file>arrow-bottom.png</file>
<file>logo.png</file>
</qresource>
</RCC>
+21
View File
@@ -0,0 +1,21 @@
from qgis.core import QgsApplication
def gitea():
file_url = QgsApplication.qgisSettingsDirPath()+'QGIS/QGIS3.ini'
recherche_1 = 'plugin_repositories\\github\\url=https://github.com/CEN-Rhone-Alpes/Plugin_QGIS/releases/latest/download/plugins.xml'
replace_1 = 'plugin_repositories\\gitea\\url=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
recherche_2 = 'github'
replace_2 = 'gitea'
# Read in the file
with open(file_url, 'r') as file:
filedata = file.read()
# Replace the target string
filedata = filedata.replace(recherche_1, replace_1)
filedata = filedata.replace(recherche_2, replace_2)
# Write the file out again
with open(file_url, 'w') as file:
file.write(filedata)
+185
View File
@@ -0,0 +1,185 @@
import sys
import socket
import os
IPAddr=socket.gethostbyname(socket.gethostname())
print(IPAddr)
if IPAddr[0:11] == "100.100.100": #4269
host = "100.100.100.11"
port = "5432"
dbname = "sig4269"
sigdb="sig4269"
refdb="ref_geo4269"
password = "McVities"
if IPAddr[0:9] == "192.168.0": #01
host = "192.168.0.201"
port = "5432"
dbname = "sig01"
sigdb="sig01"
refdb="ref_geo01"
password = "McVities"
if IPAddr[0:9] == "192.168.1": #0726
host = "192.168.1.201"
port = "5432"
dbname = "sig0726"
sigdb="sig0726"
refdb="ref_geo0726"
password = "McVities"
if sys.platform == 'linux':
os_user = os.environ['USER']
else:
os_user = os.environ['USERNAME']
if os_user == 'STAGE':
os_user='stage'
if os_user == 'Administrateur':
os_user = 'stage'
schemaname_distinct="""SELECT DISTINCT schemaname from pg_catalog.pg_tables
WHERE schemaname NOT LIKE '_archives' AND schemaname NOT LIKE 'topology' AND schemaname NOT LIKE 'information_schema' AND schemaname NOT LIKE 'pg_catalog' and schemaname NOT LIKE 'public' AND schemaname NOT LIKE '_trier'
order by schemaname;"""
schemaname_list_ref="""SELECT schemaname,tablename from pg_catalog.pg_tables
WHERE schemaname NOT LIKE '_archives' AND schemaname NOT LIKE 'topology' AND schemaname NOT LIKE 'information_schema' AND schemaname NOT LIKE 'pg_catalog' and schemaname NOT LIKE 'public' AND schemaname NOT LIKE '_trier'
order by schemaname,tablename;"""
schemaname_list="""(SELECT schemaname,tablename from pg_catalog.pg_tables
where schemaname like 'trav%' or schemaname like '\_ag%' or schemaname like '\_00%' or schemaname like '\_01%' or schemaname like '\_07%' or schemaname like '\_26%' or schemaname like '\_form%' or schemaname like '\_42%' or schemaname like '\_69%' order by schemaname,tablename)
UNION
(SELECT schemaname,matviewname AS tablename FROM pg_catalog.pg_matviews order by schemaname,tablename) order by schemaname,tablename;"""
geom = "geom"
champ_travaux_prevus_multipolygon="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, surface_m2 double precision, surface_ha double precision, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_travaux_prevus_multilinestring="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, longueur_m double precision, longueur_km double precision, date_creation date, date_maj date, geom geometry(MultiLineString,2154))"""
champ_travaux_prevus_point = """(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, x_wgs84 double precision, y_wgs84 double precision, date_creation date, date_maj date, geom geometry(Point,2154))"""
champ_viergePolygone = """(gid serial NOT NULL, commentaire text, surface_m2 double precision, surface_ha double precision, geom geometry(MultiPolygon,2154))"""
champ_viergeLigne = """(gid serial NOT NULL, commentaire text, longueur_m double precision, longueur_km double precision, geom geometry(MultiLineString,2154))"""
champ_viergePoint = """(gid serial NOT NULL, commentaire text, x_wgs84 double precision, y_wgs84 double precision, geom geometry(Point,2154))"""
champ_habitat = """(gid serial NOT NULL, cd_cb_01 text, lb_cb97_fr_01 text, occupation_01 integer, cd_cb_02 text, lb_cb97_fr_02 text, occupation_02 integer, cd_cb_03 text, lb_cb97_fr_03 text, occupation_03 integer, milieu_code text, milieu_libelle text, surface_m2 double precision, surface_ha double precision, commentaire text, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_contour="""(gid serial NOT NULL, date_creation date, date_maj date, utilisateur character varying, dept character(2), nom character varying, surface_m2 double precision, surface_ha double precision, type_site character varying, type_milieu character varying, date_premier_pg integer, date_debut_pg integer, date_fin_pg integer, referent character varying, gestion_deleguee character varying, terrain_militaire character(3), ens character(3), zh character(3), adapt_pmr character(3), inform character(3), guide character(3), ouverture_public character(3), obs character(3), anim character(3), n2000_anim character(3), contrat_n2000_conseil character(3), n2000_op character(3), contrat_n2000_benef character(3), contrat_agri character(3), bc_habitat integer, bc_amphibien integer, bc_coleoptere integer, bc_crustace integer, bc_mammifere integer, bc_chiroptere integer, bc_mollusque integer, bc_odonate integer, bc_oiseau integer, bc_orthoptere integer, bc_poisson integer, bc_reptile integer, bc_rhopalocere integer, bc_heterocere integer, bc_autre_invertebre integer, bc_flore integer, bc_bryophyte integer, bc_champignon integer, suiv_analyse_sol character(3), suiv_piezo character(3), suiv_climat character(3), suiv_topo character(3), suiv_habitat character(3), suiv_amphibien character(3), suiv_coleoptere character(3), suiv_crustace character(3), suiv_mammifere character(3), suiv_chiroptere character(3), suiv_mollusque character(3), suiv_odonate character(3), suiv_oiseau character(3), suiv_orthoptere character(3), suiv_poisson character(3), suiv_reptile character(3), suiv_rhopalocere character(3), suiv_heterocere character(3), suiv_autre_invertebre character(3), suiv_flore character(3), suiv_bryophyte character(3), suiv_champignon character(3), suiv_analyse_eau character(3), suiv_phenologie character(3), suiv_frequentation character(3), suiv_paysager character(3), suiv_autre character(3), commentaire text, geom geometry(MultiPolygon,2154))
"""
champ_vegethab_point = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(Point,2154)
)
"""
champ_vegethab_multilinestring = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiLineString,2154)
)
"""
champ_vegethab_multipolygon = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiPolygon,2154)
)
"""
+183
View File
@@ -0,0 +1,183 @@
"""Tools to work with resource files."""
import configparser
import shutil
import tempfile
import base64
import psycopg2
import psycopg2.extras
from os.path import abspath, join, pardir, dirname
from qgis.PyQt import uic
__copyright__ = "Copyright 2019, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
__revision__ = "$Format:%H$"
def plugin_path(*args):
"""Get the path to plugin root folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the plugin path.
:rtype: str
"""
path = dirname(dirname(__file__))
path = abspath(abspath(join(path, pardir)))
for item in args:
path = abspath(join(path, item))
return path
def plugin_name():
"""Return the plugin name according to metadata.txt.
:return: The plugin name.
:rtype: basestring
"""
metadata = metadata_config()
name = metadata["general"]["name"]
return name
def metadata_config() -> configparser:
"""Get the INI config parser for the metadata file.
:return: The config parser object.
:rtype: ConfigParser
"""
path = plugin_path("metadata.txt")
config = configparser.ConfigParser()
config.read(path, encoding='utf8')
return config
def plugin_test_data_path(*args, copy=False):
"""Get the path to the plugin test data path.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:param copy: If the file must be copied into a temporary directory first.
:type copy: bool
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "test", "data")))
for item in args:
path = abspath(join(path, item))
if copy:
temp = tempfile.mkdtemp()
shutil.copy(path, temp)
return join(temp, args[-1])
else:
return path
def resources_path(*args):
"""Get the path to our resources folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_Metabase\\tools")))
for item in args:
path = abspath(join(path, item))
return path
def load_ui(*args):
"""Get compile UI file.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Compiled UI file.
"""
ui_class, _ = uic.loadUiType(resources_path("ui", *args))
return ui_class
def login_base(take=None):
from .tools.PythonSQL import host,port,dbname,password,os_user
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()
if take:
return cur,con
else:
return cur
def send_issues(url,titre,body,labels):
import requests
import json
import os
import qgis
usr = os.environ['USERNAME']
token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
url=url+'?token='+token
headers = {'Authorization': 'token ' + token,'accept': 'application/json','Content-Type': 'application/json'}
payload = {'title': titre, 'body': body, 'labels': labels}
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
r = ''
if binar:
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r
def maj_verif(NAME):
import qgis
import urllib.request
iface = qgis.utils.iface
from qgis.core import Qgis
url = qgis.utils.pluginMetadata(NAME,'repository')
#URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/releases/plugins.xml'
# print(URL)
version = qgis.utils.pluginMetadata(NAME,'version')
len_version = len(version)
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
if binar:
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>',plugin_num)+9
version_plugin = version_web[valeur_version_web:valeur_version_web+len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
def devlog(NAME):
import qgis
devmaj = '<head><style>* {margin:0; padding:0; }</style></head>'
devmaj = devmaj+qgis.utils.pluginMetadata(NAME,'changelog')
return devmaj
+220
View File
@@ -0,0 +1,220 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
from qgis.core import QgsApplication
from qgis.PyQt.QtCore import QCoreApplication, Qt, QTranslator, QUrl
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtWidgets import QAction, QMessageBox
from qgis.utils import iface
import qgis
#include <QSettings>
'''
from pg_metadata.connection_manager import (
store_connections,
validate_connections_names,
)
from pg_metadata.locator import LocatorFilter
from pg_metadata.processing.provider import PgMetadataProvider
from pg_metadata.qgis_plugin_tools.tools.custom_logging import setup_logger
'''
import os
from .tools.resources import (
plugin_path,
resources_path,
maj_verif,
)
from .dock import CenRa_Metabase
from .editor import Metabase_Editor
from .about_form import MetabaseAboutDialog
#from CenRa_Metabase.issues import CenRa_Issues
from PyQt5.QtCore import *
class PgMetadata:
def __init__(self):
""" Constructor. """
self.dock = None
self.editor = None
# self.issues = None
self.provider = None
self.locator_filter = None
self.dock_action = None
self.help_action = None
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\')+1
global NAME
NAME = plugin_dir[end_find:]
maj_verif(NAME)
# Display About window on first use
version = qgis.utils.pluginMetadata('CenRa_METABASE','version')
s = QSettings()
versionUse = s.value("metadata/version", 1, type=str)
if str(versionUse) != str(version) :
s.setValue("metadata/version", str(version))
print(versionUse,version)
self.open_about_dialog()
# setup_logger('pg_metadata')
#locale, file_path = setup_translation(
# folder=plugin_path("i18n"), file_pattern="CenRa_Metabase_{}.qm")
#if file_path:
# self.translator = QTranslator()
# self.translator.load(file_path)
# noinspection PyCallByClass,PyArgumentList
# QCoreApplication.installTranslator(self.translator)
# noinspection PyPep8Naming
#def initProcessing(self):
#""" Add the QGIS Processing provider. """
#if not self.provider:
#self.provider = PgMetadataProvider()
#QgsApplication.processingRegistry().addProvider(self.provider)
# noinspection PyPep8Naming
def initGui(self):
""" Build the plugin GUI. """
#self.initProcessing()
#self.check_invalid_connection_names()
self.toolBar = iface.addToolBar("CenRa_Metabase")
self.toolBar.setObjectName("CenRa_Metabase")
icon = QIcon(resources_path('icons', 'icon.png'))
icon2 = QIcon(resources_path('icons', 'icon_2.png'))
# Open the online help
self.help_action = QAction(icon, 'CenRa_Metabase', iface.mainWindow())
iface.pluginHelpMenu().addAction(self.help_action)
self.help_action.triggered.connect(self.open_help)
if not self.editor:
self.editor = Metabase_Editor()
self.editor_action = QAction(icon2, 'CenRa_Metabase',None)
self.toolBar.addAction(self.editor_action)
self.editor_action.triggered.connect(self.open_editor)
if not self.dock:
self.dock = CenRa_Metabase()
iface.addDockWidget(Qt.RightDockWidgetArea, self.dock)
# Open/close the dock from plugin menu
self.dock_action = QAction(icon, 'CenRa_Metabase', iface.mainWindow())
iface.pluginMenu().addAction(self.dock_action)
self.dock_action.triggered.connect(self.open_dock)
# if not self.issues:
# self.issues = CenRa_Issues()
# self.issues_action = QAction(icon, 'CenRa_Metabase',None)
# self.toolBar.addAction(self.issues_action)
# self.issues_action.triggered.connect(self.open_issues)
'''
if not self.locator_filter:
self.locator_filter = LocatorFilter(iface)
iface.registerLocatorFilter(self.locator_filter)
@staticmethod
def check_invalid_connection_names():
""" Check for invalid connection names in the QgsSettings. """
valid, invalid = validate_connections_names()
n_invalid = len(invalid)
if n_invalid == 0:
return
invalid_text = ', '.join(invalid)
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setWindowTitle(tr('PgMetadata: Database connection(s) not available'))
msg.setText(tr(
f'{n_invalid} connection(s) listed in PgMetadata’s settings are invalid or '
f'no longer available: {invalid_text}'))
msg.setInformativeText(tr(
'Do you want to remove these connection(s) from the PgMetadata settings? '
'(You can also do this later with the “Set Connections” tool.)'))
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
clicked = msg.exec()
if clicked == QMessageBox.Yes:
iface.messageBar().pushSuccess('PgMetadata', tr(f'{n_invalid} invalid connection(s) removed.'))
store_connections(valid)
if clicked == QMessageBox.No:
iface.messageBar().pushInfo('PgMetadata', tr(f'Keeping {n_invalid} invalid connections.'))
'''
def open_about_dialog(self):
"""
About dialog
"""
dialog = MetabaseAboutDialog(iface)
dialog.exec_()
def open_help():
""" Open the online help. """
QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
def open_dock(self):
""" Open the dock. """
self.dock.show()
self.dock.raise_()
def open_editor(self):
self.editor.show()
self.editor.raise_()
# def open_issues(self):
# self.issues.show()
# self.issues.raise_()
def unload(self):
""" Unload the plugin. """
if self.editor:
iface.removePluginMenu('CenRa_Metabase',self.editor_action)
#self.editor.removeToolBarIcon(self.editor_action)
if self.dock:
iface.removeDockWidget(self.dock)
self.dock.deleteLater()
if self.provider:
QgsApplication.processingRegistry().removeProvider(self.provider)
del self.provider
if self.locator_filter:
iface.deregisterLocatorFilter(self.locator_filter)
del self.locator_filter
if self.dock_action:
iface.pluginMenu().removeAction(self.dock_action)
del self.dock_action
if self.help_action:
iface.pluginHelpMenu().removeAction(self.help_action)
del self.help_action
@staticmethod
def run_tests(pattern='test_*.py', package=None):
"""Run the test inside QGIS."""
try:
from pathlib import Path
from pg_metadata.qgis_plugin_tools.infrastructure.test_runner import (
test_package,
)
if package is None:
package = '{}.__init__'.format(Path(__file__).parent.name)
test_package(package, pattern)
except (AttributeError, ModuleNotFoundError):
message = 'Could not load tests. Are you using a production package?'
print(message) # NOQA
+1
View File
@@ -0,0 +1 @@
# CenRa_Metabase
+10
View File
@@ -0,0 +1,10 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
# noinspection PyPep8Naming
def classFactory(iface): # pylint: disable=invalid-name
_ = iface
from CenRa_METABASE.CenRa_Metabase import PgMetadata
return PgMetadata()
+488
View File
@@ -0,0 +1,488 @@
"""Dock file."""
__copyright__ = 'Copyright 2020, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'
import logging
import os
from collections import namedtuple
from enum import Enum
from functools import partial
from pathlib import Path
from xml.dom.minidom import parseString
from qgis.core import (
NULL,
QgsApplication,
QgsDataSourceUri,
QgsProject,
QgsProviderConnectionException,
QgsProviderRegistry,
QgsRasterLayer,
QgsSettings,
QgsVectorLayer,
)
from qgis.PyQt.QtCore import QLocale, QUrl
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtPrintSupport import QPrinter
from qgis.PyQt.QtWebKitWidgets import QWebPage
from qgis.PyQt.QtWidgets import (
QDialog,
QAction,
QDockWidget,
QFileDialog,
QInputDialog,
QMenu,
QToolButton,
)
from qgis.gui import *
from qgis.utils import iface
'''
from pg_metadata.connection_manager import (
check_pgmetadata_is_installed,
connections_list,
settings_connections_names,
)
'''
from .tools.resources import (
load_ui,
resources_path,
login_base,
)
DOCK_CLASS = load_ui('CenRa_Metabase_dockwidget_base.ui')
LOGGER = logging.getLogger('CenRa_Metabase')
class Format(namedtuple('Format', ['label', 'ext'])):
""" Format available for exporting metadata. """
pass
class OutputFormats(Format, Enum):
""" Output format for a metadata sheet. """
PDF = Format(label='PDF', ext='pdf')
HTML = Format(label='HTML', ext='html')
DCAT = Format(label='DCAT', ext='xml')
class CenRa_Metabase(QDockWidget, DOCK_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
self.current_datasource_uri = None
self.current_connection = None
self.viewer.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
self.viewer.page().linkClicked.connect(self.open_link)
# Help button
self.external_help.setText('')
self.external_help.setIcon(QIcon(QgsApplication.iconPath('mActionHelpContents.svg')))
self.external_help.clicked.connect(self.open_external_help)
# Flat table button
self.flatten_dataset_table.setText('')
#self.flatten_dataset_table.setToolTip(tr("Add the catalog table"))
self.flatten_dataset_table.setIcon(QgsApplication.getThemeIcon("/mActionAddHtml.svg"))
#self.flatten_dataset_table.clicked.connect(self.add_flatten_dataset_table)
# Settings menu
self.config.setAutoRaise(True)
#self.config.setToolTip(tr("Settings"))
self.config.setPopupMode(QToolButton.InstantPopup)
self.config.setIcon(QgsApplication.getThemeIcon("/mActionOptions.svg"))
self.auto_open_dock_action = QAction(
("Dommage, cette option n'existe pas encore."),
iface.mainWindow())
self.auto_open_dock_action.setCheckable(True)
self.auto_open_dock_action.setChecked(
self.settings.value("pgmetadata/auto_open_dock", True, type=bool)
)
self.auto_open_dock_action.triggered.connect(self.save_auto_open_dock)
menu = QMenu()
menu.addAction(self.auto_open_dock_action)
self.config.setMenu(menu)
# Setting PDF/HTML menu
self.save_button.setAutoRaise(True)
#self.save_button.setToolTip(tr("Save metadata"))
self.save_button.setPopupMode(QToolButton.InstantPopup)
self.save_button.setIcon(QIcon(QgsApplication.iconPath('mActionFileSave.svg')))
self.save_as_pdf = QAction(
('Enregistrer en PDF') + '…',
iface.mainWindow())
self.save_as_pdf.triggered.connect(partial(self.export_dock_content, OutputFormats.PDF))
self.save_as_html = QAction(
('Enregistrer en HTML') + '…',
iface.mainWindow())
self.save_as_html.triggered.connect(partial(self.export_dock_content, OutputFormats.HTML))
self.save_as_dcat = QAction(
('Enregistrer en DCAT') + '…',
iface.mainWindow())
self.save_as_dcat.triggered.connect(partial(self.export_dock_content, OutputFormats.DCAT))
self.menu_save = QMenu()
self.menu_save.addAction(self.save_as_pdf)
self.menu_save.addAction(self.save_as_html)
self.menu_save.addAction(self.save_as_dcat)
self.save_button.setMenu(self.menu_save)
self.save_button.setEnabled(False)
self.metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
# Display message in the dock
#if not settings_connections_names():
#self.default_html_content_not_installed()
#else:
self.default_html_content_not_pg_layer()
iface.layerTreeView().currentLayerChanged.connect(self.layer_changed)
if iface.activeLayer():
layer=iface.activeLayer()
iface.layerTreeView().setCurrentLayer(None)
iface.layerTreeView().setCurrentLayer(layer)
def export_dock_content(self, output_format: OutputFormats):
""" Export the current displayed metadata sheet to the given format. """
layer_name = iface.activeLayer().name()
file_path = os.path.join(
os.environ['USERPROFILE'],
'Desktop\\{name}.{ext}'.format(name=layer_name, ext=output_format.ext)
)
output_file = QFileDialog.getSaveFileName(
self,
("Enregistrer en {format}").format(format=output_format.label),
file_path,
"{label} (*.{ext})".format(
label=output_format.label,
ext=output_format.ext,
)
)
if output_file[0] == '':
return
self.settings.setValue("UI/lastFileNameWidgetDir", os.path.dirname(output_file[0]))
output_file_path = output_file[0]
parent_folder = str(Path(output_file_path).parent)
if output_format == OutputFormats.PDF:
printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setPageMargins(20, 20, 20, 20, QPrinter.Millimeter)
printer.setOutputFileName(output_file_path)
self.viewer.print(printer)
iface.messageBar().pushSuccess(
("Export PDF"),
(
"The metadata has been exported as PDF successfully in "
"<a href=\"{}\">{}</a>").format(parent_folder, output_file_path)
)
elif output_format in [OutputFormats.HTML,OutputFormats.DCAT]:
if output_format == OutputFormats.HTML:
data_str = self.viewer.page().currentFrame().toHtml()
else:
layer = iface.activeLayer()
uri = layer.dataProvider().uri()
dataall = self.sql_info(uri)
data = self.sql_to_xml(dataall)
with open(resources_path('xml', 'dcat.xml'), encoding='utf8') as xml_file:
xml_template = xml_file.read()
xml = parseString(xml_template.format(language=data[0][0], content=data[0][1]))
data_str = xml.toprettyxml()
with open(output_file[0], "w", encoding='utf8') as file_writer:
file_writer.write(data_str)
iface.messageBar().pushSuccess(
("Export") + ' ' + output_format.label,
(
"The metadata has been exported as {format} successfully in "
"<a href=\"{folder}\">{path}</a>").format(
format=output_format.label, folder=parent_folder, path=output_file_path)
)
def save_auto_open_dock(self):
""" Save settings about the dock. """
self.settings.setValue("pgmetadata/auto_open_dock", self.auto_open_dock_action.isChecked())
def sql_to_xml(self,dataall):
distribution=''
for y in dataall[1]:
distribution = distribution + (
'<dcat:distribution>'+
'<dcat:Distribution>'+
'<dct:title>{data}</dct:title>'.format(data=y[0])+
'<dcat:downloadURL>{data}</dcat:downloadURL>'.format(data=y[1])+
'<dcat:mediaType>{data}</dcat:mediaType>'.format(data=y[2])+
'<dct:format>{data}</dct:format>'.format(data=y[3])+
'<dct:bytesize>{data}</dct:bytesize>'.format(data=y[4])+
'</dcat:Distribution>'+
'</dcat:distribution>')
publisher=''
for z in dataall[2]:
publisher = publisher + (
'<dct:publisher>'+
'<foaf:Organization>'+
'<foaf:name>{data}</foaf:name>'.format(data=z[1])+
'<foaf:mbox>{data}</foaf:mbox>'.format(data=z[3])+
'</foaf:Organization>'+
'</dct:publisher>')
data_str = [[dataall[0][26],
'<dct:identifier>{data}</dct:identifier>'.format(data=dataall[0][1])+
'<dct:title>{data}</dct:title>'.format(data=dataall[0][4])+
'<dct:description>{data}</dct:description>'.format(data=dataall[0][5])+
'<dct:language>{data}</dct:language>'.format(data=dataall[0][26])+
'<dct:spatial>{data}</dct:spatial>'.format(data=dataall[0][28])+
'<dct:created rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">{data}</dct:created>'.format(data=dataall[0][20])+
'<dct:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">{data}</dct:issued>'.format(data=dataall[0][11])+
'<dct:modified rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">{data}</dct:modified>'.format(data=dataall[0][21])+
'<dct:license>{data}</dct:license>'.format(data=dataall[0][13])+
distribution+
publisher+
'<dcat:theme>{data}</dcat:theme>'.format(data=", ".join(str(x) for x in dataall[0][24]))+
'<dcat:keyword>{data}</dcat:keyword>'.format(data=", ".join(str(x) for x in dataall[0][6]))+
'<dct:accrualPeriodicity>{data}</dct:accrualPeriodicity>'.format(data=dataall[0][12])]]
return data_str
@staticmethod
def sql_for_layer(uri, output_format: OutputFormats):
""" Get the SQL query for a given layer and output format. """
locale = QgsSettings().value("locale/userLocale", QLocale().name())
locale = locale.split('_')[0].lower()
if output_format == [OutputFormats.HTML,OutputFormats.DCAT]:
sql = (
"SELECT pgmetadata.get_dataset_item_html_content('{schema}', '{table}', '{locale}');"
).format(schema=uri.schema(), table=uri.table(), locale=locale)
else:
raise NotImplementedError('Output format is not yet implemented.')
return sql
def layer_changed(self, layer):
""" When the layer has changed in the legend, we must check this new layer. """
self.current_datasource_uri = None
self.current_connection = None
self.ce_trouve_dans_psql(layer)
def add_flatten_dataset_table(self):
""" Add a flatten dataset table with all links and contacts. """
'''
connections, message = connections_list()
if not connections:
LOGGER.critical(message)
self.set_html_content('PgMetadata', message)
return
if len(connections) > 1:
dialog = QInputDialog()
dialog.setComboBoxItems(connections)
dialog.setWindowTitle(tr("Database"))
dialog.setLabelText(tr("Choose the database to add the catalog"))
if not dialog.exec_():
return
connection_name = dialog.textValue()
else:
connection_name = connections[0]
metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
connection = metadata.findConnection(connection_name)
locale = QgsSettings().value("locale/userLocale", QLocale().name())
locale = locale.split('_')[0].lower()
uri = QgsDataSourceUri(connection.uri())
uri.setTable(f'(SELECT * FROM pgmetadata.export_datasets_as_flat_table(\'{locale}\'))')
uri.setKeyColumn('uid')
layer = QgsVectorLayer(uri.uri(), '{} - {}'.format(tr("Catalog"), connection_name), 'postgres')
QgsProject.instance().addMapLayer(layer)
'''
@staticmethod
def open_external_help():
QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
@staticmethod
def open_link(url):
QDesktopServices.openUrl(url)
def set_html_content(self, title=None, body=None):
""" Set the content in the dock. """
#link_logo=resources_path('icons', 'CEN_RA.png')
css_file = resources_path('css', 'dock.css')
with open(css_file, 'r', encoding='utf8') as f:
css = f.read()
html = '<html><head>'
#html += '<script src="http://ignf.github.io/geoportal-sdk/latest/dist/2d/GpSDK2D.js" defer ></script>'
html += '<style>{css}</style></head><body>'.format(css=css)
#html += '<link rel="stylesheet" href="http://ignf.github.io/geoportal-sdk/latest/dist/2d/GpSDK2D.css" >'
#html += '<script src="file:///C:/Users/tlaveille/Desktop/maps.js" defer></script>'
#html += '<noscript>Your browser does not support JavaScript!</noscript>'
if title:
html += '<h2>{title} <img class=logo src=https://i2.wp.com/www.cen-rhonealpes.fr/wp-content/uploads/2013/04/cen-rhonealpes-couleurs1.jpg?w=340&ssl=1></h2>'.format(title=title)
if body:
html += body
html += '</body></html>'
# It must be a file, even if it does not exist on the file system.
base_url = QUrl.fromLocalFile(resources_path('images', 'must_be_a_file.png'))
self.viewer.setHtml(html, base_url)
def ce_trouve_dans_psql(self,layer):
try:
uri = layer.dataProvider().uri()
except:
self.default_html_content_not_pg_layer()
self.save_button.setEnabled(False)
uri=''
if uri != '':
if not uri.table():
layertype = layer.providerType().lower()
if layertype == 'wms' or layertype == 'wfs':
self.set_html_to_wms(layer)
else:
self.default_html_content_not_pg_layer()
self.save_button.setEnabled(False)
else:
data_count = self.sql_check(uri)
#print(data_count)
if data_count == 0:
self.default_html_content_not_metadata()
self.save_button.setEnabled(False)
else:
self.build_html_content(layer,uri)
self.save_button.setEnabled(True)
def build_html_content(self,layer,uri):
body = ''
dataall=self.sql_info(uri)
data=dataall[0]
data_url=dataall[1]
data_contact=dataall[2]
#print(len(data_url))
data_collonne=[field.name() for field in layer.dataProvider().fields()]
body += '<div><h3>Identification</h3><table class="table table-condensed">'
body += '<tr><th>Titre</th><td>{data[4]}</td></tr>'.format(data=data)
body += '<tr><th>Description</th><td>{data[5]}</td></tr>'.format(data=data)
body += '<tr><th>Categories</th><td>{data}</td></tr>'.format(data=(", ".join(str(x) for x in data[6])))
body += '<tr><th>Thèmes</th><td>{data}</td></tr>'.format(data=(", ".join(str(x) for x in data[24])))
body += '<tr><th>Mots-clés</th><td>{data[7]}</td></tr>'.format(data=data)
body += '<tr><th>Dernier mise à jour</th><td>{data[23]}</td></tr>'.format(data=data)
body += '<tr><th>Langue</th><td>{data[26]}</td></tr>'.format(data=data)
body += '</table></div>'
body += '<div><h3>Properties spatial</h3><table class="table table-condensed">'
body += '<tr><th>Niveau</th><td>{data[8]}</td></tr>'.format(data=data)
body += '<tr><th>Echelle minimum</th><td>{data[9]}</td></tr>'.format(data=data)
body += '<tr><th>Echelle maximum</th><td>{data[10]}</td></tr>'.format(data=data)
body += '<tr><th>Nombre d\'entités </th><td>{data[15]}</td></tr>'.format(data=data)
body += '<tr><th>Type de géométrie</th><td>{data[16]}</td></tr>'.format(data=data)
body += '<tr><th>Nom de projection</th><td>{data[17]}</td></tr>'.format(data=data)
body += '<tr><th>ID de projection</th><td>{data[18]}</td></tr>'.format(data=data)
body += '<tr><th>Emprise</th><td>{data[28]}</td></tr>'.format(data=data)
body += '</table></div>'
#body += '<div id="map"></div>'
body += '<div><h3>Publication</h3><table class="table table-condensed">'
body += '<tr><th>Date</th><td>{data[11]}</td></tr>'.format(data=data)
body += '<tr><th>Fréquence de mise à jour</th><td>{data[12]}</td></tr>'.format(data=data)
body += '<tr><th>Licence</th><td>{data[13]}</td></tr>'.format(data=data)
body += '<tr><th>Licence attribué</th><td>{data[25]}</td></tr>'.format(data=data)
body += '<tr><th>Restriction</th><td>{data[14]}</td></tr>'.format(data=data)
body += '</table></div>'
body += '<div><h3>Lien</h3><table class="table table-condensed table-striped table-bordered">'
body += '<tr><th>Type</th><th>URL</th><th>Type MIME</th><th>Format</th><th>Taille</th></tr>'
for value_url in data_url:
body += '<tr><td>{value_url[0]}</td><td>{value_url[1]}</td><td>{value_url[2]}</td><td>{value_url[3]}</td><td>{value_url[4]}</td></tr>'.format(value_url=value_url)
body += '</table></div>'
'''
body += '<div><h3>Liste des champs</h3><table class="table table-condensed table-striped table-bordered">'
for collonne in data_collonne:
body += '<tr><th>{collonne}</th><td>{defini}</td></tr>'.format(collonne=collonne,defini='')
body += '</table></div>'
'''
body += '<div><h3>Contacts</h3><table class="table table-condensed table-striped table-bordered">'
body += '<tr><th>Rôle</th><th>Nom</th><th>Organisation</th><th>Email</th><th>Télèphone</th></tr>'
for value_contact in data_contact:
body += '<tr><td>{value_contact[0]}</td><td>{value_contact[1]}</td><td>{value_contact[2]}</td><td>{value_contact[3]}</td><td>{value_contact[4]}</td></tr>'.format(value_contact=value_contact)
body += '</table></div>'
body += '<div><h3>Metadata</h3><table class="table table-condensed">'
body += '<tr><th>Table</th><td>{data[2]}</td></tr>'.format(data=data)
body += '<tr><th>Schema</th><td>{data[3]}</td></tr>'.format(data=data)
body += '<tr><th>Date de création</th><td>{data[20]}</td></tr>'.format(data=data)
body += '<tr><th>Date de modification</th><td>{data[21]}</td></tr>'.format(data=data)
body += '<tr><th>Encodage</th><td>{data[27]}</td></tr>'.format(data=data)
body += '<tr><th>UUID</th><td>{data[1]}</td></tr>'.format(data=data)
body += '</table></div>'
self.set_html_content(
layer.name(), body)
def set_html_to_wms(self,layer):
self.set_html_content(
'CenRa Metadata',(layer.htmlMetadata()))
def default_html_content_not_pg_layer(self):
""" When it's not a PostgreSQL layer. """
self.set_html_content(
'CenRa Metadata', ('Vous devez cliquer sur une couche dans la légende qui est stockée dans PostgreSQL.'))
def default_html_content_not_metadata(self):
self.set_html_content(
'CenRa Metadata', ('La couche ne contien pas de métadonnée.'))
def sql_check(self,uri):
cur=login_base()
table = uri.table()
schema = uri.schema()
sql_count = """SELECT count(uid) FROM metadata.dataset
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_count)
data_count = cur.fetchall()
cur.close()
return data_count[0][0]
def sql_info(self,uri):
cur=login_base()
table = uri.table()
schema = uri.schema()
#[s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1]
sql_find = """SELECT *,right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_find)
data_general = cur.fetchall()
sql_findurl = """SELECT type,url,mime,format,taille FROM metadata.dataurl WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_findurl)
data_url = cur.fetchall()
sql_findcontact = """SELECT role,nom,organisation,email,telephone FROM metadata.datacontact WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_findcontact)
data_contact = cur.fetchall()
cur.close()
return data_general[0],data_url,data_contact
+750
View File
@@ -0,0 +1,750 @@
import logging
import os
from collections import namedtuple
from enum import Enum
from functools import partial
from pathlib import Path
from xml.dom.minidom import parseString
from qgis.gui import *
from qgis.core import (
NULL,
QgsApplication,
QgsDataSourceUri,
QgsProject,
QgsProviderConnectionException,
QgsProviderRegistry,
QgsRasterLayer,
QgsSettings,
QgsVectorLayer,
QgsGeometry,
QgsWkbTypes,
)
from qgis.PyQt.QtCore import QLocale, QUrl, QDateTime
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtPrintSupport import QPrinter
from qgis.PyQt.QtWebKitWidgets import QWebPage
from qgis.PyQt.QtWidgets import (
QDialog,
QAction,
QDockWidget,
QFileDialog,
QInputDialog,
QMenu,
QToolButton,
QTableWidget,
QTableWidgetItem,
)
from qgis.utils import iface
from .tools.resources import (
load_ui,
resources_path,
login_base,
send_issues,
)
from .issues import CenRa_Issues
EDITOR_CLASS = load_ui('CenRa_Metabase_editorwidget_base.ui')
LOGGER = logging.getLogger('CenRa_Metabase')
class Metabase_Editor(QDialog, EDITOR_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
self.import_xml.setAutoRaise(True)
self.import_xml.setText('')
self.import_xml.setIcon(QIcon(QgsApplication.iconPath('mActionAddHtml.svg')))
self.import_xml.clicked.connect(self.py_import_xml)
self.issues_app.setAutoRaise(True)
self.issues_app.setText('')
self.issues_app.setIcon(QIcon(QgsApplication.iconPath('mIconInfo.svg')))
self.issues_app.clicked.connect(self.issues_open)
self.categories_select_view.itemDoubleClicked.connect(self.add_categories_view)
self.categories_view.itemDoubleClicked.connect(self.deleter_categories_view)
self.themes_select_view.itemDoubleClicked.connect(self.add_themes_view)
self.themes_view.itemDoubleClicked.connect(self.deleter_themes_view)
self.annuler_button.clicked.connect(self.close)
self.ok_button.clicked.connect(self.add_metadata)
self.add_lien_button.clicked.connect(self.add_lien)
self.add_contact_button.clicked.connect(self.add_contact)
self.delete_lien_button.clicked.connect(self.delete_lien)
self.delete_contact_button.clicked.connect(self.delete_contact)
def add_metadata(self):
table_name = layer.dataProvider().uri().table()
schema_name = layer.dataProvider().uri().schema()
text_titre = self.titre_line.text()
text_description = self.description_text.toPlainText()
text_mots_cles = self.mots_cles_text.toPlainText()
text_date_maj = str(self.date_maj_date.date().toPyDate())
text_langue = self.langue_box.currentText()
row_count_categories = self.categories_view.rowCount()
row_count_themes = self.themes_view.rowCount()
row = 1
array_categories = '{'
while row_count_categories >= row:
if row_count_categories != row:
array_categories += (self.categories_view.item(row-1,0).text())+','
else:
array_categories += (self.categories_view.item(row-1,0).text())
row = row+1
array_categories += '}'
row = 1
array_themes = '{'
while row_count_themes >= row:
if row_count_themes != row:
array_themes += (self.themes_view.item(row-1,0).text())+','
else:
array_themes += (self.themes_view.item(row-1,0).text())
row = row+1
array_themes += '}'
text_date_creation = str(self.date_creation_date.date().toPyDate())
text_date_modification = str(self.date_modification_date.date().toPyDate())
text_encode = self.encodage_box.currentText()
text_extend = self.extend_plaintext.toPlainText()
int_nbr_entites = (self.nbr_layers.toPlainText())
text_geomtype = self.typegeom_plaintext.toPlainText()
text_crsname = self.crsname_plaintext.toPlainText()
text_crscode = self.crscode_plaintext.toPlainText()
text_niveau = self.niveau_plain.toPlainText()
text_echelle_min = self.echelle_min_plain.toPlainText()
text_echelle_max = self.echelle_max_plain.toPlainText()
if text_echelle_min == '':
text_echelle_min = 'NULL'
if text_echelle_max == '':
text_echelle_max = 'NULL'
text_date_publication = str(self.date_publication_date.date().toPyDate())
text_frequence = self.frequence_box.currentText()
text_restriction = self.restriction_box.currentText()
text_licence = self.licence_box.currentText()
text_licence_attrib = self.licence_attrib_box.currentText()
'''
row_count_link = self.table_lien.rowCount()
row = 1
array_link = ''
while row_count_link >= row:
if row_count_link != row:
array_link += "('"+ table_name +"','"+ schema_name +"','"+ (self.table_lien.item(row-1,1).text()) +"','"+ (self.table_lien.item(row-1,2).text()) +"','"+ (self.table_lien.item(row-1,3).text()) +"','"+ (self.table_lien.item(row-1,4).text()) +"','"+ (self.table_lien.item(row-1,5).text()) +"')"+','
else:
array_link += "('"+ table_name +"','"+ schema_name +"','"+ (self.table_lien.item(row-1,1).text()) +"','"+ (self.table_lien.item(row-1,2).text()) +"','"+ (self.table_lien.item(row-1,3).text()) +"','"+ (self.table_lien.item(row-1,4).text()) +"','"+ (self.table_lien.item(row-1,5).text()) +"')"
row = row+1
row_count_contact = self.table_contact.rowCount()
row = 1
array_contact = ''
while row_count_contact >= row:
if row_count_contact != row:
array_contact += "('"+ table_name +"','"+ schema_name +"','"+ (self.table_contact.item(row-1,1).text()) +"','"+ (self.table_contact.item(row-1,2).text()) +"','"+ (self.table_contact.item(row-1,3).text()) +"','"+ (self.table_contact.item(row-1,4).text()) +"','"+ (self.table_contact.item(row-1,5).text()) +"')"+','
else:
array_contact += "('"+ table_name +"','"+ schema_name +"','"+ (self.table_contact.item(row-1,1).text()) +"','"+ (self.table_contact.item(row-1,2).text()) +"','"+ (self.table_contact.item(row-1,3).text()) +"','"+ (self.table_contact.item(row-1,4).text()) +"','"+ (self.table_contact.item(row-1,5).text()) +"')"
row = row+1
'''
exist=self.status_metadata(layer)
cur_con=login_base(take=True)
cur=cur_con[0]
con=cur_con[1]
list_champs_sql = ''
values_sql_add = ''
if exist:
SQL_uid = """SELECT uid from metadata.dataset where table_name like '"""+table_name+"""' and schema_name like '"""+schema_name+"""';"""
cur.execute(SQL_uid)
text_uid = (cur.fetchall())[0][0]
SQL_delete = """DELETE from metadata.dataset where table_name like '"""+table_name+"""' and schema_name like '"""+schema_name+"""';"""
cur.execute(SQL_delete)
values_sql_add += "'"+text_uid+"',"
list_champs_sql+='uid,'
global uid_delete_list_link,uid_delete_list_contact
if len(uid_delete_list_link) >= 35:
SQL_delete_link = """DELETE FROM metadata.dataurl WHERE uid IN ("""+ uid_delete_list_link[:-1] +""");"""
cur.execute(SQL_delete_link)
uid_delete_list_link = ''
if len(uid_delete_list_contact) >= 35:
SQL_delete_contact = """DELETE FROM metadata.datacontact WHERE uid IN ("""+ uid_delete_list_contact[:-1] +""");"""
cur.execute(SQL_delete_contact)
uid_delete_list_contact=''
list_champs_sql += 'table_name,schema_name,title,abstract,keywords,data_last_update,langue,categories,themes,creation_date,update_date,encode,geom,spatial_extent,feature_count,geometry_type,projection_name,projection_authid,spatial_level,minimum_optimal_scale,maximum_optimal_scale,publication_date,publication_frequency,confidentiality,license,license_attribution'
values_sql_add += "'"+table_name+"','"+schema_name+"','"+text_titre+"','"+text_description+"','"+text_mots_cles+"','"+text_date_maj+"','"+text_langue+"','"+array_categories+"','"+array_themes+"','"+text_date_creation+"','"+text_date_modification+"','"+text_encode+"','"+text_extend+"','"+text_extend+"','"+int_nbr_entites+"','"+text_geomtype+"','"+text_crsname+"','"+text_crscode+"','"+text_niveau+"',"+text_echelle_min+","+text_echelle_max+",'"+text_date_publication+"','"+text_frequence+"','"+text_restriction+"','"+text_licence+"','"+text_licence_attrib+"'"
SQL_add = """INSERT INTO metadata.dataset ("""+list_champs_sql+""") VALUES ("""+values_sql_add+""");"""
cur.execute(SQL_add)
global array_link,array_contact
if len(array_link) >= 25:
array_link=array_link[:-1]
SQL_add_link = """INSERT INTO metadata.dataurl (table_name,schema_name,type,url,mime,format,taille) VALUES """+array_link+""";"""
cur.execute(SQL_add_link)
array_link = ''
if len(array_contact) >= 25:
array_contact=array_contact[0:-1]
SQL_add_contact = """INSERT INTO metadata.datacontact (table_name,schema_name,role,nom,organisation,email,telephone) VALUES """+array_contact+""";"""
cur.execute(SQL_add_contact)
array_contact = ''
con.commit()
cur.close()
self.close()
iface.layerTreeView().setCurrentLayer(None)
iface.layerTreeView().setCurrentLayer(layer)
def raise_(self):
self.activateWindow()
global layer
layer = iface.activeLayer()
global uid_delete_list_link,uid_delete_list_contact,array_link,array_contact
uid_delete_list_link=''
uid_delete_list_contact=''
array_link = ''
array_contact = ''
is_ok=self.is_in_psql(layer)
if is_ok:
exist=self.status_metadata(layer)
if exist:
self.reload_data(layer)
else:
self.new_data(layer)
else:
self.close()
iface.messageBar().pushMessage("Information :", "Cette couche n'est pas stockée dans PostgreSQL", level=Qgis.Warning, duration=30)
def is_in_psql(self,layer):
try:
uri = layer.dataProvider().uri()
except:
uri=''
return False
if uri != '':
if not uri.table():
return False
else:
return True
def status_metadata(self,layer):
uri = layer.dataProvider().uri()
table = uri.table()
schema = uri.schema()
cur=login_base()
count_sql = """ SELECT count(uid) FROM metadata.dataset WHERE table_name LIKE '"""+table+"""' AND schema_name LIKE '"""+schema+"""';"""
cur.execute(count_sql)
data_count = (cur.fetchall())[0][0]
if data_count == 1:
return True
else:
return False
cur.close()
def new_data(self,layer):
#print(layer.name(),'is new data')
reloader=False
self.interface_view(layer,reloader)
def reload_data(self,layer):
#print(layer.name(),'reload data')
reloader=True
self.interface_view(layer,reloader)
def interface_view(self,layer,reloader):
self.description_text.setText(None)
self.mots_cles_text.setText(None)
self.uuid_ligne.setText(None)
self.niveau_plain.setPlainText(None)
self.echelle_min_plain.setPlainText(None)
self.echelle_max_plain.setPlainText(None)
self.url_line.setText(None)
self.taille_line.setText(None)
self.nom_line.setText(None)
self.email_line.setText(None)
self.telephone_line.setText(None)
self.encodage_box.clear()
self.frequence_box.clear()
self.licence_box.clear()
self.licence_attrib_box.clear()
self.restriction_box.clear()
all_list=self.fletch_ref()
categories_list=all_list[0]
themes_list=all_list[1]
langue_list=all_list[2]
encodage_list=all_list[3]
frequency_list=all_list[4]
confidentiality_list=all_list[5]
license_list=all_list[6]
type_list=all_list[7]
mime_list=all_list[8]
format_list=all_list[9]
role_list=all_list[10]
organisation_list=all_list[11]
#langue_box
self.langue_box.clear()
self.langue_box.addItem('')
#self.langue_box.addItem('Fr')
#self.langue_box.addItem('En')
for langue_list_data in langue_list:
self.langue_box.addItem(langue_list_data[0])
for encodage_list_data in encodage_list:
self.encodage_box.addItem(encodage_list_data[0])
self.table_ligne.setText(layer.dataProvider().uri().table())
self.schema_ligne.setText(layer.dataProvider().uri().schema())
#categories_select_view
self.categories_select_view.setColumnCount(1)
self.categories_select_view.setColumnWidth(0, 230)
self.categories_select_view.setHorizontalHeaderLabels(['List des categories'])
#categories_view
self.categories_view.setRowCount(0)
self.categories_view.setColumnCount(1)
self.categories_view.setColumnWidth(0, 230)
self.categories_view.setHorizontalHeaderLabels(['Categories'])
#themes_select_view
self.themes_select_view.setColumnCount(1)
self.themes_select_view.setColumnWidth(0, 230)
self.themes_select_view.setHorizontalHeaderLabels(['List des thèmes'])
#themes_view
self.themes_view.setRowCount(0)
self.themes_view.setColumnCount(1)
self.themes_view.setColumnWidth(0, 230)
self.themes_view.setHorizontalHeaderLabels(['Thèmes'])
#lien_view
self.table_lien.setRowCount(0)
self.table_lien.setColumnCount(6)
self.table_lien.setColumnWidth(0, 0)
self.table_lien.setHorizontalHeaderLabels(['','Type','URL','MIME','Format','Taille'])
#contact_view
self.table_contact.setRowCount(0)
self.table_contact.setColumnCount(6)
self.table_contact.setColumnWidth(0, 0)
self.table_contact.setHorizontalHeaderLabels(['','Rôle','Nom','Organisation','Email','Telephone'])
#print(self.date_maj_date.date().toPyDate())
vector_extend = layer.extent()
polygone_extend = QgsGeometry.fromRect(vector_extend).asWkt()
self.extend_plaintext.setPlainText(str(polygone_extend))
qgstype = str(layer.type())[10:]
if qgstype != 'Raster' :
count_layers = str(layer.featureCount())
geomtype = QgsWkbTypes.displayString(layer.wkbType())
elif qgstype == 'Raster':
count_layers = str(layer.dataProvider().bandCount())
geomtype = qgstype
self.nbr_layers.setPlainText(count_layers)
self.typegeom_plaintext.setPlainText(geomtype)
crs_name = str(layer.crs().description())
self.crsname_plaintext.setPlainText(crs_name)
crs_code = str(layer.crs().authid())
self.crscode_plaintext.setPlainText(crs_code)
self.frequence_box.addItem('')
self.restriction_box.addItem('')
self.licence_box.addItem('')
self.licence_attrib_box.addItem('')
for frequency_list_data in frequency_list:
self.frequence_box.addItem(frequency_list_data[0])
for confidentiality_list_data in confidentiality_list:
self.restriction_box.addItem(confidentiality_list_data[0])
for license_list_data in license_list:
self.licence_box.addItem(license_list_data[0])
self.type_box.clear()
self.mime_box.clear()
self.format_box.clear()
self.role_box.clear()
self.organisation_box.clear()
self.type_box.addItem('')
self.mime_box.addItem('')
self.format_box.addItem('')
self.role_box.addItem('')
self.organisation_box.addItem('')
for type_list_data in type_list:
self.type_box.addItem(type_list_data[0])
for mime_list_data in mime_list:
self.mime_box.addItem(mime_list_data[0])
for format_list_data in format_list:
self.format_box.addItem(format_list_data[0])
for role_list_data in role_list:
self.role_box.addItem(role_list_data[0])
for organisation_list_data in organisation_list:
self.organisation_box.addItem(organisation_list_data[0])
if reloader:
sql_dataload=self.sql_info(layer.dataProvider().uri())
sql_contactlink=self.sql_infoother(layer.dataProvider().uri())
sql_datalink=sql_contactlink[0]
sql_datacontact=sql_contactlink[1]
#print(sql_dataload)
self.titre_line.setText(sql_dataload[4])
self.date_maj_date.setDateTime(sql_dataload[23])
self.date_publication_date.setDateTime(sql_dataload[11])
self.description_text.setText(sql_dataload[5])
self.mots_cles_text.setText(sql_dataload[7])
array_langue_box = [self.langue_box.itemText(i) for i in range(self.langue_box.count())]
self.langue_box.setCurrentIndex(array_langue_box.index(sql_dataload[26]))
self.uuid_ligne.setText(sql_dataload[1])
self.categories_view.setRowCount(len(sql_dataload[6]))
i=0
for categorie_data in sql_dataload[6]:
self.categories_view.setItem(i,0,QTableWidgetItem(categorie_data))
i=i+1
self.themes_view.setRowCount(len(sql_dataload[24]))
i=0
for themes_data in sql_dataload[24]:
self.themes_view.setItem(i,0,QTableWidgetItem(themes_data))
i=i+1
self.categories_select_view.setRowCount(len(categories_list)-len(sql_dataload[6]))
self.themes_select_view.setRowCount(len(themes_list)-len(sql_dataload[24]))
i=0
for categorie_select_data in categories_list:
try:
in_index = sql_dataload[6].index(categorie_select_data[0])
in_index=False
except:
in_index=True
if in_index:
self.categories_select_view.setItem(i,0,QTableWidgetItem(categorie_select_data[0]))
i=i+1
i=0
for themes_select_data in themes_list:
try:
in_index = sql_dataload[24].index(themes_select_data[0])
in_index=False
except:
in_index=True
if in_index:
self.themes_select_view.setItem(i,0,QTableWidgetItem(themes_select_data[0]))
i=i+1
array_encodage_box = [self.encodage_box.itemText(i) for i in range(self.encodage_box.count())]
self.encodage_box.setCurrentIndex(array_encodage_box.index(sql_dataload[27]))
self.niveau_plain.setPlainText(sql_dataload[8])
if str(sql_dataload[9]) == 'None':
value_echelle_min = ''
else:
value_echelle_min = str(sql_dataload[9])
if str(sql_dataload[10]) == 'None':
value_echelle_max = ''
else:
value_echelle_max = str(sql_dataload[10])
self.echelle_min_plain.setPlainText(value_echelle_min)
self.echelle_max_plain.setPlainText(value_echelle_max)
array_frequence_box = [self.frequence_box.itemText(i) for i in range(self.frequence_box.count())]
self.frequence_box.setCurrentIndex(array_frequence_box.index(sql_dataload[12]))
array_licence_box = [self.licence_box.itemText(i) for i in range(self.licence_box.count())]
self.licence_box.setCurrentIndex(array_licence_box.index(sql_dataload[13]))
array_confidentiality_box = [self.restriction_box.itemText(i) for i in range(self.restriction_box.count())]
self.restriction_box.setCurrentIndex(array_confidentiality_box.index(sql_dataload[14]))
array_licence_attrib_box = [self.licence_attrib_box.itemText(i) for i in range(self.licence_attrib_box.count())]
self.licence_attrib_box.setCurrentIndex(array_licence_attrib_box.index(sql_dataload[25]))
c=0
#self.table_lien.setRowCount(len(sql_datalink))
for lien_data in sql_datalink:
self.table_lien.insertRow(c)
self.table_lien.setItem(c,0,QTableWidgetItem(lien_data[1]))
self.table_lien.setItem(c,1,QTableWidgetItem(lien_data[4]))
self.table_lien.setItem(c,2,QTableWidgetItem(lien_data[5]))
self.table_lien.setItem(c,3,QTableWidgetItem(lien_data[6]))
self.table_lien.setItem(c,4,QTableWidgetItem(lien_data[7]))
self.table_lien.setItem(c,5,QTableWidgetItem(lien_data[8]))
c=c+1
c=0
#self.table_contact.setRowCount(len(sql_datacontact))
for contact_data in sql_datacontact:
self.table_contact.insertRow(c)
self.table_contact.setItem(c,0,QTableWidgetItem(contact_data[1]))
self.table_contact.setItem(c,1,QTableWidgetItem(contact_data[4]))
self.table_contact.setItem(c,2,QTableWidgetItem(contact_data[5]))
self.table_contact.setItem(c,3,QTableWidgetItem(contact_data[6]))
self.table_contact.setItem(c,4,QTableWidgetItem(contact_data[7]))
self.table_contact.setItem(c,5,QTableWidgetItem(contact_data[8]))
c=c+1
else:
#titre_line
self.titre_line.setText(layer.name())
self.langue_box.setCurrentIndex(1)
#date_maj_date
now = QtCore.QDateTime.currentDateTime()
self.date_maj_date.setDateTime(now)
self.date_creation_date.setDateTime(now)
self.date_modification_date.setDateTime(now)
self.date_publication_date.setDateTime(now)
self.categories_select_view.setRowCount(len(categories_list))
self.themes_select_view.setRowCount(len(themes_list))
i=0
for categorie_select_data in categories_list:
self.categories_select_view.setItem(i,0,QTableWidgetItem(categorie_select_data[0]))
i=i+1
i=0
for themes_select_data in themes_list:
self.themes_select_view.setItem(i,0,QTableWidgetItem(themes_select_data[0]))
i=i+1
#print(self.langue_box.currentText())
def sql_info(self,uri):
cur=login_base()
table = uri.table()
schema = uri.schema()
#[s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1]
sql_find = """SELECT *,right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_find)
data_general = cur.fetchall()
cur.close()
return data_general[0]
def sql_infoother(self,uri):
cur=login_base()
table = uri.table()
schema = uri.schema()
sql_findlink = """SELECT * FROM metadata.dataurl
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_findlink)
data_link = cur.fetchall()
sql_findcontact = """SELECT * FROM metadata.datacontact
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_findcontact)
data_contact = cur.fetchall()
cur.close()
return data_link,data_contact
def add_categories_view(self):
values_add_categories = self.categories_select_view.selectedItems()[0].text()
self.categories_select_view.removeRow(self.categories_select_view.currentRow())
self.categories_view.insertRow(0)
self.categories_view.setItem(0,0,QTableWidgetItem(values_add_categories))
def deleter_categories_view(self):
values_deleter_categories = self.categories_view.selectedItems()[0].text()
self.categories_view.removeRow(self.categories_view.currentRow())
self.categories_select_view.insertRow(0)
self.categories_select_view.setItem(0,0,QTableWidgetItem(values_deleter_categories))
def add_themes_view(self):
values_add_themes = self.themes_select_view.selectedItems()[0].text()
self.themes_select_view.removeRow(self.themes_select_view.currentRow())
self.themes_view.insertRow(0)
self.themes_view.setItem(0,0,QTableWidgetItem(values_add_themes))
def deleter_themes_view(self):
values_deleter_themes = self.themes_view.selectedItems()[0].text()
self.themes_view.removeRow(self.themes_view.currentRow())
self.themes_select_view.insertRow(0)
self.themes_select_view.setItem(0,0,QTableWidgetItem(values_deleter_themes))
def add_lien(self):
cur=login_base()
maxrow=self.table_lien.rowCount()
self.table_lien.insertRow(maxrow)
table = layer.dataProvider().uri().table()
schema = layer.dataProvider().uri().schema()
if self.taille_line.text() == '':
sql_sizefile = """SELECT pg_size_pretty(pg_total_relation_size('"""+schema+'.'+table+"""'));"""
try:
cur.execute(sql_sizefile)
boolean = True
except:
boolean = False
if boolean == True:
size_file = (cur.fetchall())[0][0]
else:
size_file = ''
else:
size_file = self.taille_line.text()
self.table_lien.setItem(maxrow,0,QTableWidgetItem('new_value'))
self.table_lien.setItem(maxrow,1,QTableWidgetItem(self.type_box.currentText()))
self.table_lien.setItem(maxrow,2,QTableWidgetItem(self.url_line.text()))
self.table_lien.setItem(maxrow,3,QTableWidgetItem(self.mime_box.currentText()))
self.table_lien.setItem(maxrow,4,QTableWidgetItem(self.format_box.currentText()))
self.table_lien.setItem(maxrow,5,QTableWidgetItem(str(size_file)))
global array_link
array_link += "('"+ table +"','"+ schema +"','"+ self.type_box.currentText() +"','"+ self.url_line.text() +"','"+ self.mime_box.currentText() +"','"+ self.format_box.currentText() +"','"+ size_file +"'),"
cur.close()
def add_contact(self):
maxrow=self.table_contact.rowCount()
self.table_contact.insertRow(maxrow)
self.table_contact.setItem(maxrow,0,QTableWidgetItem('new_value'))
self.table_contact.setItem(maxrow,1,QTableWidgetItem(self.role_box.currentText()))
self.table_contact.setItem(maxrow,2,QTableWidgetItem(self.nom_line.text()))
self.table_contact.setItem(maxrow,3,QTableWidgetItem(self.organisation_box.currentText()))
self.table_contact.setItem(maxrow,4,QTableWidgetItem(self.email_line.text()))
self.table_contact.setItem(maxrow,5,QTableWidgetItem(self.telephone_line.text()))
table = layer.dataProvider().uri().table()
schema = layer.dataProvider().uri().schema()
global array_contact
array_contact += "('"+ table +"','"+ schema +"','"+ self.role_box.currentText() +"','"+ self.nom_line.text() +"','"+ self.organisation_box.currentText() +"','"+ self.email_line.text() +"','"+ self.telephone_line.text() +"'),"
def delete_lien(self):
global uid_delete_list_link,array_link
lien_uid = self.table_lien.item(self.table_lien.currentRow(),0).text()
self.table_lien.removeRow(self.table_lien.currentRow())
if lien_uid == 'new_value':
position = self.table_lien.currentRow()
if position < 0:
position=position+1
run_x = 0
while position >= run_x:
#print(position,run_x)
if run_x == 0:
debut = array_link.find("(")
else:
debut = array_link.find("(",fin+1)
fin = array_link.find(")",debut)
#print(debut,fin)
if run_x == 50:
break
run_x+=1
#print(array_link[fin+1:])
if debut <= 0:
debut = 1
fin+= 1
array_link = array_link[:debut-1]+array_link[fin+1:]
#print('a:',array_link)
else:
uid_delete_list_link += "'"+lien_uid+"',"
def delete_contact(self):
global uid_delete_list_contact,array_contact
contact_uid = self.table_contact.item(self.table_contact.currentRow(),0).text()
self.table_contact.removeRow(self.table_contact.currentRow())
if contact_uid == 'new_value':
position = self.table_contact.currentRow()
if position < 0:
position=position+1
#print('p:',position)
run_x = 0
while position >= run_x:
if run_x == 0:
debut = array_contact.find("(")
else:
debut = array_contact.find("(",fin+1)
fin = array_contact.find(")",debut)
#print(debut,fin)
if run_x == 50:
break
run_x+=1
#print(array_contact[fin+1:])
if debut <= 0:
debut = 1
fin+= 1
array_contact = array_contact[:debut-1]+array_contact[fin+1:]
#print('a:',array_contact)
else:
uid_delete_list_contact += "'"+contact_uid+"',"
def fletch_ref(self):
cur=login_base()
SQL_categories="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.categories' ORDER BY code,item_order;"""
SQL_themes="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.themes' ORDER BY label_fr;"""
SQL_langue="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.langue';"""
SQL_encodage="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.encodage';"""
SQL_frequency="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.publication_frequency' ORDER BY label_fr;"""
SQL_confidentiality="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.confidentiality' ORDER BY label_fr;"""
SQL_license="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.license' ORDER BY label_fr;"""
SQL_type="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.type' ORDER BY label_fr;"""
SQL_mime="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.mime' ORDER BY label_fr;"""
SQL_format="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.format' ORDER BY label_fr;"""
SQL_role="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'contact.contact_role' ORDER BY label_fr;"""
SQL_organisation="""SELECT label_fr FROM metadata.glossary WHERE field LIKE 'contact.organisation' ORDER BY label_fr;"""
cur.execute(SQL_categories)
categories_list=cur.fetchall()
cur.execute(SQL_themes)
themes_list=cur.fetchall()
cur.execute(SQL_langue)
langue_list=cur.fetchall()
cur.execute(SQL_encodage)
encodage_list=cur.fetchall()
cur.execute(SQL_frequency)
frequency_list=cur.fetchall()
cur.execute(SQL_confidentiality)
confidentiality_list=cur.fetchall()
cur.execute(SQL_license)
license_list=cur.fetchall()
cur.execute(SQL_type)
type_list=cur.fetchall()
cur.execute(SQL_mime)
mime_list=cur.fetchall()
cur.execute(SQL_format)
format_list=cur.fetchall()
cur.execute(SQL_role)
role_list=cur.fetchall()
cur.execute(SQL_organisation)
organisation_list=cur.fetchall()
return categories_list,themes_list,langue_list,encodage_list,frequency_list,confidentiality_list,license_list,type_list,mime_list,format_list,role_list,organisation_list
cur.close()
def py_import_xml(self):
folder = QFileDialog.getOpenFileName()
if folder:
folder=folder[0]
if folder[len(folder)-4:] == '.xml' :
print('is .xml')
def issues_open(self):
self.issues = CenRa_Issues()
self.issues.show()
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

+89
View File
@@ -0,0 +1,89 @@
import os
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\')+1
NAME = plugin_dir[end_find:]
#print(NAME)
from qgis.gui import *
from qgis.core import (
NULL,
QgsApplication,
QgsDataSourceUri,
QgsProject,
QgsProviderConnectionException,
QgsProviderRegistry,
QgsRasterLayer,
QgsSettings,
QgsVectorLayer,
QgsGeometry,
)
from qgis.PyQt.QtWidgets import (
QDialog,
QAction,
QDockWidget,
QFileDialog,
QInputDialog,
QMenu,
QToolButton,
QTableWidget,
QTableWidgetItem,
)
from qgis.utils import iface
from .tools.resources import (
load_ui,
resources_path,
send_issues,
)
EDITOR_CLASS = load_ui('CenRa_IssuesSend.ui')
class CenRa_Issues(QDialog, EDITOR_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
#place connect here
self.annuler_button.clicked.connect(self.close)
self.ok_button.clicked.connect(self.run_sendissues)
def run_sendissues(self):
text_titre = self.titre_line.text()
text_message = self.messages_plain.toPlainText()
statu_bug = self.check_bug.isChecked()
statu_aide = self.check_aide.isChecked()
statu_question = self.check_question.isChecked()
statu_amelioration = self.check_amelioration.isChecked()
statu_autre = self.check_autre.isChecked()
statu = []
if statu_bug == True : statu = statu + [1]
if statu_aide == True : statu = statu + [3]
if statu_question == True : statu = statu + [5]
if statu_amelioration == True : statu = statu + [2]
if statu_autre == True : statu = statu + [6]
if len(statu) >= 1:
import qgis
url = qgis.utils.pluginMetadata(NAME,'tracker')
print(text_message)
send_info = send_issues(url,text_titre,text_message,statu)
code = send_info.status_code
print(code)
else:
code = 423
if code == 201:
iface.messageBar().pushMessage("Envoyer :", "Votre messages à bien été envoyer.", level=Qgis.Success, duration=20)
self.close()
elif code == 422:
iface.messageBar().pushMessage("Erreur :", "Erreur dans le contenu du messages.", level=Qgis.Critical, duration=20)
elif code == 423:
iface.messageBar().pushMessage("Erreur :", "Pas de sujet sélectionné.", level=Qgis.Critical, duration=20)
elif code == 404:
iface.messageBar().pushMessage("Missing :", "Le serveur de messagerie est injoignable.", level=Qgis.Warning, duration=20)
+48
View File
@@ -0,0 +1,48 @@
# This file contains metadata for your plugin.
# This file should be included when you package your plugin.# Mandatory items:
[general]
name=CenRa_Metabase
qgisMinimumVersion=3.0
description=CenRa_METABASE
version=1.3
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
about=Permet de saisire et de visualisé les information lier à la metadonné d'une couche ce trouvent sur PostgreSQL
repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
homepage=https://plateformesig.cenra-outils.org/
tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues
# End of mandatory metadata
# Recommended items:
hasProcessingProvider=no
# Uncomment the following line and add your changelog:
changelog=<h2>CenRa_Metabase:</h2></br><p><h3>08/10/2024 - Version 1.3: </h3> - Lecture de métadonnée des flux WMS/WFS.</p></br><p><h3>07/10/2024 - Version 1.2: </h3> - Correctif de bug.</p></br><p><h3>03/10/2024 - Version 1.1: </h3> - Remonte la fênetre dans la pille.</p></br><p><h3>26/08/2024 - Version 1.0: </h3> - Lancement du plugin CenRa_Metabase </p></br>
# Tags are comma separated with spaces allowed
tags=python
category=Plugins
icon=icon.png
# experimental flag
experimental=False
# deprecated flag (applies to the whole plugin, not just a single version)
deprecated=False
# Since QGIS 3.8, a comma separated list of plugins to be installed
# (or upgraded) can be specified.
# Check the documentation for more information.
# plugin_dependencies=
Category of the plugin: Raster, Vector, Database or Web
# category=cenra,database,metadata
# If the plugin can run on QGIS Server.
server=False
+34
View File
@@ -0,0 +1,34 @@
Plugin Builder Results
Your plugin CenRa was created in:
C:\Users\gcostes\.qgis2\python\plugins\CenRa
Your QGIS plugin directory is located at:
C:/Users/gcostes/.qgis2/python/plugins
What's Next:
* Copy the entire directory containing your new plugin to the QGIS plugin
directory
* Compile the ui file using pyuic4
* Compile the resources file using pyrcc4
* Test the plugin by enabling it in the QGIS plugin manager
* Customize it by editing the implementation file:
cenra.py
* Create your own custom icon, replacing the default icon.png
* Modify your user interface by opening cenra.ui
in Qt Designer (don't forget to compile it with pyuic4 after changing it)
* You can use the Makefile to compile your Ui and resource files when
you make changes. This requires GNU make (gmake)
For more information, see the PyQGIS Developer Cookbook at:
http://www.qgis.org/pyqgis-cookbook/index.html
(C) 2011-2014 GeoApt LLC - geoapt.com
+28
View File
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
CenRa
A QGIS plugin
Conservatoire d'Espaces Naturels de Rhône-Alpes
-------------------
begin : 2014-03-27
copyright : (C) 2014 by Conservatoire d'Espaces Naturels de 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. *
* *
***************************************************************************/
This script initializes the plugin, making it known to QGIS.
"""
from __future__ import absolute_import
def classFactory(iface):
# load CenRa class from file CenRa
from .cenra import CenRa
return CenRa(iface)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

+940
View File
@@ -0,0 +1,940 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
CenRa
A QGIS plugin
Conservatoire d'Espaces Naturels de Rhône-Alpes
-------------------
begin : 2014-03-27
copyright : (C) 2014 by Conservatoire d'Espaces Naturels de 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
# Import the PyQt and QGIS libraries
from builtins import next
from builtins import str
from builtins import object
import qgis
from qgis.PyQt.QtCore import QSettings
from qgis.PyQt.QtWidgets import QAction, QMenu, QDialog
from qgis.PyQt.QtGui import QIcon
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from qgis.core import *
from qgis.core import QgsDataSourceUri
from .forms.about_form import PostgisAboutDialog
# Initialize Qt resources from file resources.py
from . import resources_rc
# Import the code for the dialog
from .cenradialog import CenRaDialog
from .table_postgisdialog import table_postgisDialog
from .tools.PythonSQL import *
from .tools.resources import maj_verif
import os.path
import webbrowser, os
import psycopg2
import psycopg2.extras
import base64
class CenRa(object):
def __init__(self, iface):
# 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]
localePath = os.path.join(self.plugin_dir, 'i18n', 'cenra_{}.qm'.format(locale))
if os.path.exists(localePath):
self.translator = QTranslator()
self.translator.load(localePath)
if qVersion() > '4.3.3':
QCoreApplication.installTranslator(self.translator)
# Create the dialog (after translation) and keep reference
self.dlg = CenRaDialog()
self.dlgAjout = table_postgisDialog()
maj_verif('CenRa_POSTGIS')
version = qgis.utils.pluginMetadata('CenRa_POSTGIS','version')
# Display About window on first use
s = QSettings()
versionUse = s.value("postgis/version", 1, type=str)
if str(versionUse) != str(version) :
s.setValue("postgis/version", str(version))
self.open_about_dialog()
def initGui(self):
self.toolBar = self.iface.addToolBar("CEN-RA")
self.toolBar.setObjectName("CEN-RA")
# ***Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/CenRa/page_new.png"),
u"Création d'un dossier", self.iface.mainWindow())
# connect the action to the run method
self.action.triggered.connect(self.creation)
# Add toolbar button and menu item
self.toolBar.addAction(self.action)
self.iface.addPluginToMenu(u"CenRa", self.action)
# ***Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/CenRa/page_ajout.png"),
u"Ajout d'une table", self.iface.mainWindow())
# connect the action to the run method
self.action.triggered.connect(self.ajout)
# Add toolbar button and menu item
self.toolBar.addAction(self.action)
self.iface.addPluginToMenu(u"&CenRa", self.action)
# ***Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/CenRa/help.png"),
u"Aide", self.iface.mainWindow())
# connect the action to the run method
self.action.triggered.connect(self.doHelp)
# Add toolbar button and menu item
self.toolBar.addAction(self.action)
self.iface.addPluginToMenu(u"CenRa", self.action)
self.menu = QMenu()
self.menu.setTitle( QCoreApplication.translate( "CENRA","&CenRa" ) )
self.cenra_new = QAction( QIcon(":/plugins/CenRa/page_new.png"), QCoreApplication.translate("CENRA", u"Création d'un dossier" ), self.iface.mainWindow() )
self.cenra_ajout = QAction( QIcon(":/plugins/CenRa/page_ajout.png"), QCoreApplication.translate("CENRA", "Ajout d'une table" ), self.iface.mainWindow() )
self.cenra_help = QAction( QIcon(":/plugins/CenRa/help.png"), QCoreApplication.translate("CENRA", "Aide" ), self.iface.mainWindow() )
self.menu.addActions( [self.cenra_new, self.cenra_ajout, self.cenra_help] )
menu_bar = self.iface.mainWindow().menuBar()
actions = menu_bar.actions()
lastAction = actions[ len( actions ) - 1 ]
menu_bar.insertMenu( lastAction, self.menu )
self.cenra_new.triggered.connect(self.creation)
self.cenra_ajout.triggered.connect(self.ajout)
self.cenra_help.triggered.connect(self.doHelp)
def open_about_dialog(self):
dialog = PostgisAboutDialog(self.iface)
dialog.exec_()
def unload(self):
# Remove the plugin menu item and icon
self.iface.removePluginMenu(u"&CENRA", self.action)
self.iface.removePluginMenu(u"&CenRa", self.action)
self.iface.removeToolBarIcon(self.action)
# run method that performs all the real work
def creation(self):
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result == 1:
#**********************************Debut_script****************************************
### Creation du schema pour le nouveau site
if self.dlg.at.isChecked():
schema = "_" + self.dlg.dept.currentText() + "_at_" + self.dlg.nom.text().lower() # Ajout de "_" pour eviter pb de numero en premier caractere
else :
schema = "_" + self.dlg.dept.currentText() + "_" + self.dlg.nom.text().lower() # Ajout de "_" pour eviter pb de numero en premier caractere
if self.dlg.nom.text() == "" or self.dlg.nom.text() == "NULL":
QMessageBox.warning(None, "Oups :", "Veuillez renseigner un nom de dossier.")
return
ch = [u"à", u"À", u"â", u"Â", u"ä", u"Ä", u"å", u"Å", u"ç", u"Ç", u"é", u"É", u"è", u"È", u"ê", u"Ê", u"ë", u"Ë", u"î", u"Î", u"ï", u"Ï", u"ô", u"Ô", u"ö", u"Ö", u"ù", u"Ù", u"û", u"Û", u"ü", u"Ü", u"ÿ", u"Ÿ", u"'", u"-", u" "]
for car in ch :
if self.dlg.nom.text().find(car) != -1 :
QMessageBox.warning(None, "Oups :", u"Le nom de dossier ne doit pas comporter de caractères spéciaux, ni d'espaces !\n\n\t" + self.dlg.nom.text().lower() )
return
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()
SQL_schema = "CREATE SCHEMA " + schema + ";"
SQL_GRANT_SCHEMA="GRANT CREATE, USAGE ON SCHEMA "+schema+" TO grp_qgis; GRANT CREATE, USAGE ON SCHEMA "+schema+" TO grp_sig;"
cur.execute(SQL_schema)
cur.execute(SQL_GRANT_SCHEMA)
### Creation de la table contour
if self.dlg.couche_contour.isChecked(): # Verifie si la checkbox est cochee
if self.dlg.annee_1.text() == 'aaaa' or self.dlg.annee_1.text() == '':
tablename = schema + "_contour"
else :
tablename = schema + "_contour_" + self.dlg.annee_1.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_contour = "CREATE TABLE " + schema + "."+ tablename + champ_contour
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (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_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'contour_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_contour)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
### Creation de la table habitat
if self.dlg.couche_habitat.isChecked():
if self.dlg.annee_2.text() == 'aaaa' or self.dlg.annee_2.text() == '':
tablename = schema + "_habitat"
else :
tablename = schema + "_habitat_" + self.dlg.annee_2.text()
tablename_1=tablename+"_points"
tablename_qgis = tablename_1[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_VEGETHAB = "CREATE TABLE "+ schema + "."+ tablename_1 + champ_vegethab_point
SQL_pkey = "ALTER TABLE " + schema + "." + tablename_1 + " ADD CONSTRAINT " + tablename_1 + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_coordonnees = "CREATE TRIGGER coordonnees" + tablename_1 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_1 + " FOR EACH ROW EXECUTE PROCEDURE ref.coordonnees();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename_1 + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'vegethab_points_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_1+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_1+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename_1+"_gid_seq TO grp_qgis;"
cur.execute(SQL_VEGETHAB)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_coordonnees)
cur.execute(SQL_style)
cur.execute(SQL_GRANT_TABLE)
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_1, geom)
layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres")
tablename_2=tablename+"_lignes"
tablename_qgis = tablename_2[1:]
SQL_VEGETHAB = "CREATE TABLE "+ schema + "."+ tablename_2 + champ_vegethab_multilinestring
SQL_pkey = "ALTER TABLE " + schema + "." + tablename_2 + " ADD CONSTRAINT " + tablename_2 + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_length_m = "CREATE TRIGGER length_m" + tablename_2 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_2 + " FOR EACH ROW EXECUTE PROCEDURE ref.length_m();"
SQL_trigger_length_km = "CREATE TRIGGER length_km" + tablename_2 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_2 + " FOR EACH ROW EXECUTE PROCEDURE ref.length_km();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename_2 + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'vegethab_lignes_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_2+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_2+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename_2+"_gid_seq TO grp_qgis;"
cur.execute(SQL_VEGETHAB)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_length_m)
cur.execute(SQL_trigger_length_km)
cur.execute(SQL_style)
cur.execute(SQL_GRANT_TABLE)
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_2, geom)
layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres")
tablename_3=tablename+"_polygones"
tablename_qgis = tablename_3[1:]
SQL_VEGETHAB = "CREATE TABLE "+ schema + "."+ tablename_3 + champ_vegethab_multipolygon
SQL_pkey = "ALTER TABLE " + schema + "." + tablename_3 + " ADD CONSTRAINT " + tablename_3 + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_area_m2 = "CREATE TRIGGER area_m2" + tablename_3 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_3 + " FOR EACH ROW EXECUTE PROCEDURE ref.area_m2();"
SQL_trigger_area_ha = "CREATE TRIGGER area_ha" + tablename_3 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_3 + " FOR EACH ROW EXECUTE PROCEDURE ref.area_ha();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename_3 + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'vegethab_polygones_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_3+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_3+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename_3+"_gid_seq TO grp_qgis;"
cur.execute(SQL_VEGETHAB)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_style)
cur.execute(SQL_GRANT_TABLE)
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_3, geom)
layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres")
'''
SQL_habitat = "CREATE TABLE " + schema + "."+ tablename + champ_habitat
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (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_concat_cd_cb = "CREATE TRIGGER concat_cd_cb" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.concat_cd_cb();"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'habitat_modele_v3'"""
cur.execute(SQL_habitat)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_trigger_concat_cd_cb)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
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")
'''
### Creation de la table travaux prevus
if self.dlg.couche_travaux_prevus.isChecked():
#**********Poly
if self.dlg.annee_5.text() == 'aaaa' or self.dlg.annee_5.text() == '':
tablename = schema + "_travaux_prevus_poly"
else :
tablename = schema + "_travaux_prevus_poly_" + self.dlg.annee_5.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_travaux_prevus = "CREATE TABLE " + schema + "."+ tablename + champ_travaux_prevus_multipolygon
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
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_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'travaux_prevus_poly_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_travaux_prevus)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
#**********ligne
if self.dlg.annee_5.text() == 'aaaa' or self.dlg.annee_5.text() == '':
tablename = schema + "_travaux_prevus_ligne"
else :
tablename = schema + "_travaux_prevus_ligne_" + self.dlg.annee_5.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_travaux_prevus = "CREATE TABLE " + schema + "."+ tablename + champ_travaux_prevus_multilinestring
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
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_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'travaux_prevus_ligne_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_travaux_prevus)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_trigger_length_m)
cur.execute(SQL_trigger_length_km)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
#**********point
if self.dlg.annee_5.text() == 'aaaa' or self.dlg.annee_5.text() == '':
tablename = schema + "_travaux_prevus_point"
else :
tablename = schema + "_travaux_prevus_point_" + self.dlg.annee_5.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_travaux_prevus = "CREATE TABLE " + schema + "."+ tablename + champ_travaux_prevus_point
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
SQL_trigger_coordonnees = "CREATE TRIGGER coordonnees" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.coordonnees();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'travaux_prevus_point_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_travaux_prevus)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_trigger_coordonnees)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
### Creation de la table vierge
if self.dlg.couche_vierge.isChecked():
if self.dlg.annee_4.text() == 'aaaa' or self.dlg.annee_4.text() == '':
tablename = schema + "_" + self.dlg.nom_couche_vierge.text().lower()
else :
tablename = schema + "_" + self.dlg.nom_couche_vierge.text().lower() + "_" + self.dlg.annee_4.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
if self.dlg.couche_vierge_point.isChecked() == 1 :
champ_vierge = champ_viergePoint
if self.dlg.couche_vierge_ligne.isChecked() == 1 :
champ_vierge = champ_viergeLigne
if self.dlg.couche_vierge_polygone.isChecked() == 1 :
champ_vierge = champ_viergePolygone
SQL_vierge = "CREATE TABLE " + schema + "."+ tablename + champ_vierge
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (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_vierge)
cur.execute(SQL_pkey)
if self.dlg.couche_vierge_point.isChecked() == 1 :
cur.execute(SQL_trigger_coordonnees)
if self.dlg.couche_vierge_ligne.isChecked() == 1 :
cur.execute(SQL_trigger_length_m)
cur.execute(SQL_trigger_length_km)
if self.dlg.couche_vierge_polygone.isChecked() == 1 :
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")
else :
con.commit()
con.close()
pass
### Outil Aide
def doHelp(self):
webbrowser.open("http://plateformesig.cenra-outils.org/")
### Outil Ajout de nouvelles couche a un dossier
def ajout(self):
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 schemaname,'sig' as group from pg_catalog.pg_tables
where schemaname ~ E'^_(0|1|2|3|4|6|7|f)'
group by schemaname
order by schemaname)
select string_agg(schemaname,',')
from list_schema
group by "group";"""
cur.execute(SQL)
list_brut = str(next(cur))
list = list_brut [2:-2]
listItems = list.split(",")
con.close()
self.dlgAjout.ui.schema.clear()
self.dlgAjout.ui.schema.addItems(listItems)
self.dlgAjout.ui.schema.setCurrentIndex(-1) # Pour ne pas commencer la liste au premier schema
# show the dialog
self.dlgAjout.show()
# Run the dialog event loop
result = self.dlgAjout.exec_()
# See if OK was pressed
if result == 1:
#******************************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()
if self.dlgAjout.ui.schema.currentIndex() == -1 :
QMessageBox.warning(None, "Oups :", "Veuillez choisir un nom de dossier.")
return
schema = self.dlgAjout.ui.schema.currentText()
### Creation de la table contour
if self.dlgAjout.ui.couche_contour.isChecked(): # Verifie si la checkbox est cochee
if self.dlgAjout.ui.annee_1.text() == 'aaaa' or self.dlgAjout.ui.annee_1.text() == '':
tablename = schema + "_contour"
else :
tablename = schema + "_contour_" + self.dlgAjout.ui.annee_1.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_contour = "CREATE TABLE " + schema + "."+ tablename + champ_contour
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (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_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'contour_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_contour)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
### Creation de la table habitat
if self.dlgAjout.ui.couche_habitat.isChecked():
if self.dlgAjout.ui.annee_2.text() == 'aaaa' or self.dlgAjout.ui.annee_2.text() == '':
tablename = schema + "_habitat"
else :
tablename = schema + "_habitat_" + self.dlgAjout.ui.annee_2.text()
tablename_1=tablename+"_points"
tablename_qgis = tablename_1[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_VEGETHAB = "CREATE TABLE "+ schema + "."+ tablename_1 + champ_vegethab_point
SQL_pkey = "ALTER TABLE " + schema + "." + tablename_1 + " ADD CONSTRAINT " + tablename_1 + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_coordonnees = "CREATE TRIGGER coordonnees" + tablename_1 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_1 + " FOR EACH ROW EXECUTE PROCEDURE ref.coordonnees();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename_1 + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'vegethab_points_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_1+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_1+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename_1+"_gid_seq TO grp_qgis;"
cur.execute(SQL_VEGETHAB)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_coordonnees)
cur.execute(SQL_style)
cur.execute(SQL_GRANT_TABLE)
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_1, geom)
layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres")
tablename_2=tablename+"_lignes"
tablename_qgis = tablename_2[1:]
SQL_VEGETHAB = "CREATE TABLE "+ schema + "."+ tablename_2 + champ_vegethab_multilinestring
SQL_pkey = "ALTER TABLE " + schema + "." + tablename_2 + " ADD CONSTRAINT " + tablename_2 + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_length_m = "CREATE TRIGGER length_m" + tablename_2 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_2 + " FOR EACH ROW EXECUTE PROCEDURE ref.length_m();"
SQL_trigger_length_km = "CREATE TRIGGER length_km" + tablename_2 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_2 + " FOR EACH ROW EXECUTE PROCEDURE ref.length_km();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename_2 + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'vegethab_lignes_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_2+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_2+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename_2+"_gid_seq TO grp_qgis;"
cur.execute(SQL_VEGETHAB)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_length_m)
cur.execute(SQL_trigger_length_km)
cur.execute(SQL_style)
cur.execute(SQL_GRANT_TABLE)
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_2, geom)
layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres")
tablename_3=tablename+"_polygones"
tablename_qgis = tablename_3[1:]
SQL_VEGETHAB = "CREATE TABLE "+ schema + "."+ tablename_3 + champ_vegethab_multipolygon
SQL_pkey = "ALTER TABLE " + schema + "." + tablename_3 + " ADD CONSTRAINT " + tablename_3 + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_area_m2 = "CREATE TRIGGER area_m2" + tablename_3 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_3 + " FOR EACH ROW EXECUTE PROCEDURE ref.area_m2();"
SQL_trigger_area_ha = "CREATE TRIGGER area_ha" + tablename_3 + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename_3 + " FOR EACH ROW EXECUTE PROCEDURE ref.area_ha();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename_3 + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'vegethab_polygones_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_3+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename_3+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename_3+"_gid_seq TO grp_qgis;"
cur.execute(SQL_VEGETHAB)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_style)
cur.execute(SQL_GRANT_TABLE)
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_3, geom)
layer = self.iface.addVectorLayer(uri.uri(), tablename_qgis, "postgres")
'''
SQL_habitat = "CREATE TABLE " + schema + "."+ tablename + champ_habitat
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (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_concat_cd_cb = "CREATE TRIGGER concat_cd_cb" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.concat_cd_cb();"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'habitat_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_habitat)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_trigger_concat_cd_cb)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
'''
### Creation de la table travaux prevus
if self.dlgAjout.ui.couche_travaux_prevus.isChecked():
#**********Poly
if self.dlgAjout.ui.annee_5.text() == 'aaaa' or self.dlgAjout.ui.annee_5.text() == '':
tablename = schema + "_travaux_prevus_poly"
else :
tablename = schema + "_travaux_prevus_poly_" + self.dlgAjout.ui.annee_5.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_travaux_prevus = "CREATE TABLE " + schema + "."+ tablename + champ_travaux_prevus_multipolygon
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
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_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'travaux_prevus_poly_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_travaux_prevus)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_trigger_area_m2)
cur.execute(SQL_trigger_area_ha)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
#**********ligne
if self.dlgAjout.ui.annee_5.text() == 'aaaa' or self.dlgAjout.ui.annee_5.text() == '':
tablename = schema + "_travaux_prevus_ligne"
else :
tablename = schema + "_travaux_prevus_ligne_" + self.dlgAjout.ui.annee_5.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_travaux_prevus = "CREATE TABLE " + schema + "."+ tablename + champ_travaux_prevus_multilinestring
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
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_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'travaux_prevus_ligne_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_travaux_prevus)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_trigger_length_m)
cur.execute(SQL_trigger_length_km)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
#**********point
if self.dlgAjout.ui.annee_5.text() == 'aaaa' or self.dlgAjout.ui.annee_5.text() == '':
tablename = schema + "_travaux_prevus_point"
else :
tablename = schema + "_travaux_prevus_point_" + self.dlgAjout.ui.annee_5.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
SQL_travaux_prevus = "CREATE TABLE " + schema + "."+ tablename + champ_travaux_prevus_point
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (gid)"
SQL_trigger_date_creation = "CREATE TRIGGER date_creation" + tablename + " BEFORE INSERT ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_creation();"
SQL_trigger_date_maj = "CREATE TRIGGER date_maj" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.date_maj();"
SQL_trigger_coordonnees = "CREATE TRIGGER coordonnees" + tablename + " BEFORE INSERT OR UPDATE ON " + schema + "." + tablename + " FOR EACH ROW EXECUTE PROCEDURE ref.coordonnees();"
SQL_style = """INSERT INTO layer_styles (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, update_time)
SELECT f_table_catalog, '""" + schema + "', '" + tablename + """', f_geometry_column, stylename, styleqml, stylesld, useasdefault, "owner", ui, now()
FROM layer_styles
WHERE description = 'travaux_prevus_point_modele_v3'"""
SQL_GRANT_TABLE="GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_qgis;GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON "+schema+"."+tablename+" TO grp_sig;GRANT ALL ON SEQUENCE "+schema+"."+tablename+"_gid_seq TO grp_qgis;"
cur.execute(SQL_travaux_prevus)
cur.execute(SQL_pkey)
cur.execute(SQL_trigger_date_creation)
cur.execute(SQL_trigger_date_maj)
cur.execute(SQL_trigger_coordonnees)
cur.execute(SQL_style) ## Enregistrement du style (comme style par defaut) dans la table layer_styles
cur.execute(SQL_GRANT_TABLE)
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")
### Creation de la table vierge
if self.dlgAjout.ui.couche_vierge.isChecked():
if self.dlgAjout.ui.annee_4.text() == 'aaaa' or self.dlgAjout.ui.annee_4.text() == '':
tablename = schema + "_" + self.dlgAjout.ui.nom_couche_vierge.text().lower()
else :
tablename = schema + "_" + self.dlgAjout.ui.nom_couche_vierge.text().lower() + "_" + self.dlgAjout.ui.annee_4.text()
tablename_qgis = tablename[1:] # Permet d'enlever le "_", ajouter a la premiere etape, dans qgis
if self.dlgAjout.ui.couche_vierge_point.isChecked() == 1 :
champ_vierge = champ_viergePoint
if self.dlgAjout.ui.couche_vierge_ligne.isChecked() == 1 :
champ_vierge = champ_viergeLigne
if self.dlgAjout.ui.couche_vierge_polygone.isChecked() == 1 :
champ_vierge = champ_viergePolygone
SQL_vierge = "CREATE TABLE " + schema + "."+ tablename + champ_vierge
SQL_pkey = "ALTER TABLE " + schema + "." + tablename + " ADD CONSTRAINT " + tablename + "_pkey" + " PRIMARY KEY (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_vierge)
cur.execute(SQL_pkey)
if self.dlgAjout.ui.couche_vierge_point.isChecked() == 1 :
cur.execute(SQL_trigger_coordonnees)
if self.dlgAjout.ui.couche_vierge_ligne.isChecked() == 1 :
cur.execute(SQL_trigger_length_m)
cur.execute(SQL_trigger_length_km)
if self.dlgAjout.ui.couche_vierge_polygone.isChecked() == 1 :
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")
else :
con.commit()
con.close()
pass
@@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
/*************************************************************************** /***************************************************************************
CopieDialog CenRaDialog
A QGIS plugin A QGIS plugin
Permet la copie d'une table dans une base PostGis Conservatoire d'Espaces Naturels de Rhône-Alpes
------------------- -------------------
begin : 2015-04-13 begin : 2014-03-27
git sha : $Format:%H$ copyright : (C) 2014 by Conservatoire d'Espaces Naturels de Rhône-Alpes
copyright : (C) 2015 by Guillaume COSTES - CEN Rhône-Alpes
email : guillaume.costes@espaces-naturels.fr email : guillaume.costes@espaces-naturels.fr
***************************************************************************/ ***************************************************************************/
@@ -21,18 +20,15 @@
***************************************************************************/ ***************************************************************************/
""" """
import os from qgis.PyQt import QtCore, QtGui
from qgis.PyQt.QtWidgets import QDialog
from PyQt4 import QtGui, uic from .ui_cenra import Ui_cenra
# create the dialog for zoom to point
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'copie_dialog_base.ui'))
class CopieDialog(QtGui.QDialog, FORM_CLASS): class CenRaDialog(QDialog, Ui_cenra):
def __init__(self, parent=None): def __init__(self):
"""Constructor.""" QDialog.__init__(self)
super(CopieDialog, self).__init__(parent)
# Set up the user interface from Designer. # Set up the user interface from Designer.
# After setupUI you can access any designer object by doing # After setupUI you can access any designer object by doing
# self.<objectname>, and you can use autoconnect slots - see # self.<objectname>, and you can use autoconnect slots - see
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

+39
View File
@@ -0,0 +1,39 @@
# This file contains metadata for your plugin. Beginning
# with version 1.8 this is the preferred way to supply information about a
# plugin. The current method of embedding metadata in __init__.py will
# be supported until version 2.0
# This file should be included when you package your plugin.
# Mandatory items:
[general]
name=CenRa_POSTGIS
qgisMinimumVersion=3.0
description=Permet de crée un dossier dans la base PostGis
version=1.8
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
# end of mandatory metadata
# Optional items:
# Uncomment the following line and add your changelog entries:
changelog=<h2>CenRa_POSTGIS:</h2></br><p><h3>13/09/2024 - Version 1.8:</h3>- Ajoute d'un changelog et vérification de mise à jour.</p>
# tags are comma separated with spaces allowed
tags=cenra, postgis, database
repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
homepage=https://plateformesig.cenra-outils.org/
category=Plugins
icon=cenra.png
# experimental flag
experimental=False
# deprecated flag (applies to the whole plugin, not just a single version
deprecated=False
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

+914
View File
@@ -0,0 +1,914 @@
# -*- coding: utf-8 -*-
# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2)
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore
qt_resource_data = b"\
\x00\x00\x15\x6a\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x22\x00\x00\x00\x23\x08\x06\x00\x00\x01\x86\x1c\xe8\xf1\
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x2e\x23\x00\x00\x2e\x23\
\x01\x78\xa5\x3f\x76\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\
\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\
\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\
\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\
\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\
\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\
\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\
\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\
\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\
\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\
\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\
\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\
\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\
\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\
\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\
\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\
\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\
\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\
\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\
\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\
\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\
\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\
\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\
\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\
\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\
\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\
\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\
\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\
\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\
\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\
\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\
\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\
\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\
\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\
\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\
\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\
\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\
\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\
\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\
\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\
\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\
\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\
\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\
\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\
\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\
\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\
\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\
\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\
\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\
\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\
\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\
\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\
\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\
\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\
\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\
\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\
\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\
\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\
\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\
\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\
\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\
\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\
\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\
\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\
\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\
\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\
\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\
\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\
\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\
\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\
\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\
\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\
\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\
\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\
\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\
\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\
\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\
\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\
\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\
\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\
\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\
\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\
\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\
\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\
\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\
\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\
\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\
\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\
\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\
\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\
\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\
\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\
\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\
\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\
\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\
\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\
\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\
\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\
\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\
\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\
\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\
\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\
\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\
\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\
\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\
\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\
\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\
\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\
\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\
\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\
\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\
\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\
\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\
\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\
\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\
\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\
\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\
\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\
\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\
\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\
\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\
\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\
\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\
\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\
\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\
\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\
\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\
\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\
\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\
\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\
\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\
\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\
\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\
\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\
\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\
\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\
\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\
\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\
\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\
\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\
\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\
\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\
\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\
\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\
\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\
\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\
\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\
\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\
\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\
\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\
\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\
\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\
\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\
\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\
\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\
\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\
\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\
\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\
\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\
\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\
\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\
\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\
\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\
\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\
\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\
\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\
\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\
\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\
\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x0a\x95\
\x49\x44\x41\x54\x78\xda\x62\xfa\xff\xff\x3f\x03\x3a\x66\x62\x60\
\x60\x60\x28\xdf\xa1\xf5\xbf\x76\xb7\xc9\x7f\x06\x28\x60\x62\x60\
\x60\x60\xd0\x95\x70\x67\xf8\xf5\xf7\x1b\x03\x8a\xa0\xc9\xca\x45\
\x0c\x33\xba\xb2\x19\x0a\xe6\x14\xfc\x87\x0b\x6a\xb4\xbf\x65\xfc\
\xb8\x2f\x9b\xf1\xf5\xc7\xd7\x0c\x0c\x0c\x0c\x0c\x00\x00\x00\x00\
\xff\xff\x62\xc2\xb0\xa4\x74\xbb\xda\xff\x3f\xff\x7e\xfe\x9f\x7c\
\x3c\x0c\xa2\x8d\x91\x91\xa5\xe8\xe4\xe3\xd5\x0c\x35\xd5\xf6\x5f\
\x19\x18\x18\x18\x98\x92\x0e\xbe\xec\xb3\x89\xfc\xc3\xc8\xc0\xc0\
\xc0\x5d\x30\xa7\xe0\x3f\x93\x46\xfb\x5b\xc6\xff\xc7\x12\x18\x60\
\x06\x03\x00\x00\x00\xff\xff\x62\xfa\xff\xff\x3f\x43\xe9\x76\x8d\
\xa4\xb6\x03\x4e\xff\x0b\xb7\x28\xfe\x5f\x7d\xb9\xe6\xff\xaf\xbf\
\x3f\x4e\x60\xf8\x86\x91\x81\x71\x92\xbe\xa4\x17\x83\xba\xa8\x2d\
\xc3\xf1\x47\xcb\x18\x78\x6d\x96\xf8\x30\x20\x01\x26\x06\x06\x06\
\x86\xc4\x83\x2f\x2f\xef\xbb\x37\x7b\xc1\xed\x37\xc7\x18\x3e\xbf\
\x97\x64\x64\xe7\xf8\xf1\x1a\x43\x91\x46\xfb\x5b\xcb\x1e\x8f\x1b\
\x89\x3d\x5e\xb7\x19\x67\x45\x1f\x61\xf8\xb8\x2f\x9b\xf1\xd5\xeb\
\xd7\xff\x5f\xbd\x7e\xfd\x9f\x81\x81\x81\x01\x00\x00\x00\xff\xff\
\x62\xc2\x16\xa2\x28\xee\x29\xdf\xa1\xc5\xb0\xfc\x62\xe9\xff\xf2\
\x1d\x5a\xff\x1b\xf6\x5a\xfc\xff\xfe\xfb\xd3\xff\x9f\x7f\xbe\x20\
\xac\x61\x61\x62\x67\x38\xff\x7c\x33\x43\xb0\x4e\x23\xc3\x8b\xcf\
\xb7\x19\xe6\x9d\x4d\x67\xa8\xdc\xa9\x87\x50\xf0\xe7\xdf\x0f\x06\
\x06\x06\x46\x06\x3e\x76\x71\x06\x7e\x0e\x71\x86\x47\x9f\x8f\xa6\
\xcd\xed\x2d\xe6\x86\x2b\xf8\xc5\xcc\xc4\xf0\xe7\xef\x4f\x06\x45\
\x41\x13\x86\x1f\x7f\x3e\x33\x3c\xb8\xa9\x3b\x9b\x81\x81\x01\x6e\
\x07\x53\xfa\xbe\x17\x5c\x8e\x77\x7e\x31\x7e\xfb\xfd\x81\x81\x83\
\x85\xf7\xda\xb6\x35\x3e\x69\xe8\x5e\xf5\x51\x7d\xf1\xfd\xff\x97\
\x26\x05\x89\x19\x5d\xd9\x4a\x4c\x4c\xff\x66\xfa\xfa\x1c\x67\x28\
\x9e\x57\xfc\x3f\xa6\x2f\xe6\x3f\x93\x46\xfb\xdb\x55\x1a\xed\x6f\
\x19\x65\xdb\x7f\xbd\xfc\xb8\x2f\x9b\xf3\xe3\xbe\x6c\x46\x6e\x0e\
\x1e\x86\x72\xdf\x0a\x06\x6e\x0e\x1e\x48\x60\xa1\x83\x2f\xdf\x3f\
\x33\x14\x2e\x2a\x60\xf8\xf2\xfd\x33\x03\x80\x91\xfa\x07\x69\x23\
\x0c\xc3\x00\xfe\x7c\x26\x27\x26\x1a\x8d\x29\x96\x46\x23\x76\xd0\
\x34\x69\xb1\x81\x62\x41\x4a\x41\x17\x0b\x22\x38\xa4\x83\x8b\x9b\
\xba\x18\x23\x84\x84\x6b\x91\x76\x28\x1a\x52\x8a\x8a\xd2\x16\x9d\
\x3a\x08\x59\x8a\x8a\x94\xe8\x21\x6a\x88\x1d\x1c\x1c\x34\x5a\xfc\
\x03\x1a\x44\x10\xce\x82\xf1\x3c\x8f\x6b\x4c\x72\x77\x9f\x83\x38\
\x08\x1e\xf4\x9d\xde\xe9\xc7\x33\x3c\xef\x5b\x40\x29\x05\xcb\xb9\
\xf1\x69\xe5\x15\xfc\xbf\x2a\x4b\x58\xce\xed\x65\x39\xf7\x20\xcb\
\x3d\xfd\x3c\xb0\xe8\xe9\x65\x39\x57\x7d\xf7\xac\x85\x50\x4a\xa1\
\x69\x0a\x74\xab\x0a\x00\x72\x4e\xd0\x4c\x4c\x99\x04\x90\x19\x9b\
\xc9\xf1\x41\xd5\x72\xef\xc2\x6f\x92\xdf\x0b\x0d\xe6\xed\x62\xa6\
\x5c\x0b\x2e\xd4\xd2\x10\xf7\xe4\xbe\x50\x37\x08\xa5\x2a\x18\x43\
\x11\x6d\xac\xee\x40\x5e\xfd\x87\x17\x95\xed\xa8\xb6\x3e\x47\x6c\
\xff\x0b\x32\x8a\x04\x42\x88\x8c\x02\x91\x94\xca\xdd\xfa\x48\x83\
\xe3\x2d\xdc\x15\xcd\x27\x7f\x4e\x17\x91\xd7\x72\x68\xa9\xeb\xc3\
\xc1\xd9\x1a\xa4\xec\x19\x6a\x6d\x8d\xb0\x99\xab\x9e\x4d\x86\x07\
\xc7\x47\x27\x2c\x09\x5d\xe4\xe5\xd4\x24\x2c\xbf\x7f\xd6\x48\xca\
\xc5\x47\x33\x63\x45\x26\x7f\x89\xd2\xa2\x0a\x24\xf9\x18\x8e\xc5\
\xf5\xa5\x89\xb1\xf6\x63\x23\xa3\xf6\x03\x68\xd2\x45\xb2\x46\xd2\
\xe6\xe4\x33\xb4\x2b\xf1\xf7\x75\x5b\xf2\x9c\xec\x1c\x4d\x93\xf2\
\xe2\x07\x64\x39\xd6\x42\xbe\x0e\x05\x5a\x65\xa9\xe4\xf6\xb4\xb7\
\x74\x11\x00\xf3\x00\x18\x00\x81\x87\x62\x0e\x8f\xa6\xfc\x78\x3f\
\xd0\x89\xc3\x5d\xa7\xd7\x60\x54\x52\x00\x54\x00\xdf\x7a\x3a\x8f\
\x3c\xc3\x73\x23\xf4\x5c\x10\xe8\xf0\xdc\x08\x0d\xfd\x08\xdd\xf9\
\x04\x70\x45\xd2\x8a\x2b\x92\xde\x73\x45\xd2\x70\x0c\xc9\x50\x57\
\xbb\x20\xc6\x7d\xb3\x62\xdc\xf7\x58\x8c\xfb\x8c\x62\xdc\xe7\xe7\
\x05\x1e\x9b\xa9\x0d\x64\xaf\xae\xb0\x99\xda\x00\x2f\xf0\x77\x92\
\xfc\xd7\x44\x83\x51\x12\x0d\x46\x89\xdd\x6e\x27\xb7\x3b\x00\x5c\
\x53\x52\x6e\x21\x4d\xc6\x61\x18\xff\xfd\xbf\xa9\x13\xc3\x9a\xc7\
\x0d\x52\xd3\x28\x0f\x95\x9a\x74\x20\xb5\x2e\x23\xf2\x00\x51\x61\
\x20\xb6\x8a\xea\x42\xb4\x5a\x61\x59\x41\x65\x18\x49\x91\x22\x11\
\x41\x60\x41\x9a\x90\x84\xbb\x30\x48\x0d\x59\x84\xa6\x61\x05\x91\
\x59\xd0\x81\x3c\xa4\x96\xb9\x60\x6d\x6e\x73\xf3\xfb\xfe\xdd\x78\
\x11\xc1\x2c\x2f\x9e\xbb\x87\xdf\xc5\xfb\x3e\xcf\xf3\xcf\x56\xfe\
\x8f\x14\x80\x53\xed\xa9\x58\x07\xab\x38\xd9\x9e\x92\x5e\xd9\xb1\
\xea\x44\x65\x47\xda\xd5\xae\x4f\x37\xcf\x9f\xea\x48\x2b\xac\x78\
\xb4\x32\xea\x5a\x77\x1e\x52\x6a\x48\xa9\x06\xce\x89\x10\x0a\x9f\
\x7f\xf6\xcb\x9c\x84\xe2\x37\x3e\xd5\x5d\x0b\xe2\xa4\x2a\x67\x2f\
\x0a\x44\x5b\x79\x76\xcb\xd4\xd1\x9c\x56\xe9\xd7\xbc\x46\x9f\xea\
\x61\xbe\xef\x64\x4d\x4d\x0f\xd1\x33\xdc\x44\x51\x7a\x0d\x7e\xd5\
\x4b\x86\x69\x1b\x85\xa9\xa7\xa9\xed\x29\xe4\x4c\xe7\x1a\xce\x74\
\x66\x58\xcf\x3e\x5e\x1b\x18\x12\xa4\x84\x84\xfa\x55\x0f\x41\x4a\
\x08\xd6\xc1\x0b\xac\x36\x6e\xe5\xd9\xf0\x3d\x5a\x07\x2f\xb0\xcc\
\x90\xc9\x8a\xa8\x6c\xc2\x82\x0d\x9f\x03\x1d\x5c\x01\xf0\xa9\x1e\
\xd7\xf2\xc8\x8d\x24\x18\x32\x99\x99\x75\x73\x70\xfd\x2d\x04\x0a\
\xa6\xf0\x95\x8c\xfd\x7a\xc7\x07\x7b\x77\x6e\xd8\x6c\x8e\x79\xb1\
\x7b\x7f\x60\x88\x22\x14\xe7\xa8\x63\x80\x8f\x53\xbd\x24\x47\x6f\
\x46\x93\x2a\x4f\xbf\xdc\xc6\x3e\x3d\x82\x40\x61\x72\x74\x45\xef\
\xe5\x2b\x69\x27\xea\x6e\x46\x04\x86\xac\x5b\xba\xc3\x9e\x12\xbd\
\x19\x21\x74\xa4\xc4\x6c\xa1\xe1\xe5\x21\x16\x85\x44\x90\x9d\x50\
\x4c\x6c\x78\xd2\x74\xff\x93\x6d\x28\x8a\x56\x0b\xc4\x06\x84\xf4\
\x7d\x6b\x73\x0e\x4e\xda\xd8\x10\xb7\x93\xde\x91\x66\xbc\xfe\x5f\
\x98\xc2\x93\x79\x3e\x7a\x9f\xe9\xd9\xe1\xa6\xb1\xaf\x86\xc4\x39\
\xff\xee\x80\x90\x63\x9d\xe3\x10\xac\x17\xaf\xc7\x1f\x92\x97\x52\
\x81\x39\xeb\x06\x5f\x1d\x6f\x01\x70\xbb\xc3\x4a\x15\x9d\x56\x35\
\xe7\x4f\x08\x08\xf1\x06\x2b\x47\xca\x1f\x4f\x44\x6a\xba\xa0\xd0\
\xd6\x81\x73\x38\x7d\x3f\x10\x42\x41\x1f\x3a\xb3\xf1\x4e\xfd\x61\
\x74\x3a\x75\xdf\x9c\xff\xfb\x7c\x39\xd9\x35\x13\x24\xec\xa5\x5d\
\x13\x7a\xe3\xf8\xa4\x88\x5f\x92\x21\x46\xbe\x18\xc5\xf5\x4b\x96\
\x17\x9a\xa6\x34\xff\xe1\x6f\x9b\x0f\x12\x0a\xe0\xd7\x09\xc7\xf6\
\x8f\xb2\xb7\xde\xbc\x9e\xf6\x07\x45\x77\xa5\xa6\x48\xa0\x18\xa0\
\xb0\xa0\x8f\xbd\x7b\xde\x7f\xb2\x34\x58\xa4\xa5\xc1\x22\xcb\x6f\
\x95\xcb\x92\xba\x12\xf9\x27\x64\x13\x90\x04\xc4\x80\xcc\x79\x35\
\x93\x01\xc8\x03\x80\x15\xf0\x01\x93\x26\x83\x89\x44\x63\x12\x71\
\xd1\xf1\xc4\x45\xc7\x93\x68\x4c\xc2\x64\x30\xf1\xf7\x9e\x0c\xa5\
\xd6\xd8\xa7\x52\x6b\xec\x34\xb5\xdc\xc1\x61\x2b\xd3\x1c\xb6\xb2\
\x5d\x0e\x5b\x99\xde\x61\x2b\x33\x3a\xbd\x2e\x0a\x32\xf3\x31\xe7\
\x9a\x31\xe7\x9a\x29\xc8\xcc\xc7\xe9\x75\x2d\x6c\x4f\x5c\x1e\x27\
\xd5\xd6\x6a\x8e\x37\x5a\x38\xde\x68\xa1\xda\x5a\x8d\xcb\xe3\x5c\
\xf8\x28\xcd\xdb\x9d\x85\xac\xda\xdf\x02\xf8\xcd\x7a\xb9\xc6\xc4\
\x51\x46\x61\xf8\x9d\xd9\x9d\xd9\x4b\x61\xcb\xdd\x52\x96\x22\x97\
\x05\xc1\x8a\xa1\x2d\x6c\x4d\x05\x0b\x05\x0b\x06\x94\x04\x41\xdb\
\xa4\xda\xc4\x6a\xdb\xb0\x82\x0d\x54\x2c\x44\x29\xb1\x11\xa5\xd6\
\x46\x4b\x7f\x78\x69\x09\x12\xa2\x41\xc4\xc6\x00\xe5\xba\xdc\x2c\
\xb7\x02\xb5\x85\x0a\x85\x42\x29\x72\xdd\x05\xba\xbb\xb0\x37\x76\
\xd9\xf1\x87\x8c\x11\x52\x4d\x16\xf8\x26\xe7\xc7\xcc\x9c\xbc\x79\
\xe6\x9b\x2f\xe7\xbc\x67\x53\x2a\xdb\xa6\x55\xc7\x15\xe7\x88\xf7\
\xaf\x3f\x85\xec\x3a\x29\xaa\x87\x2e\xed\x3d\xd7\x10\x7a\x29\xad\
\xd2\xbb\x39\xbd\x52\x32\x92\x51\x15\xa0\xce\xa8\x0a\x30\x65\x54\
\x05\x58\x4e\x5f\xf7\xb3\xd4\x0c\x7d\x65\xc8\xae\x93\xce\xa5\x57\
\x4a\x06\x53\xcb\x77\x34\x9d\xaa\xf0\x2a\xc8\xa8\xf2\x4f\x2b\xba\
\x95\xfa\x3c\x7b\xe4\x36\xb4\xad\x04\x41\xda\x18\xcc\x0b\xc3\x35\
\x43\x5f\xb6\xcd\xe9\xfe\x94\xd9\x0b\xc4\xa1\xd1\xbe\xa7\x3c\x3d\
\xec\x82\x44\x4b\xcb\x3a\x2e\x00\xc2\xc2\x98\x09\x8a\xc3\xe7\x05\
\xba\x46\x3b\x7c\x18\xd1\x22\xc9\x8b\x19\x08\x3b\x14\xf8\xd9\x51\
\x7f\x97\x88\xcf\x67\x16\xef\xb7\x7c\xda\x14\xa5\xcf\x6b\x8e\xce\
\xcd\x6d\x8a\x44\x6e\x53\xa4\xf5\x20\xcc\xdf\x57\x10\x00\x2f\x2e\
\x49\x83\xe6\x08\xb1\x60\x54\xa2\xe2\xde\x79\x58\x18\x13\x12\x9e\
\xce\x81\xc6\x30\x83\xd0\x27\x8f\x22\xdc\xeb\x1d\xe8\x97\xd4\xc8\
\xaa\x09\x42\x66\x75\x20\x4a\xfa\xb2\x70\x67\xba\x0a\x93\x9a\x7e\
\x28\xb5\x23\x98\xd5\x8e\xc6\xa8\xf4\x93\x84\x4a\x3f\x69\x3d\x48\
\x88\xf8\x55\x48\xc5\x89\xda\x60\x71\x02\x7c\x1c\xf7\x82\x22\x79\
\x30\x2d\x1b\x40\x73\x04\x18\x9a\x6b\xc3\xd2\xb2\x01\xf9\xaf\x4c\
\xc3\xdb\x21\x04\x27\xaf\x39\x61\x46\x3b\x8c\x83\x92\x14\x44\x78\
\x1f\x87\x54\x9c\x88\x20\xd7\x58\x04\xba\x46\xab\x82\xc5\x09\x65\
\x21\x1e\xb1\x6f\x79\x39\xfb\x33\x3e\x2e\x3b\xad\x07\xb9\x39\xfe\
\x33\x3a\xc7\x4b\x75\x9d\xe3\xa5\xa6\x7e\x45\x23\x8c\xcb\x3a\x48\
\xdd\x93\xb0\xf3\x89\x28\x18\xcd\x5a\xf0\x29\x1b\xcc\xeb\xc6\xa1\
\xd4\x8e\x62\xb7\x38\x1e\x63\xaa\xdb\x68\x7a\x70\x15\xcd\x0f\x0a\
\xd0\x35\xf1\x0b\xee\x2a\x6a\x0a\xef\xcd\xca\xed\x2f\x17\xcf\x25\
\x1c\x93\x79\x76\xa7\xa6\x44\x22\x25\x65\xbf\xf5\x20\x04\x41\x82\
\x20\xc8\x79\x30\x8c\x86\x7d\xd6\x35\x51\x86\xa1\xd9\x1b\x38\x29\
\x2d\x46\xb0\x5b\x02\xc6\x54\x77\x70\xed\x8f\x8f\x31\xa8\xfc\x0d\
\x24\x41\x42\x40\x6d\x85\x9b\x28\x00\xbe\x4e\xfb\xb0\x6b\xc7\x81\
\x82\xdb\x8d\x47\xd0\xd1\xbc\x27\x9e\x01\x18\x1e\xcf\x22\xa3\x69\
\x66\xbd\x35\x80\x51\x72\x48\x6a\xc2\xd5\xd6\x0f\x52\xf7\x24\xf8\
\x39\x85\x61\x5e\x3f\x8e\xd6\xb1\x62\x50\x1c\x3e\x6a\xef\xe7\x43\
\xc4\x77\x46\x9c\xff\x07\xf0\x77\x0e\x87\xce\xa4\xc2\xe8\xa3\x1e\
\x0c\xce\x37\xf4\x35\xf6\xb6\xb5\x74\x74\x0b\xc1\xe7\x21\x73\x45\
\xec\x23\x00\xe1\x56\x83\x78\xce\xe8\xe0\xae\xd4\x33\x16\x66\xf9\
\x59\x85\xfe\xe1\xb1\x9b\xe3\xa5\xe8\x9d\xa9\x46\x94\x44\x06\x7b\
\x81\x1b\x14\xda\x11\xbc\xec\x9f\x89\xc0\x6d\x31\x28\xe9\xcd\xc4\
\xf0\x7c\x27\xb8\x24\x0d\x8a\xc3\x07\x8f\x66\xde\xeb\xed\xda\x6d\
\xd1\x2e\xda\xbe\x4e\x90\x96\xe0\x15\x49\x67\x00\xfb\xad\x06\x79\
\xa1\x5f\xcd\x39\x70\x57\xed\x78\xa2\x6e\x5a\x14\x36\xa0\xb9\x62\
\x26\x49\x82\xa6\x44\x45\xf2\xe1\xaf\x61\x30\x2d\xc0\x65\x8b\x17\
\x4c\xcb\x7a\xdc\x78\x58\x04\x21\x65\x07\x80\x01\x80\x59\x1e\xdf\
\xf8\xcc\xef\x1d\xbb\xea\xbb\x5b\xf7\x38\xf0\x78\xc6\x0b\x6b\xf4\
\x39\xeb\xf9\x35\x3b\x00\x64\x1b\x29\x42\x2d\x99\xd6\x37\xca\x6a\
\xa7\x6c\x43\x07\xd4\x6f\x50\xb4\x2d\xd9\xae\x28\x7f\xb1\x7d\xa2\
\xf4\x72\xe0\xb6\xe8\x1f\x9c\x84\x1e\xf9\x24\x57\x97\xc4\x13\x18\
\x6d\xe6\x94\x8e\xce\xdf\x7d\x71\xbc\xaf\xbe\x22\xd2\x9e\xa2\x4d\
\x1d\x00\xb6\xff\x4b\x4f\x0d\xa0\x75\x3d\x20\x87\x01\x24\xb1\x1b\
\x64\xe4\x12\x1a\xdf\x69\xfd\xad\x13\x75\xd3\xfb\xd2\xeb\x54\xb5\
\xdb\x8b\x73\x64\x83\x4d\x85\x87\x7f\x2d\x8b\x7f\xf7\xe2\xd9\xd3\
\x3f\x9d\x3f\x73\x46\x58\x72\xe5\x50\xa4\x76\x71\x4b\x03\x97\x6b\
\x9e\x07\xe0\xc3\x0a\xc5\xc5\xb6\x21\x2e\xb6\x6d\xeb\x91\xd7\xfa\
\x2b\xd8\x86\x9d\x76\x35\x8d\x59\xdb\xbc\xd9\x06\xbe\x16\xe4\x13\
\x00\x2f\x01\x68\x07\x60\x00\x60\x06\xe0\x6e\xe6\x10\x59\x66\x9a\
\x8a\x20\x35\x23\xb8\xf8\x4d\x3d\x7a\x7a\xed\xc1\xa3\xf1\x2d\xcd\
\x37\x2a\x08\x92\xa9\x7d\xdc\x39\x10\x09\x45\x10\x09\x45\xab\x9a\
\x7e\xf2\x41\xd9\x2a\x03\xc0\xe6\x3c\x0e\x84\x01\xd0\x03\xe0\x39\
\x00\x82\x95\x69\xc5\x09\x40\x0c\x00\x39\x00\xe8\x2d\x14\x9b\xfb\
\x36\x00\x02\x80\x18\x40\x22\x80\xb3\x2b\x1f\xf2\x26\x00\x27\x21\
\x2d\x84\x90\x16\xae\x82\xb3\x13\xda\xad\xba\x5f\x9b\xf3\x0f\xc8\
\x8a\x2b\xf9\xcf\x10\x9f\xd3\xa2\xf0\xc7\x02\x76\xf2\x61\x63\x42\
\x2d\x4f\x2e\x55\xcb\x93\x73\xd4\xf2\xe4\x2c\xb5\x3c\xf9\x7b\xb5\
\x3c\x79\x6e\xea\xd1\x14\xd8\x69\x88\x0d\x76\x2a\x62\x83\xcd\xb1\
\xda\x4b\x6c\x74\x29\x34\x8a\xcd\x31\x35\x1b\x5d\x79\xe5\x79\xff\
\xfb\xfe\xaf\x01\x00\x3d\xb9\x4e\x56\xa9\x10\xde\xd1\x00\x00\x00\
\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x15\xd7\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x22\x00\x00\x00\x23\x08\x06\x00\x00\x01\x86\x1c\xe8\xf1\
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x2e\x23\x00\x00\x2e\x23\
\x01\x78\xa5\x3f\x76\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\
\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\
\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\
\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\
\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\
\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\
\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\
\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\
\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\
\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\
\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\
\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\
\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\
\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\
\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\
\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\
\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\
\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\
\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\
\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\
\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\
\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\
\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\
\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\
\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\
\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\
\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\
\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\
\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\
\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\
\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\
\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\
\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\
\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\
\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\
\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\
\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\
\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\
\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\
\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\
\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\
\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\
\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\
\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\
\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\
\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\
\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\
\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\
\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\
\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\
\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\
\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\
\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\
\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\
\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\
\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\
\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\
\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\
\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\
\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\
\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\
\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\
\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\
\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\
\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\
\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\
\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\
\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\
\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\
\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\
\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\
\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\
\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\
\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\
\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\
\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\
\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\
\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\
\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\
\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\
\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\
\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\
\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\
\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\
\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\
\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\
\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\
\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\
\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\
\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\
\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\
\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\
\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\
\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\
\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\
\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\
\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\
\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\
\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\
\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\
\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\
\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\
\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\
\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\
\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\
\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\
\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\
\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\
\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\
\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\
\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\
\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\
\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\
\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\
\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\
\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\
\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\
\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\
\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\
\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\
\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\
\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\
\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\
\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\
\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\
\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\
\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\
\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\
\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\
\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\
\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\
\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\
\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\
\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\
\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\
\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\
\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\
\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\
\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\
\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\
\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\
\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\
\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\
\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\
\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\
\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\
\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\
\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\
\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\
\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\
\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\
\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\
\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\
\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\
\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\
\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\
\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\
\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\
\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\
\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\
\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\
\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\
\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\
\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\
\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\
\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\
\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\
\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\
\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x0b\x02\
\x49\x44\x41\x54\x78\xda\x62\xfa\xff\xff\x3f\x03\x3a\x66\x62\x60\
\x60\x60\x28\xdf\xa1\xf5\xbf\x76\xb7\xc9\x7f\x06\x28\x60\x62\x60\
\x60\x60\xd0\x95\x70\x67\xf8\xf5\xf7\x1b\x03\x8a\xa0\xc9\xca\x45\
\x0c\x33\xba\xb2\x19\xae\xed\xf5\xfd\x0f\x17\xd4\x68\x7f\xcb\xf8\
\x71\x5f\x36\xe3\xfb\x27\x5b\x18\x18\x18\x18\x18\x00\x00\x00\x00\
\xff\xff\x62\xc2\xb0\xa4\x74\xbb\xda\xff\x3f\xff\x7e\xfe\x9f\x7c\
\x3c\x0c\xa2\x8d\x91\x91\xa5\xe8\xe4\xe3\xd5\x0c\x35\xd5\xf6\x5f\
\x19\x18\x18\x18\x98\x92\x0e\xbe\xec\xb3\x89\xfc\xc3\xc8\xc0\xc0\
\xc0\x7d\x6d\xaf\xef\x7f\x26\x8d\xf6\xb7\x8c\xff\x8f\x25\x30\xc0\
\x0c\x06\x00\x00\x00\xff\xff\x62\xfa\xff\xff\x3f\x43\xe9\x76\x8d\
\xa4\xb6\x03\x4e\xff\x0b\xb7\x28\xfe\x5f\x7d\xb9\xe6\xff\xaf\xbf\
\x3f\x4e\x60\xf8\x86\x91\x81\x71\x92\xbe\xa4\x17\x83\xba\xa8\x2d\
\xc3\xf1\x47\xcb\x18\x78\x6d\x96\xf8\x30\x20\x01\x26\x06\x06\x06\
\x86\xc4\x83\x2f\x2f\xef\xbb\x37\x7b\xc1\xed\x37\xc7\x18\x3e\xbf\
\x97\x64\x64\xe7\xf8\xf1\x1a\x43\x91\x46\xfb\x5b\xcb\x1e\x8f\x1b\
\x89\x3d\x5e\xb7\x19\x67\x45\x1f\x61\xf8\xb8\x2f\x9b\xf1\xf7\xdf\
\x1f\xff\x7f\xff\xfd\xf1\x9f\x81\x81\x81\x01\x00\x00\x00\xff\xff\
\x62\xc2\x16\xa2\x28\xee\x29\xdf\xa1\xc5\xb0\xfc\x62\xe9\xff\xf2\
\x1d\x5a\xff\x1b\xf6\x5a\xfc\xff\xfe\xfb\xd3\xff\x9f\x7f\xbe\x20\
\xac\x61\x61\x62\x67\x38\xff\x7c\x33\x43\xb0\x4e\x23\xc3\x8b\xcf\
\xb7\x19\xe6\x9d\x4d\x67\xa8\xdc\xa9\x87\x50\xf0\xe7\xdf\x0f\x06\
\x06\x06\x46\x06\x3e\x76\x71\x06\x7e\x0e\x71\x86\x47\x9f\x8f\xa6\
\xcd\xed\x2d\xe6\x86\x2b\xf8\xc5\xcc\xc4\xf0\xe7\xef\x4f\x06\x45\
\x41\x13\x86\x1f\x7f\x3e\x33\x3c\xb8\xa9\x3b\x9b\x81\x81\x01\x6e\
\x07\x53\xfa\xbe\x17\x5c\x8e\x77\x7e\x31\x7e\xfb\xfd\x81\x81\x83\
\x85\xf7\xda\xb6\x35\x3e\x69\xe8\x5e\xf5\x51\x7d\xf1\xfd\xff\x97\
\x26\x05\x89\x19\x5d\xd9\x4a\x4c\x4c\xff\x66\x1e\xa9\x58\xc7\xf0\
\x97\x81\xe1\xff\xe5\x5d\xce\xff\x99\x34\xda\xdf\xae\xd2\x68\x7f\
\xcb\x28\xdb\xfe\xeb\xe5\xc7\x7d\xd9\x9c\x1f\xf7\x65\x33\x7e\x7a\
\xbe\x9f\xe1\xe5\xad\x59\x0c\x9f\x9e\xef\x87\x04\x16\x3a\xf8\xcf\
\xf0\x9f\xe1\xfe\xf1\x74\x86\xff\x0c\xff\x19\x00\x8c\x93\x4f\x48\
\x53\x71\x00\xc7\x3f\x3f\xb7\x97\x3a\x9d\xcd\x17\x46\xe8\xa4\x0e\
\x66\x5b\x51\x41\x94\x68\x06\x75\xc8\x28\x44\x0f\x76\xe8\x32\xd9\
\x41\x4f\xcd\x05\x52\xbc\x42\xea\x10\x2a\x8b\x0e\x51\x54\xe8\x55\
\xbd\x45\x79\x88\xd9\x43\x56\xc3\xa2\x3a\xec\x34\x8a\xfe\x40\x45\
\x08\xc1\x0a\x5c\xf5\x7a\xbc\x1e\xdb\xde\x7b\xbf\x0e\x11\x15\x34\
\xe8\x0b\xdf\xeb\x87\xcf\xe1\xfb\xad\x91\x52\xa2\xe9\x51\x2e\x3e\
\xd8\x4f\xf2\x6e\x6b\xa3\xa6\x47\x87\x34\x3d\x3a\xa9\xe9\xdb\x2f\
\x4d\x2c\xef\x3e\xa9\xe9\x91\x9d\xa3\x8b\x41\x21\xa5\xc4\xf3\x1c\
\xaa\x4e\x15\xc0\x2a\x7f\xf1\xea\x95\xf5\x26\x88\x3b\x6a\x7d\xf8\
\xbc\xeb\x95\xcf\x4e\x1f\xc9\xdf\x5c\xe7\x0b\x3c\x6b\x50\x9a\xbd\
\xd3\xf7\x3a\xe4\x19\x7d\xdb\xbf\xa4\x7e\x42\xa4\x74\x51\x7c\x75\
\xb2\xbb\xfd\x04\x15\xf7\x3b\x7b\x5a\x07\x69\x0f\xed\x22\xfd\xfa\
\x32\xb6\x63\x22\x84\xb0\xa8\x31\x44\x93\x35\x5a\x1d\xb2\x37\x7c\
\x9c\x68\xcb\xa1\x0f\xcf\x3f\x2e\x53\xf1\xca\xf4\x6d\x1d\xe3\xcd\
\xda\x53\xcc\xd2\x1a\x1d\x6a\x37\x6a\xa0\x6d\xc7\xec\xf4\xe4\xb5\
\x2b\x33\xc1\x95\xaa\x90\x7d\xf3\xb3\x04\x1f\xdd\xda\x6c\x3a\x5f\
\x2f\x04\x94\x10\x76\xe5\x1b\x4d\x75\x2d\xe4\x0b\x69\x56\x8d\x5c\
\x66\xe6\xea\xe0\xaa\x5f\x71\x4f\x01\x07\xab\x42\x4a\x7e\xd1\xdf\
\x59\xb0\xe5\xc8\xca\xa7\x03\xfd\xf9\xcf\xe2\xc5\xfb\xdb\xa2\xb9\
\x61\x83\xb8\x9f\xee\x13\xd7\xa7\xc6\x8f\x59\x66\xa3\x04\x58\x8a\
\x8f\xf1\x64\x4e\xc8\x5f\x7d\x3c\x27\x7e\x9f\x18\x58\x02\x14\x60\
\x7c\xa3\x51\x66\xd3\x7c\x92\x73\x13\x31\xde\xbe\xec\x1c\xf2\xf9\
\x9d\x77\x80\x0b\xdc\x50\xc3\x03\x74\x0d\x97\x88\x1c\xd6\xe9\x1a\
\x2e\xa1\x86\x07\xfe\x3a\x0c\x91\x54\xd1\x89\xa4\x8a\xaf\x22\xa9\
\x22\xe1\x29\x0b\xf7\xe1\x08\x46\x36\xb1\x68\x64\x13\x5b\x8c\x6c\
\xc2\x6f\x64\x13\x49\xa3\x90\x21\xb7\x50\x4b\xa8\xed\x28\xb9\x85\
\x5a\x8c\x42\x86\x3f\x4d\xfe\x2b\x3d\x31\x5b\xf4\xc6\xa5\xf0\x81\
\xe8\x8d\x4b\xd1\x13\xb3\x05\xc0\x0f\xce\xca\x2c\x24\xca\x30\x0a\
\xc3\xcf\xf7\x8d\x1b\x86\xa6\x96\x8e\x90\xda\x82\xe9\x58\xa9\x49\
\x26\xa9\x85\x57\x11\x45\x03\x51\xe1\x85\x90\x26\xd5\x85\x68\x0b\
\xe2\x92\x41\x65\x10\x49\x91\x11\x11\x42\x50\x41\x98\x4c\x11\x7a\
\x51\xe0\x46\x4c\x44\x6a\x51\x86\x51\xd9\x45\x25\xe6\x92\x95\xcd\
\x08\x93\xcd\xa8\x33\xfe\xff\xd7\x45\x12\x5a\xfc\x25\x1d\x78\xef\
\xde\xf3\x70\x38\x9c\xe5\x9f\x5b\x39\x1f\x49\x80\x8a\x16\x0b\x4d\
\xbd\xd5\x94\xb7\x24\x26\x57\xb6\xae\x2a\xad\x6c\x4d\x3a\x77\xff\
\x7d\xdd\x89\x8a\xd6\x24\x6b\x59\xf3\xca\x45\xe7\x1f\x6d\x43\x29\
\x1d\xa5\x34\xe3\x39\x11\x42\xd2\x37\xf6\x54\x65\xc5\xe5\xbd\xf4\
\x6a\x9e\x5a\x10\xe5\x9a\x9a\x3e\x25\x10\x77\x4b\x32\x6f\x3b\x0e\
\x65\x35\x2a\x9f\x3e\x69\xf6\x6a\x13\xc6\x10\x20\xcd\xe1\xfe\x40\
\xc7\x40\x3d\xb9\xc9\x35\xf8\xb4\x49\x52\xa2\xb7\x60\xb5\x1c\xa5\
\xb6\xc3\x4a\x55\xdb\x1a\xaa\xda\x52\x9a\x8e\xb5\xaf\x35\x86\xf8\
\xc9\x80\x20\x9f\x36\x81\x9f\x0c\xa0\xa9\xf7\x24\xab\xcd\x9b\xe9\
\x1c\xb8\x49\x63\xef\x49\x96\x86\xa5\x12\xbf\x28\x93\x60\xff\xb0\
\x3e\xa3\x86\x4b\x00\xaf\x36\xf1\x7d\x45\x44\x06\x71\x61\xa9\x4c\
\x4d\x7b\xd8\x97\x7e\x05\x81\x24\x3a\x64\x25\x1f\xbf\xbd\xe1\xad\
\xf3\x51\x76\xf0\x74\x56\x7e\xa8\x67\xaf\x31\x44\x0a\x39\x3e\xe4\
\x7a\xc5\x3b\x47\x17\x09\x8b\x37\xa2\x2b\x8d\x87\xfd\xd7\x70\xba\
\x07\x11\x48\x46\x87\xe2\xbb\xce\x9c\x4d\x2a\xbd\x50\x17\x6e\x0c\
\x59\xb7\x64\x87\x33\x71\xf1\x46\x84\x30\x91\x18\xb9\x89\xab\xdd\
\xfb\x59\x10\x10\x4e\x66\x5c\x1e\x51\x21\xcb\xdd\x4f\x1f\x6c\x41\
\x4a\xbd\x16\x88\x32\x84\x3c\xfe\x7c\x77\xbc\x77\xd4\xce\xfa\x98\
\x9d\x74\x0d\x36\x30\xe9\xfb\x46\x74\x48\x02\x4f\x86\x6e\xe1\x9e\
\x1e\xa8\xff\x38\x1c\xb6\x6c\xc6\xbf\xdb\x10\x72\xb8\x6d\x04\xfc\
\x03\xc5\x8b\x91\x7b\x6c\x4b\x2c\x23\x3f\xed\x32\xc3\xae\xd7\x00\
\x78\x3c\xc1\x45\xd2\xa4\x57\xcf\xf8\xe3\x0c\x21\x93\xfe\xf2\x60\
\x49\xfb\xa7\x08\xdd\xe4\x17\xd4\xf8\xea\x38\xe3\xde\xaf\x08\x21\
\x09\x0c\x9a\xca\xb8\x7e\xf1\x00\x26\x93\x56\x30\xe3\xff\xf2\xb7\
\x39\xd9\x35\xe5\x27\x9c\x45\xf7\x3f\x05\x9a\x47\x46\x45\xec\xc2\
\x14\x31\xd8\x6f\x16\x97\x4e\x1f\x79\xa6\xeb\xb2\x01\xa0\xb9\xb0\
\x84\xe6\x82\x92\x0b\xb3\x4f\x41\x67\xfd\xdc\x53\x10\x04\xe0\x33\
\x09\xd7\xd6\x77\xaa\xeb\x62\x7e\x3a\x2d\x77\x72\x6f\x28\x5d\x2a\
\x20\x0f\x00\x1d\xc2\x63\xad\x84\xc7\x6c\xff\xa9\x58\x2b\xe8\x73\
\x2b\xd9\x00\x2c\x07\x22\x41\x65\x3d\x9f\x4a\x01\x54\x21\xd0\x04\
\x78\x81\x51\x80\x50\x73\x0e\xf1\x39\x36\xe2\x73\x6c\x84\x9a\x73\
\xfe\x78\xc0\x58\x6a\x9c\x1f\x2c\x35\x4e\x87\xa5\xc6\x49\xfd\xed\
\xeb\xb8\xec\xc5\xba\xcb\x5e\xbc\xcb\x65\x2f\x0e\x74\xd9\x8b\xcd\
\x00\xee\xb1\x1e\x94\xee\x43\xe9\x3e\xdc\x63\x3d\x7f\xf4\x64\x5e\
\xe1\xe8\xb7\xd1\x6d\x8b\xa0\xdb\x16\x81\xa3\xdf\xf6\x1f\x10\x09\
\x28\x7d\xd6\x0b\xd4\x7f\x65\xcf\x1b\x92\xbd\x47\x89\xec\x82\xdf\
\xb4\x47\x09\x80\x1f\xb4\x98\x6b\x50\x94\x55\x18\xc7\x7f\xef\x2e\
\x7b\x01\x05\x41\xc1\x44\x16\x49\x2e\x12\x68\x28\x08\x62\xa3\x78\
\x41\x48\x68\xb4\x9c\x21\x31\x9c\x29\x9c\x49\x53\x07\xc2\x48\x89\
\x84\x31\x71\x72\x32\xb5\x72\x4c\xfd\xd0\xc5\xc8\x1c\x86\xc6\xc8\
\xb4\x40\xee\x08\x98\x0a\x78\x4b\xc0\x50\x56\x50\x14\x94\x3b\xbb\
\xe8\xee\xb2\xb0\xbb\x6f\x1f\x62\x1d\xd3\x6c\x06\xc7\xce\x99\xe7\
\xcb\x3b\xe7\xfc\xdf\xdf\x79\xce\x33\xcf\x3c\xcf\x79\x26\x99\xed\
\x99\x65\xc7\xe1\xca\x91\x0f\xf2\x5f\x60\x6b\x49\x28\x85\xea\x7d\
\xb3\xb7\x9f\x0c\xdb\xb7\xf1\x84\x57\xe5\xa6\x13\x3e\xcd\xa9\x05\
\xfe\xda\xd4\x02\xff\xa1\xd4\x02\x7f\x4b\x4a\xbe\xaf\xa5\x48\xfd\
\xe5\xc0\xd6\x92\xd0\x9e\x4d\x27\x7c\x1a\x37\xe4\x4e\xaa\x48\xce\
\xf3\xcc\x4c\x2d\xf0\xdb\x78\xf8\xd2\x86\xb9\xd6\x90\x1b\xe9\xf8\
\x87\x5b\x05\x41\x32\x7a\xc0\x74\xaf\xa9\x48\xbd\xf7\x6c\x8f\xfe\
\x76\xa2\x93\xad\x2a\x2c\x6a\x4a\xf2\x64\x0f\xc7\x40\x87\x41\xb3\
\xde\x06\x10\x2c\xa2\x49\x90\x49\x95\x8a\x00\xd7\xa8\xb1\x5b\xc2\
\x4f\xf9\xec\x8a\xbe\x3a\x2f\x2e\x60\xe7\x2a\xbf\xf1\xe1\x9f\x75\
\xdc\xbf\x7e\xea\xd3\x8a\x48\xc3\xae\xca\xa8\x1d\x3b\x2a\x22\xd8\
\x51\x11\x31\x72\x10\xf1\xef\x19\x08\x78\xda\x48\xe4\xc8\xa5\x76\
\xdc\x33\x76\x91\x77\x6d\x37\x16\x71\x88\x98\xa9\xdb\xe8\x1f\xe8\
\x20\xec\xf9\x55\x2c\xf4\x7c\x07\xc3\xa0\x96\xf4\xa2\x40\xd2\x0a\
\x03\x38\x52\x9f\x4e\x6d\x7b\x01\x77\xfa\x1b\xe8\xd2\x35\xd3\xad\
\xbb\x19\xad\x31\xdc\x11\x34\x86\x3b\x23\x07\x99\xa5\x7a\x9d\x50\
\xd5\x72\x5d\x88\x2a\x06\xef\x71\xb3\x91\x49\x14\x0c\x99\x07\x90\
\x4b\x6d\x51\xf7\x9c\x65\xd0\x3c\xc0\xfe\xd7\xda\xf1\x1a\x3b\x8b\
\xf5\xc7\x9c\xe9\xd0\x35\xb1\xd8\x27\x89\x70\xaf\xb5\x84\xaa\x96\
\x13\xe8\xba\x84\x00\xd7\x28\x4d\x88\x2a\xe6\xe8\x2c\x8f\x25\x6f\
\x7b\xba\xf8\x89\xde\xe3\xa7\x8d\x1c\xe4\x5c\xeb\xcf\xd4\xb4\xe6\
\xe8\x6b\x5a\x73\x86\x1a\x3a\xcb\x31\x9a\xf5\x84\xba\xc7\x32\xed\
\xb9\x48\x8c\x26\x1d\x4a\xd9\x68\x7a\xf5\xad\x74\xe9\x6e\x32\x53\
\xb5\x8c\x5b\x9a\xcb\x54\xdc\xf8\x8e\xca\x1b\x99\x9c\x6f\xfb\x85\
\x2b\x9d\x45\x87\xae\x75\x97\x39\x1d\xc8\xea\x89\x59\x9d\x38\xf9\
\xc2\x86\xa4\x08\x92\x92\x16\x8c\x1c\x44\x10\x24\x08\x82\xa4\x17\
\x51\xec\xb7\x7e\x3b\xdf\x76\x14\x75\xf7\x69\xd6\x87\x66\x11\xe2\
\x16\xc3\x2d\x4d\x2d\xc7\xfe\xfc\x98\xc6\xae\xdf\x91\x08\x12\x6c\
\x65\x63\x70\x73\xf0\x67\x8a\xf3\x1c\x82\x26\x2d\xca\xbc\x5c\xfe\
\x26\xd5\x95\xc1\xcb\x44\x10\x15\x0a\x4b\xa2\x5c\x2e\x3e\x5d\xb0\
\x82\xd8\x25\x95\xc8\xda\x5c\xed\x7d\x09\x75\x8f\xc5\xd7\x79\x1e\
\xbd\x86\x56\xce\xdc\xca\x42\x26\x55\x52\x7c\x7d\x3f\x0e\x4a\x17\
\x96\xfa\x7d\x88\x9f\xcb\x42\xf4\x43\x1a\x6e\xf6\x5d\xa4\xb1\xf7\
\x64\x7d\x79\xdd\xd9\x53\xd5\x17\xec\x50\x2a\x48\x1b\x16\xfb\x08\
\x58\x38\x62\x90\xc9\x1d\x7a\xdc\xbb\x0c\xa2\x45\x34\x4f\xef\x34\
\xb4\xac\x3e\xd7\x9a\x43\x5d\x47\x21\x91\x3e\x89\x38\xd9\xba\xd1\
\xa9\x6b\xe6\x55\xbf\x34\x02\x26\x44\x73\xa4\x2e\x8d\xa6\xde\x1a\
\x6c\x24\x72\x64\x52\x25\x0a\xb9\xf8\x5e\xdd\xf9\x99\x16\xdd\x7d\
\xfb\x37\x04\x89\x25\x64\x58\xd2\x05\x58\x30\x62\x90\xf9\x0d\x5a\
\xe9\xa2\x2b\xda\x71\xeb\x4a\xda\x1d\xe6\x5d\xed\x3f\x68\x92\x48\
\x04\xb9\xcc\xe1\x70\x59\xd3\x57\x0c\x0c\xdd\x63\xfc\x28\x4f\x86\
\xcc\x06\x4e\xb7\x1c\xc6\x4e\xe6\x08\x88\x00\xdd\x0a\xa5\xf1\xc5\
\x3f\xaa\x83\x4a\x2f\x9c\x09\x1e\xab\x50\x18\x3f\x7f\x44\x5f\xfa\
\x34\x57\x33\x09\xd8\x6a\x94\x09\x5a\x9f\x76\x43\x79\x62\xf1\x5d\
\xfb\xb0\xab\xda\xb7\x64\x72\x7b\x49\x55\x67\xee\xcb\x55\x6d\x39\
\x07\x02\x26\x44\x65\x3b\xdb\x79\xec\x97\xd8\xe8\x63\x15\xb6\xc6\
\xd1\x3d\x5d\xe3\x5c\xbe\xfd\x62\x6d\x7d\x69\x5e\x84\x93\x4c\x3e\
\x54\x0d\x4c\x7c\x48\x4f\x0b\x9c\x79\x1a\x90\x95\x40\xac\xd5\x41\
\x46\x1b\xa1\x7f\x4a\xbb\xe1\xd2\xba\x92\xf6\x39\x9b\x4a\x34\xc5\
\x13\xb3\xb6\x25\x36\x56\x1c\x5a\xf9\xeb\xd1\x65\xef\xee\xc9\x48\
\xf9\x69\xf7\xe6\xcd\x76\x47\x0e\xc6\x45\xe8\xee\x8f\x3a\x69\x63\
\x63\xea\x05\xbc\xad\x42\x79\xf1\x89\x14\xae\x49\x1f\x53\xf9\xfe\
\xf7\x79\xb5\xf9\x61\x62\x7d\x51\xa4\x68\x06\xb1\xbe\x28\x52\xac\
\xcd\x0f\x13\x2f\xe7\x86\x88\x55\xd9\x8e\x0f\x1a\x82\x47\x41\x3e\
\x01\x5e\x01\xaa\x80\x01\xc0\x04\xb8\x9b\xa4\x42\xba\x49\x2e\x0b\
\x97\xf4\x37\xb3\xe7\xeb\x52\x2e\xd6\x39\xa1\x90\xf3\x8d\x5c\x69\
\xec\x14\x24\x62\xf1\xbf\xc5\x81\x00\x78\x04\xed\xc4\x7b\x7e\x36\
\x8e\x6e\x8b\x51\x4d\xdf\x02\x80\x6a\xfa\x16\x1c\xdd\x16\xe3\x3d\
\x3f\x1b\x8f\xa0\x9d\x08\x4f\xf0\x88\x08\x5c\x04\x5e\x02\x6c\x87\
\xbb\x15\x67\x20\x1a\x28\x03\x30\x58\x64\xd6\xb5\x6b\x86\xff\xa7\
\x02\x96\x03\x19\xc3\x07\x89\x1f\xde\x43\x5f\x6b\x2e\x2d\x35\xc9\
\xb8\x4e\x4d\xc1\x6c\xd2\x73\xad\x74\x29\x66\x93\x1e\xd7\xa9\x29\
\xb4\xd4\x24\x63\x7d\xce\x78\x0c\x64\xb8\x2a\x79\xa2\xa9\xb6\xeb\
\x38\xf4\x63\xa6\xb5\xf3\xb1\x5a\x9b\xb6\x2c\x21\x47\x5b\x96\xb0\
\x4d\x5b\x96\x90\xae\x2d\x4b\xf8\x41\x5b\x96\xd0\x03\xa0\xb4\xf7\
\x42\x35\x23\x03\x75\xc5\x0a\xcc\x83\x1a\x7c\x17\xfd\x86\x79\x50\
\x83\xba\x62\x05\xaa\x19\x19\x28\xed\xbd\xfe\x2b\x8f\x3c\x9b\x21\
\x02\x77\x1b\xf6\x52\x97\x1b\x4c\xdf\xed\xe3\xa8\x2b\xe3\x00\x50\
\x57\xc6\xd1\x77\xfb\x38\x75\xb9\xc1\xdc\x6d\xd8\x8b\xf8\x7f\x83\
\xcc\x8d\x7f\xbc\x00\xb2\xb6\x78\x0f\xdb\xdc\x78\xf1\x41\x98\xfc\
\x35\x00\xe1\xfe\x7a\x92\x1d\x0a\xb2\xf0\x00\x00\x00\x00\x49\x45\
\x4e\x44\xae\x42\x60\x82\
\x00\x00\x08\xb7\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
\x00\x00\x08\x6e\x49\x44\x41\x54\x58\x85\xc5\x97\x7b\x70\x55\xd5\
\x15\xc6\x7f\x7b\x9f\x73\x6e\x6e\x6e\xde\xb9\x97\x20\x84\x47\x5e\
\x04\x12\x02\x11\x05\x05\x22\x05\x44\x0a\xa2\x28\xd6\xe2\x4c\xa7\
\x75\xa8\x76\xac\xa3\x33\x3a\x63\x67\xb4\xd3\x87\x6d\x1c\x2b\x7d\
\x4d\xff\x68\xcb\xd8\x56\x1d\x29\x76\xaa\x45\xc6\xe7\x0c\xa1\xa9\
\xa0\x11\x5a\x01\x8d\x41\x1e\x01\xcc\x83\x24\x4a\x42\x42\x72\xf3\
\xbc\xaf\xdc\xdc\xb3\x77\xff\x38\xe7\xde\x24\xd5\x19\x69\xa7\x33\
\xee\x99\x35\xe7\xdc\x39\x77\xaf\xf5\x9d\x6f\x7d\x6b\xad\xb3\xe1\
\x4b\x5e\xe2\x4a\xff\xb8\x6e\x5d\xad\xd9\x91\x61\xad\x11\x88\xed\
\x02\xb1\x46\x43\x00\xc8\x71\x1f\x8f\x08\x18\x10\xe8\x23\x36\x7a\
\x5f\x71\x78\xe2\x48\x43\x43\x6d\xe2\xff\x02\xa0\x68\x5b\x6d\xae\
\x18\x4f\xfb\x31\x82\xfb\xca\xe6\xcd\xe0\xc6\x15\xa5\x59\x2b\xaa\
\xe6\x8a\xab\x02\x59\xf8\xb3\xd3\x01\x18\x1c\x8d\xd2\x1b\x1c\xa3\
\xb1\xf9\xa2\x3e\xf4\x41\xfb\x58\x6b\xe7\x65\xd0\x3c\xab\xd3\xc6\
\x7f\xd6\xf9\x7a\xed\xf0\xff\x0c\xa0\x68\xf3\xce\x87\xa5\x21\x9e\
\xdc\x5c\xb3\x28\xfd\xfe\xaf\xaf\xb4\xca\xe7\x05\xae\x88\xb3\xb6\
\x4f\x83\x3c\xf3\xca\xf1\x89\xfd\x87\xcf\x46\x95\x96\x8f\x77\xd6\
\x7d\xff\x77\xff\x15\x80\xa2\x75\xb5\x5e\xed\xf3\xfe\x75\x71\xe9\
\xcc\x4d\x4f\x3e\xf8\xd5\x8c\xca\xe2\x02\x10\x8e\xe3\x7f\x9d\xfc\
\x84\x13\x1f\x5f\x22\x38\x1a\x61\x70\x24\x86\x10\x10\xc8\x4d\xc7\
\x9f\x93\xc1\xb2\xf2\x59\xac\x5e\x3a\x97\x92\x39\xf9\x00\x7c\xdc\
\xd9\xcf\xe3\x4f\xbf\x15\x3e\xdd\xd6\x5b\x4f\x38\xfa\xcd\xce\x86\
\xda\xd8\x17\x02\x58\xbc\xbd\xd6\x13\x0e\xa7\xbd\xbf\x6d\x7d\x55\
\xc5\x4f\xee\xdf\xe0\x49\xf7\x58\xb4\x7e\x1a\xe4\xb9\x37\x1a\x69\
\x3c\xdb\x8d\x34\x24\x86\x94\x08\x21\x90\x52\x20\x10\x29\x2f\x5a\
\x6b\xb4\xd6\x2c\xaf\x28\x64\xc7\x2d\x57\x53\x3a\x27\x9f\x58\x3c\
\xc1\x53\xcf\xbe\x1d\x7f\xe5\xd0\xe9\x73\x3e\x5f\xec\xba\xe6\x7d\
\xb5\xf1\xa9\xf1\x8c\xe9\xe1\xb5\xc8\x2c\x3e\xf6\xea\xb6\x1b\xab\
\x56\xee\x7c\x68\x53\x9a\x65\x1a\xbc\xde\x70\x96\x27\x9e\x7b\x9b\
\x4b\x03\x21\x4c\xd3\xc0\x9a\x62\xa6\x61\x60\x9a\x06\x86\x29\x31\
\x0c\x89\x69\x18\x48\x43\x72\x29\x18\xe2\xad\xe3\xed\x64\xf9\xd2\
\xa8\x2c\x9e\xc1\x8d\x2b\x4a\x8d\xbe\xa1\x70\xde\xc9\x96\x81\x6b\
\x86\x5b\x0e\xee\x85\x27\x3e\x1f\x40\xf1\x16\xef\xa3\xab\xae\x2e\
\xba\xf7\x37\x8f\xdc\x92\x6e\x18\x92\xdf\xef\x3d\xca\x9e\xfd\x1f\
\x61\x18\x06\xa6\x69\x62\x59\x6e\x70\xcb\xf9\x6d\x9a\xc6\xa4\x49\
\x03\xc3\x65\xc7\x30\x24\x00\x8d\xe7\x7b\x08\x45\xe2\x5c\x5b\x31\
\x9b\x35\xcb\x8a\xcd\x33\xed\x7d\x73\x43\xd9\xfb\xe3\x43\x2d\x07\
\xdf\xfb\x4c\x0a\x0a\xef\xd8\xe9\xcf\xd4\x56\xcb\x9b\xbf\xfd\x76\
\xfe\xbc\x99\xb9\xbc\x54\x7f\x92\xe7\xde\xf8\x10\xd3\x32\xa7\xbc\
\xad\x64\x69\xd9\x0c\x96\x94\x14\x50\x51\x14\xa0\x20\xcf\x47\x6e\
\x56\x3a\xe3\xf1\x04\x7d\x83\x61\x9a\x5a\xfa\xa8\x3f\xde\x41\x28\
\x1a\xc7\x56\x0a\xdb\x56\x24\x6c\xc5\xdd\x9b\x97\x72\xe7\xfa\x0a\
\x2e\x5e\x1e\x65\xeb\xc3\xbb\x07\x47\x89\x97\x77\xbf\xf6\xc3\xe0\
\x34\x06\xfc\xa5\x37\xed\xba\xe7\xf6\xe5\xd7\xdf\xbc\x7a\xa1\x3c\
\x73\xa1\x8f\x9f\xef\x39\x8c\x69\x18\x58\x2e\x00\xcb\x72\xee\x7f\
\xfd\xc0\x57\x58\x34\xdf\xcf\x8c\x5c\x1f\x3e\xaf\x07\xc3\x90\xa4\
\x79\x4c\xf2\xb2\xbc\x2c\x9a\x9f\xcf\xaa\xaa\xd9\x9c\x6a\xef\x27\
\x16\xb7\x1d\x9d\x00\xa7\xda\xfb\xa8\x2e\x9b\x49\x49\x61\x1e\x13\
\xb6\xf2\x9c\x38\xdd\x5d\x30\xd4\x72\xf0\x4d\x00\x09\xb0\x78\x5d\
\x6d\xa6\x65\xca\xbb\xee\xb9\x6d\x85\xa1\xd1\x3c\xbd\xef\x38\x52\
\xc8\x69\x14\x3b\x40\x4c\x84\x10\x08\xe1\x10\x17\x4f\x28\xe2\x09\
\x85\x94\x12\xe9\x0a\x33\x3f\xcb\xcb\xf6\xf5\x0b\xb1\x2c\x13\x8f\
\x65\x62\x59\x26\x86\x34\xd8\xbd\xff\x23\x34\x70\xf7\x96\x6b\x0c\
\xd3\x34\xee\x5a\xbc\xae\x36\x13\xc0\x04\x88\xf8\xbc\x5b\xd6\x5e\
\x5d\x2c\xf3\xb3\xd3\x39\xd5\xd6\x4b\xcb\x27\x41\x3c\x1e\x73\x8a\
\xe8\xdc\x34\x98\x06\x09\x5b\x71\xfc\x7c\x3f\xef\x35\xf7\xd2\x3b\
\x14\xc1\x10\x82\x0d\xcb\xe7\x73\x7b\x4d\x69\x0a\x5c\xe5\x7c\x3f\
\x1e\xcb\x24\x21\x6d\x5c\xac\x74\x74\x0f\x73\xae\x73\x80\xca\xa2\
\x00\x6b\xaf\x2d\x91\x07\x8f\xb6\x6e\x01\x5e\x96\x8e\xf6\xf5\x8e\
\x9b\xae\x5b\xe0\x43\xc0\x91\x8f\xba\x1c\x31\x19\x4e\xde\x0d\x37\
\xf7\x49\x30\xbf\x78\xe9\x04\xaf\xfd\xf3\x02\x03\xa3\xe3\xa4\x79\
\x2c\x2c\x8f\xc5\xd9\xae\x41\xb4\xd6\x29\x31\x4b\x49\x8a\xb1\xa9\
\x2c\xbe\xdf\xdc\x0d\xc0\xc6\x95\xe5\x3e\x21\xc5\x8e\x14\x03\x68\
\x96\x55\x95\xcd\x04\xa0\xf5\x93\xe0\x34\x35\x9b\xc6\x64\x2a\x2c\
\xd3\x24\x34\x6e\x63\x59\xa6\x0b\x4e\x22\xa5\x60\xcd\x92\xc2\x54\
\x0f\xd0\x5a\x73\xb1\x3f\x8c\x65\x19\xae\x6b\x8d\xd6\xa0\x94\xe6\
\xc2\xa5\x21\x00\x2a\x4b\x0a\xd0\x5a\x2f\x9b\x04\x20\xf0\x17\xe4\
\x67\x02\x4e\x5f\x97\x6e\xf0\xa9\xe6\x00\x91\x93\x3d\xc0\xb5\x9a\
\xc5\x57\xb1\xaa\x72\x66\x2a\xb8\xad\x14\xef\x9e\xee\xc3\x32\x0d\
\xd0\x4e\x73\x52\x4a\x63\x18\x92\x91\xd0\x38\x08\xc1\x8c\xdc\x0c\
\x34\xda\x3f\x95\x01\xf2\xdc\xc1\x32\x16\x89\xbb\xa2\x12\x93\x40\
\xa4\x93\x12\xc3\x6d\x3c\xc9\xd2\x5c\xbb\x74\x16\x6b\x16\x4f\x09\
\x6e\xdb\x1c\x68\xec\xa6\x67\x30\x8a\x69\x18\x4e\x60\x25\x31\x6c\
\xc7\x4f\x24\xe6\x0c\xc8\x9c\xcc\xb4\x54\xfd\xcb\x64\x37\x18\x1a\
\x8d\xba\x0f\xbd\x48\x21\xa6\x9b\x94\x18\x52\x4c\x63\xa3\xba\x38\
\x9f\xd5\x8b\x02\x28\xa5\x50\x4a\x61\xdb\x36\x75\x1f\x5e\xe2\xe3\
\xee\x31\xb7\x3b\x4e\x6f\x4c\x52\x0a\xb2\x33\xbd\x00\x8c\x84\xc7\
\x53\x2d\x48\x02\x08\x4d\xb0\x7f\x28\x0c\x40\x20\xcf\x87\x10\x38\
\x8a\x96\x8e\x49\x29\x10\x2e\x2b\x49\x87\xd7\x2f\xf4\xa7\x82\x2b\
\xa5\x38\xd6\x32\x44\x57\x7f\xd4\x65\xca\x01\x9c\x64\x52\xb8\x2f\
\x92\x9f\xed\x00\x08\x0e\x47\x10\x10\x9c\x04\x20\xe4\x89\xe6\x0b\
\x97\x01\x58\x38\x2f\xe0\xd4\xb9\x10\x08\x40\x20\xdc\xf2\x22\x55\
\x66\x52\x08\xb2\xd3\x8d\x14\xf5\x4a\x29\xda\xfa\x22\x29\x86\xa4\
\x10\x08\x91\xbc\x3a\x7b\x11\x82\x92\xd9\x79\x00\x9c\xeb\xec\x47\
\x48\x79\x22\xa5\x01\xad\xf5\x9e\x43\xc7\xdb\xd6\xdd\xb1\xbe\xd2\
\x57\xb3\x74\x2e\x07\x8e\xb6\x4d\xf6\x68\x91\xbc\x4c\x19\x9c\x42\
\xf0\x87\xfa\x0e\xd2\x3c\x16\x1e\x8f\x85\xc7\x63\xa2\x34\xa9\x06\
\xe5\xe2\x9f\xb2\x9c\xdd\xcb\x17\xcd\x02\xe0\xad\x63\xad\x11\x65\
\xab\x3d\x29\x00\xbe\x48\xac\xee\x48\xd3\x05\x35\x3c\x16\xa3\xb2\
\xa4\x80\x05\xf3\xfc\x74\xf5\x8e\x90\x14\x68\xf2\x4d\xd1\xc9\xb2\
\xd2\xec\x58\x3b\x27\x35\x92\x01\x5e\x3e\xd6\x8f\x52\xca\x61\x24\
\xb9\x07\x8d\x76\x9d\x14\xcd\xca\x61\xc1\x9c\x7c\x46\x43\xe3\xbc\
\xf3\x7e\xab\xf2\x45\x62\x75\xa9\x14\x34\x37\xd4\x86\x12\x09\xb5\
\xf7\x2f\x75\x4d\xb6\x00\xee\xbd\x75\x19\x42\x08\xd7\x99\x53\xc7\
\xc9\x7b\xa5\x34\xca\x56\x58\x06\x58\x06\x98\xd2\xb1\xf8\x44\x82\
\x89\x84\x4d\xc2\x56\x28\x5b\x39\xff\x53\x1a\xad\x1c\xe0\x77\xad\
\xaf\x00\x01\x7f\xfb\xc7\x49\xdb\xb6\xd5\xde\xe6\x86\xda\xd0\x64\
\x15\x00\xf1\x84\xf5\xd8\xee\xd7\x3e\x18\xee\xee\x1f\x63\xd1\x7c\
\x3f\xdf\xd8\x58\xe5\x04\x57\x4e\x8e\xed\xe4\xd5\x9d\x70\x53\x05\
\xa8\x94\x22\x3e\x31\xc1\xc4\x84\x4d\x22\x61\x93\xb0\x6d\x6c\xdb\
\x4e\x3d\xdb\x5a\x53\x46\x69\x61\x2e\x7d\xc1\x10\x7f\xda\x77\x6c\
\x38\x16\xb7\x1e\x4b\xc6\x4d\x4d\xc3\xd1\xf6\xfa\x68\x4e\xd9\x06\
\xdd\xd1\x33\x5c\xb3\xb9\xa6\xdc\xaa\x2c\x0a\x10\x8e\x4d\xd0\xde\
\x3d\xe4\x28\x5a\x48\xa7\x22\x84\x93\xd1\x6b\x4a\x73\xb1\xb5\x26\
\x61\x3b\xa0\x3e\x68\x1b\x26\x61\x2b\x07\x80\xcb\xc4\x44\xc2\xe6\
\x86\x25\x85\x6c\x5d\x5d\x4a\xc2\x56\xfc\x60\x57\x7d\xa4\xad\xab\
\xff\xa9\xae\x03\x8f\x1e\xfa\x0f\x89\x25\x97\x16\xa5\xb7\xfe\xea\
\xf5\xed\x9b\xaa\x37\xfd\xf4\xbb\x1b\xd2\x84\x10\x1c\x6a\xec\x60\
\xef\xa1\x73\x48\x29\xdd\xe9\x96\xfc\x18\x71\x9b\x93\x5b\x66\x5a\
\x83\xd2\x0e\xfd\x09\x37\x05\xb7\xad\x2e\xe1\x86\x25\x85\x68\x60\
\xe7\xf3\x0d\xe3\x2f\xd6\x35\xd5\xb7\xbd\xf9\xe8\x36\x10\xfa\x33\
\x0c\x38\xeb\x09\x66\x57\xdf\xf0\xea\xc9\xf3\x03\x5b\x07\x46\xa2\
\x81\x55\x4b\xe7\x19\x0b\xe6\xfa\xa9\x2e\x2b\x20\x38\x1a\xa5\x6f\
\x28\xe2\x40\x76\xb7\x27\xf3\x3c\xf5\xe3\x23\x61\xdb\x2c\x28\xcc\
\xe5\x5b\x1b\x2b\xa8\x2a\x0e\x30\x3e\x61\xf3\xcb\x17\x0e\xc7\x5f\
\xac\x6b\x3a\x93\x96\x16\xd9\xdc\x7f\x76\xbd\x3d\xbd\x3e\x3e\x67\
\xcd\x59\xf5\x48\xba\x95\x1f\x78\xa9\xba\x7c\xce\xc6\xa7\x1e\xba\
\xd9\x57\xea\x7e\xe5\x5e\xbc\x3c\xca\xa9\xf6\x7e\x5a\xbb\x87\x18\
\x0b\x4f\x30\x16\x8b\x23\x85\x20\x27\xd3\x4b\x8e\x2f\x8d\xb2\xc2\
\x5c\xaa\x8a\xfd\xcc\x0e\x38\x73\xa5\xe3\xd2\x30\x3f\xda\xf5\xf7\
\x68\x53\xf3\x85\x77\x7b\x8f\xbd\x70\x5f\x74\xb0\x2d\x08\x44\xbf\
\x10\x00\xe0\x03\xb2\x0b\xd7\x7e\xef\x41\x6f\x76\xe0\x91\x3b\x37\
\x2c\xf3\x7e\xe7\x6b\x2b\xcc\xf9\x57\xe5\x5e\xd1\x51\xea\xd3\xcb\
\xa3\x3c\xff\x46\x63\xe2\xe5\x03\x1f\x8e\x47\x83\x5d\xcf\x74\x1f\
\xfd\xe3\x6e\x60\xcc\xb5\x21\x40\x7d\x11\x80\x34\x20\x0b\xc8\x4a\
\x2f\x28\x9d\xed\xaf\xdc\xf6\x80\x95\xe1\xdf\x56\x55\x3a\x4b\x6c\
\x5e\x53\x99\x7e\x6d\x45\xa1\x98\x91\xe7\x23\x27\xc3\x0b\x02\x46\
\x43\xe3\x0c\x8c\x44\x68\x3a\xdf\xa3\xeb\x0e\x37\xc7\xce\xb4\xf6\
\xe8\xd8\x58\x4f\x7d\xf0\xd4\xab\x7f\x1e\x1f\xee\xe9\x75\x03\x87\
\x80\x41\x20\x7c\x25\x0c\x80\x53\xa2\x19\x40\x36\x90\x61\x59\xbe\
\xac\xec\xf2\x8d\x2b\x7d\x05\x0b\x36\x5a\xe9\xd9\xd5\x60\xe4\x68\
\x21\x7d\x8e\x13\x15\x45\xdb\xa3\xf1\xf0\xd0\x99\x48\xdf\xf9\x77\
\x46\xdb\xde\x69\x4a\x24\x62\x21\x1c\xba\x43\xc0\xb0\x0b\xe2\x33\
\xe7\xc5\x2b\x3d\x9c\x1a\x80\x05\x78\x5d\x76\xbc\x38\x5d\xd4\x72\
\x81\x2a\xc0\x06\xe2\xae\xc5\x80\x71\xf7\xfe\x8a\x0e\xa9\x5f\xda\
\xfa\x37\x3d\x87\xb9\xea\xf9\xa4\xbb\x03\x00\x00\x00\x00\x49\x45\
\x4e\x44\xae\x42\x60\x82\
"
qt_resource_name = b"\
\x00\x07\
\x07\x3b\xe0\xb3\
\x00\x70\
\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x73\
\x00\x05\
\x00\x49\xc3\x81\
\x00\x43\
\x00\x65\x00\x6e\x00\x52\x00\x61\
\x00\x0e\
\x09\x71\xe2\xe7\
\x00\x70\
\x00\x61\x00\x67\x00\x65\x00\x5f\x00\x61\x00\x6a\x00\x6f\x00\x75\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0c\
\x0a\x09\xe1\x87\
\x00\x70\
\x00\x61\x00\x67\x00\x65\x00\x5f\x00\x6e\x00\x65\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x08\
\x0c\x33\x5a\x87\
\x00\x68\
\x00\x65\x00\x6c\x00\x70\x00\x2e\x00\x70\x00\x6e\x00\x67\
"
qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x14\x00\x02\x00\x00\x00\x03\x00\x00\x00\x03\
\x00\x00\x00\x24\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x15\x6e\
\x00\x00\x00\x64\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x49\
"
qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x14\x00\x02\x00\x00\x00\x03\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x24\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x48\x3f\x38\x20\x60\
\x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x15\x6e\
\x00\x00\x01\x48\x3f\x38\x20\x60\
\x00\x00\x00\x64\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x49\
\x00\x00\x01\x48\x3f\x38\x20\x60\
"
qt_version = [int(v) for v in QtCore.qVersion().split('.')]
if qt_version < [5, 8, 0]:
rcc_version = 1
qt_resource_struct = qt_resource_struct_v1
else:
rcc_version = 2
qt_resource_struct = qt_resource_struct_v2
def qInitResources():
QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
def qCleanupResources():
QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
qInitResources()
+34
View File
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
table_postgisDialog
A QGIS plugin
table_postgis
-------------------
begin : 2013-10-15
copyright : (C) 2013 by gcostes
email : sfdg
***************************************************************************/
/***************************************************************************
* *
* 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 qgis.PyQt import QtCore, QtGui
from qgis.PyQt.QtWidgets import QDialog
from .ui_table_postgis import Ui_table_postgis
# create the dialog for zoom to point
class table_postgisDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
# Set up the user interface from Designer.
self.ui = Ui_table_postgis()
self.ui.setupUi(self)
+21
View File
@@ -0,0 +1,21 @@
from qgis.core import QgsApplication
def gitea():
file_url = QgsApplication.qgisSettingsDirPath()+'QGIS/QGIS3.ini'
recherche_1 = 'plugin_repositories\\github\\url=https://github.com/CEN-Rhone-Alpes/Plugin_QGIS/releases/latest/download/plugins.xml'
replace_1 = 'plugin_repositories\\gitea\\url=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
recherche_2 = 'github'
replace_2 = 'gitea'
# Read in the file
with open(file_url, 'r') as file:
filedata = file.read()
# Replace the target string
filedata = filedata.replace(recherche_1, replace_1)
filedata = filedata.replace(recherche_2, replace_2)
# Write the file out again
with open(file_url, 'w') as file:
file.write(filedata)
+172
View File
@@ -0,0 +1,172 @@
import sys
import socket
import os
IPAddr=socket.gethostbyname(socket.gethostname())
if IPAddr[0:11] == "100.100.100": #4269
host = "100.100.100.11"
port = "5432"
dbname = "sig4269"
sigdb="sig4269"
refdb="ref_geo4269"
password = "McVities"
if IPAddr[0:9] == "192.168.0": #01
host = "192.168.0.201"
port = "5432"
dbname = "sig01"
sigdb="sig01"
refdb="ref_geo01"
password = "McVities"
if IPAddr[0:9] == "192.168.1": #0726
host = "192.168.1.201"
port = "5432"
dbname = "sig0726"
sigdb="sig0726"
refdb="ref_geo0726"
password = "McVities"
if sys.platform == 'linux':
os_user = os.environ['USER']
else:
os_user = os.environ['USERNAME']
if os_user == 'STAGE':
os_user='stage'
geom = "geom"
champ_travaux_prevus_multipolygon="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, surface_m2 double precision, surface_ha double precision, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_travaux_prevus_multilinestring="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, longueur_m double precision, longueur_km double precision, date_creation date, date_maj date, geom geometry(MultiLineString,2154))"""
champ_travaux_prevus_point = """(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, x_wgs84 double precision, y_wgs84 double precision, date_creation date, date_maj date, geom geometry(Point,2154))"""
champ_viergePolygone = """(gid serial NOT NULL, commentaire text, surface_m2 double precision, surface_ha double precision, geom geometry(MultiPolygon,2154))"""
champ_viergeLigne = """(gid serial NOT NULL, commentaire text, longueur_m double precision, longueur_km double precision, geom geometry(MultiLineString,2154))"""
champ_viergePoint = """(gid serial NOT NULL, commentaire text, x_wgs84 double precision, y_wgs84 double precision, geom geometry(Point,2154))"""
champ_habitat = """(gid serial NOT NULL, cd_cb_01 text, lb_cb97_fr_01 text, occupation_01 integer, cd_cb_02 text, lb_cb97_fr_02 text, occupation_02 integer, cd_cb_03 text, lb_cb97_fr_03 text, occupation_03 integer, milieu_code text, milieu_libelle text, surface_m2 double precision, surface_ha double precision, commentaire text, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_contour="""(gid serial NOT NULL, date_creation date, date_maj date, utilisateur character varying, dept character(2), nom character varying, surface_m2 double precision, surface_ha double precision, type_site character varying, type_milieu character varying, date_premier_pg integer, date_debut_pg integer, date_fin_pg integer, referent character varying, gestion_deleguee character varying, terrain_militaire character(3), ens character(3), zh character(3), adapt_pmr character(3), inform character(3), guide character(3), ouverture_public character(3), obs character(3), anim character(3), n2000_anim character(3), contrat_n2000_conseil character(3), n2000_op character(3), contrat_n2000_benef character(3), contrat_agri character(3), bc_habitat integer, bc_amphibien integer, bc_coleoptere integer, bc_crustace integer, bc_mammifere integer, bc_chiroptere integer, bc_mollusque integer, bc_odonate integer, bc_oiseau integer, bc_orthoptere integer, bc_poisson integer, bc_reptile integer, bc_rhopalocere integer, bc_heterocere integer, bc_autre_invertebre integer, bc_flore integer, bc_bryophyte integer, bc_champignon integer, suiv_analyse_sol character(3), suiv_piezo character(3), suiv_climat character(3), suiv_topo character(3), suiv_habitat character(3), suiv_amphibien character(3), suiv_coleoptere character(3), suiv_crustace character(3), suiv_mammifere character(3), suiv_chiroptere character(3), suiv_mollusque character(3), suiv_odonate character(3), suiv_oiseau character(3), suiv_orthoptere character(3), suiv_poisson character(3), suiv_reptile character(3), suiv_rhopalocere character(3), suiv_heterocere character(3), suiv_autre_invertebre character(3), suiv_flore character(3), suiv_bryophyte character(3), suiv_champignon character(3), suiv_analyse_eau character(3), suiv_phenologie character(3), suiv_frequentation character(3), suiv_paysager character(3), suiv_autre character(3), commentaire text, geom geometry(MultiPolygon,2154))
"""
champ_vegethab_point = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
x_wgs84 double precision,
y_wgs84 double precision,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(Point,2154)
)
"""
champ_vegethab_multilinestring = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
longueur_m double precision,
longueur_km double precision,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiLineString,2154)
)
"""
champ_vegethab_multipolygon = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiPolygon,2154)
)
"""
+183
View File
@@ -0,0 +1,183 @@
"""Tools to work with resource files."""
import configparser
import shutil
import tempfile
import base64
import psycopg2
import psycopg2.extras
from os.path import abspath, join, pardir, dirname
from qgis.PyQt import uic
__copyright__ = "Copyright 2019, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
__revision__ = "$Format:%H$"
def plugin_path(*args):
"""Get the path to plugin root folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the plugin path.
:rtype: str
"""
path = dirname(dirname(__file__))
path = abspath(abspath(join(path, pardir)))
for item in args:
path = abspath(join(path, item))
return path
def plugin_name():
"""Return the plugin name according to metadata.txt.
:return: The plugin name.
:rtype: basestring
"""
metadata = metadata_config()
name = metadata["general"]["name"]
return name
def metadata_config() -> configparser:
"""Get the INI config parser for the metadata file.
:return: The config parser object.
:rtype: ConfigParser
"""
path = plugin_path("metadata.txt")
config = configparser.ConfigParser()
config.read(path, encoding='utf8')
return config
def plugin_test_data_path(*args, copy=False):
"""Get the path to the plugin test data path.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:param copy: If the file must be copied into a temporary directory first.
:type copy: bool
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "test", "data")))
for item in args:
path = abspath(join(path, item))
if copy:
temp = tempfile.mkdtemp()
shutil.copy(path, temp)
return join(temp, args[-1])
else:
return path
def resources_path(*args):
"""Get the path to our resources folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_Metabase\\resources")))
for item in args:
path = abspath(join(path, item))
return path
def load_ui(*args):
"""Get compile UI file.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Compiled UI file.
"""
ui_class, _ = uic.loadUiType(resources_path("ui", *args))
return ui_class
def login_base(take=None):
from CenRa_Metabase.resources.PythonSQL import host,port,dbname,password,os_user
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()
if take:
return cur,con
else:
return cur
def send_issues(url,titre,body,labels):
import requests
import json
import os
import qgis
usr = os.environ['USERNAME']
token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
url=url+'?token='+token
headers = {'Authorization': 'token ' + token,'accept': 'application/json','Content-Type': 'application/json'}
payload = {'title': titre, 'body': body, 'labels': labels}
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
r = ''
if binar:
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r
def maj_verif(NAME):
import qgis
import urllib.request
iface = qgis.utils.iface
from qgis.core import Qgis
url = qgis.utils.pluginMetadata(NAME,'repository')
#URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/releases/plugins.xml'
# print(URL)
version = qgis.utils.pluginMetadata(NAME,'version')
len_version = len(version)
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
if binar:
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>',plugin_num)+9
version_plugin = version_web[valeur_version_web:valeur_version_web+len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
def devlog(NAME):
import qgis
devmaj = '<head><style>* {margin:0; padding:0; }</style></head>'
devmaj = devmaj+qgis.utils.pluginMetadata(NAME,'changelog')
return devmaj
+350
View File
@@ -0,0 +1,350 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_cenra.ui'
#
# Created: Fri Aug 29 15:27:40 2014
# by: PyQt4 UI code generator 4.9.6
#
# WARNING! All changes made in this file will be lost!
from builtins import object
from qgis.PyQt import QtCore, QtGui
from qgis.PyQt.QtWidgets import *
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QApplication.translate(context, text, disambig)
class Ui_cenra(object):
def setupUi(self, cenra):
cenra.setObjectName(_fromUtf8("cenra"))
cenra.resize(533, 565)
self.buttonBox = QDialogButtonBox(cenra)
self.buttonBox.setGeometry(QtCore.QRect(350, 530, 171, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.Titre = QLabel(cenra)
self.Titre.setGeometry(QtCore.QRect(40, 10, 441, 31))
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.Titre.setFont(font)
self.Titre.setObjectName(_fromUtf8("Titre"))
self.groupBox = QGroupBox(cenra)
self.groupBox.setGeometry(QtCore.QRect(10, 50, 511, 121))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox.setFont(font)
self.groupBox.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.horizontalLayoutWidget = QWidget(self.groupBox)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 126, 31))
self.horizontalLayoutWidget.setObjectName(_fromUtf8("horizontalLayoutWidget"))
self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setMargin(0)
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.label_dept = QLabel(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_dept.setFont(font)
self.label_dept.setObjectName(_fromUtf8("label_dept"))
self.horizontalLayout.addWidget(self.label_dept)
self.dept = QComboBox(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.dept.setFont(font)
self.dept.setObjectName(_fromUtf8("dept"))
self.dept.addItem(_fromUtf8(""))
self.dept.setItemText(0, _fromUtf8(""))
self.dept.addItem(_fromUtf8(""))
self.dept.addItem(_fromUtf8(""))
self.dept.addItem(_fromUtf8(""))
self.dept.addItem(_fromUtf8(""))
self.dept.addItem(_fromUtf8(""))
self.dept.addItem(_fromUtf8(""))
self.dept.addItem(_fromUtf8(""))
self.horizontalLayout.addWidget(self.dept)
self.horizontalLayoutWidget_2 = QWidget(self.groupBox)
self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(20, 50, 481, 31))
self.horizontalLayoutWidget_2.setObjectName(_fromUtf8("horizontalLayoutWidget_2"))
self.horizontalLayout_2 = QHBoxLayout(self.horizontalLayoutWidget_2)
self.horizontalLayout_2.setMargin(0)
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.label_nom = QLabel(self.horizontalLayoutWidget_2)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_nom.setFont(font)
self.label_nom.setObjectName(_fromUtf8("label_nom"))
self.horizontalLayout_2.addWidget(self.label_nom)
self.nom = QLineEdit(self.horizontalLayoutWidget_2)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.nom.setFont(font)
self.nom.setObjectName(_fromUtf8("nom"))
self.horizontalLayout_2.addWidget(self.nom)
self.horizontalLayoutWidget_3 = QWidget(self.groupBox)
self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(20, 80, 479, 31))
self.horizontalLayoutWidget_3.setObjectName(_fromUtf8("horizontalLayoutWidget_3"))
self.horizontalLayout_3 = QHBoxLayout(self.horizontalLayoutWidget_3)
self.horizontalLayout_3.setMargin(0)
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
self.label_2 = QLabel(self.horizontalLayoutWidget_3)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.horizontalLayout_3.addWidget(self.label_2)
self.label = QLabel(self.horizontalLayoutWidget_3)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label.setFont(font)
self.label.setObjectName(_fromUtf8("label"))
self.horizontalLayout_3.addWidget(self.label)
self.horizontalLayoutWidget_6 = QWidget(self.groupBox)
self.horizontalLayoutWidget_6.setGeometry(QtCore.QRect(339, 20, 161, 31))
self.horizontalLayoutWidget_6.setObjectName(_fromUtf8("horizontalLayoutWidget_6"))
self.horizontalLayout_6 = QHBoxLayout(self.horizontalLayoutWidget_6)
self.horizontalLayout_6.setMargin(0)
self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6"))
self.at = QCheckBox(self.horizontalLayoutWidget_6)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.at.setFont(font)
self.at.setObjectName(_fromUtf8("at"))
self.horizontalLayout_6.addWidget(self.at)
self.groupBox_2 = QGroupBox(cenra)
self.groupBox_2.setGeometry(QtCore.QRect(10, 190, 511, 241))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_2.setFont(font)
self.groupBox_2.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
self.gridLayoutWidget = QWidget(self.groupBox_2)
self.gridLayoutWidget.setGeometry(QtCore.QRect(20, 30, 162, 141))
self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget"))
self.gridLayout = QGridLayout(self.gridLayoutWidget)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.couche_habitat = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_habitat.setFont(font)
self.couche_habitat.setObjectName(_fromUtf8("couche_habitat"))
self.gridLayout.addWidget(self.couche_habitat, 1, 0, 1, 1)
self.couche_contour = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_contour.setFont(font)
self.couche_contour.setObjectName(_fromUtf8("couche_contour"))
self.gridLayout.addWidget(self.couche_contour, 0, 0, 1, 1)
self.annee_4 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_4.setFont(font)
self.annee_4.setAlignment(QtCore.Qt.AlignCenter)
self.annee_4.setObjectName(_fromUtf8("annee_4"))
self.gridLayout.addWidget(self.annee_4, 4, 1, 1, 1)
self.couche_travaux_prevus = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_travaux_prevus.setFont(font)
self.couche_travaux_prevus.setObjectName(_fromUtf8("couche_travaux_prevus"))
self.gridLayout.addWidget(self.couche_travaux_prevus, 3, 0, 1, 1)
self.annee_5 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_5.setFont(font)
self.annee_5.setAlignment(QtCore.Qt.AlignCenter)
self.annee_5.setObjectName(_fromUtf8("annee_5"))
self.gridLayout.addWidget(self.annee_5, 3, 1, 1, 1)
self.couche_vierge = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge.setFont(font)
self.couche_vierge.setObjectName(_fromUtf8("couche_vierge"))
self.gridLayout.addWidget(self.couche_vierge, 4, 0, 1, 1)
self.annee_1 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_1.setFont(font)
self.annee_1.setAlignment(QtCore.Qt.AlignCenter)
self.annee_1.setObjectName(_fromUtf8("annee_1"))
self.gridLayout.addWidget(self.annee_1, 0, 1, 1, 1)
self.annee_2 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_2.setFont(font)
self.annee_2.setAlignment(QtCore.Qt.AlignCenter)
self.annee_2.setObjectName(_fromUtf8("annee_2"))
self.gridLayout.addWidget(self.annee_2, 1, 1, 1, 1)
self.horizontalLayoutWidget_4 = QWidget(self.groupBox_2)
self.horizontalLayoutWidget_4.setGeometry(QtCore.QRect(50, 170, 451, 31))
self.horizontalLayoutWidget_4.setObjectName(_fromUtf8("horizontalLayoutWidget_4"))
self.horizontalLayout_4 = QHBoxLayout(self.horizontalLayoutWidget_4)
self.horizontalLayout_4.setMargin(0)
self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
self.label_nom_couche_vierge = QLabel(self.horizontalLayoutWidget_4)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_nom_couche_vierge.setFont(font)
self.label_nom_couche_vierge.setObjectName(_fromUtf8("label_nom_couche_vierge"))
self.horizontalLayout_4.addWidget(self.label_nom_couche_vierge)
self.nom_couche_vierge = QLineEdit(self.horizontalLayoutWidget_4)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.nom_couche_vierge.setFont(font)
self.nom_couche_vierge.setObjectName(_fromUtf8("nom_couche_vierge"))
self.horizontalLayout_4.addWidget(self.nom_couche_vierge)
self.horizontalLayoutWidget_5 = QWidget(self.groupBox_2)
self.horizontalLayoutWidget_5.setGeometry(QtCore.QRect(50, 200, 341, 31))
self.horizontalLayoutWidget_5.setObjectName(_fromUtf8("horizontalLayoutWidget_5"))
self.horizontalLayout_5 = QHBoxLayout(self.horizontalLayoutWidget_5)
self.horizontalLayout_5.setMargin(0)
self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5"))
self.label_geom_couche_vierge = QLabel(self.horizontalLayoutWidget_5)
self.label_geom_couche_vierge.setMinimumSize(QtCore.QSize(152, 0))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_geom_couche_vierge.setFont(font)
self.label_geom_couche_vierge.setObjectName(_fromUtf8("label_geom_couche_vierge"))
self.horizontalLayout_5.addWidget(self.label_geom_couche_vierge)
self.couche_vierge_point = QRadioButton(self.horizontalLayoutWidget_5)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge_point.setFont(font)
self.couche_vierge_point.setObjectName(_fromUtf8("couche_vierge_point"))
self.horizontalLayout_5.addWidget(self.couche_vierge_point)
self.couche_vierge_ligne = QRadioButton(self.horizontalLayoutWidget_5)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge_ligne.setFont(font)
self.couche_vierge_ligne.setObjectName(_fromUtf8("couche_vierge_ligne"))
self.horizontalLayout_5.addWidget(self.couche_vierge_ligne)
self.couche_vierge_polygone = QRadioButton(self.horizontalLayoutWidget_5)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge_polygone.setFont(font)
self.couche_vierge_polygone.setObjectName(_fromUtf8("couche_vierge_polygone"))
self.horizontalLayout_5.addWidget(self.couche_vierge_polygone)
self.label_3 = QLabel(self.groupBox_2)
self.label_3.setGeometry(QtCore.QRect(320, 60, 60, 29))
self.label_3.setObjectName(_fromUtf8("label_3"))
self.label_4 = QLabel(self.groupBox_2)
self.label_4.setGeometry(QtCore.QRect(240, 90, 221, 16))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_4.setFont(font)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.label_5 = QLabel(self.groupBox_2)
self.label_5.setGeometry(QtCore.QRect(240, 110, 221, 16))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_5.setFont(font)
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.groupBox_3 = QGroupBox(cenra)
self.groupBox_3.setGeometry(QtCore.QRect(10, 440, 511, 81))
font = QtGui.QFont()
font.setBold(True)
font.setItalic(True)
font.setWeight(75)
self.groupBox_3.setFont(font)
self.groupBox_3.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_3.setObjectName(_fromUtf8("groupBox_3"))
self.label_6 = QLabel(self.groupBox_3)
self.label_6.setGeometry(QtCore.QRect(20, 20, 471, 16))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_6.setFont(font)
self.label_6.setObjectName(_fromUtf8("label_6"))
self.label_7 = QLabel(self.groupBox_3)
self.label_7.setGeometry(QtCore.QRect(120, 50, 141, 16))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_7.setFont(font)
self.label_7.setObjectName(_fromUtf8("label_7"))
self.label_8 = QLabel(self.groupBox_3)
self.label_8.setGeometry(QtCore.QRect(270, 40, 41, 41))
self.label_8.setText(_fromUtf8(""))
self.label_8.setTextFormat(QtCore.Qt.PlainText)
self.label_8.setPixmap(QtGui.QPixmap(_fromUtf8("page_ajout.png")))
self.label_8.setObjectName(_fromUtf8("label_8"))
self.retranslateUi(cenra)
#QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), cenra.accept)
self.buttonBox.accepted.connect(cenra.accept)
#QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), cenra.reject)
self.buttonBox.rejected.connect(cenra.reject)
QtCore.QMetaObject.connectSlotsByName(cenra)
def retranslateUi(self, cenra):
cenra.setWindowTitle(_translate("cenra", "Nouveau Projet Cartographique", None))
self.Titre.setText(_translate("cenra", "Création d\'un nouveau dossier cartographique", None))
self.groupBox.setTitle(_translate("cenra", "Généralités", None))
self.label_dept.setText(_translate("cenra", "Département :", None))
self.dept.setItemText(1, _translate("cenra", "00", None))
self.dept.setItemText(2, _translate("cenra", "01", None))
self.dept.setItemText(3, _translate("cenra", "07", None))
self.dept.setItemText(4, _translate("cenra", "26", None))
self.dept.setItemText(5, _translate("cenra", "42", None))
self.dept.setItemText(6, _translate("cenra", "69", None))
self.dept.setItemText(7, _translate("cenra", "form", None))
self.label_nom.setText(_translate("cenra", "Code analytique et Nom du site :", None))
self.label_2.setText(_translate("cenra", "Attention :", None))
self.label.setText(_translate("cenra", "Le code analytique ne doit comporter ni caractères spéciaux, ni espaces, ni majuscules", None))
self.at.setText(_translate("cenra", "Animation Territoriale", None))
self.groupBox_2.setTitle(_translate("cenra", "Liste des couches à ajouter lors de la création", None))
self.couche_habitat.setText(_translate("cenra", "Habitat", None))
self.couche_contour.setText(_translate("cenra", "Contour", None))
self.annee_4.setText(_translate("cenra", "aaaa", None))
self.couche_travaux_prevus.setText(_translate("cenra", "Travaux Prévus", None))
self.annee_5.setText(_translate("cenra", "aaaa", None))
self.couche_vierge.setText(_translate("cenra", "Vierge", None))
self.annee_1.setText(_translate("cenra", "aaaa", None))
self.annee_2.setText(_translate("cenra", "aaaa", None))
self.label_nom_couche_vierge.setText(_translate("cenra", "- Nom de la couche vierge :", None))
self.label_geom_couche_vierge.setText(_translate("cenra", "- Geométrie de la couche vierge :", None))
self.couche_vierge_point.setText(_translate("cenra", "Point", None))
self.couche_vierge_ligne.setText(_translate("cenra", "Ligne", None))
self.couche_vierge_polygone.setText(_translate("cenra", "Polygone", None))
self.label_3.setText(_translate("cenra", "Attention :", None))
self.label_4.setText(_translate("cenra", "Le nom de la couche vierge ne doit comporter", None))
self.label_5.setText(_translate("cenra", "ni caractères spéciaux, ni espaces", None))
self.groupBox_3.setTitle(_translate("cenra", "Note", None))
self.label_6.setText(_translate("cenra", "Vous pourez à tous moment ajouter de nouvelles couches à votre dossier, à l\'aide de l\'outil :", None))
self.label_7.setText(_translate("cenra", "Ajout de nouvelles couches", None))
+661
View File
@@ -0,0 +1,661 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>cenra</class>
<widget class="QDialog" name="cenra">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>533</width>
<height>565</height>
</rect>
</property>
<property name="windowTitle">
<string>Nouveau Projet Cartographique</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>350</x>
<y>530</y>
<width>171</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="Titre">
<property name="geometry">
<rect>
<x>40</x>
<y>10</y>
<width>441</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Création d'un nouveau dossier cartographique</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>511</width>
<height>121</height>
</rect>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="title">
<string>Généralités</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>126</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_dept">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Département :</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="dept">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<item>
<property name="text">
<string/>
</property>
</item>
<item>
<property name="text">
<string extracomment="Ain">01</string>
</property>
</item>
<item>
<property name="text">
<string>07</string>
</property>
</item>
<item>
<property name="text">
<string>26</string>
</property>
</item>
<item>
<property name="text">
<string>42</string>
</property>
</item>
<item>
<property name="text">
<string>69</string>
</property>
</item>
<item>
<property name="text">
<string>form</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_2">
<property name="geometry">
<rect>
<x>20</x>
<y>50</y>
<width>481</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_nom">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Code analytique :</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nom">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_3">
<property name="geometry">
<rect>
<x>20</x>
<y>80</y>
<width>479</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Attention :</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Le code analytique ne doit comporter ni caractères spéciaux, ni espaces, ni majuscules</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_6">
<property name="geometry">
<rect>
<x>339</x>
<y>20</y>
<width>161</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QCheckBox" name="at">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Animation Territoriale</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>10</x>
<y>190</y>
<width>511</width>
<height>241</height>
</rect>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="title">
<string>Liste des couches à ajouter lors de la création</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>166</width>
<height>141</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1">
<widget class="QLineEdit" name="annee_4">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="couche_vierge">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Vierge</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="annee_1">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="couche_travaux_prevus">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Travaux Prévus</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="annee_5">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="couche_habitat">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Habitat</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="couche_contour">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Contour</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="annee_2">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_4">
<property name="geometry">
<rect>
<x>50</x>
<y>170</y>
<width>451</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_nom_couche_vierge">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>- Nom de la couche vierge :</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nom_couche_vierge">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_5">
<property name="geometry">
<rect>
<x>50</x>
<y>200</y>
<width>341</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_geom_couche_vierge">
<property name="minimumSize">
<size>
<width>152</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>- Geométrie de la couche vierge :</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="couche_vierge_point">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Point</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="couche_vierge_ligne">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Ligne</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="couche_vierge_polygone">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Polygone</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>320</x>
<y>60</y>
<width>60</width>
<height>29</height>
</rect>
</property>
<property name="text">
<string>Attention :</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>240</x>
<y>90</y>
<width>221</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Le nom de la couche vierge ne doit comporter</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>240</x>
<y>110</y>
<width>221</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>ni caractères spéciaux, ni espaces</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_3">
<property name="geometry">
<rect>
<x>10</x>
<y>440</y>
<width>511</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="title">
<string>Note</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>471</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Vous pourez à tous moment ajouter de nouvelles couches à votre dossier, à l'aide de l'outil :</string>
</property>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>120</x>
<y>50</y>
<width>141</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Ajout de nouvelles couches</string>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>270</x>
<y>40</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="pixmap">
<pixmap>page_ajout.png</pixmap>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>cenra</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>cenra</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+234
View File
@@ -0,0 +1,234 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_table_postgis.ui'
#
# Created: Thu Mar 27 16:17:32 2014
# by: PyQt4 UI code generator 4.9.6
#
# WARNING! All changes made in this file will be lost!
from builtins import object
from qgis.PyQt import QtCore, QtGui
from qgis.PyQt.QtWidgets import *
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QApplication.translate(context, text, disambig)
class Ui_table_postgis(object):
def setupUi(self, table_postgis):
table_postgis.setObjectName(_fromUtf8("table_postgis"))
table_postgis.resize(532, 364)
self.buttonBox = QDialogButtonBox(table_postgis)
self.buttonBox.setGeometry(QtCore.QRect(360, 330, 161, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.Titre = QLabel(table_postgis)
self.Titre.setGeometry(QtCore.QRect(170, 0, 171, 31))
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.Titre.setFont(font)
self.Titre.setObjectName(_fromUtf8("Titre"))
self.groupBox_2 = QGroupBox(table_postgis)
self.groupBox_2.setGeometry(QtCore.QRect(10, 80, 511, 241))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_2.setFont(font)
self.groupBox_2.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
self.gridLayoutWidget = QWidget(self.groupBox_2)
self.gridLayoutWidget.setGeometry(QtCore.QRect(20, 30, 162, 141))
self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget"))
self.gridLayout = QGridLayout(self.gridLayoutWidget)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.couche_habitat = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_habitat.setFont(font)
self.couche_habitat.setObjectName(_fromUtf8("couche_habitat"))
self.gridLayout.addWidget(self.couche_habitat, 1, 0, 1, 1)
self.couche_contour = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_contour.setFont(font)
self.couche_contour.setObjectName(_fromUtf8("couche_contour"))
self.gridLayout.addWidget(self.couche_contour, 0, 0, 1, 1)
self.annee_4 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_4.setFont(font)
self.annee_4.setAlignment(QtCore.Qt.AlignCenter)
self.annee_4.setObjectName(_fromUtf8("annee_4"))
self.gridLayout.addWidget(self.annee_4, 4, 1, 1, 1)
self.couche_travaux_prevus = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_travaux_prevus.setFont(font)
self.couche_travaux_prevus.setObjectName(_fromUtf8("couche_travaux_prevus"))
self.gridLayout.addWidget(self.couche_travaux_prevus, 3, 0, 1, 1)
self.annee_5 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_5.setFont(font)
self.annee_5.setAlignment(QtCore.Qt.AlignCenter)
self.annee_5.setObjectName(_fromUtf8("annee_5"))
self.gridLayout.addWidget(self.annee_5, 3, 1, 1, 1)
self.couche_vierge = QCheckBox(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge.setFont(font)
self.couche_vierge.setObjectName(_fromUtf8("couche_vierge"))
self.gridLayout.addWidget(self.couche_vierge, 4, 0, 1, 1)
self.annee_1 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_1.setFont(font)
self.annee_1.setAlignment(QtCore.Qt.AlignCenter)
self.annee_1.setObjectName(_fromUtf8("annee_1"))
self.gridLayout.addWidget(self.annee_1, 0, 1, 1, 1)
self.annee_2 = QLineEdit(self.gridLayoutWidget)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.annee_2.setFont(font)
self.annee_2.setAlignment(QtCore.Qt.AlignCenter)
self.annee_2.setObjectName(_fromUtf8("annee_2"))
self.gridLayout.addWidget(self.annee_2, 1, 1, 1, 1)
self.horizontalLayoutWidget_4 = QWidget(self.groupBox_2)
self.horizontalLayoutWidget_4.setGeometry(QtCore.QRect(50, 170, 451, 31))
self.horizontalLayoutWidget_4.setObjectName(_fromUtf8("horizontalLayoutWidget_4"))
self.horizontalLayout_4 = QHBoxLayout(self.horizontalLayoutWidget_4)
self.horizontalLayout_4.setMargin(0)
self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
self.label_nom_couche_vierge = QLabel(self.horizontalLayoutWidget_4)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_nom_couche_vierge.setFont(font)
self.label_nom_couche_vierge.setObjectName(_fromUtf8("label_nom_couche_vierge"))
self.horizontalLayout_4.addWidget(self.label_nom_couche_vierge)
self.nom_couche_vierge = QLineEdit(self.horizontalLayoutWidget_4)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.nom_couche_vierge.setFont(font)
self.nom_couche_vierge.setObjectName(_fromUtf8("nom_couche_vierge"))
self.horizontalLayout_4.addWidget(self.nom_couche_vierge)
self.horizontalLayoutWidget_5 = QWidget(self.groupBox_2)
self.horizontalLayoutWidget_5.setGeometry(QtCore.QRect(50, 200, 341, 31))
self.horizontalLayoutWidget_5.setObjectName(_fromUtf8("horizontalLayoutWidget_5"))
self.horizontalLayout_5 = QHBoxLayout(self.horizontalLayoutWidget_5)
self.horizontalLayout_5.setMargin(0)
self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5"))
self.label_geom_couche_vierge = QLabel(self.horizontalLayoutWidget_5)
self.label_geom_couche_vierge.setMinimumSize(QtCore.QSize(152, 0))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_geom_couche_vierge.setFont(font)
self.label_geom_couche_vierge.setObjectName(_fromUtf8("label_geom_couche_vierge"))
self.horizontalLayout_5.addWidget(self.label_geom_couche_vierge)
self.couche_vierge_point = QRadioButton(self.horizontalLayoutWidget_5)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge_point.setFont(font)
self.couche_vierge_point.setObjectName(_fromUtf8("couche_vierge_point"))
self.horizontalLayout_5.addWidget(self.couche_vierge_point)
self.couche_vierge_ligne = QRadioButton(self.horizontalLayoutWidget_5)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge_ligne.setFont(font)
self.couche_vierge_ligne.setObjectName(_fromUtf8("couche_vierge_ligne"))
self.horizontalLayout_5.addWidget(self.couche_vierge_ligne)
self.couche_vierge_polygone = QRadioButton(self.horizontalLayoutWidget_5)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.couche_vierge_polygone.setFont(font)
self.couche_vierge_polygone.setObjectName(_fromUtf8("couche_vierge_polygone"))
self.horizontalLayout_5.addWidget(self.couche_vierge_polygone)
self.label_3 = QLabel(self.groupBox_2)
self.label_3.setGeometry(QtCore.QRect(320, 60, 60, 29))
self.label_3.setObjectName(_fromUtf8("label_3"))
self.label_4 = QLabel(self.groupBox_2)
self.label_4.setGeometry(QtCore.QRect(240, 90, 221, 16))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_4.setFont(font)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.label_5 = QLabel(self.groupBox_2)
self.label_5.setGeometry(QtCore.QRect(240, 110, 221, 16))
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.label_5.setFont(font)
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.horizontalLayoutWidget = QWidget(table_postgis)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 40, 511, 31))
self.horizontalLayoutWidget.setObjectName(_fromUtf8("horizontalLayoutWidget"))
self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setMargin(0)
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.schema_label = QLabel(self.horizontalLayoutWidget)
self.schema_label.setMaximumSize(QtCore.QSize(85, 16777215))
self.schema_label.setObjectName(_fromUtf8("schema_label"))
self.horizontalLayout.addWidget(self.schema_label)
self.schema = QComboBox(self.horizontalLayoutWidget)
self.schema.setObjectName(_fromUtf8("schema"))
self.horizontalLayout.addWidget(self.schema)
self.retranslateUi(table_postgis)
#QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), table_postgis.accept)
self.buttonBox.accepted.connect(table_postgis.accept)
#QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), table_postgis.reject)
self.buttonBox.rejected.connect(table_postgis.reject)
QtCore.QMetaObject.connectSlotsByName(table_postgis)
def retranslateUi(self, table_postgis):
table_postgis.setWindowTitle(_translate("table_postgis", "Ajout d\'une table", None))
self.Titre.setText(_translate("table_postgis", "Création de table", None))
self.groupBox_2.setTitle(_translate("table_postgis", "Liste des couches à ajouter dans le projet", None))
self.couche_habitat.setText(_translate("table_postgis", "Habitat", None))
self.couche_contour.setText(_translate("table_postgis", "Contour", None))
self.annee_4.setText(_translate("table_postgis", "aaaa", None))
self.couche_travaux_prevus.setText(_translate("table_postgis", "Travaux Prévus", None))
self.annee_5.setText(_translate("table_postgis", "aaaa", None))
self.couche_vierge.setText(_translate("table_postgis", "Vierge", None))
self.annee_1.setText(_translate("table_postgis", "aaaa", None))
self.annee_2.setText(_translate("table_postgis", "aaaa", None))
self.label_nom_couche_vierge.setText(_translate("table_postgis", "- Nom de la couche vierge :", None))
self.label_geom_couche_vierge.setText(_translate("table_postgis", "- Geométrie de la couche vierge :", None))
self.couche_vierge_point.setText(_translate("table_postgis", "Point", None))
self.couche_vierge_ligne.setText(_translate("table_postgis", "Ligne", None))
self.couche_vierge_polygone.setText(_translate("table_postgis", "Polygone", None))
self.label_3.setText(_translate("table_postgis", "Attention :", None))
self.label_4.setText(_translate("table_postgis", "Le nom de la couche vierge ne doit comporter", None))
self.label_5.setText(_translate("table_postgis", "ni caractères spéciaux, ni espaces", None))
self.schema_label.setText(_translate("table_postgis", "Code analytique :", None))
+425
View File
@@ -0,0 +1,425 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>table_postgis</class>
<widget class="QDialog" name="table_postgis">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>532</width>
<height>364</height>
</rect>
</property>
<property name="windowTitle">
<string>Ajout d'une table</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>360</x>
<y>330</y>
<width>161</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="Titre">
<property name="geometry">
<rect>
<x>170</x>
<y>0</y>
<width>171</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Création de table</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>10</x>
<y>80</y>
<width>511</width>
<height>241</height>
</rect>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="title">
<string>Liste des couches à ajouter dans le projet</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>166</width>
<height>141</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1">
<widget class="QLineEdit" name="annee_4">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="annee_5">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="couche_vierge">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Vierge</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="annee_1">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="couche_habitat">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Habitat</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="couche_travaux_prevus">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Travaux Prévus</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="couche_contour">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Contour</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="annee_2">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>aaaa</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_4">
<property name="geometry">
<rect>
<x>50</x>
<y>170</y>
<width>451</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_nom_couche_vierge">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>- Nom de la couche vierge :</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nom_couche_vierge">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_5">
<property name="geometry">
<rect>
<x>50</x>
<y>200</y>
<width>341</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_geom_couche_vierge">
<property name="minimumSize">
<size>
<width>152</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>- Geométrie de la couche vierge :</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="couche_vierge_point">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Point</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="couche_vierge_ligne">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Ligne</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="couche_vierge_polygone">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Polygone</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>320</x>
<y>60</y>
<width>60</width>
<height>29</height>
</rect>
</property>
<property name="text">
<string>Attention :</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>240</x>
<y>90</y>
<width>221</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Le nom de la couche vierge ne doit comporter</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>240</x>
<y>110</y>
<width>221</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>ni caractères spéciaux, ni espaces</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>511</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="schema_label">
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Code analytique :</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="schema"/>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>table_postgis</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>table_postgis</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+34
View File
@@ -0,0 +1,34 @@
Plugin Builder Results
Your plugin SICEN was created in:
C:\Users\gcostes\.qgis2\python\plugins\SICEN
Your QGIS plugin directory is located at:
C:/Users/gcostes/.qgis2/python/plugins
What's Next:
* Copy the entire directory containing your new plugin to the QGIS plugin
directory
* Compile the ui file using pyuic4
* Compile the resources file using pyrcc4
* Test the plugin by enabling it in the QGIS plugin manager
* Customize it by editing the implementation file:
sicen.py
* Create your own custom icon, replacing the default icon.png
* Modify your user interface by opening sicen.ui
in Qt Designer (don't forget to compile it with pyuic4 after changing it)
* You can use the Makefile to compile your Ui and resource files when
you make changes. This requires GNU make (gmake)
For more information, see the PyQGIS Developer Cookbook at:
http://www.qgis.org/pyqgis-cookbook/index.html
(C) 2011-2014 GeoApt LLC - geoapt.com
+28
View File
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
SICEN
A QGIS plugin
Filtre sur données SICEN
-------------------
begin : 2014-10-17
copyright : (C) 2014 by Guillaume COSTES
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. *
* *
***************************************************************************/
This script initializes the plugin, making it known to QGIS.
"""
from __future__ import absolute_import
def classFactory(iface):
# load SICEN class from file SICEN
from .sicen import SICEN
return SICEN(iface)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

+39
View File
@@ -0,0 +1,39 @@
# This file contains metadata for your plugin. Beginning
# with version 1.8 this is the preferred way to supply information about a
# plugin. The current method of embedding metadata in __init__.py will
# be supported until version 2.0
# This file should be included when you package your plugin.
# Mandatory items:
[general]
name=CenRa SICEN
qgisMinimumVersion=3.0
description=Filtre des données saisies dans SICEN et export d'une liste d'espèces.
version=1.7
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
# end of mandatory metadata
# Optional items:
# Uncomment the following line and add your changelog entries:
changelog=<h2>CenRa_SICEN:</h2></br><p><h3>13/09/2024 - Version 1.7:</h3> - Il est maintenant possible de sélectionné plusieurs entité pour le filtre par Emprise.</br>- Ajoute d'un changelog.</br>- Ajoute une vérification de mise à jour.</p>
# tags are comma separated with spaces allowed
tags=cenra, postgis, sicen
repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
homepage=https://plateformesig.cenra-outils.org/
category=Plugins
icon=cenra.png
# experimental flag
experimental=False
# deprecated flag (applies to the whole plugin, not just a single version
deprecated=False
+566
View File
@@ -0,0 +1,566 @@
# -*- coding: utf-8 -*-
# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2)
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore
qt_resource_data = b"\
\x00\x00\x0d\x89\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x24\x00\x00\x00\x29\x08\x06\x00\x00\x00\x5d\x9e\x8b\x46\
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\
\x01\x00\x9a\x9c\x18\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\
\x25\x00\x00\x80\x83\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\
\x30\x00\x00\xea\x60\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\
\x46\x00\x00\x0d\x0f\x49\x44\x41\x54\x78\xda\xac\x98\x7b\x50\x54\
\x57\x9e\xc7\xbf\xf7\xd1\x0f\xe0\x76\x43\x0b\xdd\x76\x0b\x74\xf3\
\x68\x24\x38\xc0\x62\x8b\x04\x15\xc5\x58\x92\x07\x3b\x06\x0d\x1a\
\x34\xbb\x15\x2b\x6b\x25\xc6\x75\x35\x0f\x2b\x9b\xca\xce\x5a\x26\
\xd4\x26\xba\x6e\xca\x11\x33\xc6\x1d\x93\xd1\xe0\x90\x38\x4a\x92\
\xb1\x8c\x92\x04\xb5\x70\x65\xa0\x8a\x97\x44\x5b\x85\xf0\xec\x06\
\x3a\x74\x37\x2d\xdd\x4d\x3f\x6e\x3f\xee\x63\xff\x30\xa4\x9c\x44\
\x34\x26\xfe\xaa\x7e\xff\xdc\x7b\xbe\xbf\xf3\xb9\xe7\xfc\xce\x3d\
\xe7\xfc\x88\x23\x47\x8e\x60\xda\x38\x8e\x03\xc7\x71\x48\x4b\x4b\
\x43\x7e\x7e\x3e\x74\x3a\x1d\x78\x9e\x07\x45\x51\x20\x49\x12\x36\
\x9b\x0d\xbd\xbd\xbd\xb0\xdb\xed\xa0\x28\x0a\x06\x83\x01\xf3\xe6\
\xcd\x43\x7c\x7c\x3c\xfa\xfb\xfb\x89\x6d\xdb\xb6\x89\x3d\x3d\x3d\
\xa8\xa8\xa8\x40\x75\x75\x35\x02\x81\x00\x74\x3a\x1d\x46\x46\x46\
\x30\x34\x34\x84\x98\x98\x18\x74\x77\x77\x43\xab\xd5\x62\xc7\x8e\
\x1d\xb0\x58\x2c\x78\xee\xb9\xe7\x90\x9b\x9b\x8b\xb2\xb2\x32\xc4\
\xc5\xc5\x81\xc6\x6d\x46\xd3\x34\x68\x9a\x86\xd5\x6a\x85\xcd\x66\
\x43\x76\x76\x36\x72\x73\x73\xa1\x50\x28\xc0\x71\x1c\x92\x93\x93\
\xa1\xd5\x6a\x31\x38\x38\x88\xbe\xbe\x3e\x8c\x8f\x8f\xc3\xed\x76\
\x4b\x62\x63\x63\xe7\x29\x95\x4a\x51\x26\x93\xcd\x05\x70\x16\x00\
\x8b\x5f\x68\xf4\x9d\x1e\xca\x64\x32\x00\xc0\xf5\xeb\xd7\xd1\xd7\
\xd7\x87\xe2\xe2\x62\x18\x0c\x06\x08\x82\x00\x8a\xa2\x30\x77\xee\
\x5c\x64\x64\x64\xe0\xcc\x99\x33\x86\xd1\xd1\xd1\x15\xb5\xb5\xb5\
\x6b\x7b\x7b\x7b\x8b\x75\x3a\x9d\x9b\x20\x88\x6d\x72\xb9\x7c\x1b\
\x80\xab\x0f\x0c\xe8\x76\x30\x9b\xcd\x86\x89\x89\x09\x68\x34\x1a\
\xc8\x64\x32\x90\x24\x09\x92\x24\x41\xd3\x34\x2e\x5e\xbc\xf8\xd2\
\xd9\xb3\x67\x57\x0d\x0c\x0c\x18\x01\xc0\xed\x76\xcf\x92\x4a\xa5\
\x69\x83\x83\x83\xd5\x72\xb9\x7c\xb5\xdf\xef\xbf\x6f\x20\x92\x61\
\x18\x90\x24\xf9\x93\x17\x14\x45\xc1\xef\xf7\x23\x25\x25\x05\x85\
\x85\x85\x08\x06\x83\x08\x06\x83\x60\x18\x06\x14\x45\xa1\xb6\xb6\
\x76\xed\x81\x03\x07\xb6\x4c\xc3\x4c\x5b\x24\x12\xa1\x3e\xff\xfc\
\xf3\x8a\x96\x96\x96\x25\x34\x4d\xdf\x3f\x50\x53\x53\x13\x78\x9e\
\x47\x5c\x5c\xdc\xdf\xbd\x08\x87\xc3\x08\x04\x02\x58\xb4\x68\x11\
\x02\x81\xc0\x74\xe2\x62\xff\xfe\xfd\x70\x38\x1c\xb1\xfb\xf7\xef\
\x7f\x49\x14\x45\xe9\x4c\x81\x4f\x9f\x3e\xfd\xdb\xc4\xc4\x44\x90\
\x24\x09\x51\x14\x7f\xfe\x94\xd5\xd7\xd7\xe3\xfa\xf5\xeb\x58\xbc\
\x78\x31\xf2\xf3\xf3\x01\x00\x3c\xcf\x83\x20\x88\x59\x0b\x17\x2e\
\x9c\xcc\xce\xce\xc6\xf0\xf0\x30\xa4\x52\x29\x2c\x16\x0b\x1a\x1b\
\x1b\xc9\x9e\x9e\x9e\x7f\xec\xe9\xe9\x99\x0f\x80\x9c\x29\xb0\xdd\
\x6e\x9f\x23\x91\x48\xe0\xf3\xf9\x60\xb3\xd9\x40\x10\x04\x08\x82\
\x80\x44\x22\xb9\x3b\x90\xcb\xe5\x42\x57\x57\x17\x06\x07\x07\x61\
\x32\x99\xb0\x74\xe9\xd2\x74\x82\x20\x1e\x99\x98\x98\x30\xd4\xd5\
\xd5\x65\x86\xc3\xe1\x8f\xcb\xcb\xcb\xbf\x6c\x6e\x6e\x46\x52\x52\
\x12\x5e\x79\xe5\x15\xe2\xdc\xb9\x73\x46\x9a\xa6\xc9\x70\x38\x7c\
\xe7\xa0\x34\xcd\x25\x26\x26\x7a\x42\xa1\x90\xcc\x66\xb3\x85\x23\
\x91\x08\x12\x12\x12\x40\x51\x14\x5c\x2e\x57\x76\x56\x56\x16\x08\
\x82\x90\x02\x30\xff\x44\x4b\x10\x04\x02\x81\x00\x82\xc1\x20\x7c\
\x3e\x1f\x06\x06\x06\xfe\x83\xa6\xe9\xe5\x66\xb3\xd9\x08\x00\x17\
\x2e\x5c\xf8\xa7\x83\x07\x0f\xfe\x9b\x20\x08\xff\xdb\xdf\xdf\xcf\
\xd7\xd4\xd4\x08\x47\x8e\x1c\x29\x08\x04\x02\x31\x33\x7d\x25\xc7\
\x71\x74\x62\x62\xa2\x47\x2e\x97\x73\xe1\x70\x18\x0c\xc3\x80\x65\
\xd9\x9c\x77\xdf\x7d\x77\x87\xd3\xe9\xfc\x87\xc6\xc6\x46\x96\xe3\
\x38\x3d\x80\xd3\x04\x41\xfc\x27\x80\xa9\x1f\x80\x34\x1a\x0d\x26\
\x27\x27\x11\x8d\x46\x31\x35\x35\xf5\xcf\x2c\xcb\x6e\x8a\x46\xa3\
\xc4\xed\x1d\x54\x57\x57\xff\x6e\xfd\xfa\xf5\xe7\x14\x0a\x45\x9f\
\xd7\xeb\x65\xdc\x6e\x77\x1c\x41\x10\xa2\x28\x8a\xc4\x9d\x80\x54\
\x2a\xd5\xd4\x13\x4f\x3c\x71\xbe\xb3\xb3\x93\xd7\x6a\xb5\x38\x74\
\xe8\xd0\x4b\xc7\x8e\x1d\x7b\x75\x6c\x6c\x4c\x7f\x9b\x4e\x04\xb0\
\x0d\x00\xcd\xf3\xfc\x2b\x00\xc2\x00\x40\xce\x9f\x3f\x1f\x59\x59\
\x59\x88\x8f\x8f\x57\x48\xa5\xd2\x37\x7e\x0c\x03\x00\x0e\x87\x43\
\x37\x35\x35\xb5\x71\xeb\xd6\xad\x68\x6b\x6b\x0b\x18\x0c\x06\xeb\
\x4c\x30\x00\xf0\xe8\xa3\x8f\x5e\x72\x3a\x9d\x57\x4f\x9d\x3a\x95\
\xf0\xe9\xa7\x9f\xfe\xeb\xfb\xef\xbf\x5f\x6d\xb3\xd9\xf4\x00\x70\
\x9b\x8e\x00\x80\x86\x86\x86\xa7\x94\x4a\xa5\x41\x10\x84\x5b\xab\
\xec\x99\x67\x9e\x41\x59\x59\x19\xb1\x64\xc9\x92\x32\x85\x42\x91\
\x33\x53\x27\x56\xab\xb5\x38\x3e\x3e\x5e\x42\xd3\xb4\xa0\xd3\xe9\
\xae\xcc\xd4\x2e\x29\x29\xc9\x5d\x5a\x5a\xfa\x97\xaf\xbf\xfe\xda\
\x3b\x31\x31\x51\xf1\xd1\x47\x1f\x6d\xf1\x78\x3c\xca\x99\x56\x9a\
\xdd\x6e\x9f\x9d\x96\x96\x96\xa2\x52\xa9\x6e\x01\xe9\x74\x3a\xac\
\x5e\xbd\x9a\x2e\x2e\x2e\xce\x08\x06\x83\xa1\x99\x3a\xb2\xd9\x6c\
\xa9\x67\xcf\x9e\x4d\x22\x49\x12\x4a\xa5\xb2\xe1\xe1\x87\x1f\xee\
\xbf\xc3\x8f\x34\xfc\xe2\x8b\x2f\xfe\x91\xa2\xa8\xd3\x2c\xcb\xa6\
\x5b\xad\xd6\x7f\x31\x9b\xcd\xb9\x77\x5b\x55\x4a\xa5\xd2\x27\x97\
\xcb\x43\x31\x31\xb7\x52\x92\xfc\x3e\xfb\xa3\x7e\xbf\x5f\xc5\xb2\
\xec\x8c\x89\xca\xf3\x3c\x91\x99\x99\xc9\x05\x02\x01\x30\x0c\x63\
\xd3\xeb\xf5\xbf\x93\x4a\xa5\xac\x4c\x26\x8b\x02\x40\x41\x41\xc1\
\x95\x0d\x1b\x36\xfc\x79\xeb\xd6\xad\x7f\x90\x48\x24\x81\xb9\x73\
\xe7\x16\x9b\xcd\xe6\xb9\xd3\x53\x31\x93\xe5\xe6\xe6\x0e\x5b\x2c\
\x96\x90\xd9\x6c\x06\x45\x51\xa0\xf5\x7a\x3d\x78\x9e\x87\xcf\xe7\
\x23\xef\x26\xd4\x6a\xb5\xb6\x84\x84\x84\x40\x28\x14\xc2\xde\xbd\
\x7b\xc5\x82\x82\x82\x7a\xb3\xd9\x6c\xd9\xb3\x67\x4f\x95\xc9\x64\
\xfa\x56\x22\x91\x38\xca\xca\xca\xba\xb4\x5a\xad\x6d\xdd\xba\x75\
\x78\xfb\xed\xb7\x0b\x1d\x0e\x87\xe6\x6e\x31\x19\x86\x09\xa7\xa7\
\xa7\xb7\xb5\xb7\xb7\xf7\xf4\xf6\xf6\xc2\x6a\xb5\x82\x8e\x46\xa3\
\xa0\x28\x0a\x8f\x3c\xf2\x48\xe7\xa1\x43\x87\x66\x14\x17\x15\x15\
\x75\xa4\xa6\xa6\xb2\xb3\x66\xcd\xc2\xce\x9d\x3b\x61\x30\x18\x90\
\x95\x95\xd5\xf1\xf2\xcb\x2f\x77\x5c\xbb\x76\x2d\x26\x3f\x3f\x9f\
\xcd\xc8\xc8\x80\xcb\xe5\x42\x6c\x6c\xac\xbc\xb3\xb3\x33\x87\xe7\
\xf9\x19\x3f\x92\x24\x49\x31\x27\x27\x67\x44\x10\x84\x7a\xbb\xdd\
\xce\x7a\x3c\x1e\xf8\x7c\xbe\x5b\x7f\x5a\x89\x44\x82\xc5\x8b\x17\
\x37\x69\x34\x1a\xc7\x0c\xa3\xe3\xa8\xac\xac\xac\xf7\x7a\xbd\x22\
\x45\x51\x20\x08\x02\xa9\xa9\xa9\x68\x69\x69\xc1\x8d\x1b\x37\x90\
\x9e\x9e\xce\xa6\xa7\xa7\xa3\xa3\xa3\x03\x32\x99\x0c\xdf\x7c\xf3\
\x0d\x6f\x34\x1a\xfb\xef\x36\x3a\xe9\xe9\xe9\xd6\xa2\xa2\xa2\xa3\
\xa2\x28\x9e\x13\x45\x11\xc1\x60\x10\x4e\xa7\x13\xa4\x28\x8a\x88\
\x89\x89\xc1\x89\x13\x27\xdc\x55\x55\x55\x07\xee\x24\xde\xb2\x65\
\xcb\x1f\xe6\xcc\x99\x73\xfd\xdc\xb9\x73\xe8\xec\xec\x44\x73\x73\
\x33\xfa\xfa\xfa\x70\xe2\xc4\x09\xa8\xd5\x6a\x24\x27\x27\xe3\xe2\
\xc5\x8b\xe8\xea\xea\x42\x30\x18\xc4\xe0\xe0\x60\x74\xe5\xca\x95\
\x17\xa6\xf3\xeb\xc7\x96\x9a\x9a\x6a\x7d\xf5\xd5\x57\xff\xa7\xb0\
\xb0\xf0\x48\x6a\x6a\x2a\x12\x13\x13\x21\x8a\x22\xdc\x6e\x37\xa8\
\x5d\xbb\x76\xa1\xbf\xbf\x1f\x27\x4f\x9e\xc4\xc6\x8d\x1b\xdb\x94\
\x4a\xe5\x6c\xa7\xd3\x39\xcb\xe3\xf1\xa8\xf2\xf3\xf3\xaf\x56\x54\
\x54\x9c\xd9\xb5\x6b\xd7\x4e\x85\x42\x11\x3c\x7c\xf8\x30\x26\x26\
\x26\xb0\x60\xc1\x02\xe2\xda\xb5\x6b\xe0\x79\x1e\xe5\xe5\xe5\xf8\
\xf6\xdb\x6f\xe1\x72\xb9\x40\xd3\x34\x48\x92\xc4\xe4\xe4\x24\x2e\
\x5f\xbe\x3c\xa6\x56\xab\x67\x5b\x2c\x96\x05\x6a\xb5\x7a\xc2\xef\
\xf7\xc7\x65\x64\x64\x0c\x3c\xfe\xf8\xe3\xe7\x9f\x7d\xf6\xd9\xda\
\x17\x5e\x78\xe1\x38\x80\x49\x8d\x46\x83\xa1\xa1\x21\x8c\x8d\x8d\
\x41\x14\x45\xd0\x2c\xcb\xe2\xf8\xf1\xe3\x58\xb0\x60\x01\x02\x81\
\x40\x24\x36\x36\xf6\xed\x9d\x3b\x77\x36\x46\xa3\x51\x26\x27\x27\
\x67\x80\x65\xd9\x2b\xa2\x28\x4a\x2e\x5f\xbe\x9c\x35\x32\x32\x22\
\x09\x85\x42\x25\x8b\x16\x2d\xba\xd1\xd5\xd5\x65\x58\xb3\x66\x4d\
\x13\x4d\xd3\x36\x8f\xc7\x23\x46\x22\x91\xb0\x52\xa9\x44\x4c\x4c\
\x0c\x12\x13\x13\x71\xfe\xfc\xf9\xc0\xc1\x83\x07\x37\x3b\x1c\x8e\
\xaf\x4a\x4a\x4a\x7e\x63\xb3\xd9\xdc\x8f\x3d\xf6\xd8\x00\x80\x9e\
\xaa\xaa\xaa\x91\x4b\x97\x2e\xe1\xa1\x87\x1e\x92\x5c\xbd\x7a\x35\
\x3a\x3c\x3c\x0c\x96\x65\x51\x58\x58\x08\x5a\x2e\x97\xc3\x66\xb3\
\xe1\xe9\xa7\x9f\xc6\x57\x5f\x7d\x85\xa2\xa2\xa2\x91\xc4\xc4\xc4\
\x91\x65\xcb\x96\x61\x6c\x6c\x2c\xb6\xbe\xbe\x7e\xc9\xf1\xe3\xc7\
\x9f\xb6\x58\x2c\x86\xf6\xf6\xf6\xc5\xc9\xc9\xc9\x6c\x6d\x6d\x6d\
\x52\x5a\x5a\xda\x58\x5d\x5d\xdd\xef\xd7\xaf\x5f\x7f\x72\xe5\xca\
\x95\xa7\x35\x1a\xcd\xdf\x64\x32\xd9\xcd\xb4\xb4\x34\xb8\xdd\x6e\
\xac\x5d\xbb\x16\x0c\xc3\x20\x39\x39\xf9\xaf\x05\x05\x05\x7f\xdd\
\xb0\x61\x03\x82\xc1\x20\x04\x41\x90\x7e\xf0\xc1\x07\x99\xad\xad\
\xad\x8b\x9f\x7f\xfe\xf9\xe1\xf6\xf6\xf6\x78\x9f\xcf\xd7\x90\x90\
\x90\x20\x2e\x5f\xbe\x1c\x10\x45\x11\x4e\xa7\x13\x2e\x97\x0b\x83\
\x83\x83\x10\x45\x11\xc3\xc3\xc3\x74\x73\x73\xf3\x92\x15\x2b\x56\
\x9c\xcd\xce\xce\x1e\x8c\x89\x89\x09\x7e\xbf\xf7\xdc\xd1\x55\x2a\
\xd5\xcd\xed\xdb\xb7\x1f\x18\x1f\x1f\x57\xb8\x5c\x2e\xd4\xd4\xd4\
\xe0\x93\x4f\x3e\xc1\xd4\xd4\x14\x8e\x1e\x3d\x8a\x70\x38\x8c\xfe\
\xfe\x7e\xd5\x97\x5f\x7e\x59\xba\x7d\xfb\xf6\xfd\x09\x09\x09\xe3\
\x7a\xbd\xfe\x66\x52\x52\xd2\x44\x5e\x5e\x5e\xcf\xf2\xe5\xcb\x8f\
\xee\xde\xbd\x5b\x3d\x34\x34\x04\x04\x02\x01\x88\xa2\xf8\x83\x5b\
\xad\xd6\x94\xcd\x9b\x37\xef\xcb\xcc\xcc\xec\xa1\x28\x2a\x7a\x37\
\x90\x1f\x7b\x45\x45\xc5\xc9\xa6\xa6\xa6\xf8\xa7\x9e\x7a\x0a\x9b\
\x37\x6f\x86\xd7\xeb\x85\x28\x8a\xe0\x79\x9e\x7c\xe3\x8d\x37\x76\
\x99\x4c\xa6\xcb\x77\xd2\xc5\xc7\xc7\xfb\x0f\x1f\x3e\xbc\xcd\x62\
\xb1\x50\xe8\xee\xee\x86\xdd\x6e\x07\xc7\x71\xe4\xf9\xf3\xe7\x97\
\x56\x56\x56\xfe\x99\x61\x18\xef\xfd\x80\xdc\xe6\x42\x75\x75\xf5\
\x8b\x65\x65\x65\xb8\x76\xed\x1a\xba\xbb\xbb\xe1\x70\x38\x24\xef\
\xbc\xf3\xce\x8e\x7b\x69\x8b\x8b\x8b\x2f\x45\x22\x11\xe0\xe3\x8f\
\x3f\x46\x6b\x6b\x2b\x75\xe5\xca\x95\xac\x45\x8b\x16\x5d\x92\x4a\
\xa5\xec\x2f\x84\x11\x01\x88\x7a\xbd\xbe\xf7\xc3\x0f\x3f\x8c\xf7\
\x78\x3c\xb8\x7a\xf5\x2a\x1a\x1a\x1a\x56\xa8\xd5\xea\xf1\xbb\x69\
\x48\x92\x14\x57\xad\x5a\xd5\xd4\xd0\xd0\x20\xc1\x9e\x3d\x7b\x50\
\x57\x57\x67\xaa\xac\xac\xfc\xec\xd7\x80\x4c\xbb\x44\x22\x09\x5d\
\xb8\x70\xa1\x62\x70\x70\x10\x13\x13\x13\xd2\xb5\x6b\xd7\x1e\xbf\
\x97\x86\x24\x49\x51\xaf\xd7\x1f\x2b\x2e\x2e\x96\xe1\x8b\x2f\xbe\
\x90\xbf\xf6\xda\x6b\x7b\x62\x62\x62\xd8\x07\x01\x04\x40\xac\xaa\
\xaa\xaa\xf5\x7a\xbd\xb0\x5a\xad\xc9\x2a\x95\x6a\xfc\x5e\xed\x09\
\x82\xf0\x90\x24\x69\x92\xcb\xe5\x80\xcd\x66\x63\x4a\x4a\x4a\x9a\
\x1f\x14\xcc\xf7\xd3\xd6\x27\x8a\x22\xda\xda\xda\x8c\x04\x41\x44\
\xee\x02\x22\x30\x0c\x23\x32\x0c\xb3\xf7\x87\x3d\x6e\xf6\xec\xd9\
\x91\xc9\xc9\xc9\x38\x3c\x40\x23\x49\x92\x39\x73\xe6\x8c\x7a\x60\
\x60\xe0\xa6\xc9\x64\x32\xcf\xd4\x4e\xa1\x50\x04\x4a\x4b\x4b\x8f\
\xeb\xf5\xfa\xff\x4e\x4a\x4a\x82\x4c\x26\x03\xf5\xd6\x5b\x6f\xf1\
\x76\xbb\x3d\xbd\xbd\xbd\x7d\x11\xc7\x71\xe4\x83\x00\x12\x45\x51\
\x50\xa9\x54\x5f\xd3\x34\x3d\xb0\x62\xc5\x8a\xc0\xa9\x53\xa7\x56\
\x33\x0c\x13\x8d\x44\x22\x54\x5c\x5c\x9c\x10\x8d\x46\x89\xbc\xbc\
\xbc\x2b\x3b\x76\xec\xd8\xb7\x64\xc9\x92\x3f\x46\x22\x11\x9b\x5c\
\x2e\x07\xcf\xf3\xb7\xae\xd2\x1a\x8d\xe6\xa0\x46\xa3\xc9\x71\xb9\
\x5c\x4f\x8a\xa2\x18\x66\x59\x56\xf6\x6b\x80\x7c\x3e\x9f\xa2\xa8\
\xa8\x48\x91\x99\x99\x29\x14\x16\x16\xd6\xc9\xe5\x72\xcf\xbe\x7d\
\xfb\x9e\x59\xb6\x6c\x99\xbb\xb5\xb5\x55\xaf\xd3\xe9\x2e\x6c\xda\
\xb4\xe9\xff\x8c\x46\xe3\x90\x4c\x26\xf3\x6a\xb5\x5a\x74\x75\x75\
\xa1\xa3\xa3\xe3\x16\x50\x34\x1a\x1d\x15\x04\xa1\x42\x22\x91\x6c\
\x32\x99\x4c\xab\xe2\xe2\xe2\x62\x1b\x1b\x1b\x4b\x55\x2a\x55\xf0\
\xe6\xcd\x9b\x0c\xc7\x71\xf7\x75\x27\x26\x08\x42\xa0\x69\x9a\xca\
\xcd\xbd\x75\x7a\xf5\xfb\xfd\x67\x0c\x06\xc3\x99\x92\x92\x92\x39\
\xa1\x50\xe8\x3b\xa3\xd1\x48\x26\x25\x25\x09\x32\x99\x0c\x2c\xcb\
\xc2\x68\x34\x42\xaf\xd7\x23\x3b\x3b\xfb\xef\x8b\x0d\xa2\x28\xfe\
\x49\x10\x84\x4f\xd7\xac\x59\x93\xf1\xde\x7b\xef\x85\x76\xef\xde\
\x5d\x66\x34\x1a\xe9\xb6\xb6\xb6\xc5\x9f\x7d\xf6\xd9\x6a\x00\xd4\
\xcf\x05\x1a\x1d\x1d\x35\xc8\x64\x32\x70\x1c\x07\x97\xcb\x85\xf2\
\xf2\x72\x98\xcd\xe6\xef\x48\x92\x44\x72\x72\xb2\xa0\xd1\x68\x10\
\x0c\x06\x41\x10\x04\x58\x96\x05\x41\x10\x30\x99\x4c\x77\xbc\x0a\
\x7b\xbd\x5e\x6f\x77\x4a\x4a\x4a\xcf\xd2\xa5\x4b\x0f\xe4\xe7\xe7\
\xff\xe9\xe8\xd1\xa3\xeb\x2e\x5e\xbc\xb8\xbc\xb2\xb2\xf2\xe4\xcf\
\x01\xe2\x38\x4e\x2a\x91\x48\xa2\x04\x41\x40\x14\x45\x6c\xdf\xbe\
\x1d\xa3\xa3\xa3\x18\x1e\x1e\x46\x4a\x4a\x0a\x72\x72\x72\x10\x8d\
\x46\x41\x10\xc4\xed\x83\x81\x40\x20\x30\xf3\xdd\x3c\x14\x0a\x21\
\x18\x0c\x82\xa6\x69\xaf\xcf\xe7\x13\x4b\x4b\x4b\xff\x56\x5f\x5f\
\x5f\x55\x53\x53\xf3\xef\x0c\xc3\xdc\xb3\xce\x22\x93\xc9\x38\x9e\
\xe7\xc1\x71\x1c\x08\x82\x40\x79\x79\x39\x52\x53\x53\x31\x6f\xde\
\x3c\x28\x95\x4a\x70\x1c\x77\xe7\x15\x7a\xaf\xc0\x82\x20\x40\x14\
\x45\xf8\x7c\x3e\x8c\x8d\x8d\xc1\x64\x32\xfd\x7e\xcb\x96\x2d\x35\
\xf7\xd2\xcd\x99\x33\xc7\x3e\x5d\x95\x8b\x44\x22\x28\x28\x28\xc0\
\xeb\xaf\xbf\x8e\x82\x82\x82\xe9\x63\xc8\x2f\x03\xfa\xb1\x75\x74\
\x74\x70\x6b\xd6\xac\xd9\xbb\x6e\xdd\xba\x19\xa7\xcf\x64\x32\xf5\
\x4f\x4e\x4e\x8e\x34\x35\x35\xc1\x66\xb3\x41\x22\x91\x20\x1c\x0e\
\x83\xe7\xf9\x1f\x8e\xbc\x4a\xa5\x12\x82\x20\xfc\x04\xec\xbe\x2b\
\x4a\x52\xa9\x14\x0a\x85\x62\xea\xcd\x37\xdf\x7c\xc5\x6e\xb7\x67\
\xb5\xb4\xb4\xcc\xbf\x3d\xa8\x44\x22\x11\x93\x92\x92\xfa\x1a\x1a\
\x1a\x6e\xea\xf5\x7a\x0c\x0c\x0c\x20\x3f\x3f\x1f\x19\x19\x19\x50\
\xab\xd5\x88\x44\x22\x00\x00\xb5\x5a\x0d\x86\x61\xe0\x76\xbb\xc1\
\xb2\x2c\x48\x92\x04\x41\x10\xf7\x0f\x34\x5d\xad\xf5\xfb\xfd\xdf\
\xe9\x74\xba\x6d\x52\xa9\xf4\x50\x34\x1a\xcd\xa3\x69\x3a\x12\x0e\
\x87\xa5\x85\x85\x85\x37\x04\x41\x38\x66\xb7\xdb\xed\x5e\xaf\x17\
\xe3\xe3\xe3\xb0\xdb\xed\x30\x1a\x8d\xc8\xcb\xcb\x83\xc1\x60\x00\
\xc3\x30\x08\x87\xc3\x90\x4a\xa5\xd0\xe9\x74\xf0\xfb\xfd\xf0\x78\
\x3c\x88\x44\x22\xbf\x0c\xe8\xb6\xf2\x5d\x0b\x80\x85\x14\x45\xbd\
\xf6\xe4\x93\x4f\xe6\xb3\x2c\x3b\xb5\x71\xe3\xc6\xbf\x74\x74\x74\
\xb4\x9a\xcd\x66\x4c\x4d\x4d\x21\x12\x89\xc0\xe3\xf1\xc0\xe1\x70\
\x60\x6c\x6c\x0c\x39\x39\x39\xc8\xc9\xc9\x41\x6a\x6a\x2a\x48\x92\
\x44\x24\x12\x01\xc3\x30\x88\x8d\x8d\x85\xd7\xeb\xfd\x75\x40\xd3\
\xd5\x3f\x51\x14\xff\x4b\x22\x91\xcc\xde\xb4\x69\x93\x63\x72\x72\
\x52\xba\x70\xe1\xc2\x88\xc1\x60\x80\xd9\x6c\x46\x5f\x5f\x1f\xdc\
\x6e\x37\x42\xa1\x10\x9c\x4e\x27\x9c\x4e\x27\x2c\x16\x0b\xf2\xf2\
\xf2\x90\x95\x95\x05\xad\x56\x0b\x9e\xe7\x21\x08\x02\x66\xcd\x9a\
\x85\xff\x1f\x00\x22\x1e\x83\x11\xc8\x4f\x82\x09\x00\x00\x00\x00\
\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x11\x4b\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x2c\x00\x00\x00\x32\x08\x06\x00\x00\x00\x27\x58\x39\xea\
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\
\x01\x00\x9a\x9c\x18\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\
\x25\x00\x00\x80\x83\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\
\x30\x00\x00\xea\x60\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\
\x46\x00\x00\x10\xd1\x49\x44\x41\x54\x78\xda\xac\x98\x5b\x6c\x1c\
\xd7\x79\xc7\x7f\xe7\x32\x33\x7b\xe3\x2e\x6f\xa2\x68\xaa\x94\x1c\
\xc5\xa2\x75\xa1\x68\x45\x69\x62\xa9\x32\x6c\xa9\xb5\x61\x20\x70\
\x02\x03\x95\x03\x01\x79\x29\x90\xc6\x01\x02\x14\x01\x92\x97\xb4\
\x40\xde\xda\x87\x1a\x6e\x1d\x24\x2f\x8a\x6b\xc7\x80\x5b\x3b\x85\
\x82\x16\x88\x1f\x8c\x2a\x8e\xe3\x42\x6e\x24\x07\xb1\xab\xc8\x96\
\x2d\x33\x96\x68\x49\x94\x48\x8a\x12\x29\x2e\xf7\x3e\x97\x73\xfa\
\x30\x97\xdd\x15\x05\xa4\x40\x3b\x04\xc9\xd9\x73\x66\x76\xfe\xdf\
\x77\xfe\xdf\xff\xfb\x9f\x11\x42\x88\xc7\x73\xa3\x95\xbd\x4e\xd1\
\x1b\x00\xac\xb0\xd6\x02\x18\x2c\xc6\x1a\xa4\x94\x48\x21\x88\x4c\
\x44\x7a\x08\x91\x9d\x22\xa5\x44\xd0\x33\x20\xe2\x5f\xd1\xf3\x31\
\x3e\x6c\xef\x87\xbe\xcb\xe3\x2f\xe2\xae\x87\x00\xa4\x14\xc2\x44\
\x66\xad\x3a\x5f\x7d\x5b\x4b\x47\x8d\x4f\x1e\xde\x7b\x6c\x78\xcf\
\xb6\xfb\x2c\x46\x08\x63\x40\x80\x1f\xf9\x04\xc6\xc7\xd1\x0e\x9e\
\xe3\xd2\x0e\xda\x08\x22\xac\x00\x21\x41\x08\x8b\xc5\xe2\x28\x45\
\x4e\xbb\x28\xa5\x00\x8b\x90\x09\x60\x11\x03\x94\x80\x15\x02\x81\
\x45\xa6\x73\x98\x38\x68\x29\x10\xc2\x22\x2c\x08\xd5\x45\x28\xd2\
\x40\x64\xfc\x7d\xda\x53\xf8\xd5\xf6\xed\x5f\xff\xc3\xe9\x1b\x1a\
\x21\xa4\x5b\x74\x8b\xde\x90\x57\x31\x58\xda\xad\x06\x9e\x76\xf9\
\xe2\xbd\x0f\xb0\xeb\x9e\xed\x7c\xb4\x38\xcb\x27\x37\xaf\x70\x74\
\xe7\xe3\x0c\xe4\x8a\x58\x2c\x02\x8b\x56\x9a\x56\xd8\xe2\xc3\xa5\
\x8f\xb9\xb8\x72\x19\x84\xc5\xd1\x0e\x02\x9b\xac\x42\x2f\xc0\xf8\
\x1e\x21\xe3\x4c\x8a\x74\x95\x92\xc0\x05\xf4\x04\x0a\x24\x41\x90\
\x24\x47\xe7\x04\xca\x31\x42\x6a\xe9\x6a\xc0\x5a\x13\x85\xc2\xfa\
\x46\x12\xc9\x4e\x50\x43\xe0\x31\xbd\x79\x3b\x7f\xf1\xe0\x9f\xf3\
\x1f\x1f\xbd\xc5\xf5\xd5\x6b\x3c\x35\xf3\x38\x13\x83\xe3\x08\x6b\
\x01\x49\x64\x23\xea\x7e\x83\xdf\x0e\x6f\xe5\x5f\xde\x3d\xc1\xdc\
\xea\x65\x86\x4a\x95\x2e\x60\x0c\xd6\x82\x90\x02\xb0\xf1\xa8\x00\
\x61\x32\x82\x20\x0c\x58\x11\x07\x62\x4d\xb2\x6a\x49\x40\x46\x12\
\x3f\xcb\x82\x8d\x14\x36\x8c\x42\x81\x35\x1a\xc0\xca\x08\xd7\x81\
\x6d\xde\x26\x1a\x5e\x89\x85\x60\x8d\xb3\x8b\xe7\x18\x38\xe7\xf2\
\xe9\xca\x3c\x56\x44\xbc\x77\xed\x77\xcc\xad\x0e\x62\xac\x21\xb0\
\x11\x93\x83\xf7\xb0\x6b\x6c\x8a\xfb\xc7\xb6\x33\x3c\x50\xe6\x52\
\x35\x40\x29\x93\xf1\x5b\xa4\x5c\x96\xb6\xcb\x67\x95\xf2\xdf\x26\
\xfc\x4f\xb2\x29\xbb\xf7\xa4\xf7\x4b\x05\x22\xa9\x0e\x2d\x15\x51\
\x52\x2b\x3a\xfe\x22\x83\xd6\x82\xd1\x5c\x99\x01\x37\xc7\xed\x56\
\x9d\x85\xda\x22\xef\xcc\xbd\xc7\x7a\x50\xa3\x6d\x1a\xfc\xe4\xdd\
\x57\x90\x52\x61\x6c\x44\x23\xa8\x73\x78\xfb\x43\xfc\xd5\xa1\xa7\
\x63\x9e\x2a\x8b\x72\x2c\x52\x19\x84\x10\xd9\x52\xca\xac\x08\x6d\
\x17\x8c\xec\x9e\x67\x63\xa2\x4b\x93\xb4\x80\xa5\x4c\xcf\x05\x5a\
\x48\xb4\x8c\xa3\xd2\x42\x80\x56\x12\xb4\xe5\x8a\x5d\xa6\xda\x5c\
\x23\x24\xe2\x91\x6d\x07\x79\x6c\xc7\xc3\xbc\xbf\x74\x9e\x7f\xfd\
\xe0\xdf\x58\xf5\x1b\x31\x18\x0c\xb5\x4e\x95\x95\xd6\x32\xed\xb0\
\x93\xf0\xcf\xa0\xb4\x45\xea\x1e\x20\x69\x66\x93\x02\x8c\x0b\x35\
\xfe\x2c\x45\x17\x5c\x7c\xbd\xc8\x44\x24\x1d\x4b\xf5\x43\x00\x4a\
\x4a\x14\x32\xce\x36\x80\x52\x16\xa5\x0c\x2d\xdb\xa0\x16\xae\x93\
\xf3\x72\xdc\x3b\xb2\x85\xfd\x5b\x67\x88\xa4\x8f\xfe\x58\x30\xe2\
\x0d\xe0\x28\x0d\x58\x0a\xbe\x62\xb0\x38\x80\x96\x12\x3f\xb2\x48\
\x05\x4a\x83\xd2\x06\x21\x05\x22\x51\x05\x54\x22\x4b\x3d\x19\x44\
\x88\x58\x15\x04\x88\x04\x84\x48\x52\x2c\xd2\x9f\x04\x70\x3c\x67\
\x51\x42\xa2\x44\x46\x09\x8b\xd5\x06\x57\x0b\xf6\xc8\x7b\x59\x29\
\x96\xb9\xa6\x6e\xd2\xb0\x75\x8c\x35\x34\xc3\x16\x52\x46\xf1\xfa\
\x4a\xb0\xd6\x62\x45\x00\x32\xca\xaa\x5a\x29\x83\xd6\x71\x96\xd3\
\x4c\xa6\x00\x25\x5d\x2e\xa6\x64\x95\x42\x74\xaf\x41\xc4\x52\x89\
\xe8\xbf\x36\xcb\xb6\x44\x8b\x98\x16\xa4\x1c\x96\xc2\x22\xb4\xa1\
\x99\x6f\x51\xb7\x0d\xac\x09\x51\x42\x90\xb6\x10\x74\x14\xeb\xaa\
\x02\xac\x05\x1d\x62\x65\x88\xb5\x31\x1f\xa5\x06\xe9\x58\x94\x92\
\x09\x98\x3b\x1f\x1a\x9f\xc9\x6c\x5c\x64\x5a\x2b\xb2\xf3\x6e\xb5\
\x4a\x12\x9a\x24\x87\x12\x12\x19\x93\x3a\x06\xec\x2a\x89\xd0\x86\
\xcb\xc1\x35\x56\x83\x55\x8a\x6e\x1e\x57\x49\x94\x94\x4c\x0c\x4c\
\xf0\xc0\xf8\x0c\x81\xed\xe0\x48\x85\xc1\xd0\x31\x1d\x76\x8d\xde\
\x4f\xc9\x2b\xd2\x6c\xd6\x91\x52\xa2\xa5\xc2\x49\xbb\x9e\xe8\xe5\
\x63\x17\xba\x64\x63\x20\x19\x60\xd1\x1b\x0a\x3d\xc1\x91\x50\x22\
\x51\x8c\xf8\xaf\xc1\xd1\x92\xb1\xf6\x28\x25\xe1\x52\x77\x6b\x74\
\x44\x1b\x80\x1d\x23\x3b\xf8\xeb\x43\x7f\x93\x34\x8c\xae\xa6\xba\
\xd2\xc1\x51\x2e\xc6\xc4\x4d\xc1\x91\x12\x2d\xd4\x5d\x38\xd8\x03\
\x52\x80\x4c\x7b\xb0\x20\x0e\x20\xe1\x86\xec\xcd\xb3\xe8\xd2\x03\
\x04\x8e\xd4\x84\x22\x44\xa6\x19\x0e\xe9\x10\x8a\x16\x15\x2f\x8f\
\xeb\x5a\xd6\xec\x32\xbf\x5b\xfe\x2d\x6f\x5f\xfd\x0c\x93\x03\xdb\
\x30\x98\x4c\x3b\x41\x60\x85\xc5\x51\x2e\xad\xa0\xc5\x6f\x17\x7f\
\xcd\x52\x7d\x1e\x47\x6a\x22\x13\xf6\x78\x0d\xd1\x27\x55\xc2\x0a\
\x84\x04\x93\xb4\xba\x38\xf4\x24\x1c\x03\xa6\x87\x26\x08\x91\xa5\
\x07\x04\xd2\x58\x22\x1b\xc4\x6c\x4c\x5a\x09\x46\x77\xb8\xe6\x5c\
\x21\xf0\x43\x84\x6f\xb9\xba\x76\x89\x9f\x9c\x3f\x4e\x51\x97\xb2\
\xee\x45\x5a\xd9\x22\x16\xf3\xd0\x44\xd4\xfc\x2a\x7e\xd8\xc2\x93\
\x2e\xc6\x26\x80\x6d\xb7\x01\x58\x04\x12\x99\x2c\xb9\x88\x57\xca\
\xc4\xf3\x36\xad\x5a\xdb\x6f\x85\x44\x6f\x07\x41\x80\x15\x60\x63\
\xf3\xa5\xb5\xd4\x7c\xe1\x9e\x2f\xb2\x77\xcb\x34\xd7\x16\xe7\x91\
\xc2\x61\x72\x72\x0b\x48\x4b\xb5\x5d\xc5\x60\x92\xa5\x4b\x2a\x9c\
\xae\x6c\x09\x04\x9e\xce\x91\xd7\x05\x94\x90\x64\x06\x20\x91\x32\
\x9b\x70\x11\x12\x93\x23\x04\x58\x99\x65\xde\x26\xca\xd0\x0d\x4d\
\x74\x33\x2f\xba\x73\x6e\xde\xa5\x5a\xac\x72\xd2\x7b\x17\xad\xa5\
\xc3\xa1\xc9\xc3\xfc\xd9\xb6\x3f\xe5\xe3\xda\x2c\x9e\xca\x31\x75\
\xdf\x0e\xdc\xbc\x4b\x14\x46\x3d\x81\x66\xeb\xd8\x53\x20\x49\x02\
\xd8\xe8\x1c\x45\xcf\xb8\xed\xb5\xa4\x7d\x17\x27\x7a\x4d\xef\x64\
\x8f\xe9\xb4\xb1\x23\x54\x5a\x73\x33\xb7\xcc\xa0\xf7\x22\x5a\x20\
\x28\xc8\x22\x63\xc5\xcd\x94\x76\x57\x30\x61\x44\x31\x57\x8c\x0d\
\x89\x06\x8b\xc9\x9e\x26\x65\x5c\x60\xbd\x99\xa4\xef\x54\x60\xad\
\xec\x33\xb3\x22\x31\x40\xb1\x44\xf6\x02\xb2\x58\x0b\x32\x99\x8b\
\x8b\x3a\xc3\x99\x74\xcb\xae\xb1\x2e\xa8\x32\x4a\x3a\x71\xd1\x35\
\xfd\x26\x9d\xa8\x83\xc8\x43\x14\x84\xd4\xfc\x75\xea\xf5\x06\xf5\
\x7a\x3d\xb9\x51\x22\x05\x18\x2b\x89\xac\xca\xba\x12\x3d\x5d\x0a\
\x40\xcb\x08\x95\x70\xd0\xf6\x48\x55\xb2\x27\x48\x9c\x5b\xf7\x5e\
\x6b\x6d\xa2\xe5\xa2\xef\x3b\x8d\x31\x58\x6b\x29\x16\x8b\x0c\x0e\
\x0e\xe2\x38\x0e\x91\x0d\x31\xd6\x24\x3a\xec\x38\x84\x51\xc4\xfb\
\xe7\xce\x51\x2c\x16\xb9\xf7\x33\x9f\xa1\xd9\x6c\x72\xf3\xc6\x0d\
\xf2\x85\x02\x5a\x2b\xa4\x12\xac\x34\xf3\x5c\x6d\x55\x70\xb5\x44\
\x09\x8b\xb1\xa0\x24\xf8\xa1\xc4\x98\x90\x2d\xb9\x15\x36\x17\x5a\
\x44\x56\x66\x80\xad\xb5\xd4\xeb\x75\x94\x52\xe4\xf3\xf9\x6c\x2c\
\xfd\x5f\xab\xd5\x70\x1c\x87\x5c\x2e\xd7\x65\xb3\xb5\xb4\x5a\x2d\
\xca\xe5\x32\xe5\x72\xb9\x8f\x6a\x3a\xbd\x40\x0a\x41\xa5\x52\xc1\
\xf3\x3c\xb0\x16\x61\x2d\xf9\x7c\x9e\x81\x81\x12\x4a\x49\xb4\x12\
\xd4\x45\x09\xcd\x30\x9e\x2b\x50\x12\x22\x0b\x5a\x02\x11\x84\xbe\
\x8f\xe3\xb6\xc9\xe5\x2d\x91\xe9\x02\x36\xc6\xe0\xfb\x3e\x4a\x29\
\x72\xb9\x1c\x52\x4a\x8c\x31\x19\xe0\x4e\xa7\x83\xe3\x38\xe4\xf3\
\xf9\x0c\x6c\x3a\xa7\x94\xca\x56\xa7\x0f\x70\x18\x86\x28\xa5\x98\
\xda\xb9\x13\x13\x19\x3a\xed\x16\x61\xe8\x63\xc2\x80\xd0\xef\x80\
\x96\x08\x23\x31\x51\x80\x14\x06\x29\x54\x57\x05\x00\x25\x20\x14\
\x96\x8e\xdf\xa1\xd1\x68\x60\xac\xea\xa3\x84\xef\xfb\xd9\xb9\x94\
\xb2\x4b\x83\x64\xce\x18\xd3\x07\xca\x5a\x4b\xbb\xdd\xc6\x75\xdd\
\x0d\x7b\xbc\xc4\xad\x29\x8c\x31\xcc\x5f\xb9\x42\x4e\x0b\x2a\x23\
\x9b\xe8\x38\xa3\x5c\x6f\x0b\x9c\x20\xee\xe3\xa1\x31\xd4\x42\xc1\
\xc0\xb0\x65\xb8\x10\x7b\x0b\x6b\x41\x69\x45\x27\x80\x46\x50\xc7\
\x31\x4d\x1c\xd7\x05\x54\x2c\x59\x52\x12\x45\x11\x5a\xeb\x0d\x19\
\x4e\xff\x3b\x8e\x93\xcd\xdd\x99\x61\x29\xe5\xdd\x01\xa7\x37\x2f\
\x2e\x2c\x52\x29\x38\x94\x07\x37\x61\xbd\x51\xa2\xf2\x20\xda\xb1\
\xf8\x91\xa0\x1d\x5a\xda\x1d\xc9\x81\x2d\x92\xf1\x72\x4f\xfb\x15\
\xd0\x69\x77\xb8\x9d\x6b\xa2\xa8\x30\xb6\x79\x73\x9f\x71\x89\xa2\
\x88\xb5\xb5\x35\x1c\xc7\xa1\x54\x2a\xf5\x81\x88\xa2\x88\xd5\xd5\
\x55\x72\xb9\x1c\xa5\x52\xa9\xef\xbe\x5a\xad\x46\xab\xd5\xda\x90\
\x7d\x9d\xde\xa8\x94\x62\x66\xef\x34\x5a\x46\x18\x21\x68\x87\x02\
\x5f\x78\x00\x04\x06\xda\x06\x5a\x06\xc2\xa0\x85\x08\x03\x24\x12\
\x63\x05\x52\x2b\x08\x1a\x18\xbf\x89\x93\x2b\xc4\xdd\x2c\x55\x05\
\xd1\xad\xfa\x28\x8a\xb2\xb1\xde\xf9\x54\x11\x7a\x8f\x34\xa8\x54\
\x45\x36\x00\xee\x95\x1f\x63\x05\x52\x82\x8c\x9a\xd8\x96\xc0\x68\
\x85\x06\x72\x56\x60\x6c\xc8\xcd\x1b\x37\x51\xf5\x0e\x20\x88\xac\
\xc0\x75\x1d\xc2\x30\xe4\xda\xb5\x25\x6a\xb5\x75\x76\xef\xde\x4d\
\xa1\x50\xe8\x5b\xf6\xb5\xb5\xb5\x8c\x1e\x4a\x29\xc2\x30\xcc\x40\
\x55\xab\x55\x9a\xcd\x26\x41\x10\x64\x18\x94\x52\xac\xaf\xaf\xc7\
\xdd\xee\x0e\x5a\xf4\x71\xf8\xc2\x85\x8f\x29\x15\x0b\x6c\xdf\xbe\
\x9d\x21\xbd\xce\x66\xb1\x46\xc1\x2b\xe2\x68\x89\xd4\x8a\x46\xa3\
\xce\xa0\x27\x28\x14\x4a\x08\x29\x88\x8c\xc5\x71\x1c\x00\x72\xb9\
\x5b\x2c\x2f\xb7\x50\x4a\x51\x28\x14\x88\xa2\x28\x03\xe9\xba\x6e\
\xa6\x04\xe9\x58\x5a\x7c\x8e\xe3\xe0\x79\x1e\x9e\xe7\xf5\x15\x64\
\x2e\x97\xcb\x56\xe5\xae\x94\x00\x18\x1a\x1a\x24\x97\x2f\x60\x01\
\xc7\x34\xd8\xe4\x56\x19\xc8\x5b\xb4\x56\x68\x57\xb3\x1e\xd6\x18\
\x1e\xd9\xc2\xe8\xa6\x71\x84\x20\xcb\xa2\xb5\x96\x30\x0c\x19\x19\
\x19\x61\xcb\x96\x2d\x59\x10\x29\x1d\x82\x20\xc0\xf3\x3c\x86\x86\
\x86\x36\x00\x08\xc3\x90\x4a\xa5\xb2\x41\x11\x1c\xc7\xa1\x5a\xad\
\xde\x9d\x12\xc6\x18\xb4\xd6\x4c\xed\xd8\x81\x05\xda\x9d\x0e\x1d\
\xdf\xd0\xf4\x81\x66\x80\x72\x40\xf9\x96\x7a\xcb\xe2\x36\xdb\xb8\
\xeb\xd5\x3e\x05\x08\x82\x80\x20\x08\x18\x18\x18\xc0\xf7\x7d\x5a\
\xad\x56\xc6\xc5\x28\x8a\x68\xb5\x5a\x04\x41\x90\xa9\x45\x9a\x61\
\xa5\x14\xb5\x5a\x8d\x5b\xb7\x6e\x51\xa9\x54\x28\x97\xcb\x19\x0d\
\xd6\xd7\xd7\x33\x9a\x6c\x00\xac\xb5\xc6\x18\xc3\xe5\xf9\x79\x1c\
\xcf\x63\x64\x64\x04\xa9\x24\xad\x76\x1b\x93\x2c\x9b\x10\x82\x76\
\xbb\x4d\x6d\x7d\x3d\xdb\x06\xa5\x80\xc3\x30\xa4\x56\xab\x21\xa5\
\xa4\xd3\xe9\x74\xcd\x51\x72\x4d\xad\x56\xcb\x9a\x40\xaf\x64\xad\
\xaf\xaf\x73\xf2\xe4\x49\xde\x7c\xf3\x4d\xee\xb9\xe7\x1e\xbe\xf1\
\x8d\x6f\x30\x39\x39\x49\x18\x86\xd4\xeb\xf5\xec\xb9\x77\x2d\xba\
\x30\x0c\x99\xbf\x76\x8d\x72\xa5\xc2\xd0\xf0\x30\xae\xeb\x52\x2e\
\x97\x19\x18\x18\x40\x29\x85\xd6\x9a\x6a\xb5\xca\xe6\xcd\x9b\x19\
\x19\x19\xc9\x00\x48\x29\xf1\x7d\x9f\xd5\xd5\x55\x84\x10\x8c\x8e\
\x8e\xf6\x71\x31\x0c\x43\x5c\xd7\xc5\x75\x5d\x86\x86\x86\x92\x77\
\x70\xb1\x6c\x9d\x38\x71\x82\xef\x7f\xff\xfb\x34\x9b\x4d\x72\xb9\
\x1c\x47\x8e\x1c\x61\xff\xfe\xfd\xd9\xb3\x6a\xb5\xda\x06\x59\x93\
\x00\x41\x10\xe0\x38\x0e\x07\x0f\x1e\x64\x7a\x7a\x1a\x29\x44\x5f\
\x77\xea\x35\x30\xa9\xd4\x58\x6b\x33\x49\xea\xe5\x59\xef\x78\xaf\
\x44\x75\x3a\x1d\xc2\x30\xcc\xae\x9b\x9d\x9d\xe5\x87\x3f\xfc\x21\
\xcd\x66\x13\x80\x76\xbb\xcd\x99\x33\x67\xb8\x79\xf3\x66\xdf\x7d\
\x77\xd5\xe1\x34\xcb\xed\x76\x3b\xde\x50\x26\x14\xa9\x56\xab\xb4\
\xdb\x6d\xb4\xd6\x48\x29\x69\xb5\x5a\x99\x31\xe9\xa5\x44\x14\x45\
\x89\xb3\x8b\xbf\x23\x0d\xc2\x71\x1c\xa2\x28\xe2\xcd\x37\xdf\xe4\
\x57\xbf\xfa\x15\x5b\xb7\x6e\xe5\xe8\xd1\xa3\x6c\xdb\xb6\x8d\xf3\
\xe7\xcf\xb3\xbc\xbc\xbc\x81\xa3\x8d\x46\x83\x85\x85\x05\xce\x9e\
\x3d\xcb\xf9\xf3\xe7\x19\x19\x19\xe1\xc9\x27\x9f\x44\x6b\x8d\x10\
\xc9\x36\xdf\x71\x1c\x82\x20\xe0\xbf\xcf\x9e\xa5\x52\x2e\x33\x35\
\x35\x85\xe7\x79\xe4\xf3\x79\x4a\xa5\x12\x4a\x29\x94\x52\x48\x29\
\x19\x1a\x1a\x62\x78\x78\x38\x2b\xa8\xf4\xde\x74\x7e\x74\x74\xb4\
\xaf\x01\xbc\xf5\xd6\x5b\x3c\xff\xfc\xf3\xbc\xff\xfe\xfb\xe4\x72\
\x39\x3c\xcf\xe3\xbb\xdf\xfd\x2e\xe5\x72\xb9\x2f\xe3\x5a\x6b\x8e\
\x1c\x39\xc2\xd8\xd8\x18\x2f\xbc\xf0\x02\x2f\xbc\xf0\x02\x2b\x2b\
\x2b\x0c\x0d\x0d\xd1\x6a\xb5\x38\x7a\xf4\x68\xfc\xae\x1a\xc0\x1a\
\x83\x52\x8a\xcf\x7e\xf6\xb3\x6c\xf9\xa3\x3f\xca\x04\xdf\x75\xdd\
\x4c\x23\x3d\xcf\xc3\x75\x5d\xf2\xf9\x3c\xc5\x62\x91\x42\xa1\x40\
\xa9\x54\x22\x97\xcb\x51\x28\x14\xc8\xe5\x72\xe4\x72\x39\xf2\xf9\
\x7c\xf6\xeb\xba\x2e\xe7\xce\x9d\x63\x76\x76\x96\x56\xab\xc5\xed\
\xdb\xb7\x39\x7d\xfa\x34\xb5\x5a\x8d\x5d\xbb\x76\x51\x2a\x95\x32\
\xc0\x4f\x3d\xf5\x14\x0f\x3c\xf0\x00\x3f\xff\xf9\xcf\x79\xfe\xf9\
\xe7\xb9\x70\xe1\x02\xcb\xcb\xcb\xcc\xce\xce\x72\xfa\xf4\x69\x8c\
\x31\xc2\x75\x5d\x1d\xeb\x70\x22\x6b\x13\x13\x13\x88\x84\xd3\xa9\
\x1c\xa5\x4b\x2b\xa5\xa4\xd1\x68\x50\xad\x56\xfb\x5a\x6c\xaf\x4a\
\x64\x6f\xe4\x13\x69\xf2\x7d\x9f\xc5\xc5\xc5\x3e\x1e\x5e\xbf\x7e\
\x9d\x2b\x57\xae\x70\xdf\x7d\xf7\xf1\xb5\xaf\x7d\x8d\x33\x67\xce\
\x30\x35\x35\xc5\xb7\xbf\xfd\x6d\x56\x57\x57\x79\xf1\xc5\x17\x99\
\x9d\x9d\xcd\xae\xf7\x3c\x2f\xd5\x76\xa7\xdd\x6e\xd7\xb3\x4e\x17\
\x04\x01\x97\x2e\x5d\xa2\x50\x28\x30\x3e\x3e\x9e\x2d\x79\xda\x46\
\x8d\x31\x18\x63\x08\xc3\x30\x5b\xca\x94\xab\xbd\x63\xa9\x76\x4a\
\x19\xbb\xbc\xb1\xb1\x31\xb4\xce\x4a\x85\xed\xdb\xb7\x53\x2c\x16\
\x71\x5d\x97\x6f\x7d\xeb\x5b\x1c\x39\x72\x84\x2d\x5b\xb6\x30\x33\
\x33\xc3\x2f\x7e\xf1\x0b\xe6\xe6\xe6\xfa\x38\xfd\xf9\xcf\x7f\x9e\
\x23\x47\x8e\x70\xf2\xe4\xc9\xff\x9c\x9b\x9b\xfb\x50\xf7\x66\xab\
\xd1\x68\x64\x92\xa4\x94\xa2\x58\x2c\xf6\x71\x58\x29\xc5\xf0\xf0\
\x30\x83\x83\x83\xd9\x75\x69\x26\xd3\xcc\x0e\x0f\x0f\xc7\xbb\x6a\
\x21\x50\x4a\xf1\xd8\x63\x8f\x71\xf2\xe4\x49\xde\x7d\xf7\x5d\x66\
\x66\x66\x78\xfa\xe9\xa7\xd9\xbb\x77\x2f\xd6\x5a\x76\xec\xd8\x41\
\x3e\x9f\xa7\xd3\xf1\xb9\x7e\x7d\x81\x4e\xa7\xc3\xc0\xc0\x00\x00\
\xc5\x62\x91\x7d\xfb\xf6\xf1\xd5\xaf\x7e\x35\x58\x5c\x5c\xfc\xaf\
\x67\x9e\x79\xe6\xef\x96\x96\x96\x66\x33\x03\xef\xba\x2e\x9f\xfb\
\xdc\xe7\x40\x08\x4c\x92\xd9\x5e\x29\xeb\xcd\x68\x14\x45\xd9\x58\
\xaf\x13\xbb\x53\x86\x82\x20\x60\xef\xde\xbd\x1c\x3b\x76\x8c\xed\
\xdb\xb7\xf3\xa5\x2f\x7d\x89\x43\x87\x0e\x71\xf9\xf2\xe5\xcc\xf4\
\x2c\x2f\x2f\x27\xd4\x8a\x9b\xc4\xe1\xc3\x87\x19\x1f\x1f\xe7\xfe\
\xfb\xef\xe7\x2b\x5f\xf9\x4a\x64\x8c\xf9\xf0\xb9\xe7\x9e\xfb\xc7\
\xeb\xd7\xaf\x9f\x99\x98\x98\xe8\x36\x8e\x28\x8a\xe2\x4c\x29\x85\
\x4e\xcc\xd0\xfa\xfa\x3a\xed\x76\x3b\xeb\x38\x9d\x4e\x07\x6b\x2d\
\xcd\x66\x33\xb3\x86\xbd\x1c\x4e\x65\x2d\x05\x9e\xea\xf8\xc3\x0f\
\x3f\xcc\x83\x0f\x3e\x48\xad\x56\xe3\xc7\x3f\xfe\x31\xbf\xfc\xe5\
\x2f\xa9\xd5\x6a\x94\xcb\x65\xf6\xec\xd9\xc3\xee\xdd\xbb\xd9\xb6\
\x6d\x1b\xdb\xb6\xed\xe4\xc0\x81\x03\x99\xff\x38\x7f\xfe\x7c\xe3\
\xb5\xd7\x5e\xfb\x3d\xa0\x8f\x1d\x3b\x56\xa9\x54\x2a\xeb\x99\xac\
\xf9\xbe\xcf\x6f\x7e\xf3\x1b\xca\xe5\x32\xd3\xd3\xd3\xc9\x7e\x6e\
\x80\x62\xb1\x98\xe9\x70\xbd\x5e\x67\x74\x74\x94\xd1\xd1\xd1\x2c\
\x48\xd7\x75\x09\x82\x80\x95\x95\x15\x84\x10\x8c\x8d\x8d\x65\xcd\
\x23\xad\x8f\x8b\x17\x2f\xf2\xb3\x9f\xfd\x8c\x97\x5f\x7e\x99\x85\
\x85\x85\x3e\x8e\xbe\xfd\xf6\xdb\x3c\xfe\xf8\xe3\xfc\xe0\x07\x3f\
\x60\x72\x72\x92\x4e\xa7\xc3\xd2\xd2\x12\x3f\xfd\xe9\x4f\xed\xf1\
\xe3\xc7\xbd\x85\x85\x85\xa7\xc6\xc6\xc6\x1e\xdd\xb1\x63\xc7\x73\
\x8d\x46\xe3\x59\xe5\x79\xde\xbe\x27\x9e\x78\xe2\x4f\xf6\xee\xdd\
\xbb\x69\x64\x64\x44\x6c\xda\xb4\x29\x73\x4a\x9d\x4e\x87\x5c\x2e\
\x97\xf1\x37\x08\x82\xac\x5d\x6b\xad\xb3\x40\xd2\xcd\xa4\x52\xaa\
\x8f\xf3\x5a\x6b\x3e\xf9\xe4\x13\xbe\xf3\x9d\xef\xf0\xca\x2b\xaf\
\xb0\xbe\xbe\xbe\xa1\x51\x44\x51\xc4\xa7\x9f\x7e\x8a\x94\x92\x7d\
\xfb\xf6\x51\xab\xd5\x78\xf6\xd9\x67\x39\x7e\xfc\xb8\x58\x59\x59\
\xd1\x80\xb0\xd6\xba\x61\x18\xda\xd5\xd5\xd5\x7f\xd7\xbd\x37\x57\
\x2a\x15\x84\x10\x99\xfb\x6a\x36\x9b\x99\x74\x09\x21\x68\x36\x9b\
\x99\xac\xa5\xca\x91\xba\xb5\x6a\xb5\x9a\x15\x5b\xea\x23\xae\x5e\
\xbd\xca\xf7\xbe\xf7\x3d\x4e\x9d\x3a\x75\x57\xe7\x95\x1e\xbe\xef\
\xf3\xda\x6b\xaf\xf1\xf5\xaf\x7f\x9d\xcb\x97\x2f\x73\xea\xd4\xa9\
\xbe\xe0\x9a\xcd\x66\x70\xf1\xe2\xc5\x0f\x94\x52\x7e\xb6\xa7\x0b\
\x82\x80\x0b\x17\x2e\x50\x2c\x16\x99\x9c\x9c\xa4\x54\x2a\x61\xad\
\xcd\x2c\x9f\xb5\x96\xb5\xb5\xb5\x3e\x2f\x71\xe7\x4e\xb7\xb7\xcd\
\x03\x5c\xba\x74\x89\x73\xe7\xce\xe1\xfb\x3e\x7f\xe8\x58\x5a\x5a\
\xe2\xbd\xf7\xde\xbb\x79\xf9\xf2\xe5\x4f\x17\x17\x17\x77\x00\x43\
\x69\x07\x1c\x1f\x1f\x3f\xe3\xfb\xfe\x3f\x75\x3a\x9d\x76\x56\x74\
\x42\x88\x6c\x67\x90\x66\x6e\x7c\x7c\x9c\xc1\xc1\xc1\x8c\x93\x69\
\xa6\x2b\x95\x4a\xe6\xba\xd2\x15\xb9\x53\xd6\x00\x76\xee\xdc\xc9\
\xd6\xad\x5b\xb9\x75\xeb\xd6\x86\x00\xef\x96\xe5\xd7\x5f\x7f\xfd\
\x6d\xa5\xd4\x4b\x53\x53\x53\x4f\x5c\xbd\x7a\xf5\xc9\x52\xa9\xb4\
\xfa\xe8\xa3\x8f\xbe\xa5\x94\xfa\xe7\x57\x5f\x7d\xf5\x42\xe6\x25\
\xd2\xbd\xd6\xae\x5d\xbb\x32\x93\x93\x9a\xee\xde\x65\xae\xd7\xeb\
\x68\xad\xfb\xb6\x33\xe9\xea\xa4\x86\x28\x75\x5f\x00\x13\x13\x13\
\x7c\xf3\x9b\xdf\xe4\xcc\x99\x33\x2c\x2c\x2c\xb0\xb6\xb6\xc6\xc2\
\xc2\x02\xf3\xf3\xf3\x1b\x00\x4b\x29\xf9\xe8\xa3\x8f\xae\x6f\xde\
\xbc\xf9\xcc\xc1\x83\x07\x67\xa7\xa7\xa7\xdf\xa8\xd7\xeb\xeb\x33\
\x33\x33\x1f\xb6\x5a\xad\x85\xb4\x31\xf5\xc9\xda\xad\x5b\xb7\x50\
\x4a\x51\xa9\x54\x28\x14\x0a\x99\x1f\x4d\xad\x5e\xaa\xb7\xa9\x84\
\xa5\x59\x4f\xb5\x58\x08\x41\xbd\x5e\xcf\xec\xa5\x52\x8a\x2f\x7f\
\xf9\xcb\x1c\x38\x70\x80\xdb\xb7\x6f\xe3\xfb\x3e\x73\x73\x73\xbc\
\xf1\xc6\x1b\x9c\x3a\x75\xaa\xcf\xad\x09\x21\xd0\x5a\x17\x82\x20\
\xc8\x8d\x8c\x8c\x7c\x32\x31\x31\xf1\xc9\xc5\x8b\x17\xb3\x6d\x52\
\x66\x05\x00\x91\x6e\x42\xe7\xe6\xe6\xf0\x3c\x8f\x99\x99\x19\x36\
\x6d\xda\x44\x2e\x97\xeb\x7b\xa1\x31\x38\x38\x98\x01\xed\x7d\x90\
\x10\x22\xa3\x4e\x6f\xf3\x48\xed\xe7\xd0\xd0\x50\xe6\x2f\x1e\x7a\
\xe8\x21\x0e\x1d\x3a\xc4\xcb\x2f\xbf\xcc\x8f\x7e\xf4\xa3\x6c\x3b\
\x15\x04\x01\xe3\xe3\xe3\xb6\x58\x2c\x8a\x74\xe7\x12\x86\x61\xdf\
\x6b\x81\x34\xc3\x46\x29\xa5\x0b\x85\x82\x9c\x9e\x9e\x46\x08\x11\
\xbf\x5f\x83\x0d\x2f\xe2\xfe\x2f\x47\xda\x98\x1c\xc7\x61\x62\x62\
\x62\x6d\xcf\x9e\x3d\x1f\xec\xdf\xbf\x5f\xbd\xf3\xce\x3b\x5f\x88\
\xa2\xc8\xf1\x3c\x2f\x1c\x1c\x1c\x9c\x1d\x1a\x1a\xaa\x85\x61\x98\
\x51\x6c\xc3\x9e\xce\x5a\xbb\xb6\xb2\xb2\x72\x6b\x7e\x7e\x7e\x25\
\x7d\x5d\xb4\xb4\xb4\xf4\x07\x8b\xe4\x7f\x73\xf4\x3e\xd0\x98\x08\
\xad\x1d\xd1\x6e\xb7\xc3\x57\x5f\x7d\xf5\xf5\x13\x27\x4e\xfc\xfd\
\xe1\xc3\x87\xf3\x1f\x7c\xf0\xc1\xdf\x2a\xa5\xfe\x78\xf7\xee\xdd\
\x67\x8d\x31\x6f\xd4\x6a\xb5\xea\xca\xca\x0a\x5a\xeb\x3e\xfb\x99\
\x01\x6e\xb5\x5a\xbf\x7f\xe6\x99\x67\x9e\x7b\xe9\xa5\x97\x2a\x42\
\x08\x6b\x13\xa4\xff\x1f\x80\xef\x38\xac\xeb\xba\xba\xd9\x6c\xae\
\x5e\xb8\x70\xe1\x6c\x3e\x9f\xbf\x62\x8c\x91\x5a\xeb\xbf\x9c\x99\
\x99\x99\x79\xe4\x91\x47\x2e\xde\xb8\x71\xe3\x4a\xa3\xd1\xc8\x76\
\xd7\x77\x3b\xfe\x67\x00\x18\x7d\x83\xf6\xc5\x2b\x17\x8a\x00\x00\
\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
"
qt_resource_name = b"\
\x00\x07\
\x07\x3b\xe0\xb3\
\x00\x70\
\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x73\
\x00\x05\
\x00\x79\xf9\xbe\
\x00\x73\
\x00\x69\x00\x63\x00\x65\x00\x6e\
\x00\x09\
\x09\xc1\xa4\xa7\
\x00\x73\
\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x10\
\x0e\x02\xb7\xc7\
\x00\x73\
\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x5f\x00\x65\x00\x78\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
"
qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\
\x00\x00\x00\x24\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x00\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x8d\
"
qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x24\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x4a\x05\x7c\x00\x4f\
\x00\x00\x00\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x8d\
\x00\x00\x01\x4a\x05\x7c\x00\x51\
"
qt_version = [int(v) for v in QtCore.qVersion().split('.')]
if qt_version < [5, 8, 0]:
rcc_version = 1
qt_resource_struct = qt_resource_struct_v1
else:
rcc_version = 2
qt_resource_struct = qt_resource_struct_v2
def qInitResources():
QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
def qCleanupResources():
QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
qInitResources()
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

+940
View File
@@ -0,0 +1,940 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
SICEN
A QGIS plugin
Filtre sur données SICEN
-------------------
begin : 2014-10-17
copyright : (C) 2014 by Guillaume COSTES (CENRA)
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
# Import the PyQt and QGIS libraries
from builtins import str
from builtins import object
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from qgis.utils import iface"""
from builtins import str
from builtins import object
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from qgis.PyQt import uic
from qgis.core import *
from qgis.core import QgsDataSourceUri, QgsWkbTypes, QgsLayerTreeGroup, QgsLayerTreeLayer
from qgis.PyQt.QtGui import QFont
from qgis.PyQt.QtWidgets import QMenu, QAction, QDialog, QDialogButtonBox, QLabel, QApplication, QTabWidget, QWidget, QGroupBox, QGridLayout, QComboBox, QCheckBox, QCalendarWidget, QToolBox, QFrame, QLineEdit, QSizePolicy, QFileDialog #Modifié
# Initialize Qt resources from file resources.py
from . import resources_rc
# Import the code for the dialog
from .sicendialog import SICENDialog
from .tools.PythonSQL import *
from .tools.resources import maj_verif
import os.path
import qgis
import datetime
import csv
from .forms.about_form import SicenAboutDialog
import psycopg2
import psycopg2.extras
import base64
#import socket
import os
#import sys
class SICEN(object):
def __init__(self, iface):
# 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]
localePath = os.path.join(self.plugin_dir, 'i18n', 'sicen_{}.qm'.format(locale))
if os.path.exists(localePath):
self.translator = QTranslator()
self.translator.load(localePath)
if qVersion() > '4.3.3':
QCoreApplication.installTranslator(self.translator)
# Create the dialog (after translation) and keep reference
self.dlg = SICENDialog()
maj_verif('CenRa_SICEN')
version = qgis.utils.pluginMetadata('CenRa_SICEN','version')
# Display About window on first use
s = QSettings()
versionUse = s.value("sicen/version", 1, type=str)
if str(versionUse) != str(version) :
s.setValue("sicen/version", str(version))
self.open_about_dialog()
def initGui(self):
self.toolBar = self.iface.addToolBar("SICEN")
self.toolBar.setObjectName("SICEN")
## Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/sicen/sicen.png"),
u"Ouverture des données SICEN", self.iface.mainWindow())
# connect the action to the run method
self.action.triggered.connect(self.ouverture)
# Add toolbar button and menu item
self.toolBar.addAction(self.action)
self.iface.addPluginToMenu(u"SICEN", self.action)
## Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/sicen/sicen_export.png"),
u"Export liste d'espèces", self.iface.mainWindow())
# connect the action to the run method
self.action.triggered.connect(self.export)
# Add toolbar button and menu item
self.toolBar.addAction(self.action)
self.iface.addPluginToMenu(u"SICEN", self.action)
self.menu = QMenu()
self.menu.setTitle( QCoreApplication.translate( "SICEN","&SICEN" ) )
self.sicen_ouverture = QAction( QIcon(":/plugins/SICEN/sicen.png"), QCoreApplication.translate("SICEN", u"Ouverture des données SICEN" ), self.iface.mainWindow() )
self.sicen_export = QAction( QIcon(":/plugins/SICEN/sicen_export.png"), QCoreApplication.translate("SICEN", u"Export liste d'espèces" ), self.iface.mainWindow() )
self.menu.addActions( [self.sicen_ouverture, self.sicen_export] )
menu_bar = self.iface.mainWindow().menuBar()
actions = menu_bar.actions()
lastAction = actions[ len( actions ) - 1 ]
menu_bar.insertMenu( lastAction, self.menu )
self.sicen_ouverture.triggered.connect(self.ouverture)
self.sicen_export.triggered.connect(self.export)
def open_about_dialog(self):
dialog = SicenAboutDialog(self.iface)
dialog.exec_()
def unload(self):
# Remove the plugin menu item and icon
self.iface.removePluginMenu(u"&SICEN", self.action)
self.iface.removeToolBarIcon(self.action)
# run method that performs all the real work
def ouverture(self):
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 des listes deroulantes
# Listing de valeur des champs
SQL_observateur = u"""SELECT DISTINCT nom || '_' || prenom as nom FROM md.personne ORDER BY nom"""
SQL_nom_com = u"""SELECT DISTINCT nom FROM saisie.commune ORDER BY nom"""
SQL_nom_vern = u"""SELECT DISTINCT nom_vern FROM _agregation_ra.observations_table ORDER BY nom_vern"""
SQL_nom_complet = u"""SELECT DISTINCT nom_complet FROM _agregation_ra.observations_table ORDER BY nom_complet"""
SQL_ordre = u"""SELECT DISTINCT ordre FROM _agregation_ra.observations_table ORDER BY ordre"""
# Generation des listes
cur.execute(SQL_observateur)
list_observateur = cur.fetchall()
cur.execute(SQL_nom_com)
list_nom_com = cur.fetchall()
cur.execute(SQL_nom_vern)
list_nom_vern = cur.fetchall()
cur.execute(SQL_nom_complet)
list_nom_complet = cur.fetchall()
cur.execute(SQL_ordre)
list_ordre = cur.fetchall()
con.close()
# Ajout des items dans les combobox
self.dlg.observateur_1.clear()
i = 0
while i < len(list_observateur):
self.dlg.observateur_1.addItems(list_observateur[i])
i=i+1
self.dlg.observateur_1.setCurrentIndex(-1) # Pour ne pas commencer la liste au premier item
self.dlg.observateur_2.clear()
i = 0
while i < len(list_observateur):
self.dlg.observateur_2.addItems(list_observateur[i])
i=i+1
self.dlg.observateur_2.setCurrentIndex(-1)
self.dlg.observateur_3.clear()
i = 0
while i < len(list_observateur):
self.dlg.observateur_3.addItems(list_observateur[i])
i=i+1
self.dlg.observateur_3.setCurrentIndex(-1)
self.dlg.observateur_4.clear()
i = 0
while i < len(list_observateur):
self.dlg.observateur_4.addItems(list_observateur[i])
i=i+1
self.dlg.observateur_4.setCurrentIndex(-1)
self.dlg.nom_com_1.clear()
i = 0
while i < len(list_nom_com):
self.dlg.nom_com_1.addItems(list_nom_com[i])
i=i+1
self.dlg.nom_com_1.setCurrentIndex(-1)
self.dlg.nom_com_2.clear()
i = 0
while i < len(list_nom_com):
self.dlg.nom_com_2.addItems(list_nom_com[i])
i=i+1
self.dlg.nom_com_2.setCurrentIndex(-1)
self.dlg.nom_vern.clear()
i = 0
while i < len(list_nom_vern):
self.dlg.nom_vern.addItems(list_nom_vern[i])
i=i+1
self.dlg.nom_vern.setCurrentIndex(-1)
self.dlg.nom_complet.clear()
i = 0
while i < len(list_nom_complet):
self.dlg.nom_complet.addItems(list_nom_complet[i])
i=i+1
self.dlg.nom_complet.setCurrentIndex(-1)
self.dlg.ordre.clear()
i = 0
while i < len(list_ordre):
self.dlg.ordre.addItems(list_ordre[i])
i=i+1
self.dlg.ordre.setCurrentIndex(-1)
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result == 1:
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()
# Requete filtre observateur
if self.dlg.observateur_1.currentIndex() != -1 :
sql_obs1 = """ "observateur" LIKE '%""" + self.dlg.observateur_1.currentText() + "%' "
else :
sql_obs1 = ''
if self.dlg.observateur_2.currentIndex() != -1 :
sql_obs2 = """ "observateur" LIKE '%""" + self.dlg.observateur_2.currentText() + "%' "
else :
sql_obs2 = ''
if self.dlg.observateur_3.currentIndex() != -1 :
sql_obs3 = """ "observateur" LIKE '%""" + self.dlg.observateur_3.currentText() + "%' "
else :
sql_obs3 = ''
if self.dlg.observateur_4.currentIndex() != -1 :
sql_obs4 = """ "observateur" LIKE '%""" + self.dlg.observateur_4.currentText() + "%' "
else :
sql_obs4 = ''
reqwhere_obs = sql_obs1 + 'OR' + sql_obs2 + 'OR' + sql_obs3 + 'OR' + sql_obs4
while reqwhere_obs[-2:] == 'OR' :
reqwhere_obs = reqwhere_obs[:-2]
while reqwhere_obs[:2] == 'OR' :
reqwhere_obs = reqwhere_obs[2:]
# Requete communes
# Connexion a la BD
#con = psycopg2.connect("dbname="+ dbname + " user=" + user + " host=" + host + " password=" + password + " port=" + port)
#cur = con.cursor()
if self.dlg.nom_com_1.currentIndex() != -1 :
nom_com = self.dlg.nom_com_1.currentText()
SQL_code_INSEE = u"""SELECT DISTINCT code_insee FROM saisie.commune WHERE nom = '""" + nom_com + "'"
cur.execute(SQL_code_INSEE)
list_code_INSEE = cur.fetchall()
code_INSEE = list_code_INSEE[0][0]
sql_insee_1 = """ "code_insee" = '""" + code_INSEE + "' "
else :
sql_insee_1 = ''
if self.dlg.nom_com_2.currentIndex() != -1 :
nom_com = self.dlg.nom_com_2.currentText()
SQL_code_INSEE = u"""SELECT DISTINCT code_insee FROM saisie.commune WHERE nom = '""" + nom_com + "'"
cur.execute(SQL_code_INSEE)
list_code_INSEE = cur.fetchall()
code_INSEE = list_code_INSEE[0][0]
sql_insee_2 = """ "code_insee" = '""" + code_INSEE + "' "
else :
sql_insee_2 = ''
reqwhere_insee = sql_insee_1 + 'OR' + sql_insee_2
while reqwhere_insee[-2:] == 'OR' :
reqwhere_insee = reqwhere_insee[:-2]
while reqwhere_insee[:2] == 'OR' :
reqwhere_insee = reqwhere_insee[2:]
con.close()
# Requete date
today = datetime.datetime.now().strftime("%Y-%m-%d")
date_min = self.dlg.date_min.selectedDate().toString("yyyy-MM-dd")
date_max = self.dlg.date_max.selectedDate().toString("yyyy-MM-dd")
if date_min != today :
sql_date_min = """ "date_obs" >= '""" + date_min + "' "
else :
sql_date_min = ''
if date_max != today :
sql_date_max = """ "date_obs" <= '""" + date_max + "' "
else :
sql_date_max = ''
reqwhere_date = sql_date_min + 'AND' + sql_date_max
while reqwhere_obs[-3:] == 'AND' :
reqwhere_obs = reqwhere_obs[:-3]
while reqwhere_obs[:3] == 'AND' :
reqwhere_obs = reqwhere_obs[3:]
# Requete regne
if self.dlg.Animalia.isChecked() == 1 :
sql_Animalia = """"regne" = 'Animalia'"""
else :
sql_Animalia = ''
if self.dlg.Plantae.isChecked() == 1 :
sql_Plantae = """"regne" = 'Plantae'"""
else :
sql_Plantae = ''
reqwhere_regne = sql_Animalia + 'OR' + sql_Plantae
while reqwhere_regne[-2:] == 'OR' :
reqwhere_regne = reqwhere_regne[:-2]
while reqwhere_regne[:2] == 'OR' :
reqwhere_regne = reqwhere_regne[2:]
# Requete ordre
if self.dlg.ordre.currentIndex() != -1 :
reqwhere_ordre = """"ordre" = '""" + self.dlg.ordre.currentText() + "'"
else :
reqwhere_ordre = ''
# Requete sp
if self.dlg.nom_vern.currentIndex() != -1 :
sql_nom_vern = """"nom_vern" = '""" + self.dlg.nom_vern.currentText() + "'"
else :
sql_nom_vern = ''
if self.dlg.nom_complet.currentIndex() != -1 :
sql_nom_complet = """"nom_complet" = '""" + self.dlg.nom_complet.currentText() + "'"
else :
sql_nom_complet = ''
reqwhere_sp = sql_nom_vern + 'OR' + sql_nom_complet
while reqwhere_sp[-2:] == 'OR' :
reqwhere_sp = reqwhere_sp[:-2]
while reqwhere_sp[:2] == 'OR' :
reqwhere_sp = reqwhere_sp[2:]
# Requete filtre patrimonialite
if self.dlg.LRD_01.isChecked() == 1 :
sql_lrd01 = """ lrd01 IN ('VU','EN','RE','CR') """
else :
sql_lrd01 = ''
if self.dlg.LRD_07.isChecked() == 1 :
sql_lrd07 = """ lrd07 IN ('VU','EN','RE','CR') """
else :
sql_lrd07 = ''
if self.dlg.LRD_26.isChecked() == 1 :
sql_lrd26 = """ lrd26 IN ('VU','EN','RE','CR') """
else :
sql_lrd26 = ''
if self.dlg.LRD_38.isChecked() == 1 :
sql_lrd38 = """ lrd38 IN ('VU','EN','RE','CR', 'AS-1', 'AS-2', 'AS-3') """
else :
sql_lrd38 = ''
if self.dlg.LRD_42.isChecked() == 1 :
sql_lrd42 = """ lrd42 IN ('VU','EN','RE','CR') """
else :
sql_lrd42 = ''
if self.dlg.LRD_69.isChecked() == 1 :
sql_lrd69 = """ lrd69 IN ('VU','EN','RE','CR') """
else :
sql_lrd69 = ''
if self.dlg.LRD_73.isChecked() == 1 :
sql_lrd73 = """ lrd73 IN ('VU','EN','RE','CR') """
else :
sql_lrd73 = ''
if self.dlg.LRD_74.isChecked() == 1 :
sql_lrd74 = """ lrd74 IN ('VU','EN','RE','CR') """
else :
sql_lrd74 = ''
if self.dlg.LRR_Flore.isChecked() == 1 :
sql_LRR_Flore = u""" "TAXO_GROUPE" IN ('Plantes') AND (lrr like '%CR%' OR lrr like '%EN%' OR lrr like '%EW%' OR lrr like '%RE%' OR lrr like '%VU%')"""
else :
sql_LRR_Flore = ''
if self.dlg.LRR_Oiseaux.isChecked() == 1 :
sql_LRR_Oiseaux = u""" "TAXO_GROUPE" = 'Oiseaux' AND (lrr like '%RE %' OR lrr like '%CR %' OR lrr like '%EN %' OR lrr like '%VU %') """
else :
sql_LRR_Oiseaux = ''
if self.dlg.LRR_Autre.isChecked() == 1 :
sql_LRR_Autre = u""" (lrr like '%RE %' OR lrr like '%CR %' OR lrr like '%EN %' OR lrr like '%VU %') AND "TAXO_GROUPE" NOT IN ('Oiseaux', 'Plantes') """
else :
sql_LRR_Autre = ''
if self.dlg.LRN_Flore.isChecked() == 1 :
sql_LRN_Flore = u""" "TAXO_GROUPE" ilike 'plantes' AND (lrr like '%CR%' OR lrr like '%EN%' OR lrr like '%EW%' OR lrr like '%RE%' OR lrr like '%VU%') """
else :
sql_LRN_Flore = ''
if self.dlg.LRN_Oiseaux.isChecked() == 1 :
sql_LRN_Oiseaux = u""" "TAXO_GROUPE" = 'Oiseaux' AND (lrn like '%RE %' OR lrn like '%CR %' OR lrn like '%EN %' OR lrn like '%VU %') """
else :
sql_LRN_Oiseaux = ''
if self.dlg.LRN_Ortho.isChecked() == 1 :
sql_LRN_Ortho = u""" "TAXO_GROUPE" ilike 'orthoptères' AND (lrn like '1%' OR lrn like '2%' OR lrn like '3%') """
else :
sql_LRN_Ortho = ''
if self.dlg.LRN_Autre.isChecked() == 1 :
sql_LRN_Autre = u""" (lrr like '%CR%' OR lrr like '%EN%' OR lrr like '%EW%' OR lrr like '%RE%' OR lrr like '%VU%') AND "TAXO_GROUPE" NOT IN ('Oiseaux', 'Plantes', 'Orthoptères') """
else :
sql_LRN_Autre = ''
if self.dlg.LRE.isChecked() == 1 :
sql_lre = """ lre IN ('VU','EN','RE','CR', 'EW', 'EX') """
else :
sql_lre = ''
if self.dlg.UICN.isChecked() == 1 :
sql_UICN = """ lrm IN ('VU','EN','RE','CR', 'EW', 'EX') """
else :
sql_UICN = ''
if self.dlg.PATRIMONIALITE.isChecked() == 1 :
sql_patrimonialite = """"patrimonialite" IS NOT NULL """
else :
sql_patrimonialite = ''
if self.dlg.PATRI01.isChecked() == 1 :
sql_patri01 = """"patri01" IS NOT NULL """
else :
sql_patri01 = ''
if self.dlg.PATRI07.isChecked() == 1 :
sql_patri07 = """"patri07" IS NOT NULL """
else :
sql_patri07 = ''
if self.dlg.PATRI26.isChecked() == 1 :
sql_patri26 = """"patri26" IS NOT NULL """
else :
sql_patri26 = ''
if self.dlg.PATRI38.isChecked() == 1 :
sql_patri38 = """"patri38" IS NOT NULL """
else :
sql_patri38 = ''
if self.dlg.PATRI42.isChecked() == 1 :
sql_patri42 = """"patri42" IS NOT NULL """
else :
sql_patri42 = ''
if self.dlg.PATRI69.isChecked() == 1 :
sql_patri69 = """"patri69" IS NOT NULL """
else :
sql_patri69 = ''
if self.dlg.PATRI73.isChecked() == 1 :
sql_patri73 = """"patri73" IS NOT NULL """
else :
sql_patri73 = ''
if self.dlg.PATRI74.isChecked() == 1 :
sql_patri74 = """"patri74" IS NOT NULL """
else :
sql_patri74 = ''
if self.dlg.ZNIEFF.isChecked() == 1 :
sql_znieff = """"znieff" IS NOT NULL """
else :
sql_znieff = ''
if self.dlg.DH_AnnII.isChecked() == 1 :
sql_dh_an2 = """"dh_an2" IS NOT NULL """
else :
sql_dh_an2 = ''
if self.dlg.PD_38.isChecked() == 1 :
sql_pd38 = """"pd38" IS NOT NULL """
else :
sql_pd38 = ''
if self.dlg.PD_42.isChecked() == 1 :
sql_pd42 = """"pd42" IS NOT NULL """
else :
sql_pd42 = ''
if self.dlg.PN.isChecked() == 1 :
sql_pn = """"pn" IS NOT NULL """
else :
sql_pn = ''
if self.dlg.PR.isChecked() == 1 :
sql_pr = """"pr" IS NOT NULL """
else :
sql_pr = ''
reqwhere_pat = sql_lrd01 + 'OR' + sql_lrd07 + 'OR' + sql_lrd26 + 'OR' + sql_lrd38 + 'OR' + sql_lrd42 + 'OR' + sql_lrd69 + 'OR' + sql_lrd73 + 'OR' + sql_lrd74 + 'OR' + sql_lre + 'OR' + sql_LRN_Flore + 'OR' + sql_LRN_Oiseaux + 'OR' + sql_LRN_Ortho + 'OR' + sql_LRN_Autre + 'OR' + sql_LRR_Flore + 'OR' + sql_LRR_Oiseaux + 'OR' + sql_LRR_Autre + 'OR' + sql_UICN + 'OR' + sql_pd38 + 'OR' + sql_pd42 + 'OR' + sql_pn + 'OR' + sql_pr + 'OR' + sql_dh_an2 + 'OR' + sql_patri01 + 'OR' + sql_patri07 + 'OR' + sql_patri26 + 'OR' + sql_patri38 + 'OR' + sql_patri42 + 'OR' + sql_patri69 + 'OR' + sql_patri73 + 'OR' + sql_patri74 + 'OR' + sql_patrimonialite
while reqwhere_pat.find('OROR') != -1 :
reqwhere_pat = reqwhere_pat.replace('OROR','OR')
while reqwhere_pat[-2:] == 'OR' :
reqwhere_pat = reqwhere_pat[:-2]
while reqwhere_pat[:2] == 'OR' :
reqwhere_pat = reqwhere_pat[2:]
# Requete geom
if self.dlg.bouton_geom.isChecked() == 1 :
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 :
selection = layer.selectedFeatures()
if layer.selectedFeatureCount() >= 1 :
GEOM = ''
for feature in selection:
geom = feature.geometry()
poly = "ST_GeomFromText('"+geom.asWkt()+"',2154),"
GEOM = GEOM + poly
poly = GEOM[0:-1]
#print(poly)
buffer = self.dlg.buffer.text()
reqwhere_geom = " ST_intersects(geometrie,ST_Buffer(ST_Collect(array[" + poly + "]), " + buffer + " ))"
# Requete finale
reqwhere_final = '(' + reqwhere_obs + ')' + 'AND' + reqwhere_insee + 'AND' + reqwhere_ordre + 'AND' + reqwhere_sp + 'AND' + '(' + reqwhere_pat + ')' + 'AND' + reqwhere_regne + 'AND' + reqwhere_date + 'AND' + reqwhere_geom
# Nettoyage de la requete finale
while reqwhere_final.find('ANDAND') != -1 :
reqwhere_final = reqwhere_final.replace('ANDAND','AND')
while reqwhere_final.find('AND()AND') != -1 :
reqwhere_final = reqwhere_final.replace('AND()AND','AND')
while reqwhere_final[-3:] == 'AND' :
reqwhere_final = reqwhere_final[:-3]
while reqwhere_final[:5] == '()AND' :
reqwhere_final = reqwhere_final[5:]
while reqwhere_final[-5:] == 'AND()' :
reqwhere_final = reqwhere_final[:-5]
while reqwhere_final[:3] == 'AND' :
reqwhere_final = reqwhere_final[3:]
## Affichage des tables
table_name = 'observations'
uri = QgsDataSourceUri()
uri.setConnection(host ,port ,dbname ,user ,mdp)
if self.dlg.centroide.isChecked() == 1 :
### Centroide
if reqwhere_final.find('()') != -1 :
reqwhere_final = ''
print(reqwhere_final)
uri.setDataSource("_agregation_ra", "observations_centroide", "geometrie", reqwhere_final, "gid")
layer = self.iface.addVectorLayer(uri.uri(), table_name + '_centroides', "postgres")
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 group de couches
#i = qgis.utils.iface
#legende = i.legendInterface()
legende = QgsProject.instance().layerTreeRoot()
#nomgroupe = 'Observations'
#groupe = legende.addGroup(nomgroupe,False)
groupe = legende.insertGroup(1, "Observations")
groupe = legende.findGroup("Observations")
# Récupération de la liste de groupes
#toc = iface.layerTreeView()
#toc = qgis.utils.iface.legendInterface()
#groups = toc.
#groups = toc.groups()
#index = groups.index(nomgroupe)
index = 1
### Polygone
reqwhere_final_poly = '(' + reqwhere_final + " AND GeometryType(geometrie) LIKE '%POLYGON%'" + ')'
if reqwhere_final_poly.find('()') != -1 :
reqwhere_final_poly = "(GeometryType(geometrie) LIKE '%POLYGON%')"
SQL_count_poly = u"""SELECT DISTINCT count(gid) AS count FROM _agregation_ra.observations_table WHERE """ + reqwhere_final_poly
cur.execute(SQL_count_poly)
list_count_poly = cur.fetchall()
count_poly = list_count_poly[0][0]
if count_poly != 0:
uri.setDataSource("_agregation_ra", "observations_table", "geometrie", reqwhere_final_poly, "gid")
#layer_poly = self.iface.addVectorLayer(uri.uri(), table_name + '_poly', "postgres")
layer_poly = QgsVectorLayer(uri.uri(), table_name + '_poly', "postgres")
QgsProject.instance().addMapLayer(layer_poly, False)
#legende.moveLayer(layer_poly,index)
#groupe.addLayer(layer_poly)
groupe.insertChildNode(0, QgsLayerTreeLayer(layer_poly))
### Point
reqwhere_final_point = '(' + reqwhere_final + " AND GeometryType(geometrie) LIKE '%POINT%'" + ')'
if reqwhere_final_point.find('()') != -1 :
reqwhere_final_point = "(GeometryType(geometrie) LIKE '%POINT%')"
SQL_count_point = u"""SELECT DISTINCT count(gid) AS count FROM _agregation_ra.observations_table WHERE """ + reqwhere_final_point
cur.execute(SQL_count_point)
list_count_point = cur.fetchall()
count_point = list_count_point[0][0]
if count_point != 0:
uri.setDataSource("_agregation_ra", "observations_table", "geometrie", reqwhere_final_point, "gid")
#layer_point = self.iface.addVectorLayer(uri.uri(), table_name + '_point', "postgres")
layer_point = QgsVectorLayer(uri.uri(), table_name + '_point', "postgres")
QgsProject.instance().addMapLayer(layer_point, False)
#legende.moveLayer(layer_point,index)
#groupe.addLayer(layer_point)
groupe.insertChildNode(0, QgsLayerTreeLayer(layer_point))
### Ligne
reqwhere_final_ligne = '(' + reqwhere_final + " AND GeometryType(geometrie) LIKE '%LINE%'" + ')'
if reqwhere_final_ligne.find('()') != -1 :
reqwhere_final_ligne = "(GeometryType(geometrie) LIKE '%LINE%')"
SQL_count_ligne = u"""SELECT DISTINCT count(gid) AS count FROM _agregation_ra.observations_table WHERE """ + reqwhere_final_ligne
cur.execute(SQL_count_ligne)
list_count_ligne = cur.fetchall()
count_ligne = list_count_ligne[0][0]
if count_ligne != 0:
uri.setDataSource("_agregation_ra", "observations_table", "geometrie", reqwhere_final_ligne, "gid")
#layer_ligne = self.iface.addVectorLayer(uri.uri(), table_name + '_ligne', "postgres")
layer_ligne = QgsVectorLayer(uri.uri(), table_name + '_ligne', "postgres")
QgsProject.instance().addMapLayer(layer_ligne, False)
#legende.moveLayer(layer_ligne,index)
#groupe.addLayer(layer_ligne)
groupe.insertChildNode(0, QgsLayerTreeLayer(layer_ligne))
# ajout des couches dans le groupe Observations
#legende.setGroupExpanded (index, True)
#self.iface.messageBar().pushMessage(u"Extraction réussie : ", u" Pensez à renommer vos couches pour plus de lisibilité.", level=QgsMessageBar.INFO, duration=10)
self.iface.messageBar().pushMessage("Info", u"Extraction réussie : ", u" Pensez à renommer vos couches pour plus de lisibilité.", level=Qgis.Success, duration=4)
elif layer.selectedFeatureCount() == 0 :
#self.iface.messageBar().pushMessage(u"Vous devez sélectionner au moins un polygone !", level=QgsMessageBar.WARNING, duration=5)
self.iface.messageBar().pushMessage("Ooops", u"Vous devez sélectionner au moins un polygone !", level=Qgis.Warning, duration=5)
reqwhere_geom = ''
else :
#self.iface.messageBar().pushMessage(u"Vous devez sélectionner qu'un seul polygone !", level=QgsMessageBar.WARNING, duration=5)
self.iface.messageBar().pushMessage("Ooops", u"Vous ne devez sélectionner qu'un seul polygone !", level=Qgis.Warning, duration=5)
reqwhere_geom = ''
else :
# Requete finale
reqwhere_final = '(' + reqwhere_obs + ')' + 'AND' + reqwhere_insee + 'AND' + reqwhere_ordre + 'AND' + reqwhere_sp + 'AND' + '(' + reqwhere_pat + ')' + 'AND' + reqwhere_regne + 'AND' + reqwhere_date
# Nettoyage de la requete finale
while reqwhere_final.find('ANDAND') != -1 :
reqwhere_final = reqwhere_final.replace('ANDAND','AND')
while reqwhere_final.find('AND()AND') != -1 :
reqwhere_final = reqwhere_final.replace('AND()AND','AND')
while reqwhere_final[-3:] == 'AND' :
reqwhere_final = reqwhere_final[:-3]
while reqwhere_final[:5] == '()AND' :
reqwhere_final = reqwhere_final[5:]
while reqwhere_final[-5:] == 'AND()' :
reqwhere_final = reqwhere_final[:-5]
while reqwhere_final[:3] == 'AND' :
reqwhere_final = reqwhere_final[3:]
## Affichage des tables
table_name = 'observations'
uri = QgsDataSourceUri()
uri.setConnection(host ,port ,dbname ,user ,mdp)
## Centroide
if self.dlg.centroide.isChecked() == 1 :
if reqwhere_final.find('()') != -1 :
reqwhere_final = ''
uri.setDataSource("_agregation_ra", "observations_centroide", "geometrie", reqwhere_final, "gid")
layer = self.iface.addVectorLayer(uri.uri(), table_name + '_centroides', "postgres")
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 group de couches
i = qgis.utils.iface
#legende = i.legendInterface()
legende = QgsProject.instance().layerTreeRoot()
#nomgroupe = 'Observations'
#groupe = legende.addGroup(nomgroupe,False)
groupe = legende.insertGroup(1, "Observations")
groupe = legende.findGroup("Observations")
# Récupération de la liste de groupes
#toc = iface.layerTreeView()
#toc = qgis.utils.iface.legendInterface()
#groups = toc.
#groups = toc.groups()
#index = groups.index(nomgroupe)
index = 1
### Polygone
reqwhere_final_poly = '(' + reqwhere_final + " AND GeometryType(geometrie) LIKE '%POLYGON%'" + ')'
if reqwhere_final_poly.find('()') != -1 :
reqwhere_final_poly = "(GeometryType(geometrie) LIKE '%POLYGON%')"
SQL_count_poly = u"""SELECT DISTINCT count(gid) AS count FROM _agregation_ra.observations_table WHERE """ + reqwhere_final_poly
cur.execute(SQL_count_poly)
list_count_poly = cur.fetchall()
count_poly = list_count_poly[0][0]
if count_poly != 0:
uri.setDataSource("_agregation_ra", "observations_table", "geometrie", reqwhere_final_poly, "gid")
#layer_poly = self.iface.addVectorLayer(uri.uri(), table_name + '_poly', "postgres")
layer_poly = QgsVectorLayer(uri.uri(), table_name + '_poly', "postgres")
QgsProject.instance().addMapLayer(layer_poly, False)
#legende.moveLayer(layer_poly,index)
#groupe.addLayer(layer_poly)
groupe.insertChildNode(0, QgsLayerTreeLayer(layer_poly))
### Point
reqwhere_final_point = '(' + reqwhere_final + " AND GeometryType(geometrie) LIKE '%POINT%'" + ')'
if reqwhere_final_point.find('()') != -1 :
reqwhere_final_point = "(GeometryType(geometrie) LIKE '%POINT%')"
SQL_count_point = u"""SELECT DISTINCT count(gid) AS count FROM _agregation_ra.observations_table WHERE """ + reqwhere_final_point
cur.execute(SQL_count_point)
list_count_point = cur.fetchall()
count_point = list_count_point[0][0]
if count_point != 0:
uri.setDataSource("_agregation_ra", "observations_table", "geometrie", reqwhere_final_point, "gid")
#layer_point = self.iface.addVectorLayer(uri.uri(), table_name + '_point', "postgres")
layer_point = QgsVectorLayer(uri.uri(), table_name + '_point', "postgres")
QgsProject.instance().addMapLayer(layer_point, False)
#legende.moveLayer(layer_point,index)
#groupe.addLayer(layer_point)
groupe.insertChildNode(0, QgsLayerTreeLayer(layer_point))
### Ligne
reqwhere_final_ligne = '(' + reqwhere_final + " AND GeometryType(geometrie) LIKE '%LINE%'" + ')'
if reqwhere_final_ligne.find('()') != -1 :
reqwhere_final_ligne = "(GeometryType(geometrie) LIKE '%LINE%')"
SQL_count_ligne = u"""SELECT DISTINCT count(gid) AS count FROM _agregation_ra.observations_table WHERE """ + reqwhere_final_ligne
cur.execute(SQL_count_ligne)
list_count_ligne = cur.fetchall()
count_ligne = list_count_ligne[0][0]
if count_ligne != 0:
uri.setDataSource("_agregation_ra", "observations_table", "geometrie", reqwhere_final_ligne, "gid")
#layer_ligne = self.iface.addVectorLayer(uri.uri(), table_name + '_ligne', "postgres")
layer_ligne = QgsVectorLayer(uri.uri(), table_name + '_ligne', "postgres")
QgsProject.instance().addMapLayer(layer_ligne, False)
#legende.moveLayer(layer_ligne,index)
#groupe.addLayer(layer_ligne)
groupe.insertChildNode(0, QgsLayerTreeLayer(layer_ligne))
# ajout des couches dans le groupe Observations
#legende.setGroupExpanded (index, True)
#self.iface.messageBar().pushMessage(u"Extraction réussie : ", u" Pensez à renommer vos couches pour plus de lisibilité.", level=QgsMessageBar.INFO, duration=10)
self.iface.messageBar().pushMessage("Info", u"Extraction réussie : ", u" Pensez à renommer vos couches pour plus de lisibilité.", level=Qgis.Success, duration=10)
pass
def export(self):
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 :
selection = layer.selectedFeatures()
if (layer.selectedFeatureCount() == 1) :
for feature in selection:
geom = feature.geometry()
poly = geom.asWkt()
buffer = '100'
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()
SQL_list_sp = u"""SELECT DISTINCT classe::text,ordre::text,nom_complet::text,split_part(nom_vern::text,',',1) as nom_vern,cd_ref::text as cd_ref,max(COALESCE(date_obs, date_debut_obs))::text AS derniere_obs FROM _agregation_ra.observations_table WHERE ST_intersects(geometrie,ST_Buffer(ST_geomFromText('""" + poly + "',2154), " + buffer + " ))GROUP BY classe::text, ordre::text, nom_complet::text, nom_vern::text, cd_ref::text ORDER BY nom_complet::text"""
cur.execute(SQL_list_sp)
data_sp = cur.fetchall()
chemin_fichier, __ = QFileDialog.getSaveFileName(None, 'Enregistrer sous...', r"C:\Users\\Desktop\\" + str(os.environ.get("USERNAME")) + '_liste_sp.csv', "Fichiers CSV (*.csv)")
#file = open(chemin_fichier, 'wb')
file = open(chemin_fichier, 'w', newline='', encoding='utf-8')
#file.write('\ufeff'.encode('utf8')) # BOM (optionel...Permet a Excel d'ouvrir proprement le fichier en UTF-8)
file.write('\ufeff')
writer = csv.writer(file, delimiter = ';') # délimiteur ';' pour faciliter l'ouverture avec Excel
writer.writerow(['Classe', 'Ordre', 'Nom Complet', 'Nom Vernaculaire','cd_ref', 'Date Derniere Observation']) # Création des entêtes
for row in data_sp : # Boucle d'écriture ligne par ligne dans le csv
#print(1)
list_sp = []
if row[0] == None : # Si la valeur est 'None' l'encodage ne peut se faire donc boucle d'évitement
row0 = str(row[0])
row0 = ''
else :
row0 = row[0]
#print(row0)
list_sp.append(row0)
if row[1] == None : # Si la valeur est 'None' l'encodage ne peut se faire donc boucle d'évitement
row1 = str(row[1])
row1 = ''
else :
row1 = row[1]
list_sp.append(row1)
if row[2] == None : # Si la valeur est 'None' l'encodage ne peut se faire donc boucle d'évitement
row2 = str(row[2])
row2 = ''
else :
row2 = row[2]
list_sp.append(row2)
if row[3] == None : # Si la valeur est 'None' l'encodage ne peut se faire donc boucle d'évitement
row3 = str(row[3])
row3 = ''
else :
row3 = row[3]
list_sp.append(row3)
if row[4] == None :
row4 = str(row[4])
row4 = ''
else :
row4 = row[4]
list_sp.append(row4)
if row[5] == None :
row5 = str(row[5])
row5 = ''
else :
row5 = row[5]
print(row5)
list_sp.append(row5)
writer.writerow(list_sp)
file.close()
#self.iface.messageBar().pushMessage(u"Export réussi dans " + chemin_fichier , level=QgsMessageBar.INFO, duration=5)
self.iface.messageBar().pushMessage("Ooops", u"Export réussi dans " + chemin_fichier, level=Qgis.Success, duration=5)
elif (layer.selectedFeatureCount() == 0) :
#self.iface.messageBar().pushMessage(u"Vous devez sélectionner au moins un polygone !", level=QgsMessageBar.WARNING, duration=5)
self.iface.messageBar().pushMessage("Ooops", u"Vous devez sélectionner au moins un polygone !", level=Qgis.Warning, duration=5)
else :
#self.iface.messageBar().pushMessage(u"Vous devez sélectionner qu'un seul polygone !", level=QgsMessageBar.WARNING, duration=5)
self.iface.messageBar().pushMessage("Ooops", u"Vous ne devez sélectionner qu'un seul polygone !", level=Qgis.Warning, duration=5)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

+37
View File
@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
SICENDialog
A QGIS plugin
Filtre sur données SICEN
-------------------
begin : 2014-10-17
copyright : (C) 2014 by Guillaume COSTES
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 qgis.PyQt import QtCore, QtGui
from qgis.PyQt.QtWidgets import QAction, QDialog
from .ui_sicen import Ui_SICEN
# create the dialog for zoom to point
class SICENDialog(QDialog, Ui_SICEN):
def __init__(self):
QDialog.__init__(self)
# Set up the user interface from Designer.
# After setupUI you can access any designer object by doing
# self.<objectname>, 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)
+21
View File
@@ -0,0 +1,21 @@
from qgis.core import QgsApplication
def gitea():
file_url = QgsApplication.qgisSettingsDirPath()+'QGIS/QGIS3.ini'
recherche_1 = 'plugin_repositories\\github\\url=https://github.com/CEN-Rhone-Alpes/Plugin_QGIS/releases/latest/download/plugins.xml'
replace_1 = 'plugin_repositories\\gitea\\url=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
recherche_2 = 'github'
replace_2 = 'gitea'
# Read in the file
with open(file_url, 'r') as file:
filedata = file.read()
# Replace the target string
filedata = filedata.replace(recherche_1, replace_1)
filedata = filedata.replace(recherche_2, replace_2)
# Write the file out again
with open(file_url, 'w') as file:
file.write(filedata)
+172
View File
@@ -0,0 +1,172 @@
import sys
import socket
import os
IPAddr=socket.gethostbyname(socket.gethostname())
if IPAddr[0:11] == "100.100.100": #4269
host = "100.100.100.11"
port = "5432"
dbname = "sig4269"
sigdb="sig4269"
refdb="ref_geo4269"
password = "McVities"
if IPAddr[0:9] == "192.168.0": #01
host = "192.168.0.201"
port = "5432"
dbname = "sig01"
sigdb="sig01"
refdb="ref_geo01"
password = "McVities"
if IPAddr[0:9] == "192.168.1": #0726
host = "192.168.1.201"
port = "5432"
dbname = "sig0726"
sigdb="sig0726"
refdb="ref_geo0726"
password = "McVities"
if sys.platform == 'linux':
os_user = os.environ['USER']
else:
os_user = os.environ['USERNAME']
if os_user == 'STAGE':
os_user='stage'
geom = "geom"
champ_travaux_prevus_multipolygon="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, surface_m2 double precision, surface_ha double precision, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_travaux_prevus_multilinestring="""(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, longueur_m double precision, longueur_km double precision, date_creation date, date_maj date, geom geometry(MultiLineString,2154))"""
champ_travaux_prevus_point = """(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, x_wgs84 double precision, y_wgs84 double precision, date_creation date, date_maj date, geom geometry(Point,2154))"""
champ_viergePolygone = """(gid serial NOT NULL, commentaire text, surface_m2 double precision, surface_ha double precision, geom geometry(MultiPolygon,2154))"""
champ_viergeLigne = """(gid serial NOT NULL, commentaire text, longueur_m double precision, longueur_km double precision, geom geometry(MultiLineString,2154))"""
champ_viergePoint = """(gid serial NOT NULL, commentaire text, x_wgs84 double precision, y_wgs84 double precision, geom geometry(Point,2154))"""
champ_habitat = """(gid serial NOT NULL, cd_cb_01 text, lb_cb97_fr_01 text, occupation_01 integer, cd_cb_02 text, lb_cb97_fr_02 text, occupation_02 integer, cd_cb_03 text, lb_cb97_fr_03 text, occupation_03 integer, milieu_code text, milieu_libelle text, surface_m2 double precision, surface_ha double precision, commentaire text, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_contour="""(gid serial NOT NULL, date_creation date, date_maj date, utilisateur character varying, dept character(2), nom character varying, surface_m2 double precision, surface_ha double precision, type_site character varying, type_milieu character varying, date_premier_pg integer, date_debut_pg integer, date_fin_pg integer, referent character varying, gestion_deleguee character varying, terrain_militaire character(3), ens character(3), zh character(3), adapt_pmr character(3), inform character(3), guide character(3), ouverture_public character(3), obs character(3), anim character(3), n2000_anim character(3), contrat_n2000_conseil character(3), n2000_op character(3), contrat_n2000_benef character(3), contrat_agri character(3), bc_habitat integer, bc_amphibien integer, bc_coleoptere integer, bc_crustace integer, bc_mammifere integer, bc_chiroptere integer, bc_mollusque integer, bc_odonate integer, bc_oiseau integer, bc_orthoptere integer, bc_poisson integer, bc_reptile integer, bc_rhopalocere integer, bc_heterocere integer, bc_autre_invertebre integer, bc_flore integer, bc_bryophyte integer, bc_champignon integer, suiv_analyse_sol character(3), suiv_piezo character(3), suiv_climat character(3), suiv_topo character(3), suiv_habitat character(3), suiv_amphibien character(3), suiv_coleoptere character(3), suiv_crustace character(3), suiv_mammifere character(3), suiv_chiroptere character(3), suiv_mollusque character(3), suiv_odonate character(3), suiv_oiseau character(3), suiv_orthoptere character(3), suiv_poisson character(3), suiv_reptile character(3), suiv_rhopalocere character(3), suiv_heterocere character(3), suiv_autre_invertebre character(3), suiv_flore character(3), suiv_bryophyte character(3), suiv_champignon character(3), suiv_analyse_eau character(3), suiv_phenologie character(3), suiv_frequentation character(3), suiv_paysager character(3), suiv_autre character(3), commentaire text, geom geometry(MultiPolygon,2154))
"""
champ_vegethab_point = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(Point,2154)
)
"""
champ_vegethab_multilinestring = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiLineString,2154)
)
"""
champ_vegethab_multipolygon = """(
gid serial NOT NULL ,
cd_eu_01 character varying(254) COLLATE pg_catalog."default",
lb_eu_01 character varying(254) COLLATE pg_catalog."default",
occupati_1 bigint,
cd_eu_02 character varying(254) COLLATE pg_catalog."default",
lb_eu_02 character varying(254) COLLATE pg_catalog."default",
occupati_2 bigint,
cd_eu_03 character varying(254) COLLATE pg_catalog."default",
lb_eu_03 character varying(254) COLLATE pg_catalog."default",
occupati_3 bigint,
milieu_cod character varying(254) COLLATE pg_catalog."default",
milieu_lib character varying(254) COLLATE pg_catalog."default",
surface_m2 numeric,
surface_ha numeric,
commentair character varying(254) COLLATE pg_catalog."default",
date_creat date,
date_maj date,
num_phyto character varying(254) COLLATE pg_catalog."default",
type_unite character varying(254) COLLATE pg_catalog."default",
dynamique character varying(254) COLLATE pg_catalog."default",
gestio_obs character varying(254) COLLATE pg_catalog."default",
degrad_obs character varying(254) COLLATE pg_catalog."default",
eta_conser character varying(254) COLLATE pg_catalog."default",
clas_phyto character varying(254) COLLATE pg_catalog."default",
alli_phyto character varying(254) COLLATE pg_catalog."default",
syntaxon character varying(254) COLLATE pg_catalog."default",
n2000 character varying(254) COLLATE pg_catalog."default",
lrr_aura character varying(254) COLLATE pg_catalog."default",
lrr_cbna character varying(254) COLLATE pg_catalog."default",
lrr_cbnmc character varying(254) COLLATE pg_catalog."default",
vege_enjeu character varying(254) COLLATE pg_catalog."default",
num_photo character varying(254) COLLATE pg_catalog."default",
nature_obs character varying(254) COLLATE pg_catalog."default",
date_sais date,
s_al_phyto character varying(254) COLLATE pg_catalog."default",
alli_name character varying(254) COLLATE pg_catalog."default",
salli_name character varying(254) COLLATE pg_catalog."default",
class_name character varying(254) COLLATE pg_catalog."default",
geom geometry(MultiPolygon,2154)
)
"""
+184
View File
@@ -0,0 +1,184 @@
"""Tools to work with resource files."""
import configparser
import shutil
import tempfile
import base64
import psycopg2
import psycopg2.extras
from os.path import abspath, join, pardir, dirname
from qgis.PyQt import uic
__copyright__ = "Copyright 2019, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
__revision__ = "$Format:%H$"
def plugin_path(*args):
"""Get the path to plugin root folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the plugin path.
:rtype: str
"""
path = dirname(dirname(__file__))
path = abspath(abspath(join(path, pardir)))
for item in args:
path = abspath(join(path, item))
return path
def plugin_name():
"""Return the plugin name according to metadata.txt.
:return: The plugin name.
:rtype: basestring
"""
metadata = metadata_config()
name = metadata["general"]["name"]
return name
def metadata_config() -> configparser:
"""Get the INI config parser for the metadata file.
:return: The config parser object.
:rtype: ConfigParser
"""
path = plugin_path("metadata.txt")
config = configparser.ConfigParser()
config.read(path, encoding='utf8')
return config
def plugin_test_data_path(*args, copy=False):
"""Get the path to the plugin test data path.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:param copy: If the file must be copied into a temporary directory first.
:type copy: bool
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "test", "data")))
for item in args:
path = abspath(join(path, item))
if copy:
temp = tempfile.mkdtemp()
shutil.copy(path, temp)
return join(temp, args[-1])
else:
return path
def resources_path(*args):
"""Get the path to our resources folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_Metabase\\tools")))
for item in args:
path = abspath(join(path, item))
return path
def load_ui(*args):
"""Get compile UI file.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Compiled UI file.
"""
ui_class, _ = uic.loadUiType(resources_path("ui", *args))
return ui_class
def login_base(take=None):
from .tools.PythonSQL import host,port,dbname,password,os_user
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()
if take:
return cur,con
else:
return cur
def send_issues(url,titre,body,labels):
import requests
import json
import os
import qgis
usr = os.environ['USERNAME']
token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
url=url+'?token='+token
headers = {'Authorization': 'token ' + token,'accept': 'application/json','Content-Type': 'application/json'}
payload = {'title': titre, 'body': body, 'labels': labels}
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
r = ''
if binar:
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r
def maj_verif(NAME):
import qgis
import urllib.request
iface = qgis.utils.iface
from qgis.core import Qgis
url = qgis.utils.pluginMetadata(NAME,'repository')
#URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/releases/plugins.xml'
# print(URL)
version = qgis.utils.pluginMetadata(NAME,'version')
len_version = len(version)
try:
urllib.request.urlopen('https://google.com')
binar = True
except:
binar = False
if binar:
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>',plugin_num)+9
version_plugin = version_web[valeur_version_web:valeur_version_web+len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
return version_plugin
def devlog(NAME):
import qgis
devmaj = '<head><style>* {margin:0; padding:0; }</style></head>'
devmaj = devmaj+qgis.utils.pluginMetadata(NAME,'changelog')
return devmaj
+756
View File
@@ -0,0 +1,756 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_sicen.ui'
#
# Created: Wed Apr 22 14:03:07 2015
# by: PyQt4 UI code generator 4.10.2
#
# WARNING! All changes made in this file will be lost!
from builtins import object
from qgis.PyQt import QtCore, QtGui
from qgis.PyQt.QtGui import QFont
from qgis.PyQt.QtWidgets import QAction, QDialog, QDialogButtonBox, QLabel, QApplication, QTabWidget, QWidget, QGroupBox, QGridLayout, QComboBox, QCheckBox, QCalendarWidget, QToolBox, QFrame, QLineEdit, QSizePolicy #Modifié
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QApplication.translate(context, text, disambig)
class Ui_SICEN(object):
def setupUi(self, SICEN):
SICEN.setObjectName(_fromUtf8("SICEN"))
SICEN.resize(592, 556)
self.buttonBox = QDialogButtonBox(SICEN)
self.buttonBox.setGeometry(QtCore.QRect(390, 520, 161, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.Titre = QLabel(SICEN)
self.Titre.setGeometry(QtCore.QRect(110, 10, 331, 31))
font = QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.Titre.setFont(font)
self.Titre.setObjectName(_fromUtf8("Titre"))
self.Emprise = QTabWidget(SICEN)
self.Emprise.setGeometry(QtCore.QRect(10, 80, 571, 431))
self.Emprise.setTabPosition(QTabWidget.North)
self.Emprise.setTabShape(QTabWidget.Rounded)
self.Emprise.setObjectName(_fromUtf8("Emprise"))
self.tab_2 = QWidget()
self.tab_2.setObjectName(_fromUtf8("tab_2"))
self.groupBox_4 = QGroupBox(self.tab_2)
self.groupBox_4.setGeometry(QtCore.QRect(10, 9, 541, 81))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_4.setFont(font)
self.groupBox_4.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_4.setObjectName(_fromUtf8("groupBox_4"))
self.gridLayoutWidget_5 = QWidget(self.groupBox_4)
self.gridLayoutWidget_5.setGeometry(QtCore.QRect(10, 20, 521, 51))
self.gridLayoutWidget_5.setObjectName(_fromUtf8("gridLayoutWidget_5"))
self.gridLayout_5 = QGridLayout(self.gridLayoutWidget_5)
self.gridLayout_5.setMargin(0)
self.gridLayout_5.setObjectName(_fromUtf8("gridLayout_5"))
self.observateur_1 = QComboBox(self.gridLayoutWidget_5)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.observateur_1.setFont(font)
self.observateur_1.setObjectName(_fromUtf8("observateur_1"))
self.gridLayout_5.addWidget(self.observateur_1, 0, 0, 1, 1)
self.observateur_3 = QComboBox(self.gridLayoutWidget_5)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.observateur_3.setFont(font)
self.observateur_3.setObjectName(_fromUtf8("observateur_3"))
self.gridLayout_5.addWidget(self.observateur_3, 1, 0, 1, 1)
self.observateur_2 = QComboBox(self.gridLayoutWidget_5)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.observateur_2.setFont(font)
self.observateur_2.setObjectName(_fromUtf8("observateur_2"))
self.gridLayout_5.addWidget(self.observateur_2, 0, 1, 1, 1)
self.observateur_4 = QComboBox(self.gridLayoutWidget_5)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.observateur_4.setFont(font)
self.observateur_4.setObjectName(_fromUtf8("observateur_4"))
self.gridLayout_5.addWidget(self.observateur_4, 1, 1, 1, 1)
self.groupBox_5 = QGroupBox(self.tab_2)
self.groupBox_5.setGeometry(QtCore.QRect(10, 100, 541, 71))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_5.setFont(font)
self.groupBox_5.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_5.setObjectName(_fromUtf8("groupBox_5"))
self.gridLayoutWidget_6 = QWidget(self.groupBox_5)
self.gridLayoutWidget_6.setGeometry(QtCore.QRect(10, 20, 521, 41))
self.gridLayoutWidget_6.setObjectName(_fromUtf8("gridLayoutWidget_6"))
self.gridLayout_6 = QGridLayout(self.gridLayoutWidget_6)
self.gridLayout_6.setMargin(0)
self.gridLayout_6.setObjectName(_fromUtf8("gridLayout_6"))
self.label = QLabel(self.gridLayoutWidget_6)
font = QFont()
font.setBold(False)
font.setItalic(True)
font.setWeight(50)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout_6.addWidget(self.label, 0, 0, 1, 1)
self.label_2 = QLabel(self.gridLayoutWidget_6)
font = QFont()
font.setBold(False)
font.setItalic(True)
font.setWeight(50)
self.label_2.setFont(font)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.gridLayout_6.addWidget(self.label_2, 0, 1, 1, 1)
self.nom_com_1 = QComboBox(self.gridLayoutWidget_6)
self.nom_com_1.setMinimumSize(QtCore.QSize(200, 0))
font = QFont()
font.setBold(False)
font.setWeight(50)
self.nom_com_1.setFont(font)
self.nom_com_1.setObjectName(_fromUtf8("nom_com_1"))
self.gridLayout_6.addWidget(self.nom_com_1, 1, 0, 1, 1)
self.nom_com_2 = QComboBox(self.gridLayoutWidget_6)
self.nom_com_2.setMinimumSize(QtCore.QSize(200, 0))
font = QFont()
font.setBold(False)
font.setWeight(50)
self.nom_com_2.setFont(font)
self.nom_com_2.setObjectName(_fromUtf8("nom_com_2"))
self.gridLayout_6.addWidget(self.nom_com_2, 1, 1, 1, 1)
self.groupBox_7 = QGroupBox(self.tab_2)
self.groupBox_7.setGeometry(QtCore.QRect(10, 180, 541, 221))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_7.setFont(font)
self.groupBox_7.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_7.setObjectName(_fromUtf8("groupBox_7"))
self.gridLayoutWidget_8 = QWidget(self.groupBox_7)
self.gridLayoutWidget_8.setGeometry(QtCore.QRect(10, 20, 520, 191))
self.gridLayoutWidget_8.setObjectName(_fromUtf8("gridLayoutWidget_8"))
self.gridLayout_8 = QGridLayout(self.gridLayoutWidget_8)
self.gridLayout_8.setMargin(0)
self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8"))
self.label_3 = QLabel(self.gridLayoutWidget_8)
font = QFont()
font.setBold(False)
font.setItalic(True)
font.setWeight(50)
self.label_3.setFont(font)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.gridLayout_8.addWidget(self.label_3, 0, 0, 1, 1)
self.label_4 = QLabel(self.gridLayoutWidget_8)
font = QFont()
font.setBold(False)
font.setItalic(True)
font.setWeight(50)
self.label_4.setFont(font)
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.gridLayout_8.addWidget(self.label_4, 0, 1, 1, 1)
self.date_min = QCalendarWidget(self.gridLayoutWidget_8)
self.date_min.setObjectName(_fromUtf8("date_min"))
self.gridLayout_8.addWidget(self.date_min, 1, 0, 1, 1)
self.date_max = QCalendarWidget(self.gridLayoutWidget_8)
self.date_max.setObjectName(_fromUtf8("date_max"))
self.gridLayout_8.addWidget(self.date_max, 1, 1, 1, 1)
self.Emprise.addTab(self.tab_2, _fromUtf8(""))
self.tab = QWidget()
self.tab.setObjectName(_fromUtf8("tab"))
self.groupBox_8 = QGroupBox(self.tab)
self.groupBox_8.setGeometry(QtCore.QRect(10, 10, 511, 51))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_8.setFont(font)
self.groupBox_8.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_8.setObjectName(_fromUtf8("groupBox_8"))
self.gridLayoutWidget_9 = QWidget(self.groupBox_8)
self.gridLayoutWidget_9.setGeometry(QtCore.QRect(10, 20, 491, 21))
self.gridLayoutWidget_9.setObjectName(_fromUtf8("gridLayoutWidget_9"))
self.gridLayout_9 = QGridLayout(self.gridLayoutWidget_9)
self.gridLayout_9.setMargin(0)
self.gridLayout_9.setHorizontalSpacing(100)
self.gridLayout_9.setObjectName(_fromUtf8("gridLayout_9"))
self.Animalia = QCheckBox(self.gridLayoutWidget_9)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.Animalia.setFont(font)
self.Animalia.setLayoutDirection(QtCore.Qt.RightToLeft)
self.Animalia.setObjectName(_fromUtf8("Animalia"))
self.gridLayout_9.addWidget(self.Animalia, 0, 0, 1, 1)
self.Plantae = QCheckBox(self.gridLayoutWidget_9)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.Plantae.setFont(font)
self.Plantae.setObjectName(_fromUtf8("Plantae"))
self.gridLayout_9.addWidget(self.Plantae, 0, 1, 1, 1)
self.gridLayoutWidget_10 = QWidget(self.tab)
self.gridLayoutWidget_10.setGeometry(QtCore.QRect(9, 90, 511, 152))
self.gridLayoutWidget_10.setObjectName(_fromUtf8("gridLayoutWidget_10"))
self.gridLayout_11 = QGridLayout(self.gridLayoutWidget_10)
self.gridLayout_11.setMargin(0)
self.gridLayout_11.setObjectName(_fromUtf8("gridLayout_11"))
self.label_6 = QLabel(self.gridLayoutWidget_10)
self.label_6.setMinimumSize(QtCore.QSize(500, 20))
self.label_6.setMaximumSize(QtCore.QSize(100, 16777215))
font = QFont()
font.setBold(False)
font.setItalic(True)
font.setWeight(50)
self.label_6.setFont(font)
self.label_6.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_6.setAlignment(QtCore.Qt.AlignCenter)
self.label_6.setObjectName(_fromUtf8("label_6"))
self.gridLayout_11.addWidget(self.label_6, 4, 0, 1, 1)
self.nom_vern = QComboBox(self.gridLayoutWidget_10)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.nom_vern.setFont(font)
self.nom_vern.setObjectName(_fromUtf8("nom_vern"))
self.gridLayout_11.addWidget(self.nom_vern, 3, 0, 1, 1)
self.label_5 = QLabel(self.gridLayoutWidget_10)
self.label_5.setMinimumSize(QtCore.QSize(500, 20))
self.label_5.setMaximumSize(QtCore.QSize(100, 16777215))
font = QFont()
font.setBold(False)
font.setItalic(True)
font.setWeight(50)
self.label_5.setFont(font)
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.gridLayout_11.addWidget(self.label_5, 2, 0, 1, 1)
self.nom_complet = QComboBox(self.gridLayoutWidget_10)
self.nom_complet.setMinimumSize(QtCore.QSize(500, 0))
font = QFont()
font.setBold(False)
font.setWeight(50)
self.nom_complet.setFont(font)
self.nom_complet.setObjectName(_fromUtf8("nom_complet"))
self.gridLayout_11.addWidget(self.nom_complet, 5, 0, 1, 1)
self.ordre = QComboBox(self.gridLayoutWidget_10)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.ordre.setFont(font)
self.ordre.setObjectName(_fromUtf8("ordre"))
self.gridLayout_11.addWidget(self.ordre, 1, 0, 1, 1)
self.label_13 = QLabel(self.gridLayoutWidget_10)
self.label_13.setMinimumSize(QtCore.QSize(500, 20))
self.label_13.setMaximumSize(QtCore.QSize(100, 16777215))
font = QFont()
font.setBold(False)
font.setItalic(True)
font.setWeight(50)
self.label_13.setFont(font)
self.label_13.setAlignment(QtCore.Qt.AlignCenter)
self.label_13.setObjectName(_fromUtf8("label_13"))
self.gridLayout_11.addWidget(self.label_13, 0, 0, 1, 1)
self.Emprise.addTab(self.tab, _fromUtf8(""))
self.tab_3 = QWidget()
self.tab_3.setObjectName(_fromUtf8("tab_3"))
self.protections = QToolBox(self.tab_3)
self.protections.setGeometry(QtCore.QRect(10, 10, 511, 391))
self.protections.setFrameShape(QFrame.NoFrame)
self.protections.setFrameShadow(QFrame.Plain)
self.protections.setLineWidth(1)
self.protections.setObjectName(_fromUtf8("protections"))
self.page_2 = QWidget()
self.page_2.setGeometry(QtCore.QRect(0, 0, 511, 310))
self.page_2.setObjectName(_fromUtf8("page_2"))
self.groupBox = QGroupBox(self.page_2)
self.groupBox.setGeometry(QtCore.QRect(0, 0, 511, 121))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox.setFont(font)
self.groupBox.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.gridLayoutWidget_2 = QWidget(self.groupBox)
self.gridLayoutWidget_2.setGeometry(QtCore.QRect(10, 20, 491, 88))
self.gridLayoutWidget_2.setObjectName(_fromUtf8("gridLayoutWidget_2"))
self.gridLayout_2 = QGridLayout(self.gridLayoutWidget_2)
self.gridLayout_2.setMargin(0)
self.gridLayout_2.setHorizontalSpacing(50)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
self.LRD_38 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_38.setFont(font)
self.LRD_38.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRD_38.setObjectName(_fromUtf8("LRD_38"))
self.gridLayout_2.addWidget(self.LRD_38, 3, 0, 1, 1)
self.LRD_01 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_01.setFont(font)
self.LRD_01.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRD_01.setObjectName(_fromUtf8("LRD_01"))
self.gridLayout_2.addWidget(self.LRD_01, 0, 0, 1, 1)
self.LRD_07 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_07.setFont(font)
self.LRD_07.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRD_07.setObjectName(_fromUtf8("LRD_07"))
self.gridLayout_2.addWidget(self.LRD_07, 1, 0, 1, 1)
self.LRD_26 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_26.setFont(font)
self.LRD_26.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRD_26.setObjectName(_fromUtf8("LRD_26"))
self.gridLayout_2.addWidget(self.LRD_26, 2, 0, 1, 1)
self.LRD_42 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_42.setFont(font)
self.LRD_42.setObjectName(_fromUtf8("LRD_42"))
self.gridLayout_2.addWidget(self.LRD_42, 0, 1, 1, 1)
self.LRD_69 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_69.setFont(font)
self.LRD_69.setObjectName(_fromUtf8("LRD_69"))
self.gridLayout_2.addWidget(self.LRD_69, 1, 1, 1, 1)
self.LRD_73 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_73.setFont(font)
self.LRD_73.setObjectName(_fromUtf8("LRD_73"))
self.gridLayout_2.addWidget(self.LRD_73, 2, 1, 1, 1)
self.LRD_74 = QCheckBox(self.gridLayoutWidget_2)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRD_74.setFont(font)
self.LRD_74.setObjectName(_fromUtf8("LRD_74"))
self.gridLayout_2.addWidget(self.LRD_74, 3, 1, 1, 1)
self.groupBox_2 = QGroupBox(self.page_2)
self.groupBox_2.setGeometry(QtCore.QRect(0, 130, 511, 71))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_2.setFont(font)
self.groupBox_2.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
self.gridLayoutWidget_3 = QWidget(self.groupBox_2)
self.gridLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 491, 42))
self.gridLayoutWidget_3.setObjectName(_fromUtf8("gridLayoutWidget_3"))
self.gridLayout_3 = QGridLayout(self.gridLayoutWidget_3)
self.gridLayout_3.setMargin(0)
self.gridLayout_3.setHorizontalSpacing(50)
self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
self.LRR_Flore = QCheckBox(self.gridLayoutWidget_3)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRR_Flore.setFont(font)
self.LRR_Flore.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRR_Flore.setObjectName(_fromUtf8("LRR_Flore"))
self.gridLayout_3.addWidget(self.LRR_Flore, 0, 0, 1, 1)
self.LRR_Oiseaux = QCheckBox(self.gridLayoutWidget_3)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRR_Oiseaux.setFont(font)
self.LRR_Oiseaux.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRR_Oiseaux.setObjectName(_fromUtf8("LRR_Oiseaux"))
self.gridLayout_3.addWidget(self.LRR_Oiseaux, 1, 0, 1, 1)
self.LRR_Autre = QCheckBox(self.gridLayoutWidget_3)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRR_Autre.setFont(font)
self.LRR_Autre.setObjectName(_fromUtf8("LRR_Autre"))
self.gridLayout_3.addWidget(self.LRR_Autre, 0, 1, 1, 1)
self.groupBox_3 = QGroupBox(self.page_2)
self.groupBox_3.setGeometry(QtCore.QRect(0, 210, 511, 71))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_3.setFont(font)
self.groupBox_3.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_3.setObjectName(_fromUtf8("groupBox_3"))
self.gridLayoutWidget_4 = QWidget(self.groupBox_3)
self.gridLayoutWidget_4.setGeometry(QtCore.QRect(10, 20, 491, 42))
self.gridLayoutWidget_4.setObjectName(_fromUtf8("gridLayoutWidget_4"))
self.gridLayout_4 = QGridLayout(self.gridLayoutWidget_4)
self.gridLayout_4.setContentsMargins(-1, 0, -1, -1)
self.gridLayout_4.setHorizontalSpacing(50)
self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4"))
self.LRN_Autre = QCheckBox(self.gridLayoutWidget_4)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRN_Autre.setFont(font)
self.LRN_Autre.setObjectName(_fromUtf8("LRN_Autre"))
self.gridLayout_4.addWidget(self.LRN_Autre, 1, 1, 1, 1)
self.LRN_Flore = QCheckBox(self.gridLayoutWidget_4)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRN_Flore.setFont(font)
self.LRN_Flore.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRN_Flore.setObjectName(_fromUtf8("LRN_Flore"))
self.gridLayout_4.addWidget(self.LRN_Flore, 0, 0, 1, 1)
self.LRN_Oiseaux = QCheckBox(self.gridLayoutWidget_4)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRN_Oiseaux.setFont(font)
self.LRN_Oiseaux.setLayoutDirection(QtCore.Qt.RightToLeft)
self.LRN_Oiseaux.setObjectName(_fromUtf8("LRN_Oiseaux"))
self.gridLayout_4.addWidget(self.LRN_Oiseaux, 1, 0, 1, 1)
self.LRN_Ortho = QCheckBox(self.gridLayoutWidget_4)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.LRN_Ortho.setFont(font)
self.LRN_Ortho.setObjectName(_fromUtf8("LRN_Ortho"))
self.gridLayout_4.addWidget(self.LRN_Ortho, 0, 1, 1, 1)
self.gridLayoutWidget_11 = QWidget(self.page_2)
self.gridLayoutWidget_11.setGeometry(QtCore.QRect(6, 290, 501, 19))
self.gridLayoutWidget_11.setObjectName(_fromUtf8("gridLayoutWidget_11"))
self.gridLayout_12 = QGridLayout(self.gridLayoutWidget_11)
self.gridLayout_12.setMargin(0)
self.gridLayout_12.setHorizontalSpacing(50)
self.gridLayout_12.setObjectName(_fromUtf8("gridLayout_12"))
self.UICN = QCheckBox(self.gridLayoutWidget_11)
font = QFont()
font.setBold(True)
font.setWeight(75)
self.UICN.setFont(font)
self.UICN.setLayoutDirection(QtCore.Qt.RightToLeft)
self.UICN.setObjectName(_fromUtf8("UICN"))
self.gridLayout_12.addWidget(self.UICN, 0, 0, 1, 1)
self.LRE = QCheckBox(self.gridLayoutWidget_11)
font = QFont()
font.setBold(True)
font.setWeight(75)
self.LRE.setFont(font)
self.LRE.setObjectName(_fromUtf8("LRE"))
self.gridLayout_12.addWidget(self.LRE, 0, 1, 1, 1)
self.protections.addItem(self.page_2, _fromUtf8(""))
self.page = QWidget()
self.page.setGeometry(QtCore.QRect(0, 0, 100, 30))
self.page.setObjectName(_fromUtf8("page"))
self.PATRIMONIALITE = QCheckBox(self.page)
self.PATRIMONIALITE.setGeometry(QtCore.QRect(140, 10, 251, 17))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.PATRIMONIALITE.setFont(font)
self.PATRIMONIALITE.setObjectName(_fromUtf8("PATRIMONIALITE"))
self.gridLayoutWidget = QWidget(self.page)
self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 40, 501, 88))
self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget"))
self.gridLayout = QGridLayout(self.gridLayoutWidget)
self.gridLayout.setMargin(0)
self.gridLayout.setHorizontalSpacing(50)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.PATRI38 = QCheckBox(self.gridLayoutWidget)
self.PATRI38.setLayoutDirection(QtCore.Qt.RightToLeft)
self.PATRI38.setObjectName(_fromUtf8("PATRI38"))
self.gridLayout.addWidget(self.PATRI38, 3, 0, 1, 1)
self.PATRI01 = QCheckBox(self.gridLayoutWidget)
self.PATRI01.setLayoutDirection(QtCore.Qt.RightToLeft)
self.PATRI01.setObjectName(_fromUtf8("PATRI01"))
self.gridLayout.addWidget(self.PATRI01, 0, 0, 1, 1)
self.PATRI07 = QCheckBox(self.gridLayoutWidget)
self.PATRI07.setLayoutDirection(QtCore.Qt.RightToLeft)
self.PATRI07.setObjectName(_fromUtf8("PATRI07"))
self.gridLayout.addWidget(self.PATRI07, 1, 0, 1, 1)
self.PATRI26 = QCheckBox(self.gridLayoutWidget)
self.PATRI26.setLayoutDirection(QtCore.Qt.RightToLeft)
self.PATRI26.setObjectName(_fromUtf8("PATRI26"))
self.gridLayout.addWidget(self.PATRI26, 2, 0, 1, 1)
self.PATRI42 = QCheckBox(self.gridLayoutWidget)
self.PATRI42.setObjectName(_fromUtf8("PATRI42"))
self.gridLayout.addWidget(self.PATRI42, 0, 1, 1, 1)
self.PATRI69 = QCheckBox(self.gridLayoutWidget)
self.PATRI69.setObjectName(_fromUtf8("PATRI69"))
self.gridLayout.addWidget(self.PATRI69, 1, 1, 1, 1)
self.PATRI73 = QCheckBox(self.gridLayoutWidget)
self.PATRI73.setObjectName(_fromUtf8("PATRI73"))
self.gridLayout.addWidget(self.PATRI73, 2, 1, 1, 1)
self.PATRI74 = QCheckBox(self.gridLayoutWidget)
self.PATRI74.setObjectName(_fromUtf8("PATRI74"))
self.gridLayout.addWidget(self.PATRI74, 3, 1, 1, 1)
self.ZNIEFF = QCheckBox(self.page)
self.ZNIEFF.setGeometry(QtCore.QRect(140, 140, 221, 17))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.ZNIEFF.setFont(font)
self.ZNIEFF.setObjectName(_fromUtf8("ZNIEFF"))
self.protections.addItem(self.page, _fromUtf8(""))
self.page_3 = QWidget()
self.page_3.setGeometry(QtCore.QRect(0, 0, 100, 30))
self.page_3.setObjectName(_fromUtf8("page_3"))
self.groupBox_6 = QGroupBox(self.page_3)
self.groupBox_6.setGeometry(QtCore.QRect(0, 10, 511, 51))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_6.setFont(font)
self.groupBox_6.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.groupBox_6.setObjectName(_fromUtf8("groupBox_6"))
self.gridLayoutWidget_7 = QWidget(self.groupBox_6)
self.gridLayoutWidget_7.setGeometry(QtCore.QRect(10, 20, 491, 21))
self.gridLayoutWidget_7.setObjectName(_fromUtf8("gridLayoutWidget_7"))
self.gridLayout_7 = QGridLayout(self.gridLayoutWidget_7)
self.gridLayout_7.setMargin(0)
self.gridLayout_7.setHorizontalSpacing(50)
self.gridLayout_7.setObjectName(_fromUtf8("gridLayout_7"))
self.PD_42 = QCheckBox(self.gridLayoutWidget_7)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.PD_42.setFont(font)
self.PD_42.setObjectName(_fromUtf8("PD_42"))
self.gridLayout_7.addWidget(self.PD_42, 0, 1, 1, 1)
self.PD_38 = QCheckBox(self.gridLayoutWidget_7)
font = QFont()
font.setBold(False)
font.setWeight(50)
self.PD_38.setFont(font)
self.PD_38.setLayoutDirection(QtCore.Qt.RightToLeft)
self.PD_38.setObjectName(_fromUtf8("PD_38"))
self.gridLayout_7.addWidget(self.PD_38, 0, 0, 1, 1)
self.PR = QCheckBox(self.page_3)
self.PR.setGeometry(QtCore.QRect(10, 70, 171, 17))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.PR.setFont(font)
self.PR.setObjectName(_fromUtf8("PR"))
self.PN = QCheckBox(self.page_3)
self.PN.setGeometry(QtCore.QRect(10, 100, 171, 17))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.PN.setFont(font)
self.PN.setObjectName(_fromUtf8("PN"))
self.DH_AnnII = QCheckBox(self.page_3)
self.DH_AnnII.setGeometry(QtCore.QRect(10, 130, 201, 17))
font = QFont()
font.setBold(True)
font.setWeight(75)
self.DH_AnnII.setFont(font)
self.DH_AnnII.setObjectName(_fromUtf8("DH_AnnII"))
self.protections.addItem(self.page_3, _fromUtf8(""))
self.Emprise.addTab(self.tab_3, _fromUtf8(""))
self.tab_4 = QWidget()
self.tab_4.setObjectName(_fromUtf8("tab_4"))
self.gridLayoutWidget_12 = QWidget(self.tab_4)
self.gridLayoutWidget_12.setGeometry(QtCore.QRect(30, 30, 481, 130))
self.gridLayoutWidget_12.setObjectName(_fromUtf8("gridLayoutWidget_12"))
self.gridLayout_10 = QGridLayout(self.gridLayoutWidget_12)
self.gridLayout_10.setMargin(0)
self.gridLayout_10.setVerticalSpacing(20)
self.gridLayout_10.setObjectName(_fromUtf8("gridLayout_10"))
self.label_7 = QLabel(self.gridLayoutWidget_12)
font = QFont()
font.setPointSize(10)
self.label_7.setFont(font)
self.label_7.setObjectName(_fromUtf8("label_7"))
self.gridLayout_10.addWidget(self.label_7, 0, 1, 1, 1)
self.label_14 = QLabel(self.gridLayoutWidget_12)
font = QFont()
font.setPointSize(10)
self.label_14.setFont(font)
self.label_14.setObjectName(_fromUtf8("label_14"))
self.gridLayout_10.addWidget(self.label_14, 2, 1, 1, 1)
self.label_12 = QLabel(self.gridLayoutWidget_12)
font = QFont()
font.setPointSize(10)
self.label_12.setFont(font)
self.label_12.setObjectName(_fromUtf8("label_12"))
self.gridLayout_10.addWidget(self.label_12, 1, 1, 1, 1)
self.buffer = QLineEdit(self.gridLayoutWidget_12)
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.buffer.sizePolicy().hasHeightForWidth())
self.buffer.setSizePolicy(sizePolicy)
self.buffer.setMaximumSize(QtCore.QSize(100, 16777215))
self.buffer.setInputMethodHints(QtCore.Qt.ImhPreferNumbers)
self.buffer.setAlignment(QtCore.Qt.AlignCenter)
self.buffer.setObjectName(_fromUtf8("buffer"))
self.gridLayout_10.addWidget(self.buffer, 2, 2, 1, 1)
self.label_8 = QLabel(self.gridLayoutWidget_12)
self.label_8.setMaximumSize(QtCore.QSize(20, 16777215))
font = QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_8.setFont(font)
self.label_8.setObjectName(_fromUtf8("label_8"))
self.gridLayout_10.addWidget(self.label_8, 0, 0, 1, 1)
self.label_9 = QLabel(self.gridLayoutWidget_12)
self.label_9.setMaximumSize(QtCore.QSize(20, 16777215))
font = QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_9.setFont(font)
self.label_9.setObjectName(_fromUtf8("label_9"))
self.gridLayout_10.addWidget(self.label_9, 1, 0, 1, 1)
self.label_10 = QLabel(self.gridLayoutWidget_12)
self.label_10.setMaximumSize(QtCore.QSize(20, 16777215))
font = QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_10.setFont(font)
self.label_10.setObjectName(_fromUtf8("label_10"))
self.gridLayout_10.addWidget(self.label_10, 2, 0, 1, 1)
self.label_15 = QLabel(self.tab_4)
self.label_15.setGeometry(QtCore.QRect(70, 180, 111, 16))
font = QFont()
font.setPointSize(10)
self.label_15.setFont(font)
self.label_15.setObjectName(_fromUtf8("label_15"))
self.label_11 = QLabel(self.tab_4)
self.label_11.setGeometry(QtCore.QRect(40, 180, 12, 16))
self.label_11.setMaximumSize(QtCore.QSize(20, 16777215))
font = QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_11.setFont(font)
self.label_11.setObjectName(_fromUtf8("label_11"))
self.bouton_geom = QCheckBox(self.tab_4)
self.bouton_geom.setGeometry(QtCore.QRect(190, 180, 21, 16))
self.bouton_geom.setMaximumSize(QtCore.QSize(150, 16777215))
font = QFont()
font.setPointSize(10)
font.setBold(False)
font.setWeight(50)
self.bouton_geom.setFont(font)
self.bouton_geom.setLayoutDirection(QtCore.Qt.LeftToRight)
self.bouton_geom.setText(_fromUtf8(""))
self.bouton_geom.setIconSize(QtCore.QSize(20, 20))
self.bouton_geom.setObjectName(_fromUtf8("bouton_geom"))
self.Emprise.addTab(self.tab_4, _fromUtf8(""))
self.centroide = QCheckBox(SICEN)
self.centroide.setGeometry(QtCore.QRect(80, 50, 411, 20))
font = QFont()
font.setPointSize(10)
font.setItalic(True)
self.centroide.setFont(font)
self.centroide.setObjectName(_fromUtf8("centroide"))
self.retranslateUi(SICEN)
self.Emprise.setCurrentIndex(0)
self.protections.setCurrentIndex(0)
self.buttonBox.accepted.connect(SICEN.accept)
self.buttonBox.rejected.connect(SICEN.reject) #Modifié
QtCore.QMetaObject.connectSlotsByName(SICEN)
def retranslateUi(self, SICEN):
SICEN.setWindowTitle(_translate("SICEN", "SICEN", None))
self.Titre.setText(_translate("SICEN", "Ouverture des observations SICEN", None))
self.groupBox_4.setTitle(_translate("SICEN", "Observateur(s)", None))
self.groupBox_5.setTitle(_translate("SICEN", "Localisation", None))
self.label.setText(_translate("SICEN", "Commune n°1", None))
self.label_2.setText(_translate("SICEN", "Commune n°2", None))
self.groupBox_7.setTitle(_translate("SICEN", "Date", None))
self.label_3.setText(_translate("SICEN", "Supérieur à :", None))
self.label_4.setText(_translate("SICEN", "Inférieur à :", None))
self.Emprise.setTabText(self.Emprise.indexOf(self.tab_2), _translate("SICEN", "Généralités", None))
self.groupBox_8.setTitle(_translate("SICEN", "Règne", None))
self.Animalia.setText(_translate("SICEN", "Animal", None))
self.Plantae.setText(_translate("SICEN", "Végétal", None))
self.label_6.setText(_translate("SICEN", "Nom Complet : ", None))
self.label_5.setText(_translate("SICEN", "Nom Vernaculaire : ", None))
self.label_13.setText(_translate("SICEN", "Ordre :", None))
self.Emprise.setTabText(self.Emprise.indexOf(self.tab), _translate("SICEN", "Filtre par Taxons", None))
self.groupBox.setTitle(_translate("SICEN", "Départementales", None))
self.LRD_38.setText(_translate("SICEN", "Isère - 38", None))
self.LRD_01.setText(_translate("SICEN", "Ain - 01", None))
self.LRD_07.setText(_translate("SICEN", "Ardèche - 07", None))
self.LRD_26.setText(_translate("SICEN", "Drôme - 26", None))
self.LRD_42.setText(_translate("SICEN", "42 - Loire", None))
self.LRD_69.setText(_translate("SICEN", "69 - Rhône", None))
self.LRD_73.setText(_translate("SICEN", "73 - Savoie", None))
self.LRD_74.setText(_translate("SICEN", "74 - Haute-Savoie", None))
self.groupBox_2.setTitle(_translate("SICEN", "Régionales", None))
self.LRR_Flore.setText(_translate("SICEN", "Flore", None))
self.LRR_Oiseaux.setText(_translate("SICEN", "Oiseaux", None))
self.LRR_Autre.setText(_translate("SICEN", "Autre", None))
self.groupBox_3.setTitle(_translate("SICEN", "Nationales", None))
self.LRN_Autre.setText(_translate("SICEN", "Autre", None))
self.LRN_Flore.setText(_translate("SICEN", "Flore", None))
self.LRN_Oiseaux.setText(_translate("SICEN", "Oiseaux", None))
self.LRN_Ortho.setText(_translate("SICEN", "Orthoptères", None))
self.UICN.setText(_translate("SICEN", "UICN", None))
self.LRE.setText(_translate("SICEN", "Liste Rouge Européenne", None))
self.protections.setItemText(self.protections.indexOf(self.page_2), _translate("SICEN", "Listes Rouges", None))
self.PATRIMONIALITE.setText(_translate("SICEN", "Espèces Patrimoniales en Rhône-Alpes", None))
self.PATRI38.setText(_translate("SICEN", "Isère - 38", None))
self.PATRI01.setText(_translate("SICEN", "Ain - 01", None))
self.PATRI07.setText(_translate("SICEN", "Ardèche - 07", None))
self.PATRI26.setText(_translate("SICEN", "Drôme - 26", None))
self.PATRI42.setText(_translate("SICEN", "42 - Loire", None))
self.PATRI69.setText(_translate("SICEN", "69 - Rhône", None))
self.PATRI73.setText(_translate("SICEN", "73 - Savoie", None))
self.PATRI74.setText(_translate("SICEN", "74 - Haute-Savoie", None))
self.ZNIEFF.setText(_translate("SICEN", "Espèces Déterminantes ZNIEFF", None))
self.protections.setItemText(self.protections.indexOf(self.page), _translate("SICEN", "Patrimonialités", None))
self.groupBox_6.setTitle(_translate("SICEN", "Départementales", None))
self.PD_42.setText(_translate("SICEN", "42 - Loire", None))
self.PD_38.setText(_translate("SICEN", "Isère - 38", None))
self.PR.setText(_translate("SICEN", "Régionale", None))
self.PN.setText(_translate("SICEN", "Nationale", None))
self.DH_AnnII.setText(_translate("SICEN", "Directive Habitat - Annexe II", None))
self.protections.setItemText(self.protections.indexOf(self.page_3), _translate("SICEN", "Protections", None))
self.Emprise.setTabText(self.Emprise.indexOf(self.tab_3), _translate("SICEN", "Filtre par Patrimonialités / Protections", None))
self.label_7.setText(_translate("SICEN", "Sélectionnez une table", None))
self.label_14.setText(_translate("SICEN", "Déterminez un tampon autour du polygone (en mètre)", None))
self.label_12.setText(_translate("SICEN", "Sélectionnez un polygone dans cette table", None))
self.buffer.setText(_translate("SICEN", "100", None))
self.label_8.setText(_translate("SICEN", "1.", None))
self.label_9.setText(_translate("SICEN", "2.", None))
self.label_10.setText(_translate("SICEN", "3.", None))
self.label_15.setText(_translate("SICEN", "Cochez cette case", None))
self.label_11.setText(_translate("SICEN", "4.", None))
self.Emprise.setTabText(self.Emprise.indexOf(self.tab_4), _translate("SICEN", "Filtre par Emprise", None))
self.centroide.setText(_translate("SICEN", "Utiliser les centroïdes pour les observations autres que ponctuelles", None))
File diff suppressed because it is too large Load Diff
-360
View File
@@ -1,360 +0,0 @@
# -*- 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
+105
View File
@@ -0,0 +1,105 @@
<?xml version = '1.0' encoding = 'UTF-8'?>
<plugins>
<pyqgis_plugin name="CenRa_POSTGIS" version="1.8">
<description><![CDATA[Dépôt pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.]]></description>
<version>1.8</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_POSTGIS.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_POSTGIS.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2024-09-13</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,postgis</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_COPIE" version="1.5">
<description><![CDATA[Dépôt pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.]]></description>
<version>1.5</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_COPIE.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_COPIE.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2024-09-13</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,copie</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_SICEN" version="1.7">
<description><![CDATA[Dépôt pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.]]></description>
<version>1.7</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_SICEN.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_SICEN.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2024-09-13</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,sicen</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_FLUX" version="1.14">
<description><![CDATA[Dépôt pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.]]></description>
<version>1.14</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_FLUX.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_FLUX.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2024-10-03</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,flux</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_METABASE" version="1.3">
<description><![CDATA[Dépôt pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.]]></description>
<version>1.3</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_METABASE.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_METABASE.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-09-12</create_date>
<update_date>2024-10-08</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,metabase</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_AUTOMAP" version="1.6">
<description><![CDATA[Dépôt pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.]]></description>
<version>1.6</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_AUTOMAP.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_AUTOMAP.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-09-25</create_date>
<update_date>2024-10-07</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,mise en page,atlas</tags>
</pyqgis_plugin>
</plugins>