diff --git a/CenRa_AUTOMAP/CenRa_AutoMap.py b/CenRa_AUTOMAP/CenRa_AutoMap.py index 3099c39a..c64978f7 100644 --- a/CenRa_AUTOMAP/CenRa_AutoMap.py +++ b/CenRa_AUTOMAP/CenRa_AutoMap.py @@ -1,142 +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 -''' -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 .editor import AutoMap_Editor -from .about_form import AutoMapAboutDialog - -from PyQt5.QtCore import * - -class PgAutoMap: - def __init__(self): - """ Constructor. """ - 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_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.editor: - self.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.editor.show() - self.editor.raise_() - - def unload(self): - """ Unload the plugin. """ - if self.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 +__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 +''' +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 diff --git a/CenRa_AUTOMAP/canvas_editor.py b/CenRa_AUTOMAP/canvas_editor.py new file mode 100644 index 00000000..adf88efd --- /dev/null +++ b/CenRa_AUTOMAP/canvas_editor.py @@ -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() diff --git a/CenRa_AUTOMAP/metadata.txt b/CenRa_AUTOMAP/metadata.txt index 88e21b10..9322f61c 100644 --- a/CenRa_AUTOMAP/metadata.txt +++ b/CenRa_AUTOMAP/metadata.txt @@ -6,7 +6,7 @@ name=CenRa_AutoMap qgisMinimumVersion=3.0 description=CenRa_AutoMap -version=1.0 +version=1.6 author=Conservatoire d'Espaces Naturels de Rhône-Alpes email=si_besoin@cen-rhonealpes.fr @@ -21,7 +21,7 @@ tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues hasProcessingProvider=no # Uncomment the following line and add your changelog: -changelog=

CenRa_AutoMap:


26/09/2024 - Version 1.0:

- Lancement du plugin CenRa_AutoMap avec une seul mise en page.


+changelog=

CenRa_AutoMap:


07/10/2024 - Version 1.6:

- Option de bibliotheque de logo custome.


03/10/2024 - Version 1.5:

- Remonte la fênetre dans la pille.
- Gestion du nombre de colonne dans la légend.


02/10/2024 - Version 1.4:

- Mise en page plein écrant.


01/10/2024 - Version 1.3:

- Récupération du titre et sous-titre pour mise en page existente.
- Integration de bibliotheque de logo.
- Integration de gestionaire pour les source de donnée.
- Mise en place d'une bar d'echelle adaptative.


30/09/2024 - Version 1.2:

- Activation du thème.
- Ajouter une carte de suivie.


27/09/2024 - Version 1.1:

- Ajout d'une liste déroulante pour les sources de données.
- Bouton pour ajouter des fonts de carte customisés.
- Fonctionnalité de génération d'atlas.


26/09/2024 - Version 1.0:

- Lancement du plugin CenRa_AutoMap avec une seul mise en page.


# Tags are comma separated with spaces allowed tags=python @@ -41,7 +41,7 @@ deprecated=False # plugin_dependencies= Category of the plugin: Raster, Vector, Database or Web -# category=cenra,mise en page,aide +# category=cenra,mise en page,atlas # If the plugin can run on QGIS Server. server=False