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 * 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, QgsLayoutItemHtml, ) 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 import QtGui from qgis.PyQt.QtWidgets import QApplication from qgis.PyQt.QtCore import QSettings,QPointF from qgis.PyQt.QtXml import QDomDocument from qgis.utils import iface import glob from .tools.resources import ( load_ui, resources_path, send_issues, ) from .issues import CenRa_Issues from datetime import date last_select = None maxV=210 maxH=296 EDITOR_CLASS = load_ui('CenRa_PageRender_base.ui') LOGGER = logging.getLogger('CenRa_PageRender') 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 PageRender_Editor(QDialog, EDITOR_CLASS): def __init__(self, parent=None): _ = parent super().__init__() self.setupUi(self) self.settings = QgsSettings() self.s = QSettings() self.setWindowIcon(QtGui.QIcon(resources_path('icons','icon.png'))) self.varLandscape = {} self.varPortrait = {} self.rotate_object = { 'Titre':0, 'Sous_titre':0, 'Carte':0, 'Carte_2':0, 'Legande':0, 'Arrow':0, 'Echelle':0, 'Logo':0, 'Credit':0, 'Source':0, 'Echelle_2':0, 'Logo_2':0,} path = '' ix = 0 plugin_dir = str(os.path.dirname(os.path.abspath(__file__))).split(os.sep) for i in plugin_dir: ix = ix+1 path = path+'\\'+i self.path = path[1:]+'\\demoV2.py' #self.tabWidget.setStyleSheet('background-image: url('+path+'/tools/bg/Capture.png);') self.toolButton.setIcon(QtGui.QIcon(resources_path('ui','rotate.png'))) self.horizontalSlider.valueChanged.connect(self.horizontal) self.verticalSlider.valueChanged.connect(self.vertical) self.tableWidget.itemSelectionChanged.connect(self.setSlider) self.radioButton.toggled.connect(self.setSlider) self.pushButton.clicked.connect(self.export) self.spinBox.editingFinished.connect(self.valueSlider) self.spinBox_2.editingFinished.connect(self.valueSlider) self.toolButton.clicked.connect(self.rotate) self.toolButton_2.clicked.connect(self.type_page) self.pushButton_2.clicked.connect(self.load) self.verticalScrollBar.valueChanged.connect(self.moveFrame) #self.setAcceptHoverEvents(True) self.tableWidget.setTabKeyNavigation(False) def raise_(self): self.activateWindow() self.setNavigator() self.verticalScrollBar.setValue(self.frame.y()) def mousePressEvent(self, event): if self.tableWidget.currentItem() != None: QApplication.setOverrideCursor(Qt.CursorShape(18)) global lastPos lastPos = {'x':event.pos().x(),'y':event.pos().y()} def moveFrame(self): self.frame.move(self.frame.x(),self.verticalScrollBar.value()) def keyPressEvent(self, event): #if event.modifiers() & Qt.ControlModifier: if event.key() == Qt.Key(0x01000015): self.verticalSlider.setValue(self.spinBox_2.value()+1) if event.key() == Qt.Key(0x01000013): self.verticalSlider.setValue(self.spinBox_2.value()-1) if event.key() == Qt.Key(0x01000014): self.horizontalSlider.setValue(self.spinBox.value()+1) if event.key() == Qt.Key(0x01000012): self.horizontalSlider.setValue(self.spinBox.value()-1) def wheelEvent(self,event): if (event.angleDelta().y() >= 1): vsb = self.verticalScrollBar.value()+50 else: vsb = self.verticalScrollBar.value()-50 self.verticalScrollBar.setValue(vsb) def mouseMoveEvent(self, event): updated_cursor_position = event.pos() if self.tableWidget.currentItem() != None: selection_name = (self.tableWidget.currentItem()).text() all_children = self.frame.children() selection = 0 for children in all_children: if selection_name == children.objectName(): selection = children frame_x = self.frame.x() frame_y = self.frame.y() frame_w = self.frame.width()+frame_x frame_h = self.frame.height()+frame_y global lastPos orig_position_w = selection.width() orig_position_h = selection.height() if (frame_x <= round(updated_cursor_position.x()) <= frame_w and self.radioButton.isChecked() == True): updated_cursor_position_x = orig_position_w+(round(updated_cursor_position.x()-lastPos['x'])) lastPos['x'] = event.pos().x() selection.resize(updated_cursor_position_x,orig_position_h) self.horizontalSlider.setValue(round(updated_cursor_position_x/3.5)) orig_position_w = selection.width() orig_position_h = selection.height() if (frame_y <= round(updated_cursor_position.y()) <= frame_h and self.radioButton.isChecked() == True): updated_cursor_position_y = orig_position_h+(round(updated_cursor_position.y()-lastPos['y'])) lastPos['y'] = event.pos().y() selection.resize(orig_position_w,updated_cursor_position_y) self.verticalSlider.setValue(round(updated_cursor_position_y/3.5)) orig_position_x = selection.pos().x() orig_position_y = selection.pos().y() if (frame_x <= round(updated_cursor_position.x()) <= frame_w and self.radioButton.isChecked() == False): updated_cursor_position_x = orig_position_x+(round(updated_cursor_position.x()-lastPos['x'])) lastPos['x'] = event.pos().x() #print(updated_cursor_position_x) selection.move(updated_cursor_position_x,orig_position_y) self.horizontalSlider.setValue(round(updated_cursor_position_x/3.5)) orig_position_x = selection.pos().x() orig_position_y = selection.pos().y() if (frame_y <= round(updated_cursor_position.y()) <= frame_h and self.radioButton.isChecked() == False): updated_cursor_position_y = orig_position_y+(round(updated_cursor_position.y()-lastPos['y'])) lastPos['y'] = event.pos().y() #print(updated_cursor_position_y) selection.move(orig_position_x,updated_cursor_position_y) self.verticalSlider.setValue(round(updated_cursor_position_y/3.5)) def mouseReleaseEvent(self, event): #print('x: {0}, y: {1}'.format(event.pos().x(), event.pos().y())) if self.tableWidget.currentItem() != None: QApplication.restoreOverrideCursor() def select_file(self): options = QFileDialog.Options() options |= QFileDialog.ShowDirsOnly folder = QFileDialog.getOpenFileName(self, "Sélection du fichier ",'','Python(*.py)') if folder[0] != '': return folder[0] else: return '' def load(self): folder = self.select_file() logopath = folder if logopath != '': #logopath = (os.path.dirname(logopath).split('/')) sourcefile = open(logopath, 'r') splitsource = sourcefile.read().splitlines() all_children = self.frame.children() all_element = ['_locals','_size','_rotate'] for children in all_children: flen = 0 for element in all_element: flen = 0 recherche_element = children.objectName()+element for find_it in splitsource: if find_it.find(recherche_element) != -1: flen = flen+1 if flen == 1: if element != '_rotate': value_find = (find_it[find_it[:].find('(')+1:-33]).split(',') if element == '_size': Psize_h = float(value_find[0])*3.5 Psize_w = float(value_find[1])*3.5 if element == '_locals': Plocals_h = float(value_find[0])*3.5 Plocals_w = float(value_find[1])*3.5 else: Protate = float((find_it[find_it[:].find('=')+2:]).split(',')[0]) if flen == 3: if element != '_rotate': value_find = (find_it[find_it[:].find('(')+1:-33]).split(',') if element == '_size': Lsize_h = float(value_find[0])*3.5 Lsize_w = float(value_find[1])*3.5 if element == '_locals': Llocals_h = float(value_find[0])*3.5 Llocals_w = float(value_find[1])*3.5 else: Lrotate = float((find_it[find_it[:].find('=')+2:]).split(',')[0]) #print('sh',Psize_h,',sw',Psize_w,',lh',Plocals_h,',lw',Plocals_w,',r',Protate) if Lrotate == 90 or Lrotate == 270: old = Lsize_w Lsize_w = Lsize_h Lsize_h = old if Protate == 90 or Protate == 270: old = Psize_w Psize_w = Psize_h Psize_h = old if self.toolButton_2.text() == 'Landscape': children.resize(round(Lsize_h),round(Lsize_w)) children.move(round(Llocals_h),round(Llocals_w)) self.rotate_object[children.objectName()] = Lrotate if self.toolButton_2.text() == 'Portrait': children.resize(round(Psize_h),round(Psize_w)) children.move(round(Plocals_h),round(Plocals_w)) self.rotate_object[children.objectName()] = Protate def valueSlider(self): self.horizontalSlider.setValue(self.spinBox.value()) self.verticalSlider.setValue(self.spinBox_2.value()) def setNavigator(self): all_children = self.frame.children() xR=0 baseRow = self.tableWidget.rowCount() while baseRow >= xR: self.tableWidget.removeRow(0) xR = xR+1 self.tableWidget.clear() id=0 for children in all_children: position = self.tableWidget.rowCount() self.tableWidget.insertRow(position) self.tableWidget.setItem(position,0,QTableWidgetItem(children.objectName())) #print(children.objectName()) def export(self): self.type_page() self.type_page() all_children = self.frame.children() #selection_name = (self.tableWidget.currentItem()).text() export_str = """ from qgis.core import ( QgsLayoutSize, QgsUnitTypes, QgsLayoutPoint, ) def fletch_canvas(self): if self.radioButton_6.isChecked(): values_page = 'A4' else: values_page = 'A3' if self.radioButton_7.isChecked(): page_rotate = 'Portrait' else: page_rotate = 'Landscape' """ type = ["Portrait","Landscape"] page = ["A4","A3"] for page_type in type: export_str = export_str+""" if page_rotate == '"""+page_type+"""':""" for page_size in page: export_str = export_str+""" if values_page == '"""+page_size+"""':""" for children in all_children: selection = children if page_type == 'Portrait': item_rotate_object=self.varPortrait[selection.objectName()+'_rotate'][0] if item_rotate_object == 0 or item_rotate_object == 180: sw = 0 sh = 1 if item_rotate_object == 90 or item_rotate_object == 270: sw = 1 sh = 0 if page_size == 'A3': size_w = (round((self.varPortrait[selection.objectName()+'_size'][sw]/3.5)*1.41)) size_h = (round((self.varPortrait[selection.objectName()+'_size'][sh]/3.5)*1.41)) locals_w = (round((self.varPortrait[selection.objectName()+'_locals'][1]/3.5)*1.41)) locals_h = (round((self.varPortrait[selection.objectName()+'_locals'][0]/3.5)*1.41)) else: size_w = (round(self.varPortrait[selection.objectName()+'_size'][sw])/3.5) size_h = (round(self.varPortrait[selection.objectName()+'_size'][sh]/3.5)) locals_w = (round(self.varPortrait[selection.objectName()+'_locals'][1]/3.5)) locals_h = (round(self.varPortrait[selection.objectName()+'_locals'][0]/3.5)) if page_type == 'Landscape': item_rotate_object=self.varLandscape[selection.objectName()+'_rotate'][0] if item_rotate_object == 0 or item_rotate_object == 180: sw = 0 sh = 1 if item_rotate_object == 90 or item_rotate_object == 270: sw = 1 sh = 0 if page_size == 'A3': size_w = (round((self.varLandscape[selection.objectName()+'_size'][sw]/3.5)*1.41)) size_h = (round((self.varLandscape[selection.objectName()+'_size'][sh]/3.5)*1.41)) locals_w = (round((self.varLandscape[selection.objectName()+'_locals'][1]/3.5)*1.41)) locals_h = (round((self.varLandscape[selection.objectName()+'_locals'][0]/3.5)*1.41)) else: size_w = (round(self.varLandscape[selection.objectName()+'_size'][sw])/3.5) size_h = (round(self.varLandscape[selection.objectName()+'_size'][sh]/3.5)) locals_w = (round(self.varLandscape[selection.objectName()+'_locals'][1]/3.5)) locals_h = (round(self.varLandscape[selection.objectName()+'_locals'][0]/3.5)) if item_rotate_object == 270: locals_h= locals_h + size_w if item_rotate_object == 180: locals_h= locals_h + size_h locals_w= locals_w + size_w size_w = str(size_w) size_h = str(size_h) locals_w = str(locals_w) locals_h = str(locals_h) export_str = export_str+""" self.template_parameters['"""+selection.objectName()+"""_size'] = QgsLayoutSize("""+size_w+""","""+ size_h+""", QgsUnitTypes.LayoutMillimeters) self.template_parameters['"""+selection.objectName()+"""_locals'] = QgsLayoutPoint("""+locals_w+""", """+locals_h+""", QgsUnitTypes.LayoutMillimeters) self.template_parameters['"""+selection.objectName()+"""_rotate'] = """+str(item_rotate_object) export_str= export_str+""" return self.template_parameters""" sourceFile = open(self.path,'w') print(export_str, file = sourceFile) sourceFile.close() def type_page(self): all_children = self.frame.children() if self.toolButton_2.text() == 'Landscape': self.horizontalSlider.setMaximum(maxV) self.verticalSlider.setMaximum(maxH) last_children=0 for children in all_children: selection = children size_w = selection.size().width() size_h = selection.size().height() locals_h = selection.x() locals_w = selection.y() item_rotate_object = self.rotate_object[selection.objectName()] self.varLandscape[selection.objectName()+'_size'] = [size_w,size_h] self.varLandscape[selection.objectName()+'_locals'] = [locals_w,locals_h] self.varLandscape[selection.objectName()+'_rotate'] = [item_rotate_object] if self.varPortrait != {}: selection.move(self.varPortrait[selection.objectName()+'_locals'][1],self.varPortrait[selection.objectName()+'_locals'][0]) selection.resize(self.varPortrait[selection.objectName()+'_size'][0],self.varPortrait[selection.objectName()+'_size'][1]) self.rotate_object[selection.objectName()] = self.varPortrait[selection.objectName()+'_rotate'][0] self.rotate_color(selection,last_children) last_children = selection self.toolButton_2.setText('Portrait') elif self.toolButton_2.text() == 'Portrait': self.horizontalSlider.setMaximum(maxH) self.verticalSlider.setMaximum(maxV) last_children=0 for children in all_children: selection = children size_w = selection.size().width() size_h = selection.size().height() locals_h = selection.x() locals_w = selection.y() item_rotate_object = self.rotate_object[selection.objectName()] self.varPortrait[selection.objectName()+'_size'] = [size_w,size_h] self.varPortrait[selection.objectName()+'_locals'] = [locals_w,locals_h] self.varPortrait[selection.objectName()+'_rotate'] = [item_rotate_object] if self.varLandscape != {}: selection.move(self.varLandscape[selection.objectName()+'_locals'][1],self.varLandscape[selection.objectName()+'_locals'][0]) selection.resize(self.varLandscape[selection.objectName()+'_size'][0],self.varLandscape[selection.objectName()+'_size'][1]) self.rotate_object[selection.objectName()] = self.varLandscape[selection.objectName()+'_rotate'][0] self.rotate_color(selection,last_children) last_children = selection self.toolButton_2.setText('Landscape') frame_w = self.frame.width() frame_h = self.frame.height() self.frame.resize(frame_h,frame_w) frame_x = round(frame_w / 3) frame_y = self.frame.y() self.frame.move(frame_x,frame_y) def setSlider(self): if self.tableWidget.currentItem() != None: print(self.tableWidget.tabKeyNavigation()) selection_name = (self.tableWidget.currentItem()).text() all_children = self.frame.children() selection = 0 last_children = 0 for children in all_children: if last_select == children.objectName(): last_children = children if selection_name == children.objectName(): selection = children if selection != 0: self.rotate_color(selection,last_children) if self.radioButton.isChecked() == False: xx = round(selection.x()/3.5) yy = round(selection.y()/3.5) else: xx = round(selection.size().width()/3.5) yy = round(selection.size().height()/3.5) #print(xx,yy) self.horizontalSlider.setValue(xx) self.verticalSlider.setValue(yy) self.spinBox.setValue(xx) self.spinBox_2.setValue(yy) def rotate_color(self,selection,last_children): global last_select if self.radioButton.isChecked() == False: ColorCode = "10, 10, 80, 50" else: ColorCode = "249, 238, 148, 50" if self.rotate_object[selection.objectName()] == 0: selection.setStyleSheet("border: 2px solid;border-color:red;border-bottom-color: blue;background-color: rgb("+ColorCode+")") elif self.rotate_object[selection.objectName()] == 90: selection.setStyleSheet("border: 2px solid;border-color:red;border-left-color: blue;background-color: rgb("+ColorCode+")") elif self.rotate_object[selection.objectName()] == 180: selection.setStyleSheet("border: 2px solid;border-color:red;border-top-color: blue;background-color: rgb("+ColorCode+")") elif self.rotate_object[selection.objectName()] == 270: selection.setStyleSheet("border: 2px solid;border-color:red;border-right-color: blue;background-color: rgb("+ColorCode+")") if last_children != 0: if last_select != selection.objectName(): last_children.setStyleSheet("background-color: rgb(10, 10, 10, 50)") last_select = selection.objectName() def rotate(self): if self.tableWidget.currentItem() != None: selection_name = (self.tableWidget.currentItem()).text() all_children = self.frame.children() selection = 0 last_children = 0 for children in all_children: if last_select == children.objectName(): last_children = children if selection_name == children.objectName(): selection = children if selection != 0: xx = round(selection.size().width()) yy = round(selection.size().height()) selection.resize(round(yy),round(xx)) if self.radioButton.isChecked() == True: self.spinBox.setValue(yy) self.spinBox_2.setValue(xx) self.horizontalSlider.setValue(round(yy/3.5)) self.verticalSlider.setValue(round(xx/3.5)) if self.rotate_object[selection.objectName()] == 270: self.rotate_object[selection.objectName()] = 0 else: self.rotate_object[selection.objectName()] = self.rotate_object[selection.objectName()] + 90 self.rotate_color(selection,last_children) def vertical(self): if self.tableWidget.currentItem() != None: selection_name = (self.tableWidget.currentItem()).text() all_children = self.frame.children() selection = 0 for children in all_children: if selection_name == children.objectName(): selection = children if selection != 0: if self.radioButton.isChecked() == False: selection.move(round(self.horizontalSlider.value()*3.5),round(self.verticalSlider.value()*3.5)) else: selection.resize(round(self.horizontalSlider.value()*3.5),round(self.verticalSlider.value()*3.5)) self.spinBox.setValue(round(self.horizontalSlider.value())) self.spinBox_2.setValue(round(self.verticalSlider.value())) def horizontal(self): if self.tableWidget.currentItem() != None: selection_name = (self.tableWidget.currentItem()).text() all_children = self.frame.children() selection = 0 for children in all_children: if selection_name == children.objectName(): selection = children if selection != 0: if self.radioButton.isChecked() == False: selection.move(round(self.horizontalSlider.value()*3.5),round(self.verticalSlider.value()*3.5)) else: selection.resize(round(self.horizontalSlider.value()*3.5),round(self.verticalSlider.value()*3.5)) self.spinBox.setValue(round(self.horizontalSlider.value())) self.spinBox_2.setValue(round(self.verticalSlider.value()))