class SynoptiquesAtlas: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # a reference to our map canvas self.canvas = self.iface.mapCanvas() # Setup directory self.user_plugin_dir = QFileInfo( QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins" self.syn_atlas_plugin_dir = self.user_plugin_dir + "/synoptiquesatlas" # Translation to English locale = QSettings().value("locale/userLocale") self.myLocale = locale[0:2] if QFileInfo(self.syn_atlas_plugin_dir).exists(): localePath = self.syn_atlas_plugin_dir + "/i18n/synoptiquesatlas_" + self.myLocale + ".qm" if QFileInfo(localePath).exists(): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # create and show the dialog self.dlg = SynoptiquesAtlasDialog() def initGui(self): # Create action that will start plugin configuration self.action = QAction(QIcon(":/plugins/synoptiquesatlas/icon.png"), \ QCoreApplication.translate("synoptiquesatlas", "&Grids for Atlas"), self.iface.mainWindow()) # Create action for about dialog self.action_about = QAction("A&bout...", self.iface.mainWindow()) # Create action for help dialog self.action_help = QAction( QIcon(":/plugins/synoptiquesatlas/about.png"), QCoreApplication.translate("synoptiquesatlas", "&Help..."), self.iface.mainWindow()) # connect the action to the run method QObject.connect(self.action, SIGNAL("triggered()"), self.run) # connect about action to about dialog QObject.connect(self.action_about, SIGNAL("triggered()"), self.showAbout) # connect help action to help dialog QObject.connect(self.action_help, SIGNAL("triggered()"), self.showHelp) # connect signals QObject.connect(self.dlg.ui.btnCreerSyno, SIGNAL("clicked()"), self.creerSyno) # composer changed, update maps QObject.connect(self.dlg.ui.cbbComp, SIGNAL('currentIndexChanged(int)'), self.updateMaps) # refresh inLayer box QObject.connect(self.dlg.ui.cbbInLayer, SIGNAL('currentIndexChanged(int)'), self.onLayerChange) # browse button QObject.connect(self.dlg.ui.btnBrowse, SIGNAL('clicked()'), self.updateOutputDir) # refresh template button QObject.connect(self.dlg.ui.btnUpdate, SIGNAL('clicked()'), self.updateComposers) # show composer QObject.connect(self.dlg.ui.btnShow, SIGNAL('clicked()'), self.showComposer) # show about dialog QObject.connect(self.dlg.ui.aboutButton, SIGNAL('clicked()'), self.showAbout) # show help dialog QObject.connect(self.dlg.ui.helpButton, SIGNAL('clicked()'), self.showHelp) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu("&Grids for Atlas", self.action) # Add about menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_about) # add help menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_help) def updateBoxes(self): self.updateLayers() self.updateComposers() self.updateMaps() def updateLayers(self): self.dlg.ui.cbbInLayer.clear() for layer in self.iface.mapCanvas().layers(): self.dlg.ui.cbbInLayer.addItem(layer.name(), layer) # (c) Carson Farmer / fTools def getVectorLayerByName(self, myName): layermap = QgsMapLayerRegistry.instance().mapLayers() for name, layer in layermap.iteritems(): if layer.type() == QgsMapLayer.VectorLayer and layer.name( ) == myName: if layer.isValid(): return layer else: return None def onLayerChange(self): self.cLayer = self.getVectorLayerByName( self.dlg.ui.cbbInLayer.currentText()) def updateComposers(self): self.dlg.ui.cbbComp.clear() compos = self.iface.activeComposers() for cv in compos: self.dlg.ui.cbbComp.addItem(cv.composerWindow().windowTitle(), cv) self.composer = self.dlg.ui.cbbComp.itemData( self.dlg.ui.cbbComp.currentIndex()) def updateMaps(self): self.dlg.ui.cbbMap.clear() if self.dlg.ui.cbbComp.currentIndex() != -1: self.composer = self.dlg.ui.cbbComp.itemData( self.dlg.ui.cbbComp.currentIndex()) for item in self.composer.composition().items(): if item.type() == QgsComposerItem.ComposerMap: self.dlg.ui.cbbMap.addItem( QCoreApplication.translate("synoptiquesatlas", "Map ") + "%s" % item.id(), item.id) def showComposer(self): self.composer.composerWindow().show() self.composer.composerWindow().activate() def updateOutputDir(self): self.dlg.ui.lieOutDir.setText(QFileDialog.getExistingDirectory(self.dlg, \ QCoreApplication.translate("synoptiquesatlas", "Choose output directory"))) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu("&Grids for Atlas", self.action) self.iface.removeToolBarIcon(self.action) # Remove about menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_about) # Remove help menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_help) def creerSyno(self): if os.path.exists(self.dlg.ui.lieOutDir.text()): self.gridSynopt = self.dlg.ui.chkGrille.isChecked() self.dynSynopt = self.dlg.ui.chkDyn.isChecked() if self.gridSynopt or self.dynSynopt: compos = self.iface.activeComposers() if compos: cview = compos[self.dlg.ui.cbbComp.currentIndex()] cmap = self.dlg.ui.cbbMap.itemData( self.dlg.ui.cbbMap.currentIndex()) self.mapItem = cview.composition().getComposerMapById( cmap()) self.ladderHeight = self.mapItem.extent().height() self.ladderWidth = self.mapItem.extent().width() if self.cLayer: if self.cLayer.type() == 0: self.crs = self.cLayer.crs() self.URIcrs = "crs=" + self.crs.toWkt() self.doBuffer() self.extent = self.bcLayer.extent() self.orig_ladders_list = [] self.sLayer = self.addSynoFeatures( self.orig_ladders_list) self.synopt_shape_path = self.dlg.ui.lieOutDir.text( ) + QCoreApplication.translate( "synoptiquesatlas", "/classic_grid.shp") self.createPhysLayerFromList( self.synopt_shape_path, self.orig_ladders_list) if self.gridSynopt: self.sLayer = self.loadQgsVectorLayer(self.synopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","classic grid")) else: self.sLayer = QgsVectorLayer( self.synopt_shape_path, QCoreApplication.translate( "synoptiquesatlas", "classic grid"), "ogr") # TODO # Manage symbology #if not hasattr(self.sLayer, 'isUsingRendererV2'): # QMessageBox.information(self.iface.mainWindow(),"Info", \ # "La symbologie ne peut etre affichee vous utilisez une version ancienne de QGIS") #elif layer.isUsingRendererV2(): # new symbology - subclass of QgsFeatureRendererV2 class # rendererV2 = layer.rendererV2() # Grid layer was created, access to the second stage if self.dynSynopt: self.finalSynopt_shape_path = self.dlg.ui.lieOutDir.text( ) + QCoreApplication.translate( "synoptiquesatlas", "/dyn_grid.shp") self.intersect(self.bcLayer, self.sLayer) self.createIntersectionLayer() self.new_ladders_list = [] self.sLayer2 = self.centroidsToNewSyno( self.new_ladders_list) self.parseSyno() self.final_ladders_list = [] self.sLayer3 = self.centroidsToNewSyno( self.final_ladders_list) self.createPhysLayerFromList( self.finalSynopt_shape_path, self.final_ladders_list) self.sLayer3 = self.loadQgsVectorLayer(self.finalSynopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","dynamic grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Coverage layer is not vector type")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a coverage layer to generate grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a print composer, if none is active you have to create it")) else: QMessageBox.information( self.iface.mainWindow(), "Info", QCoreApplication.translate("synoptiquesatlas", "Choose a grid type")) else: QMessageBox.information( self.iface.mainWindow(), "Info", QCoreApplication.translate( "synoptiquesatlas", "Please enter an existant directory name")) def doBuffer(self): maxDim = max(self.ladderHeight, self.ladderWidth) ratio = 1000. / 2970 bufferLength = maxDim * ratio self.bcLayer = QgsVectorLayer("Polygon?" + self.URIcrs, "buffer_layer", "memory") pr = self.bcLayer.dataProvider() pr.addAttributes([QgsField("ID_BUFFER", QVariant.Int)]) provider_perimetre = self.cLayer.dataProvider() iter = provider_perimetre.getFeatures() i = 0 for feature in iter: fet = QgsFeature() fet.setGeometry(feature.geometry().buffer(bufferLength, 50)) fet.setFeatureId(i) pr.addFeatures([fet]) i = i + 1 self.bcLayer.updateExtents() def addSynoFeatures(self, ladder_list): layer = QgsVectorLayer("Polygon?" + self.URIcrs, "grid_layer", "memory") pr = layer.dataProvider() pr.addAttributes([QgsField("ID_MAILLE", QVariant.Int)]) # Initial settings provider_perimetre = self.cLayer.dataProvider() ladderHeight = self.ladderHeight ladderWidth = self.ladderWidth ladder_id = 0 yMax = self.extent.yMaximum() yMin = yMax - ladderHeight widthSum = 0 heightSum = 0 # Build columns while heightSum < self.extent.height(): widthSum = 0 xMin = self.extent.xMinimum() xMax = xMin + ladderWidth # Build lines while widthSum < self.extent.width(): # Create geometry ladder = QgsRectangle(xMin, yMin, xMax, yMax) request = QgsFeatureRequest() request.setFilterRect(ladder) for f in provider_perimetre.getFeatures(request): ladder_id = ladder_id + 1 # Add ladder to layer fet = QgsFeature() fet.setGeometry(QgsGeometry.fromRect(ladder)) fet.setAttributes([ladder_id]) pr.addFeatures([fet]) ladder_list.append(fet) # Settings for next ladder xMin = xMin + ladderWidth xMax = xMax + ladderWidth widthSum = widthSum + ladderWidth heightSum = heightSum + ladderHeight yMin = yMin - ladderHeight yMax = yMax - ladderHeight layer.updateExtents() return layer def createPhysLayerFromList(self, shapePath, fetList): # Create shapefile writer fields = QgsFields() fields.append(QgsField("ID_MAILLE", QVariant.Int)) self.writer = QgsVectorFileWriter(shapePath, "CP1250", fields, \ QGis.WKBPolygon, self.cLayer.crs(), "ESRI Shapefile") if self.writer.hasError() != QgsVectorFileWriter.NoError: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error when creating shapefile:\n") + shapePath + QCoreApplication.translate("synoptiquesatlas","\nPlease delete or rename the former grid layers")) # Add features for fet in fetList: self.writer.addFeature(fet) # Stop writing del self.writer def createGridLayer(self): # Create shapefile writer fields = {0: QgsField("ID_MAILLE", QVariant.Int)} self.writer = QgsVectorFileWriter(self.finalSynopt_shape_path, "CP1250", fields, \ QGis.WKBPolygon, self.cLayer.crs(), "ESRI Shapefile") if self.writer.hasError() != QgsVectorFileWriter.NoError: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error when creating shapefile:\n") + self.finalSynopt_shape_path + QCoreApplication.translate("synoptiquesatlas","\nPlease delete or rename the former grid layers")) # Add features for fet in self.orig_ladders_list: self.writer.addFeature(fet) # Stop writing del self.writer def intersect(self, perimetre, calepinage): # Intersect between coverage and grid self.centroid_list = [] self.splitted_fet_list = [] i = 0 if perimetre and calepinage: provider_perimetre = perimetre.dataProvider() provider_calepinage = calepinage.dataProvider() # create the select statement request = QgsFeatureRequest() request.setFilterRect(self.extent) #provider_perimetre.select([]) #provider_calepinage.select([],self.extent) # the arguments mean no attributes returned, and do a bbox filter with our buffered # rectangle to limit the amount of features for feat_perimetre in provider_perimetre.getFeatures(): # if the feat geom returned from the selection intersects our point then put it in a list for feat_calepinage in provider_calepinage.getFeatures( request): # if the feat geom returned from the selection intersects our point then put it in a list if feat_perimetre.geometry().intersects( feat_calepinage.geometry()): a = feat_perimetre.geometry().intersection( feat_calepinage.geometry()) self.centroid_list.append(a.centroid()) fet = QgsFeature() fet.setGeometry(a) fet.setAttributes([i]) self.splitted_fet_list.append(fet) i = i + 1 def createIntersectionLayer(self): self.interLayer = QgsVectorLayer("Polygon?" + self.URIcrs, "inter_layer", "memory") pr = self.interLayer.dataProvider() pr.addAttributes([QgsField("ID_INTER", QVariant.Int)]) # Add features for fet in self.splitted_fet_list: pr.addFeatures([fet]) self.interLayer.updateExtents() def centroidsToNewSyno(self, ladder_list): layer = QgsVectorLayer("Polygon?" + self.URIcrs, "layer", "memory") pr = layer.dataProvider() pr.addAttributes([QgsField("ID_MAILLE", QVariant.Int)]) ladderHeight = self.ladderHeight ladderWidth = self.ladderWidth ladder_id = 0 for centr in self.centroid_list: pt = centr.asPoint() xMin = pt.x() - ladderWidth / 2. xMax = pt.x() + ladderWidth / 2. yMin = pt.y() - ladderHeight / 2. yMax = pt.y() + ladderHeight / 2. # Create geometry ladder = QgsRectangle(xMin, yMin, xMax, yMax) # Add ladder to layer fet = QgsFeature() fet.setGeometry(QgsGeometry.fromRect(ladder)) fet.setAttributes([ladder_id]) ladder_list.append(fet) pr.addFeatures([fet]) ladder_id = ladder_id + 1 layer.updateExtents() return layer def loadQgsVectorLayer(self, shapePath, layerName): layerToLoad = QgsVectorLayer(shapePath, layerName, "ogr") if not layerToLoad.isValid(): QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error while loading layer ") + layerName + " !") else: QgsMapLayerRegistry.instance().addMapLayer(layerToLoad) return layerToLoad def parseSyno(self): i = 0 while i <= len(self.new_ladders_list) - 1: fet = self.splitted_fet_list[i] overlapped = False j = 0 while j <= i - 1 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 j = i + 1 while j <= len(self.new_ladders_list) - 2 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 if overlapped: self.splitted_fet_list.pop(i) self.new_ladders_list.pop(i) self.centroid_list.pop(i) else: i = i + 1 def showHelp(self): """Show help dialog box""" # Create a dialog and setup UI hdialog = QDialog() hdialog.ui = Ui_help_window() hdialog.ui.setupUi(hdialog) # load help file if self.myLocale == 'fr': hdialog.ui.webView.setUrl( QUrl(self.syn_atlas_plugin_dir + '/help/syn_atlas.html')) else: hdialog.ui.webView.setUrl( QUrl(self.syn_atlas_plugin_dir + '/help/syn_atlas_en.html')) hdialog.show() result = hdialog.exec_() del hdialog def showAbout(self): """Show Synoptiques Atlas about dialog box""" adialog = QDialog() adialog.ui = Ui_About_window() adialog.ui.setupUi(adialog) adialog.show() result = adialog.exec_() del adialog # run method that performs all the real work def run(self): self.updateBoxes() # show the dialog self.dlg.show() result = self.dlg.exec_() # See if OK was pressed if result == 1: # do something useful (delete the line containing pass and # substitute with your code pass
class SynoptiquesAtlas: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # a reference to our map canvas self.canvas = self.iface.mapCanvas() # Setup directory self.user_plugin_dir = QFileInfo( QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins" self.syn_atlas_plugin_dir = self.user_plugin_dir + "/synoptiquesatlas" # Translation to English #locale = QSettings().value("locale/userLocale").toString() #self.myLocale = locale[0:2] #if QFileInfo(self.syn_atlas_plugin_dir).exists(): # localePath = self.syn_atlas_plugin_dir + "/i18n/synoptiquesatlas_" + self.myLocale + ".qm" #if QFileInfo(localePath).exists(): # self.translator = QTranslator() # self.translator.load(localePath) # if qVersion() > '4.3.3': # QCoreApplication.installTranslator(self.translator) # create and show the dialog self.dlg = SynoptiquesAtlasDialog() def initGui(self): # Create action that will start plugin configuration self.action = QAction(QIcon(":/plugins/synoptiquesatlas/icon.png"), \ QCoreApplication.translate("synoptiquesatlas", "&Grids for Atlas"), self.iface.mainWindow()) # Create action for about dialog self.action_about = QAction("A&bout...", self.iface.mainWindow()) # Create action for help dialog self.action_help = QAction( QIcon(":/plugins/synoptiquesatlas/about.png"), QCoreApplication.translate("synoptiquesatlas", "&Help..."), self.iface.mainWindow()) # connect the action to the run method QObject.connect(self.action, SIGNAL("triggered()"), self.run) # connect about action to about dialog QObject.connect(self.action_about, SIGNAL("triggered()"), self.showAbout) # connect help action to help dialog QObject.connect(self.action_help, SIGNAL("triggered()"), self.showHelp) # connect signals QObject.connect(self.dlg.ui.btnCreerSyno, SIGNAL("clicked()"), self.creerSyno) # composer changed, update maps QObject.connect(self.dlg.ui.cbbComp, SIGNAL('currentIndexChanged(int)'), self.updateMaps) # refresh inLayer box QObject.connect(self.dlg.ui.cbbInLayer, SIGNAL('currentIndexChanged(int)'), self.onLayerChange) # browse button QObject.connect(self.dlg.ui.btnBrowse, SIGNAL('clicked()'), self.updateOutputDir) # refresh template button QObject.connect(self.dlg.ui.btnUpdate, SIGNAL('clicked()'), self.updateComposers) # show composer QObject.connect(self.dlg.ui.btnShow, SIGNAL('clicked()'), self.showComposer) # show about dialog QObject.connect(self.dlg.ui.aboutButton, SIGNAL('clicked()'), self.showAbout) # show help dialog QObject.connect(self.dlg.ui.helpButton, SIGNAL('clicked()'), self.showHelp) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu("&Grids for Atlas", self.action) # Add about menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_about) # add help menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_help) def updateBoxes(self): self.updateLayers() self.updateComposers() self.updateMaps() def updateLayers(self): self.dlg.ui.cbbInLayer.clear() for layer in self.iface.mapCanvas().layers(): #self.dlg.ui.cbbInLayer.addItem(layer.name(), QVariant(layer)) self.dlg.ui.cbbInLayer.addItem(layer.name(), layer) # (c) Carson Farmer / fTools def getVectorLayerByName(self, myName): layermap = QgsMapLayerRegistry.instance().mapLayers() for name, layer in layermap.iteritems(): if layer.type() == QgsMapLayer.VectorLayer and layer.name( ) == myName: if layer.isValid(): return layer else: return None def onLayerChange(self): self.cLayer = self.getVectorLayerByName( self.dlg.ui.cbbInLayer.currentText()) def updateComposers(self): self.dlg.ui.cbbComp.clear() compos = self.iface.activeComposers() for cv in compos: #self.dlg.ui.cbbComp.addItem(cv.composerWindow().windowTitle(), QVariant(cv)) self.dlg.ui.cbbComp.addItem(cv.composerWindow().windowTitle(), cv) self.composer = self.dlg.ui.cbbComp.itemData( self.dlg.ui.cbbComp.currentIndex()) #.toPyObject() def updateMaps(self): self.dlg.ui.cbbMap.clear() if self.dlg.ui.cbbComp.currentIndex() != -1: self.composer = self.dlg.ui.cbbComp.itemData( self.dlg.ui.cbbComp.currentIndex()) #.toPyObject() for item in self.composer.composition().items(): if item.type() == QgsComposerItem.ComposerMap: self.dlg.ui.cbbMap.addItem( QCoreApplication.translate("synoptiquesatlas", "Map ") + "%s" % item.id(), item.id) def showComposer(self): self.composer.composerWindow().show() self.composer.composerWindow().activate() def updateOutputDir(self): self.dlg.ui.lieOutDir.setText(QFileDialog.getExistingDirectory(self.dlg, \ QCoreApplication.translate("synoptiquesatlas", "Choose output directory"))) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu("&Grids for Atlas", self.action) self.iface.removeToolBarIcon(self.action) # Remove about menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_about) # Remove help menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_help) def creerSyno(self): if os.path.exists(self.dlg.ui.lieOutDir.text()): self.gridSynopt = self.dlg.ui.chkGrille.isChecked() self.dynSynopt = self.dlg.ui.chkDyn.isChecked() if self.gridSynopt or self.dynSynopt: compos = self.iface.activeComposers() if compos: cview = compos[self.dlg.ui.cbbComp.currentIndex()] cmap = self.dlg.ui.cbbMap.itemData( self.dlg.ui.cbbMap.currentIndex()) if cmap: self.mapItem = cview.composition().getComposerMapById( cmap()) self.ladderHeight = self.mapItem.extent().height() self.ladderWidth = self.mapItem.extent().width() self.ladderOvrlpPercent = float( self.dlg.ui.overlapInp.text()) if self.ladderOvrlpPercent < 100 and self.ladderOvrlpPercent >= 0: self.overlapW = self.ladderWidth * self.ladderOvrlpPercent / 100 self.overlapH = self.ladderHeight * self.ladderOvrlpPercent / 100 self.ladderWidth = self.ladderWidth - self.overlapW * 2. self.ladderHeight = self.ladderHeight - self.overlapH * 2. if self.cLayer: if self.cLayer.type() == 0: self.crs = self.cLayer.crs() self.URIcrs = "crs=" + self.crs.authid() self.doBuffer() #next 2 lines because of bug #http://gis.stackexchange.com/questions/87936/problem-creating-point-shapefiles-programmatically-using-python-in-qgis-2-2 #look at "and if we examine the extents:" self.bcLayer.selectAll() self.extent = self.bcLayer.boundingBoxOfSelected( ) self.sLayer = self.addSynoFeatures() self.fill_references(self.sLayer) self.synopt_shape_path = self.dlg.ui.lieOutDir.text( ) + QCoreApplication.translate( "synoptiquesatlas", "/classic_grid.shp") self.createPhysLayerFromList( self.synopt_shape_path, self.sLayer) if self.gridSynopt: self.sLayer = self.loadQgsVectorLayer(self.synopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","classic grid")) else: self.sLayer = QgsVectorLayer( self.synopt_shape_path, QCoreApplication.translate( "synoptiquesatlas", "classic grid"), "ogr") # TODO # Manage symbology #if not hasattr(self.sLayer, 'isUsingRendererV2'): # QMessageBox.information(self.iface.mainWindow(),"Info", \ # "La symbologie ne peut etre affichee vous utilisez une version ancienne de QGIS") #elif layer.isUsingRendererV2(): # new symbology - subclass of QgsFeatureRendererV2 class # rendererV2 = layer.rendererV2() # Grid layer was created, access to the second stage if self.dynSynopt: self.finalSynopt_shape_path = self.dlg.ui.lieOutDir.text( ) + QCoreApplication.translate( "synoptiquesatlas", "/dyn_grid.shp") self.intersect(self.bcLayer, self.sLayer) self.createIntersectionLayer() self.new_ladders_list = [] self.sLayer2 = self.centroidsToNewSyno( self.new_ladders_list) self.parseSyno() self.final_ladders_list = [] self.sLayer3 = self.centroidsToNewSyno( self.final_ladders_list) self.fill_references(self.sLayer3) self.createPhysLayerFromList( self.finalSynopt_shape_path, self.sLayer3) self.sLayer3 = self.loadQgsVectorLayer(self.finalSynopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","dynamic grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Coverage layer is not vector type")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a coverage layer to generate grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Overlap % must bee between 0 and 100")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","There is no map object for print composer selected")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a print composer, if none is active you have to create it")) else: QMessageBox.information( self.iface.mainWindow(), "Info", QCoreApplication.translate("synoptiquesatlas", "Choose a grid type")) else: QMessageBox.information( self.iface.mainWindow(), "Info", QCoreApplication.translate( "synoptiquesatlas", "Please enter an existant directory name")) def doBuffer(self): maxDim = max(self.ladderHeight, self.ladderWidth) ratio = 1000. / 2970 bufferLength = maxDim * ratio self.bcLayer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "buffer_layer", "memory") pr = self.bcLayer.dataProvider() pr.addAttributes([QgsField("ID_BUFFER", QVariant.Int)]) i = 0 for feature in self.cLayer.dataProvider().getFeatures(): fet = QgsFeature() bGeom = feature.geometry().buffer(bufferLength, 2) fet.setGeometry(bGeom) fet.setFeatureId(i) pr.addFeatures([fet]) i = i + 1 self.bcLayer.commitChanges() self.bcLayer.updateExtents() def addSynoFeatures(self): layer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "grid_layer", "memory") #layer.setCrs(self.crs) pr = layer.dataProvider() pr.addAttributes([ QgsField("ID_MAILLE", QVariant.Int), QgsField("row", QVariant.Int), QgsField("col", QVariant.Int) ]) layer.updateFields() # Initial settings provider_perimetre = self.cLayer.dataProvider() #feat_perimetre = QgsFeature() ladderHeight = self.ladderHeight ladderWidth = self.ladderWidth ladder_id = 0 yMax = self.extent.yMaximum() yMin = yMax - ladderHeight widthSum = 0 heightSum = 0 row = 0 # Build columns while heightSum < self.extent.height(): widthSum = 0 col = 0 xMin = self.extent.xMinimum() xMax = xMin + ladderWidth # Build lines while widthSum < self.extent.width(): # Create geometry ladder = QgsRectangle(xMin - self.overlapW, yMin - self.overlapH, xMax + self.overlapW, yMax + self.overlapH) request = QgsFeatureRequest() request.setFilterRect(ladder) for f in provider_perimetre.getFeatures(request): ladder_id = ladder_id + 1 # Add ladder to layer fet = QgsFeature() fet.setAttributes([ladder_id, row, col]) fet.setGeometry(QgsGeometry.fromRect(ladder)) pr.addFeatures([fet]) #ladder_list.append(fet) # Settings for next ladder xMin = xMin + ladderWidth xMax = xMax + ladderWidth widthSum = widthSum + ladderWidth col = col + 1 heightSum = heightSum + ladderHeight yMin = yMin - ladderHeight yMax = yMax - ladderHeight row = row + 1 layer.updateExtents() return layer def fill_references(self, layer): pr = layer.dataProvider() pr.addAttributes([ QgsField("above", QVariant.Int), QgsField("below", QVariant.Int), QgsField("left", QVariant.Int), QgsField("right", QVariant.Int), QgsField("aboveleft", QVariant.Int), QgsField("aboveright", QVariant.Int), QgsField("belowleft", QVariant.Int), QgsField("belowright", QVariant.Int) ]) layer.updateFields() layer.startEditing() for feature in layer.getFeatures(): neighbours = self.get_neighbour_features(feature, layer) positions = self.get_related_positions(feature, neighbours) for pos, f in positions.iteritems(): if not feature[pos]: feature[pos] = f['ID_MAILLE'] layer.updateFeature(feature) layer.commitChanges() def get_neighbour_features(self, feature, layer): dp = layer.dataProvider() request = QgsFeatureRequest() request.setFilterRect(feature.geometry().buffer( self.ladderWidth / 100., 1).boundingBox()) r = dp.getFeatures(request) return [f for f in r if f['ID_MAILLE'] != feature['ID_MAILLE']] def get_related_positions(self, base, neighbours): base_centroid = base.geometry().centroid().asPoint() positions = {} for n in neighbours: centroid = n.geometry().centroid().asPoint() dx = math.fabs(centroid.x() - base_centroid.x()) dy = math.fabs(centroid.y() - base_centroid.y()) horizontal = dx / self.ladderWidth > dy / self.ladderHeight position = '' if horizontal: position = 'left' if centroid.x() < base_centroid.x( ) else 'right' if dy > self.ladderHeight * 0.6: position = ('above' if centroid.y() > base_centroid.y() else 'below') + position else: position = 'above' if centroid.y() > base_centroid.y( ) else 'below' if dx > self.ladderWidth * 0.6: position = position + ('left' if centroid.x() < base_centroid.x() else 'right') if position: #curent position already occupied if position in positions: curent = positions[position] c_centroid = curent.geometry().centroid().asPoint() dx2 = math.fabs(base_centroid.x() - c_centroid.x()) dy2 = math.fabs(base_centroid.y() - c_centroid.y()) if position is 'above' or position is 'below': #our new feature is closer to center of base feature if dx2 > dx: positions[position] = n positions[position + ('right' if c_centroid.x( ) > base_centroid.x() else 'left')] = curent #old feature is close to center of base feature else: positions[position + ('right' if centroid.x( ) > base_centroid.x() else 'left')] = n elif position is 'left' or position is 'right': #our new feature is closer to center of base feature if dy2 > dy: positions[position] = n positions[('above' if c_centroid.y( ) > base_centroid.y() else 'below') + position] = curent #old feature is close to center of base feature else: positions[('above' if centroid.y() > base_centroid. y() else 'below') + position] = n #position is free, just add our feature else: positions[position] = n return positions def createPhysLayerFromList(self, shapePath, layer): # Wite to file error = QgsVectorFileWriter.writeAsVectorFormat(layer, shapePath, \ "CP1250", None, "ESRI Shapefile") if error != QgsVectorFileWriter.NoError: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error when creating shapefile:\n") + shapePath + QCoreApplication.translate("synoptiquesatlas","\nPlease delete or rename the former grid layers")) def intersect(self, perimetre, calepinage): # Intersect between coverage and grid self.centroid_list = [] self.splitted_fet_list = [] i = 0 if perimetre and calepinage: provider_perimetre = perimetre.dataProvider() provider_calepinage = calepinage.dataProvider() # create the select statement #provider_calepinage.select([],self.extent) request = QgsFeatureRequest() request.setFilterRect(self.extent) # the arguments mean no attributes returned, and do a bbox filter with our buffered # rectangle to limit the amount of features for feat_perimetre in provider_perimetre.getFeatures(): # if the feat geom returned from the selection intersects our point then put it in a list for feat_calepinage in provider_calepinage.getFeatures( request): # if the feat geom returned from the selection intersects our point then put it in a list if feat_perimetre.geometry().intersects( feat_calepinage.geometry()): a = feat_perimetre.geometry().intersection( feat_calepinage.geometry()) self.centroid_list.append(a.centroid()) fet = QgsFeature() fet.setGeometry(a) #fet.addAttribute(0, QVariant(i)) self.splitted_fet_list.append(fet) i = i + 1 def createIntersectionLayer(self): self.interLayer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "inter_layer", "memory") #self.interLayer.setCrs(self.crs) pr = self.interLayer.dataProvider() pr.addAttributes([QgsField("ID_INTER", QVariant.Int)]) # Add features for fet in self.splitted_fet_list: pr.addFeatures([fet]) self.interLayer.updateExtents() def centroidsToNewSyno(self, ladder_list): layer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "layer", "memory") #layer.setCrs(self.crs) pr = layer.dataProvider() pr.addAttributes([QgsField("ID_MAILLE", QVariant.Int)]) layer.updateFields() ladderHeight = self.ladderHeight ladderWidth = self.ladderWidth ladder_id = 0 for centr in self.centroid_list: pt = centr.asPoint() xMin = pt.x() - ladderWidth / 2. - self.overlapW xMax = pt.x() + ladderWidth / 2. + self.overlapW yMin = pt.y() - ladderHeight / 2. - self.overlapH yMax = pt.y() + ladderHeight / 2. + self.overlapH # Create geometry ladder = QgsRectangle(xMin, yMin, xMax, yMax) # Add ladder to layer fet = QgsFeature() fet.setGeometry(QgsGeometry.fromRect(ladder)) fet.setAttributes([ladder_id]) ladder_list.append(fet) pr.addFeatures([fet]) ladder_id = ladder_id + 1 layer.updateExtents() return layer def loadQgsVectorLayer(self, shapePath, layerName): layerToLoad = QgsVectorLayer(shapePath, layerName, "ogr") if not layerToLoad.isValid(): QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error while loading layer ") + layerName + " !") else: QgsMapLayerRegistry.instance().addMapLayer(layerToLoad) return layerToLoad def parseSyno(self): i = 0 while i <= len(self.new_ladders_list) - 1: fet = self.splitted_fet_list[i] overlapped = False j = 0 while j <= i - 1 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 j = i + 1 while j <= len(self.new_ladders_list) - 2 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 if overlapped: self.splitted_fet_list.pop(i) self.new_ladders_list.pop(i) self.centroid_list.pop(i) else: i = i + 1 def showHelp(self): showPluginHelp() def showAbout(self): """Show Synoptiques Atlas about dialog box""" adialog = QDialog() adialog.ui = Ui_About_window() adialog.ui.setupUi(adialog) adialog.show() result = adialog.exec_() del adialog # run method that performs all the real work def run(self): self.updateBoxes() # show the dialog self.dlg.show() result = self.dlg.exec_() # See if OK was pressed if result == 1: # do something useful (delete the line containing pass and # substitute with your code pass
class SynoptiquesAtlas: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # a reference to our map canvas self.canvas = self.iface.mapCanvas() # Setup directory self.user_plugin_dir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins" self.syn_atlas_plugin_dir = self.user_plugin_dir + "/synoptiquesatlas" # Translation to English #locale = QSettings().value("locale/userLocale").toString() #self.myLocale = locale[0:2] #if QFileInfo(self.syn_atlas_plugin_dir).exists(): # localePath = self.syn_atlas_plugin_dir + "/i18n/synoptiquesatlas_" + self.myLocale + ".qm" #if QFileInfo(localePath).exists(): # self.translator = QTranslator() # self.translator.load(localePath) # if qVersion() > '4.3.3': # QCoreApplication.installTranslator(self.translator) # create and show the dialog self.dlg = SynoptiquesAtlasDialog() def initGui(self): # Create action that will start plugin configuration self.action = QAction(QIcon(":/plugins/synoptiquesatlas/icon.png"), \ QCoreApplication.translate("synoptiquesatlas", "&Grids for Atlas"), self.iface.mainWindow()) # Create action for about dialog self.action_about = QAction("A&bout...", self.iface.mainWindow()) # Create action for help dialog self.action_help = QAction(QIcon(":/plugins/synoptiquesatlas/about.png"), QCoreApplication.translate("synoptiquesatlas", "&Help..."), self.iface.mainWindow()) # connect the action to the run method QObject.connect(self.action, SIGNAL("triggered()"), self.run) # connect about action to about dialog QObject.connect(self.action_about, SIGNAL("triggered()"), self.showAbout) # connect help action to help dialog QObject.connect(self.action_help, SIGNAL("triggered()"), self.showHelp) # connect signals QObject.connect(self.dlg.ui.btnCreerSyno, SIGNAL("clicked()"), self.creerSyno) # composer changed, update maps QObject.connect(self.dlg.ui.cbbComp, SIGNAL('currentIndexChanged(int)'), self.updateMaps) # refresh inLayer box QObject.connect(self.dlg.ui.cbbInLayer, SIGNAL('currentIndexChanged(int)'), self.onLayerChange) # browse button QObject.connect(self.dlg.ui.btnBrowse, SIGNAL('clicked()'), self.updateOutputDir) # refresh template button QObject.connect(self.dlg.ui.btnUpdate, SIGNAL('clicked()'), self.updateComposers) # show composer QObject.connect(self.dlg.ui.btnShow, SIGNAL('clicked()'), self.showComposer) # show about dialog QObject.connect(self.dlg.ui.aboutButton, SIGNAL('clicked()'), self.showAbout) # show help dialog QObject.connect(self.dlg.ui.helpButton, SIGNAL('clicked()'), self.showHelp) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu("&Grids for Atlas", self.action) # Add about menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_about) # add help menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_help) def updateBoxes(self): self.updateLayers() self.updateComposers() self.updateMaps() def updateLayers(self): self.dlg.ui.cbbInLayer.clear() for layer in self.iface.mapCanvas().layers(): #self.dlg.ui.cbbInLayer.addItem(layer.name(), QVariant(layer)) self.dlg.ui.cbbInLayer.addItem(layer.name(), layer) # (c) Carson Farmer / fTools def getVectorLayerByName(self,myName): layermap = QgsMapLayerRegistry.instance().mapLayers() for name, layer in layermap.iteritems(): if layer.type() == QgsMapLayer.VectorLayer and layer.name() == myName: if layer.isValid(): return layer else: return None def onLayerChange(self): self.cLayer = self.getVectorLayerByName(self.dlg.ui.cbbInLayer.currentText()) def updateComposers(self): self.dlg.ui.cbbComp.clear() compos = self.iface.activeComposers() for cv in compos: #self.dlg.ui.cbbComp.addItem(cv.composerWindow().windowTitle(), QVariant(cv)) self.dlg.ui.cbbComp.addItem(cv.composerWindow().windowTitle(), cv) self.composer = self.dlg.ui.cbbComp.itemData(self.dlg.ui.cbbComp.currentIndex())#.toPyObject() def updateMaps(self): self.dlg.ui.cbbMap.clear() if self.dlg.ui.cbbComp.currentIndex() != -1: self.composer = self.dlg.ui.cbbComp.itemData(self.dlg.ui.cbbComp.currentIndex())#.toPyObject() for item in self.composer.composition().items(): if item.type() == QgsComposerItem.ComposerMap: self.dlg.ui.cbbMap.addItem(QCoreApplication.translate("synoptiquesatlas", "Map ") + "%s"% item.id(), item.id) def showComposer(self): self.composer.composerWindow().show() self.composer.composerWindow().activate() def updateOutputDir(self): self.dlg.ui.lieOutDir.setText(QFileDialog.getExistingDirectory(self.dlg, \ QCoreApplication.translate("synoptiquesatlas", "Choose output directory"))) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu("&Grids for Atlas",self.action) self.iface.removeToolBarIcon(self.action) # Remove about menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_about) # Remove help menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_help) def creerSyno(self): if os.path.exists(self.dlg.ui.lieOutDir.text()): self.gridSynopt = self.dlg.ui.chkGrille.isChecked() self.dynSynopt = self.dlg.ui.chkDyn.isChecked() if self.gridSynopt or self.dynSynopt: compos = self.iface.activeComposers() if compos: cview = compos[self.dlg.ui.cbbComp.currentIndex()] cmap = self.dlg.ui.cbbMap.itemData(self.dlg.ui.cbbMap.currentIndex()) if cmap: self.mapItem = cview.composition().getComposerMapById(cmap()) self.ladderHeight = self.mapItem.extent().height() self.ladderWidth = self.mapItem.extent().width() self.ladderOvrlpPercent = float(self.dlg.ui.overlapInp.text()) if self.ladderOvrlpPercent < 100 and self.ladderOvrlpPercent >= 0: self.overlapW = self.ladderWidth * self.ladderOvrlpPercent / 100; self.overlapH = self.ladderHeight * self.ladderOvrlpPercent / 100; self.ladderWidth = self.ladderWidth - self.overlapW * 2.; self.ladderHeight = self.ladderHeight - self.overlapH * 2.; if self.cLayer: if self.cLayer.type() == 0: self.crs = self.cLayer.crs() self.URIcrs = "crs=" + self.crs.authid() self.doBuffer() #next 2 lines because of bug #http://gis.stackexchange.com/questions/87936/problem-creating-point-shapefiles-programmatically-using-python-in-qgis-2-2 #look at "and if we examine the extents:" self.bcLayer.selectAll() self.extent = self.bcLayer.boundingBoxOfSelected() self.sLayer = self.addSynoFeatures() self.fill_references(self.sLayer) self.synopt_shape_path = self.dlg.ui.lieOutDir.text() + QCoreApplication.translate("synoptiquesatlas","/classic_grid.shp") self.createPhysLayerFromList(self.synopt_shape_path, self.sLayer) if self.gridSynopt: self.sLayer = self.loadQgsVectorLayer(self.synopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","classic grid")) else: self.sLayer = QgsVectorLayer(self.synopt_shape_path, QCoreApplication.translate("synoptiquesatlas","classic grid"), "ogr") # TODO # Manage symbology #if not hasattr(self.sLayer, 'isUsingRendererV2'): # QMessageBox.information(self.iface.mainWindow(),"Info", \ # "La symbologie ne peut etre affichee vous utilisez une version ancienne de QGIS") #elif layer.isUsingRendererV2(): # new symbology - subclass of QgsFeatureRendererV2 class # rendererV2 = layer.rendererV2() # Grid layer was created, access to the second stage if self.dynSynopt: self.finalSynopt_shape_path = self.dlg.ui.lieOutDir.text() + QCoreApplication.translate("synoptiquesatlas","/dyn_grid.shp") self.intersect(self.bcLayer,self.sLayer) self.createIntersectionLayer() self.new_ladders_list = [] self.sLayer2 = self.centroidsToNewSyno(self.new_ladders_list) self.parseSyno() self.final_ladders_list = [] self.sLayer3 = self.centroidsToNewSyno(self.final_ladders_list) self.fill_references(self.sLayer3) self.createPhysLayerFromList(self.finalSynopt_shape_path, self.sLayer3) self.sLayer3 = self.loadQgsVectorLayer(self.finalSynopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","dynamic grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Coverage layer is not vector type")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a coverage layer to generate grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Overlap % must bee between 0 and 100")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","There is no map object for print composer selected")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a print composer, if none is active you have to create it")) else: QMessageBox.information(self.iface.mainWindow(),"Info", QCoreApplication.translate("synoptiquesatlas","Choose a grid type")) else: QMessageBox.information(self.iface.mainWindow(),"Info", QCoreApplication.translate("synoptiquesatlas","Please enter an existant directory name")) def doBuffer(self): maxDim = max(self.ladderHeight,self.ladderWidth) ratio = 1000./2970 bufferLength = maxDim * ratio self.bcLayer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "buffer_layer", "memory") pr = self.bcLayer.dataProvider() pr.addAttributes([QgsField("ID_BUFFER", QVariant.Int)]) i = 0 for feature in self.cLayer.dataProvider().getFeatures(): fet = QgsFeature() bGeom = feature.geometry().buffer(bufferLength,2) fet.setGeometry(bGeom) fet.setFeatureId(i) pr.addFeatures([fet]) i = i + 1 self.bcLayer.commitChanges() self.bcLayer.updateExtents() def addSynoFeatures(self): layer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "grid_layer", "memory") #layer.setCrs(self.crs) pr = layer.dataProvider() pr.addAttributes([QgsField("ID_MAILLE", QVariant.Int), QgsField("row", QVariant.Int), QgsField("col", QVariant.Int)]) layer.updateFields() # Initial settings provider_perimetre = self.cLayer.dataProvider() #feat_perimetre = QgsFeature() ladderHeight = self.ladderHeight ladderWidth = self.ladderWidth ladder_id = 0 yMax = self.extent.yMaximum() yMin = yMax - ladderHeight widthSum = 0 heightSum = 0 row = 0 # Build columns while heightSum < self.extent.height(): widthSum = 0 col = 0 xMin = self.extent.xMinimum() xMax = xMin + ladderWidth # Build lines while widthSum < self.extent.width(): # Create geometry ladder = QgsRectangle(xMin - self.overlapW, yMin - self.overlapH, xMax + self.overlapW, yMax + self.overlapH) request=QgsFeatureRequest() request.setFilterRect(ladder) for f in provider_perimetre.getFeatures(request): ladder_id = ladder_id + 1 # Add ladder to layer fet = QgsFeature() fet.setAttributes([ladder_id, row, col]) fet.setGeometry(QgsGeometry.fromRect(ladder)) pr.addFeatures([fet]) #ladder_list.append(fet) # Settings for next ladder xMin = xMin + ladderWidth xMax = xMax + ladderWidth widthSum = widthSum + ladderWidth col = col + 1 heightSum = heightSum + ladderHeight yMin = yMin - ladderHeight yMax = yMax - ladderHeight row = row + 1 layer.updateExtents() return layer def fill_references(self, layer): pr = layer.dataProvider() pr.addAttributes([QgsField("above", QVariant.Int), QgsField("below", QVariant.Int), QgsField("left", QVariant.Int), QgsField("right", QVariant.Int), QgsField("aboveleft", QVariant.Int), QgsField("aboveright", QVariant.Int), QgsField("belowleft", QVariant.Int), QgsField("belowright", QVariant.Int)]) layer.updateFields() layer.startEditing() for feature in layer.getFeatures(): neighbours = self.get_neighbour_features(feature, layer) positions = self.get_related_positions(feature, neighbours) for pos, f in positions.iteritems(): if not feature[pos]: feature[pos] = f['ID_MAILLE'] layer.updateFeature(feature) layer.commitChanges() def get_neighbour_features(self, feature, layer): dp = layer.dataProvider() request = QgsFeatureRequest() request.setFilterRect(feature.geometry().buffer(self.ladderWidth / 100.,1).boundingBox()) r = dp.getFeatures(request) return [f for f in r if f['ID_MAILLE'] != feature['ID_MAILLE']] def get_related_positions(self, base, neighbours): base_centroid = base.geometry().centroid().asPoint() positions = {} for n in neighbours: centroid = n.geometry().centroid().asPoint() dx = math.fabs(centroid.x() - base_centroid.x()) dy = math.fabs(centroid.y() - base_centroid.y()) horizontal = dx / self.ladderWidth > dy / self.ladderHeight position = '' if horizontal: position = 'left' if centroid.x() < base_centroid.x() else 'right' if dy > self.ladderHeight * 0.6: position = ('above' if centroid.y() > base_centroid.y() else 'below') + position else: position = 'above' if centroid.y() > base_centroid.y() else 'below' if dx > self.ladderWidth * 0.6: position = position + ('left' if centroid.x() < base_centroid.x() else 'right') if position: #curent position already occupied if position in positions: curent = positions[position] c_centroid = curent.geometry().centroid().asPoint() dx2 = math.fabs(base_centroid.x() - c_centroid.x()) dy2 = math.fabs(base_centroid.y() - c_centroid.y()) if position is 'above' or position is 'below': #our new feature is closer to center of base feature if dx2 > dx: positions[position] = n positions[position + ('right' if c_centroid.x() > base_centroid.x() else 'left')] = curent #old feature is close to center of base feature else: positions[position + ('right' if centroid.x() > base_centroid.x() else 'left')] = n elif position is 'left' or position is 'right': #our new feature is closer to center of base feature if dy2 > dy: positions[position] = n positions[('above' if c_centroid.y() > base_centroid.y() else 'below') + position] = curent #old feature is close to center of base feature else: positions[('above' if centroid.y() > base_centroid.y() else 'below') + position] = n #position is free, just add our feature else: positions[position] = n return positions def createPhysLayerFromList(self, shapePath, layer): # Wite to file error = QgsVectorFileWriter.writeAsVectorFormat(layer, shapePath, \ "CP1250", None, "ESRI Shapefile") if error != QgsVectorFileWriter.NoError: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error when creating shapefile:\n") + shapePath + QCoreApplication.translate("synoptiquesatlas","\nPlease delete or rename the former grid layers")) def intersect(self, perimetre, calepinage): # Intersect between coverage and grid self.centroid_list = [] self.splitted_fet_list = [] i = 0 if perimetre and calepinage: provider_perimetre = perimetre.dataProvider() provider_calepinage = calepinage.dataProvider() # create the select statement #provider_calepinage.select([],self.extent) request=QgsFeatureRequest() request.setFilterRect(self.extent) # the arguments mean no attributes returned, and do a bbox filter with our buffered # rectangle to limit the amount of features for feat_perimetre in provider_perimetre.getFeatures(): # if the feat geom returned from the selection intersects our point then put it in a list for feat_calepinage in provider_calepinage.getFeatures(request): # if the feat geom returned from the selection intersects our point then put it in a list if feat_perimetre.geometry().intersects(feat_calepinage.geometry()): a = feat_perimetre.geometry().intersection(feat_calepinage.geometry()) self.centroid_list.append(a.centroid()) fet = QgsFeature() fet.setGeometry(a) #fet.addAttribute(0, QVariant(i)) self.splitted_fet_list.append(fet) i = i + 1 def createIntersectionLayer(self): self.interLayer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "inter_layer", "memory") #self.interLayer.setCrs(self.crs) pr = self.interLayer.dataProvider() pr.addAttributes([QgsField("ID_INTER", QVariant.Int)]) # Add features for fet in self.splitted_fet_list: pr.addFeatures([fet]) self.interLayer.updateExtents() def centroidsToNewSyno(self, ladder_list): layer = QgsVectorLayer("Polygon" + "?" + self.URIcrs, "layer", "memory") #layer.setCrs(self.crs) pr = layer.dataProvider() pr.addAttributes([QgsField("ID_MAILLE", QVariant.Int)]) layer.updateFields() ladderHeight = self.ladderHeight ladderWidth = self.ladderWidth ladder_id = 0 for centr in self.centroid_list: pt = centr.asPoint() xMin = pt.x() - ladderWidth/2. - self.overlapW xMax = pt.x() + ladderWidth/2. + self.overlapW yMin = pt.y() - ladderHeight/2. - self.overlapH yMax = pt.y() + ladderHeight/2. + self.overlapH # Create geometry ladder = QgsRectangle(xMin, yMin, xMax, yMax) # Add ladder to layer fet = QgsFeature() fet.setGeometry(QgsGeometry.fromRect(ladder)) fet.setAttributes([ladder_id]) ladder_list.append(fet) pr.addFeatures([fet]) ladder_id = ladder_id + 1 layer.updateExtents() return layer def loadQgsVectorLayer(self, shapePath, layerName): layerToLoad = QgsVectorLayer(shapePath, layerName, "ogr") if not layerToLoad.isValid(): QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error while loading layer ") + layerName + " !") else: QgsMapLayerRegistry.instance().addMapLayer(layerToLoad) return layerToLoad def parseSyno(self): i = 0 while i <= len(self.new_ladders_list) - 1: fet = self.splitted_fet_list[i] overlapped = False j = 0 while j <= i - 1 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 j = i + 1 while j <= len(self.new_ladders_list) - 2 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 if overlapped: self.splitted_fet_list.pop(i) self.new_ladders_list.pop(i) self.centroid_list.pop(i) else: i = i + 1 def showHelp(self): showPluginHelp() def showAbout(self): """Show Synoptiques Atlas about dialog box""" adialog = QDialog() adialog.ui = Ui_About_window() adialog.ui.setupUi(adialog) adialog.show() result = adialog.exec_() del adialog # run method that performs all the real work def run(self): self.updateBoxes() # show the dialog self.dlg.show() result = self.dlg.exec_() # See if OK was pressed if result == 1: # do something useful (delete the line containing pass and # substitute with your code pass
class SynoptiquesAtlas: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # a reference to our map canvas self.canvas = self.iface.mapCanvas() # Setup directory self.user_plugin_dir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins" self.syn_atlas_plugin_dir = self.user_plugin_dir + "/synoptiquesatlas" # Translation to English locale = QSettings().value("locale/userLocale")#.toString() self.myLocale = locale[0:2] if QFileInfo(self.syn_atlas_plugin_dir).exists(): localePath = self.syn_atlas_plugin_dir + "/i18n/synoptiquesatlas_" + self.myLocale + ".qm" if QFileInfo(localePath).exists(): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # create and show the dialog self.dlg = SynoptiquesAtlasDialog() def initGui(self): # Create action that will start plugin configuration self.action = QAction(QIcon(":/plugins/synoptiquesatlas/icon.png"), \ QCoreApplication.translate("synoptiquesatlas", "&Grids for Atlas"), self.iface.mainWindow()) # Create action for about dialog self.action_about = QAction("A&bout...", self.iface.mainWindow()) # Create action for help dialog self.action_help = QAction(QIcon(":/plugins/synoptiquesatlas/about.png"), QCoreApplication.translate("synoptiquesatlas", "&Help..."), self.iface.mainWindow()) # connect the action to the run method QObject.connect(self.action, SIGNAL("triggered()"), self.run) # connect about action to about dialog QObject.connect(self.action_about, SIGNAL("triggered()"), self.showAbout) # connect help action to help dialog QObject.connect(self.action_help, SIGNAL("triggered()"), self.showHelp) # connect signals QObject.connect(self.dlg.ui.btnCreerSyno, SIGNAL("clicked()"), self.creerSyno) # composer changed, update maps QObject.connect(self.dlg.ui.cbbComp, SIGNAL('currentIndexChanged(int)'), self.updateMaps) # refresh inLayer box QObject.connect(self.dlg.ui.cbbInLayer, SIGNAL('currentIndexChanged(int)'), self.onLayerChange) # browse button QObject.connect(self.dlg.ui.btnBrowse, SIGNAL('clicked()'), self.updateOutputDir) # refresh template button QObject.connect(self.dlg.ui.btnUpdate, SIGNAL('clicked()'), self.updateComposers) # show composer QObject.connect(self.dlg.ui.btnShow, SIGNAL('clicked()'), self.showComposer) # show about dialog QObject.connect(self.dlg.ui.aboutButton, SIGNAL('clicked()'), self.showAbout) # show help dialog QObject.connect(self.dlg.ui.helpButton, SIGNAL('clicked()'), self.showHelp) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu("&Grids for Atlas", self.action) # Add about menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_about) # add help menu entry self.iface.addPluginToMenu("&Grids for Atlas", self.action_help) def updateBoxes(self): print "fct updateBoxes" self.updateLayers() self.updateComposers() self.updateMaps() def updateLayers(self): print "fct updateLayers" self.dlg.ui.cbbInLayer.clear() for layer in self.iface.mapCanvas().layers(): self.dlg.ui.cbbInLayer.addItem(layer.name(), layer) # (c) Carson Farmer / fTools def getVectorLayerByName(self,myName): print "fct getVectorLayerByName" layermap = QgsMapLayerRegistry.instance().mapLayers() for name, layer in layermap.iteritems(): if layer.type() == QgsMapLayer.VectorLayer and layer.name() == myName: if layer.isValid(): return layer else: return None def onLayerChange(self): print "fct onLayerChange" self.cLayer = self.getVectorLayerByName(self.dlg.ui.cbbInLayer.currentText()) def updateComposers(self): print "fct updateComposers" self.dlg.ui.cbbComp.clear() compos = self.iface.activeComposers() for cv in compos: self.dlg.ui.cbbComp.addItem(cv.composerWindow().windowTitle(), cv) self.composer = self.dlg.ui.cbbComp.itemData(self.dlg.ui.cbbComp.currentIndex())#.toPyObject() def updateMaps(self): print "fct updateMaps" self.dlg.ui.cbbMap.clear() if self.dlg.ui.cbbComp.currentIndex() != -1: self.composer = self.dlg.ui.cbbComp.itemData(self.dlg.ui.cbbComp.currentIndex())#.toPyObject() for item in self.composer.composition().items(): if item.type() == QgsComposerItem.ComposerMap: self.dlg.ui.cbbMap.addItem(QCoreApplication.translate("synoptiquesatlas", "Map ") + "%s"% item.id(), item.id) def showComposer(self): print "fct showComposer" self.composer.composerWindow().show() self.composer.composerWindow().activate() def updateOutputDir(self): print "fct updateOutputDir" self.dlg.ui.lieOutDir.setText(QFileDialog.getExistingDirectory(self.dlg, \ QCoreApplication.translate("synoptiquesatlas", "Choose output directory"))) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu("&Grids for Atlas",self.action) self.iface.removeToolBarIcon(self.action) # Remove about menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_about) # Remove help menu entry self.iface.removePluginMenu("&Grids for Atlas", self.action_help) def creerSyno(self): print "fct creerSyno" if os.path.exists(self.dlg.ui.lieOutDir.text()): self.gridSynopt = self.dlg.ui.chkGrille.isChecked() self.dynSynopt = self.dlg.ui.chkDyn.isChecked() if self.gridSynopt or self.dynSynopt: compos = self.iface.activeComposers() if compos: cview = compos[self.dlg.ui.cbbComp.currentIndex()] self.mapItem = cview.composition().getComposerMapById(\ self.dlg.ui.cbbMap.itemData(self.dlg.ui.cbbMap.currentIndex())()) self.ladderHeight = self.mapItem.extent().height() self.ladderWidth = self.mapItem.extent().width() if self.cLayer: if self.cLayer.type() == 0: self.epsg = int(self.cLayer.crs().postgisSrid ()) self.URIcrs = "crs=epsg:" + str(self.epsg) self.doBuffer() self.extent = self.bcLayer.extent() self.orig_ladders_list = [] self.sLayer = self.addSynoFeatures(self.orig_ladders_list) self.synopt_shape_path = self.dlg.ui.lieOutDir.text() + QCoreApplication.translate("synoptiquesatlas","/classic_grid.shp") self.orig_ladders_list=self.sLayer.getFeatures() self.createPhysLayerFromList(self.dlg.ui.lieOutDir.text(),"classic_grid.shp" ,self.orig_ladders_list) if self.gridSynopt: self.sLayer = self.loadQgsVectorLayer(self.synopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","classic grid")) else: self.sLayer = QgsVectorLayer(self.synopt_shape_path, QCoreApplication.translate("synoptiquesatlas","classic grid"), "ogr") # TODO # Manage symbology #if not hasattr(self.sLayer, 'isUsingRendererV2'): # QMessageBox.information(self.iface.mainWindow(),"Info", \ # "La symbologie ne peut etre affichee vous utilisez une version ancienne de QGIS") #elif layer.isUsingRendererV2(): # new symbology - subclass of QgsFeatureRendererV2 class # rendererV2 = layer.rendererV2() # Grid layer was created, access to the second stage if self.dynSynopt: self.finalSynopt_shape_path = self.dlg.ui.lieOutDir.text() + QCoreApplication.translate("synoptiquesatlas","/dyn_grid.shp") self.intersect(self.bcLayer,self.sLayer) self.createIntersectionLayer() self.new_ladders_list = [] self.sLayer2 = self.centroidsToNewSyno(self.new_ladders_list) self.parseSyno() self.final_ladders_list = [] self.sLayer3 = self.centroidsToNewSyno(self.final_ladders_list) self.final_ladders_list=self.sLayer3.getFeatures() self.createPhysLayerFromList(self.dlg.ui.lieOutDir.text(),"dyn_grid.shp" ,self.final_ladders_list) self.sLayer3 = self.loadQgsVectorLayer(self.finalSynopt_shape_path, \ QCoreApplication.translate("synoptiquesatlas","dynamic grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Coverage layer is not vector type")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a coverage layer to generate grid")) else: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Please select a print composer, if none is active you have to create it")) else: QMessageBox.information(self.iface.mainWindow(),"Info", QCoreApplication.translate("synoptiquesatlas","Choose a grid type")) else: QMessageBox.information(self.iface.mainWindow(),"Info", QCoreApplication.translate("synoptiquesatlas","Please enter an existant directory name")) def doBuffer(self): print "fct doBuffer" maxDim = max(self.ladderHeight,self.ladderWidth) ratio = 1000./2970 bufferLength = maxDim * ratio self.bcLayer = QgsVectorLayer("Polygon?" + self.URIcrs, "buffer_layer", "memory") self.bcLayer.addAttribute(QgsField("ID_BUFFER", QVariant.Int)) self.bcLayer.commitChanges() provider_perimetre = self.cLayer.selectedFeatures() feat_perimetre = QgsFeature() #provider_perimetre.Select() i = 0 for feat_perimetre in provider_perimetre: fet = QgsFeature() fet.setGeometry(feat_perimetre.geometry().buffer(bufferLength,50)) self.cLayer.changeAttributeValue(fet.id(),0, i) #print "attribut vaut : "+str(i)+" de surface "+str(fet.geometry().area()) ### test non verifie self.bcLayer.addFeatures([fet]) i = i + 1 self.bcLayer.updateExtents() def addSynoFeatures(self, ladder_list): print "fct addSynoFeatures "+"Polygon?" + self.URIcrs #layer = QgsVectorLayer("Polygon?" + self.URIcrs, "grid_layer", "memory") layer = self.iface.addVectorLayer("Polygon?" + self.URIcrs, "grid_layer", "memory") layer.startEditing() layer.addAttribute(QgsField("ID_MAILLE", QVariant.Int)) layer.commitChanges() # Initial settings ladder_id = 0 yMax = self.extent.yMaximum() yMin = yMax - self.ladderHeight widthSum = 0 heightSum = 0 # Build columns #print "Debug1 "+str(self.cLayer.boundingBoxOfSelected().height()) while heightSum < self.cLayer.boundingBoxOfSelected().height(): widthSum = 0 xMin = self.extent.xMinimum() xMax = xMin + self.ladderWidth #print "Debug2" # Build lines while widthSum < self.cLayer.boundingBoxOfSelected().width(): # Create geometry ladder = QgsRectangle(xMin, yMin, xMax, yMax) self.cLayer.select(ladder, False) #print "intersectioon = "+str(self.cLayer.selectedFeatureCount()) if self.cLayer.selectedFeatureCount(): # Add ladder to layer fet = QgsFeature(self.cLayer.dataProvider().fields()) fet.setGeometry(QgsGeometry.fromRect(ladder)) fet[0]=ladder_id #fet.addAttribute(0, QVariant(ladder_id)) #print "attribut vaut : "+str(ladder_id)+" de surface "+str(fet.geometry().area()) layer.addFeatures([fet]) ladder_id+= 1 # Settings for next ladder xMin+= self.ladderWidth xMax+= self.ladderWidth widthSum+= self.ladderWidth heightSum+= self.ladderHeight yMin-= self.ladderHeight yMax-= self.ladderHeight layer.updateExtents() QgsVectorLayerTools.stopEditing(layer, False) return layer # def createPhysLayerFromList(self, shapePath, fetList): def createPhysLayerFromList(self, shapePath, shapeName, fetList): print "fct createPhysLayerFromList" # Create shapefile writer layer = QgsVectorLayer(shapePath, shapeName, "shp") layer.startEditing() layer.addAttribute(QgsField("ID_MAILLE", QVariant.Int)) layer.commitChanges() #fields = QgsFields() #fields.append(QgsField("ID_MAILLE", QVariant.Int)) #self.writer = QgsVectorFileWriter(shapePath, "CP1250", fields, \ # QGis.WKBPolygon, self.cLayer.crs(), "ESRI Shapefile") #if self.writer.hasError() != QgsVectorFileWriter.NoError: # QMessageBox.information(self.iface.mainWindow(),"Info", \ # QCoreApplication.translate("synoptiquesatlas","Error when creating shapefile:\n") + shapePath + QCoreApplication.translate("synoptiquesatlas","\nPlease delete or rename the former grid layers")) # Add features for fet in fetList: print "area = "+str(fet.geometry().area()) layer.addFeature(fet) # Stop writing #del self.writer layer.commitChanges() layer.stopEditing() def createGridLayer(self): print "fct createGridLayer" # Create shapefile writer fields = { 0 : QgsField("ID_MAILLE", QVariant.Int)} self.writer = QgsVectorFileWriter(self.finalSynopt_shape_path, "CP1250", fields, \ QGis.WKBPolygon, self.cLayer.crs(), "ESRI Shapefile") if self.writer.hasError() != QgsVectorFileWriter.NoError: QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error when creating shapefile:\n") + self.finalSynopt_shape_path + QCoreApplication.translate("synoptiquesatlas","\nPlease delete or rename the former grid layers")) # Add features for fet in self.orig_ladders_list: self.writer.addFeature(fet) # Stop writing del self.writer # genere deux listes : # - centroid_list = liste des points d'intersection entre chaque objet de la grille # et chaque objets selectionnes de la couche vectorielle def intersect(self, perimetre, calepinage): print "fct intersect" # Intersect between coverage and grid self.centroid_list = [] self.splitted_fet_list = [] i = 0 if perimetre and calepinage: provider_perimetre = perimetre.selectedFeatures() provider_calepinage = calepinage.selectedFeatures() feat_perimetre = QgsFeature() feat_calepinage = QgsFeature() # create the select statement #provider_perimetre.select([]) #provider_calepinage.select([],self.extent) rechercher comment limiter a cette bbox # the arguments mean no attributes returned, and do a bbox filter with our buffered # rectangle to limit the amount of features for feat_perimetre in provider_perimetre: # if the feat geom returned from the selection intersects our point then put it in a list for feat_calepinage in provider_calepinage: # if the feat geom returned from the selection intersects our point then put it in a list if feat_perimetre.geometry().intersects(feat_calepinage.geometry()): a = feat_perimetre.geometry().intersection(feat_calepinage.geometry()) self.centroid_list.append(a.centroid()) fet = QgsFeature() fet.setGeometry(a) fet.addAttribute(0, QVariant(i)) self.splitted_fet_list.append(fet) i = i + 1 # pas lance def createIntersectionLayer(self): print "fct createIntersectionLayer" self.interLayer = QgsVectorLayer("Polygon?" + self.URIcrs, "inter_layer", "memory") pr = self.interLayer.dataProvider() pr.addAttributes([QgsField("ID_INTER", QVariant.Int)]) # Add features for fet in self.splitted_fet_list: pr.addFeatures([fet]) self.interLayer.updateExtents() # pas lance def centroidsToNewSyno(self, ladder_list): print "fct centroidsToNewSyno" layer = QgsVectorLayer("Polygon?" + self.URIcrs, "layer", "memory") pr = layer.dataProvider() pr.addAttributes([QgsField("ID_MAILLE", QVariant.Int)]) ladderHeight = self.ladderHeight ladderWidth = self.ladderWidth ladder_id = 0 for centr in self.centroid_list: pt = centr.asPoint() xMin = pt.x() - ladderWidth/2. xMax = pt.x() + ladderWidth/2. yMin = pt.y() - ladderHeight/2. yMax = pt.y() + ladderHeight/2. # Create geometry ladder = QgsRectangle(xMin, yMin, xMax, yMax) # Add ladder to layer fet = QgsFeature() fet.setGeometry(QgsGeometry.fromRect(ladder)) fet.addAttribute(0, QVariant(ladder_id)) ladder_list.append(fet) pr.addFeatures([fet]) ladder_id = ladder_id + 1 layer.updateExtents() return layer def loadQgsVectorLayer(self, shapePath, layerName): print "fct loadQgsVectorLayer" layerToLoad = QgsVectorLayer(shapePath, layerName, "ogr") if not layerToLoad.isValid(): QMessageBox.information(self.iface.mainWindow(),"Info", \ QCoreApplication.translate("synoptiquesatlas","Error while loading layer ") + layerName + " !") else: QgsMapLayerRegistry.instance().addMapLayer(layerToLoad) return layerToLoad def parseSyno(self): print "fct parseSyno" i = 0 while i <= len(self.new_ladders_list) - 1: fet = self.splitted_fet_list[i] overlapped = False j = 0 while j <= i - 1 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 j = i + 1 while j <= len(self.new_ladders_list) - 2 and not overlapped: fet2 = self.new_ladders_list[j] # if geom is entirely overlapped by geom2, pop it from list, pop its centroid if fet2.geometry().contains(fet.geometry()): overlapped = True j = j + 1 if overlapped: self.splitted_fet_list.pop(i) self.new_ladders_list.pop(i) self.centroid_list.pop(i) else: i = i + 1 def showHelp(self): """Show help dialog box""" # Create a dialog and setup UI hdialog = QDialog() hdialog.ui = Ui_help_window() hdialog.ui.setupUi(hdialog) # load help file if self.myLocale == 'fr': hdialog.ui.webView.setUrl(QUrl(self.syn_atlas_plugin_dir + '/help/syn_atlas.html')) else: hdialog.ui.webView.setUrl(QUrl(self.syn_atlas_plugin_dir + '/help/syn_atlas_en.html')) hdialog.show() result = hdialog.exec_() del hdialog def showAbout(self): """Show Synoptiques Atlas about dialog box""" adialog = QDialog() adialog.ui = Ui_About_window() adialog.ui.setupUi(adialog) adialog.show() result = adialog.exec_() del adialog # run method that performs all the real work def run(self): self.updateBoxes() # show the dialog self.dlg.show() result = self.dlg.exec_() # See if OK was pressed if result == 1: # do something useful (delete the line containing pass and # substitute with your code pass