def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict): """ Loads a layer :param lyrName: Layer nmae :param idSubgrupo: sub group id :param uniqueLoad: boolean to mark if the layer should only be loaded once :param stylePath: path to the styles used :param domLayerDict: domain dictionary :return: """ lyrName, schema, geomColumn, tableName, srid = self.getParams( inputParam) lyr = self.checkLoaded(tableName) if uniqueLoad and lyr: return lyr self.setDataSource('', '_'.join([schema, tableName]), geomColumn, '') vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider) QgsProject.instance().addMapLayer(vlayer, addToLegend=False) crs = QgsCoordinateReferenceSystem( int(srid), QgsCoordinateReferenceSystem.EpsgCrsId) vlayer.setCrs(crs) vlayer = self.setDomainsAndRestrictionsWithQml(vlayer) vlayer = self.setMulti(vlayer, domLayerDict) if stylePath: fullPath = self.getStyle(stylePath, tableName) if fullPath: vlayer.loadNamedStyle(fullPath, True) parentNode.addLayer(vlayer) if not vlayer.isValid(): QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical) vlayer = self.createMeasureColumn(vlayer) return vlayer
def special_search(self, easter_code="isogeo"): """Make some special actions in certains cases. :param str easter_code: easter egg label. Available values: * isogeo: display Isogeo logo and zoom in our office location * picasa: change QGS project title """ canvas = iface.mapCanvas() if easter_code == "isogeo": # WMS wms_params = {"service": "WMS", "version": "1.3.0", "request": "GetMap", "layers": "Isogeo:isogeo_logo", "crs": "EPSG:3857", "format": "image/png", "styles": "isogeo_logo", "url": "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?" } wms_uri = unquote(urlencode(wms_params)) wms_lyr = QgsRasterLayer(wms_uri, u"Ici c'est Isogeo !", "wms") if wms_lyr.isValid: QgsMapLayerRegistry.instance().addMapLayer(wms_lyr) logger.info("Isogeo easter egg used and WMS displayed!") else: logger.error("WMS layer failed: {}" .format(wms_lyr.error().message())) # WFS uri = QgsDataSourceURI() uri.setParam("url", "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?") uri.setParam("service", "WFS") uri.setParam("version", "1.1.0") uri.setParam("typename", "Isogeo:isogeo_logo") uri.setParam("srsname", "EPSG:3857") uri.setParam("restrictToRequestBBOX", "0") wfs_uri = uri.uri() wfs_lyr = QgsVectorLayer(wfs_uri, u"Ici c'est Isogeo !", "WFS") if wfs_lyr.isValid: wfs_style = path.join(path.dirname(path.realpath(__file__)), "isogeo.qml") wfs_lyr.loadNamedStyle(wfs_style) QgsMapLayerRegistry.instance().addMapLayer(wfs_lyr) canvas.setExtent(wfs_lyr.extent()) logger.debug("Isogeo easter egg used") else: logger.error("Esater egg - WFS layer failed: {}" .format(wfs_lyr.error().message())) elif easter_code == "picasa": project = QgsProject.instance() project.setTitle(u"Isogeo, le Picasa de l'information géographique") logger.debug("Picasa easter egg used") else: pass # ending method return
def loadEDGVLayer(self, uri, layer_name, provider): vlayer = QgsVectorLayer(uri.uri(), layer_name, provider) vlayer.setCrs(self.crs) QgsMapLayerRegistry.instance().addMapLayer(vlayer) #added due to api changes if self.isSpatialite and (self.dbVersion == '3.0' or self.dbVersion == '2.1.3'): lyr = '_'.join(layer_name.replace('\r', '').split('_')[1::]) else: lyr = layer_name.replace('\r','') vlayerQml = os.path.join(self.qmlPath, lyr+'.qml') vlayer.loadNamedStyle(vlayerQml, False) QgsMapLayerRegistry.instance().addMapLayer(vlayer) if not vlayer.isValid(): QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
def loadLayer(self, inputParam, parentNode, useInheritance, useQml, uniqueLoad, stylePath, domainDict, multiColumnsDict, domLayerDict, edgvVersion, geomColumn = None, isView = False, editingDict=None, customForm = False): """ Loads a layer :param lyrName: Layer name :param idSubgrupo: sub group id :param uniqueLoad: boolean to mark if the layer should only be loaded once :param stylePath: path to the styles used :param domLayerDict: domain dictionary :return: """ lyrName, schema, geomColumn, tableName, srid = self.getParams(inputParam) lyr = self.checkLoaded(tableName) if uniqueLoad and lyr is not None: return lyr fullName = '''"{0}"."{1}"'''.format(schema, tableName) pkColumn = self.abstractDb.getPrimaryKeyColumn(fullName) if useInheritance or self.abstractDb.getDatabaseVersion() in ['3.0', 'Non_EDGV','Non_Edgv', '2.1.3 Pro', '3.0 Pro']: sql = '' else: sql = self.abstractDb.gen.loadLayerFromDatabase(fullName, pkColumn=pkColumn) self.setDataSource(schema, tableName, geomColumn, sql, pkColumn=pkColumn) vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider) QgsProject.instance().addMapLayer(vlayer, addToLegend = False) crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId) if vlayer is not None: vlayer.setCrs(crs) if useQml: vlayer = self.setDomainsAndRestrictionsWithQml(vlayer) else: vlayer = self.setDomainsAndRestrictions(vlayer, tableName, domainDict, multiColumnsDict, domLayerDict) if stylePath: fullPath = self.getStyle(stylePath, tableName) if fullPath: vlayer.loadNamedStyle(fullPath, True) # remove qml temporary file self.utils.deleteQml(fullPath) # clear fullPath variable del fullPath if customForm: vlayer = self.loadFormCustom(vlayer) if editingDict is not None: editLyr, joinLyrFieldName = self.loadEditLayer(lyrName, editingDict) self.buildJoin(vlayer, pkColumn, editLyr, joinLyrFieldName) parentNode.addLayer(vlayer) if not vlayer.isValid(): QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical) vlayer = self.createMeasureColumn(vlayer) return vlayer
def special_search(self, easter_code="isogeo"): """Make some special actions in certains cases.""" canvas = iface.mapCanvas() if easter_code == "isogeo": # WMS # wms_params = {"service": "WMS", # "version": "1.3.0", # "request": "GetMap", # "layers": "Isogeo:isogeo_logo", # "crs": "EPSG:3857", # "format": "image/png", # "styles": "isogeo_logo", # "url": "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?" # } # wms_uri = unquote(urlencode(wms_params)) # wms_lyr = QgsRasterLayer(wms_uri, u"Ici c'est Isogeo !", "wms") # if wms_lyr.isValid: # QgsMapLayerRegistry.instance().addMapLayer(wms_lyr) # logger.info("Isogeo easter egg used and WMS displayed!") # else: # logger.error("WMS layer failed: {}" # .format(wms_lyr.error().message())) # WFS wfs_params = {"service": "WFS", "version": "1.0.0", "request": "GetFeature", "typename": "Isogeo:isogeo_logo", "srsname": "EPSG:3857", } wfs_uri = "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?"\ + unquote(urlencode(wfs_params)) wfs_lyr = QgsVectorLayer(wfs_uri, u"Ici c'est Isogeo !", "WFS") if wfs_lyr.isValid: wfs_style = path.join(path.dirname(path.realpath(__file__)), "isogeo.qml") wfs_lyr.loadNamedStyle(wfs_style) QgsMapLayerRegistry.instance().addMapLayer(wfs_lyr) logger.info("Isogeo easter egg used and WFS displayed!") else: logger.error("WFS layer failed: {}" .format(wfs_lyr.error().message())) canvas.setExtent(QgsRectangle(2.224199,48.815573,2.469921, 48.902145)) else: pass # ending method return
def get_layer(self, table_name, display_name=None, geom_field="the_geom"): if display_name is None: display_name = table_name uri = self._get_uri(table_name, geom_field) layer = QgsVectorLayer(uri.uri(), display_name, "spatialite") if layer.isValid(): return layer else: logger.error( "error loading table {table_name} from spatialite file " "{path}. Error message: {error}.".format( table_name=table_name, path=self.path, error=layer.error() ) ) return None
class InputNetworkTabManager(QtCore.QObject): ''' Class to hide managing of relative tab ''' projectModified = QtCore.pyqtSignal() def __init__(self, parent=None): '''constructor''' super(InputNetworkTabManager, self).__init__(parent) # parent is the dock widget with all graphical elements self.gui = parent # init some globals self.applicationPath = os.path.dirname(os.path.realpath(__file__)) self.project = None self.projectPath = None self.roadLayer = None self.roadLayerId = None # retrieve the current tab index self.initTabTabIndex() # disable tab at the beginning self.gui.tabWidget.setTabEnabled(self.tabIndex, False) # set basic events self.gui.inputLayer_lineEdit.returnPressed.connect(self.loadLayer) self.gui.selectLayer_TButton.clicked.connect(self.askLayer) self.gui.selectFile_TButton.clicked.connect(self.askLayerFile) self.gui.inputNetwork_validate_PButton.clicked.connect(self.validateWithNotification) def initTabTabIndex(self): ''' Retrieve what tab index refer the current tab manager ''' for tabIndex in range(self.gui.tabWidget.count()): if self.gui.tabWidget.tabText(tabIndex) == "Input Network": self.tabIndex = tabIndex def setProject(self, project=None): ''' setting the new project on which the tab is based ''' self.project = project if self.project: # set some globals confFileName = self.project.fileName() self.projectPath = os.path.dirname(confFileName) # emit configurationLoaded with the status of loading self.setTabGUIBasingOnProject() # enable current tab because project has been loaded self.gui.tabWidget.setTabEnabled(self.tabIndex, True) else: # disable current tab because no project has been loaded yet self.gui.tabWidget.setTabEnabled(self.tabIndex, False) def setTabGUIBasingOnProject(self): '''Set tab basing on project conf ''' if not self.project: return # get conf parameters inputLayerFile = self.project.value('InputNetwork/inputLayer', '') columnRoadType = self.project.value('InputNetwork/columnRoadType', '') columnRoadLenght = self.project.value('InputNetwork/columnRoadLenght', '') columnRoadSlope = self.project.value('InputNetwork/columnRoadSlope', '') # if layer exist load it otherwise only reset comboboxes if os.path.exists(inputLayerFile): # check if layer is already loaded in layer list checking it's source # that would be equal to the inputLayerFile (for this reason is not simple # to work with db data) found = False for layerName, layer in QgsMapLayerRegistry.instance().mapLayers().items(): if inputLayerFile == layer.publicSource(): # set the found layer as roadLayer self.roadLayer = layer found = True break # if layer is not loaded... load it if not found: # get layer name to set as public name in the legend layerName = os.path.splitext( os.path.basename(inputLayerFile) )[0] # load layer self.roadLayer = QgsVectorLayer(inputLayerFile, layerName, 'ogr') if not self.roadLayer.isValid(): message = self.tr("Error loading layer: %s" % self.roadLayer.error().message(QgsErrorMessage.Text)) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return # show layer in the canvas QgsMapLayerRegistry.instance().addMapLayer(self.roadLayer) # now layer is available self.roadLayerId = self.roadLayer.id() else: message = self.tr("Input network does not exist: %s" % inputLayerFile) iface.messageBar().pushMessage(message, QgsMessageBar.WARNING) self.roadLayer = None self.roadLayerId = None # avoid emitting signal in case of reset of indexes try: # to avoid add multiple listener, remove previous listener self.gui.inputLayer_lineEdit.returnPressed.disconnect(self.saveTabOnProject) self.gui.roadType_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.roadLenght_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.roadGradient_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) except (Exception) as ex: pass # set text of loaded layer if self.roadLayer: self.gui.inputLayer_lineEdit.setText(self.roadLayer.publicSource()) else: self.gui.inputLayer_lineEdit.setText(inputLayerFile) # now populare combo boxes with layer colums if self.roadLayer: fieldNames = sorted([field.name() for field in self.roadLayer.pendingFields().toList()]) else: fieldNames = [] unknownIndex = -1 self.gui.roadType_CBox.clear() self.gui.roadLenght_CBox.clear() self.gui.roadGradient_CBox.clear() self.gui.roadType_CBox.addItems(fieldNames) self.gui.roadLenght_CBox.addItems(fieldNames) self.gui.roadGradient_CBox.addItems(fieldNames) # select the combobox item as in the project file... if not available then "Please select" index = self.gui.roadType_CBox.findText(columnRoadType) self.gui.roadType_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.roadLenght_CBox.findText(columnRoadLenght) self.gui.roadLenght_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.roadGradient_CBox.findText(columnRoadSlope) self.gui.roadGradient_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) # add all modification events to notify project modification self.gui.inputLayer_lineEdit.returnPressed.connect(self.saveTabOnProject) self.gui.roadType_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.roadLenght_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.roadGradient_CBox.currentIndexChanged.connect(self.saveTabOnProject) # # set parameters for vechicle count/speed columns # # get parameters fron project columnPassengerCars = self.project.value('VehicleCountSpeed/columnPassengerCars', '') columnLightDutyVehicle = self.project.value('VehicleCountSpeed/columnLightDutyVehicle', '') columnHeavyDutyVechicle = self.project.value('VehicleCountSpeed/columnHeavyDutyVechicle', '') columnUrbanBuses = self.project.value('VehicleCountSpeed/columnUrbanBuses', '') columnMotorcycle = self.project.value('VehicleCountSpeed/columnMotorcycle', '') columnCouch = self.project.value('VehicleCountSpeed/columnCouch', '') columnAverageSpeed = self.project.value('VehicleCountSpeed/columnAverageSpeed', '') # avoid emitting signal in case of reset of indexes try: # to avoid add multiple listener, remove previous listener self.gui.passengerCarsCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.lightDutyVehicleCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.heavyDutyVehicleCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.urbanBusesCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.coachesCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.motorcycleCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject) self.gui.averageVehicleSpeed_Cbox.currentIndexChanged.disconnect(self.saveTabOnProject) except (Exception) as ex: pass # now populare combo boxes with layer colums self.gui.passengerCarsCount_CBox.clear() self.gui.lightDutyVehicleCount_CBox.clear() self.gui.heavyDutyVehicleCount_CBox.clear() self.gui.urbanBusesCount_CBox.clear() self.gui.coachesCount_CBox.clear() self.gui.motorcycleCount_CBox.clear() self.gui.averageVehicleSpeed_Cbox.clear() self.gui.passengerCarsCount_CBox.addItems(fieldNames) self.gui.lightDutyVehicleCount_CBox.addItems(fieldNames) self.gui.heavyDutyVehicleCount_CBox.addItems(fieldNames) self.gui.urbanBusesCount_CBox.addItems(fieldNames) self.gui.coachesCount_CBox.addItems(fieldNames) self.gui.motorcycleCount_CBox.addItems(fieldNames) self.gui.averageVehicleSpeed_Cbox.addItems(fieldNames) # select the combobox item as in the project file... if not available then "Please select" index = self.gui.passengerCarsCount_CBox.findText(columnPassengerCars) self.gui.passengerCarsCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.lightDutyVehicleCount_CBox.findText(columnLightDutyVehicle) self.gui.lightDutyVehicleCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.heavyDutyVehicleCount_CBox.findText(columnHeavyDutyVechicle) self.gui.heavyDutyVehicleCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.urbanBusesCount_CBox.findText(columnUrbanBuses) self.gui.urbanBusesCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.coachesCount_CBox.findText(columnCouch) self.gui.coachesCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.motorcycleCount_CBox.findText(columnMotorcycle) self.gui.motorcycleCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex ) index = self.gui.averageVehicleSpeed_Cbox.findText(columnAverageSpeed) self.gui.averageVehicleSpeed_Cbox.setCurrentIndex( index if index >= 0 else unknownIndex ) # add all modification events to notify project modification self.gui.passengerCarsCount_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.lightDutyVehicleCount_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.heavyDutyVehicleCount_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.urbanBusesCount_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.coachesCount_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.motorcycleCount_CBox.currentIndexChanged.connect(self.saveTabOnProject) self.gui.averageVehicleSpeed_Cbox.currentIndexChanged.connect(self.saveTabOnProject) def saveTabOnProject(self): ''' Save tab configuration in the project basing on GUI values ''' if self.sender(): message = "QTraffic: saveTabOnProject by sender {}".format(self.sender().objectName()) QgsLogger.debug(message, debuglevel=3) # get values from the GUI inputLayerFile = self.gui.inputLayer_lineEdit.text() columnRoadType = self.gui.roadType_CBox.currentText() columnRoadLenght = self.gui.roadLenght_CBox.currentText() columnRoadSlope = self.gui.roadGradient_CBox.currentText() # set conf parameters self.project.setValue('InputNetwork/inputLayer', inputLayerFile) self.project.setValue('InputNetwork/columnRoadType', columnRoadType) self.project.setValue('InputNetwork/columnRoadLenght', columnRoadLenght) self.project.setValue('InputNetwork/columnRoadSlope', columnRoadSlope) # # save parameters for vechicle count/speed columns # # get values from the GUI columnPassengerCars = self.gui.passengerCarsCount_CBox.currentText() columnLightDutyVehicle = self.gui.lightDutyVehicleCount_CBox.currentText() columnHeavyDutyVechicle = self.gui.heavyDutyVehicleCount_CBox.currentText() columnUrbanBuses = self.gui.urbanBusesCount_CBox.currentText() columnCouch = self.gui.coachesCount_CBox.currentText() columnMotorcycle = self.gui.motorcycleCount_CBox.currentText() columnAverageSpeed = self.gui.averageVehicleSpeed_Cbox.currentText() # set conf parameters self.project.setValue('VehicleCountSpeed/columnPassengerCars', columnPassengerCars) self.project.setValue('VehicleCountSpeed/columnLightDutyVehicle', columnLightDutyVehicle) self.project.setValue('VehicleCountSpeed/columnHeavyDutyVechicle', columnHeavyDutyVechicle) self.project.setValue('VehicleCountSpeed/columnUrbanBuses', columnUrbanBuses) self.project.setValue('VehicleCountSpeed/columnMotorcycle', columnMotorcycle) self.project.setValue('VehicleCountSpeed/columnCouch', columnCouch) self.project.setValue('VehicleCountSpeed/columnAverageSpeed', columnAverageSpeed) # notify project modification self.projectModified.emit() def askLayer(self): ''' Ask for the layer to load Look for layer already loaded in the layer list ''' # create dialog to select layer dlg = SelectLayerDialog(self.gui) ret = dlg.exec_() if ret: # get selected layer newLayer = dlg.selectLayer_CBox.currentLayer() # set gui with the new layer name self.gui.inputLayer_lineEdit.setText(newLayer.publicSource()) # then load layer self.loadLayer() def askLayerFile(self): ''' Ask for the layer file to load Don't load it if already loaded comparing source of tre layer ''' if not self.project: return # if a layer is present in the project start from the path of that layer oldLayer = self.project.value('InputNetwork/inputLayer', '') if oldLayer: startPath = os.path.dirname(oldLayer) else: startPath = self.projectPath # get porject path layerFileName = QtGui.QFileDialog.getOpenFileName(self.gui, "Select road layer", startPath, self.tr("Shp (*.shp);;All (*)")) if not layerFileName: return # set gui with the new layer name self.gui.inputLayer_lineEdit.setText(layerFileName) # then load layer self.loadLayer() def loadLayer(self): ''' Load a shape layer ''' # get layer filename layerFileName = self.gui.inputLayer_lineEdit.text() if not layerFileName: return if not os.path.exists(layerFileName): title = self.tr("Warning") message = self.tr("Layer does not exist") iface.messageBar().pushMessage(message, QgsMessageBar.WARNING) return currentLayerFile = self.project.value('InputNetwork/inputLayer', '') if currentLayerFile != layerFileName: self.project.setValue('InputNetwork/inputLayer', layerFileName) self.setTabGUIBasingOnProject() # notify project modification if layer source is modified if currentLayerFile != layerFileName: self.projectModified.emit() def getRoadLayer(self): return self.roadLayer def getRoadLayerId(self): return self.roadLayerId def removeRoadLayer(self): ''' Remove current road layer from canvas ''' if self.roadLayer and self.roadLayer.isValid(): # do nothing if layer already removed by user QgsMapLayerRegistry.instance().removeMapLayer(self.roadLayer.id()) def validateWithNotification(self): ''' Do validation and notify if it success ''' if self.validate(): message = self.tr("QTraffic: Input Network validation passed successfully") iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS) def validate(self): ''' Validate parameters inserted in the Input Network tab: Validation performed is: Mandatory parameters: Input layer Road Type Road lenght Road Gradient Average vehicle speed At least one of vehicle count Value validation: Road Type have to be integer Road lenght, lenght, Gradient have to be float Average vehicle speed have to be lfoat Count column have to be float or integer Inter tab validation Road type column values have to be present as categories in Fleet Distribution classes This method notify the error in case of validation failure This method notify success in case of correct validation @return: True is validated or False if not ''' if not self.project: return False inputLayerFile = self.gui.inputLayer_lineEdit.text() columnRoadType = self.gui.roadType_CBox.currentText() columnRoadLenght = self.gui.roadLenght_CBox.currentText() columnRoadSlope = self.gui.roadGradient_CBox.currentText() columnAverageSpeed = self.gui.averageVehicleSpeed_Cbox.currentText() columnPassengerCars = self.gui.passengerCarsCount_CBox.currentText() columnLightDutyVehicle = self.gui.lightDutyVehicleCount_CBox.currentText() columnHeavyDutyVechicle = self.gui.heavyDutyVehicleCount_CBox.currentText() columnUrbanBuses = self.gui.urbanBusesCount_CBox.currentText() columnCouch = self.gui.coachesCount_CBox.currentText() columnMotorcycle = self.gui.motorcycleCount_CBox.currentText() # mandatory fields if not inputLayerFile: message = self.tr("Validation error: Input shape have to be choosed") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False if not columnRoadType: message = self.tr("Validation error: Road type column have to be selected from input layer") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False if not columnRoadLenght: message = self.tr("Validation error: Road lenght column have to be selected from input layer") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False if not columnRoadSlope: message = self.tr("Validation error: Road gradient column have to be selected from input layer") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False if not columnRoadLenght: message = self.tr("Validation error: Road slope column have to be selected from input layer") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False if not columnAverageSpeed: message = self.tr("Validation error: Average vechicle speed column have to be selected from input layer") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False # at least one column count have to be selected if (not columnPassengerCars and not columnLightDutyVehicle and not columnHeavyDutyVechicle and not columnUrbanBuses and not columnCouch and not columnMotorcycle): message = self.tr("Validation error: At least a vehicle count column have to be selected from input layer") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False # value validations fields = self.roadLayer.pendingFields() checkDict = { columnRoadType: [QtCore.QVariant.Int, QtCore.QVariant.LongLong], columnRoadLenght: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnRoadSlope: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnAverageSpeed: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnPassengerCars: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnLightDutyVehicle: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnHeavyDutyVechicle: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnUrbanBuses: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnCouch: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], columnMotorcycle: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong], } for columnName, admissibleTypes in checkDict.items(): if not columnName: continue field = fields.field(columnName) if not field.type() in admissibleTypes: message = self.tr("Validation error: column {} has incompatible type {}".format(columnName, field.typeName())) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False # inter tab validation index = self.roadLayer.fieldNameIndex(columnRoadType) roadTypes = self.roadLayer.uniqueValues(index, -1) if len(roadTypes) == 0: message = self.tr("Validation error: column {} has no values".format(columnRoadType)) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False # check if each road type is present in the list of road types in the fleet distribution tab fleetDistributionRoadTypes = self.gui.getRoadTypes() for roadType in roadTypes: if not str(roadType) in fleetDistributionRoadTypes: message = self.tr("Validation error: Road type value {} is not defined in Fleet Composition tab".format(roadType)) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False return True # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QtCore.QCoreApplication.translate('QTraffic', message)
class OutputTabManager(QtCore.QObject): ''' Class to hide managing of relative tab ''' projectModified = QtCore.pyqtSignal() def __init__(self, parent=None): '''constructor''' super(OutputTabManager, self).__init__(parent) # parent is the dock widget with all graphical elements self.gui = parent self.plugin = parent.parent # init some globals self.applicationPath = os.path.dirname(os.path.realpath(__file__)) self.project = None self.projectPath = None self.outLayer = None self.outLayerId = None self.outLayerRemoved = False # retrieve the current tab index self.initTabTabIndex() # disable tab at the beginning self.gui.tabWidget.setTabEnabled(self.tabIndex, False) # add some gui events self.gui.createNewLayer_RButton.toggled.connect(self.setInputLayer) self.gui.selectOutfile_TButton.clicked.connect(self.selectNewOutFile) self.gui.calculate_PButton.clicked.connect(self.calculate) def initTabTabIndex(self): ''' Retrieve what tab index refer the current tab manager ''' for tabIndex in range(self.gui.tabWidget.count()): if self.gui.tabWidget.tabText(tabIndex) == "Output": self.tabIndex = tabIndex def setProject(self, project=None): ''' setting the new project on which the tab is based ''' self.project = project if self.project: # write everything on disk self.project.sync() # set some globals confFileName = self.project.fileName() self.projectPath = os.path.dirname(confFileName) # emit configurationLoaded with the status of loading self.setTabGUIBasingOnProject() # enable current tab because project has been loaded self.gui.tabWidget.setTabEnabled(self.tabIndex, True) else: # disable current tab because no project has been loaded yet self.gui.tabWidget.setTabEnabled(self.tabIndex, False) def selectNewOutFile(self): ''' Select the the file ''' oldOutputLayer = self.gui.outFile_LEdit.text() # get last conf to start from its path startPath = self.projectPath newOutputLayer = self.project.value( 'Processing.OutputFileDefinition/newOutputLayer', '') if newOutputLayer: startPath = os.path.dirname(newOutputLayer) # ask for the new out file newOutputLayer = QtGui.QFileDialog.getSaveFileName( self.gui, "Select an autput file", startPath, self.plugin.tr("All (*)")) if not newOutputLayer: return if oldOutputLayer == newOutputLayer: return # add shp extension components = os.path.splitext(newOutputLayer) if len(components) == 1: newOutputLayer = newOutputLayer + '.shp' else: if components[1] != '.shp': newOutputLayer = components[0] + '.shp' # update gui self.gui.outFile_LEdit.setText(newOutputLayer) self.saveTabOnProject() def setInputLayer(self): ''' Set GUI basing on toggled ComboBox to set if the layer is the input one or have to select a new one ''' self.gui.outFile_LEdit.setEnabled( self.gui.createNewLayer_RButton.isChecked()) self.gui.selectOutfile_TButton.setEnabled( self.gui.createNewLayer_RButton.isChecked()) def setTabGUIBasingOnProject(self): '''Set tab basing on project conf ''' if not self.project: return # get conf parameters addToInputLayer = self.project.value( 'Processing.OutputFileDefinition/addToInputLayer', False, bool) newOutputLayer = self.project.value( 'Processing.OutputFileDefinition/newOutputLayer', '') Gasoline_Consumption = self.project.value( 'Processing.Parameters/Gasoline_Consumption', False, bool) Diesel_Consumption = self.project.value( 'Processing.Parameters/Diesel_Consumption', False, bool) LPG_Consumption = self.project.value( 'Processing.Parameters/LPG_Consumption', False, bool) NewFuel_Consumption = self.project.value( 'Processing.Parameters/NewFuel_Consumption', False, bool) Fuel_Consumption_Total = self.project.value( 'Processing.Parameters/Fuel_Consumption_Total', False, bool) Energy_Consumption = self.project.value( 'Processing.Parameters/Energy_Consumption', False, bool) CO = self.project.value('Processing.Parameters/CO', False, bool) NOx = self.project.value('Processing.Parameters/NOx', False, bool) NMVOC = self.project.value('Processing.Parameters/NMVOC', False, bool) CO2 = self.project.value('Processing.Parameters/CO2', False, bool) CH4 = self.project.value('Processing.Parameters/CH4', False, bool) N2O = self.project.value('Processing.Parameters/N2O', False, bool) NH3 = self.project.value('Processing.Parameters/NH3', False, bool) SO2 = self.project.value('Processing.Parameters/SO2', False, bool) PM25 = self.project.value('Processing.Parameters/PM', False, bool) C6H6 = self.project.value('Processing.Parameters/C6H6', False, bool) # avoid emitting signal in case of reset of indexes try: # to avoid add multiple listener, remove previous listener self.gui.addToOriginaLayer_RButton.toggled.disconnect( self.saveTabOnProject) self.gui.createNewLayer_RButton.toggled.disconnect( self.saveTabOnProject) self.gui.outFile_LEdit.returnPressed.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionGasoline_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionDiesel_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionLPG_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionNewFuels_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.totalFuelConsumption_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.energyConsumption_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsCO_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsNOx_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsNMVOCs_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsCO2_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsCH4_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsN2O_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsNH3_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsSO2_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsPM25_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsC6H6_CBox.clicked.disconnect( self.saveTabOnProject) except (Exception) as ex: pass # now populate interface self.gui.addToOriginaLayer_RButton.setChecked(addToInputLayer) self.gui.createNewLayer_RButton.setChecked(not addToInputLayer) self.gui.outFile_LEdit.setText(newOutputLayer) self.gui.fuelEnergyConsumptionGasoline_CBox.setChecked( Gasoline_Consumption) self.gui.fuelEnergyConsumptionDiesel_CBox.setChecked( Diesel_Consumption) self.gui.fuelEnergyConsumptionLPG_CBox.setChecked(LPG_Consumption) self.gui.fuelEnergyConsumptionNewFuels_CBox.setChecked( NewFuel_Consumption) self.gui.totalFuelConsumption_CBox.setChecked(Fuel_Consumption_Total) self.gui.energyConsumption_CBox.setChecked(Energy_Consumption) self.gui.pollutantsCO_CBox.setChecked(CO) self.gui.pollutantsNOx_CBox.setChecked(NOx) self.gui.pollutantsNMVOCs_CBox.setChecked(NMVOC) self.gui.pollutantsCO2_CBox.setChecked(CO2) self.gui.pollutantsCH4_CBox.setChecked(CH4) self.gui.pollutantsN2O_CBox.setChecked(N2O) self.gui.pollutantsNH3_CBox.setChecked(NH3) self.gui.pollutantsSO2_CBox.setChecked(SO2) self.gui.pollutantsPM25_CBox.setChecked(PM25) self.gui.pollutantsC6H6_CBox.setChecked(C6H6) # add all modification events to notify project modification self.gui.addToOriginaLayer_RButton.toggled.connect( self.saveTabOnProject) self.gui.createNewLayer_RButton.toggled.connect(self.saveTabOnProject) self.gui.outFile_LEdit.returnPressed.connect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionGasoline_CBox.clicked.connect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionDiesel_CBox.clicked.connect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionLPG_CBox.clicked.connect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionNewFuels_CBox.clicked.connect( self.saveTabOnProject) self.gui.totalFuelConsumption_CBox.clicked.connect( self.saveTabOnProject) self.gui.energyConsumption_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCO_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNOx_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNMVOCs_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCO2_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCH4_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsN2O_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNH3_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsSO2_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsPM25_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsC6H6_CBox.clicked.connect(self.saveTabOnProject) # if and output file is specified and it's available => load it if newOutputLayer and os.path.exists(newOutputLayer): # check if layer is already loaded in layer list checking it's source found = False for layerName, layer in QgsMapLayerRegistry.instance().mapLayers( ).items(): if newOutputLayer == layer.publicSource(): # set the found layer as roadLayer self.outLayer = layer self.outLayerId = self.outLayer.id() found = True break if not found: # get layer name to set as public name in the legend layerName = os.path.splitext( os.path.basename(newOutputLayer))[0] # load layer self.outLayer = QgsVectorLayer(newOutputLayer, layerName, 'ogr') if not self.outLayer.isValid(): message = self.tr( "Error loading layer: %s" % self.outLayer.error().message(QgsErrorMessage.Text)) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return self.outLayerId = self.outLayer.id() # show layer in the canvas QgsMapLayerRegistry.instance().addMapLayer(self.outLayer) def saveTabOnProject(self): ''' Save tab configuration in the project basing on GUI values ''' # get values from the GUI addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() Gasoline_Consumption = self.gui.fuelEnergyConsumptionGasoline_CBox.isChecked( ) Diesel_Consumption = self.gui.fuelEnergyConsumptionDiesel_CBox.isChecked( ) LPG_Consumption = self.gui.fuelEnergyConsumptionLPG_CBox.isChecked() NewFuel_Consumption = self.gui.fuelEnergyConsumptionNewFuels_CBox.isChecked( ) Fuel_Consumption_Total = self.gui.totalFuelConsumption_CBox.isChecked() Energy_Consumption = self.gui.energyConsumption_CBox.isChecked() CO = self.gui.pollutantsCO_CBox.isChecked() NOx = self.gui.pollutantsNOx_CBox.isChecked() NMVOC = self.gui.pollutantsNMVOCs_CBox.isChecked() CO2 = self.gui.pollutantsCO2_CBox.isChecked() CH4 = self.gui.pollutantsCH4_CBox.isChecked() N2O = self.gui.pollutantsN2O_CBox.isChecked() NH3 = self.gui.pollutantsNH3_CBox.isChecked() SO2 = self.gui.pollutantsSO2_CBox.isChecked() PM25 = self.gui.pollutantsPM25_CBox.isChecked() C6H6 = self.gui.pollutantsC6H6_CBox.isChecked() # set conf parameters self.project.setValue( 'Processing.OutputFileDefinition/addToInputLayer', int(addToInputLayer)) self.project.setValue('Processing.OutputFileDefinition/newOutputLayer', newOutputLayer) self.project.setValue('Processing.Parameters/Gasoline_Consumption', int(Gasoline_Consumption)) self.project.setValue('Processing.Parameters/Diesel_Consumption', int(Diesel_Consumption)) self.project.setValue('Processing.Parameters/LPG_Consumption', int(LPG_Consumption)) self.project.setValue('Processing.Parameters/NewFuel_Consumption', int(NewFuel_Consumption)) self.project.setValue('Processing.Parameters/Fuel_Consumption_Total', int(Fuel_Consumption_Total)) self.project.setValue('Processing.Parameters/Energy_Consumption', int(Energy_Consumption)) self.project.setValue('Processing.Parameters/CO', int(CO)) self.project.setValue('Processing.Parameters/NOx', int(NOx)) self.project.setValue('Processing.Parameters/NMVOC', int(NMVOC)) self.project.setValue('Processing.Parameters/CO2', int(CO2)) self.project.setValue('Processing.Parameters/CH4', int(CH4)) self.project.setValue('Processing.Parameters/N2O', int(N2O)) self.project.setValue('Processing.Parameters/NH3', int(NH3)) self.project.setValue('Processing.Parameters/SO2', int(SO2)) self.project.setValue('Processing.Parameters/PM', int(PM25)) self.project.setValue('Processing.Parameters/C6H6', int(C6H6)) # notify project modification self.projectModified.emit() def calculate(self): ''' Prepare environment to run the alg and run it. After run, merge produced data basing on plugin configuration. Before calculation a parametere validation will be executed ''' # perform validation if not self.gui.validate(): return else: # notify successful validation message = self.tr( "QTraffic: Parameters validation passed successfully") iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS) # set number of classes in the project config (that is the temporary one... but equal to the official one) fleetDistributionRoadTypes = self.gui.getRoadTypes() self.project.setValue('Processing.Parameters/maximum_type', len(fleetDistributionRoadTypes)) self.project.sync() # create the algorithm self.alg = Algorithm() roadLayer = self.gui.getRoadLayer() # prepare layer where to add result addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if addToInputLayer: self.outLayer = roadLayer self.outLayerId = self.outLayer.id() else: # if layer is present... remove it # out layer would not be the same of input road layer... in thi scase don't remove it if self.outLayer and self.outLayer.isValid(): # to be sure, remove only if roadLayer and outLayer are different if self.outLayer.publicSource() != roadLayer.publicSource(): self.outLayerRemoved = False QgsMapLayerRegistry.instance().layerRemoved.connect( self.checkOutLayerRemoved) QgsMapLayerRegistry.instance().removeMapLayer( self.outLayer.id()) # remove file when it has been removed from qgis while not self.outLayerRemoved: sleep(0.1) QgsMapLayerRegistry.instance().layerRemoved.disconnect( self.checkOutLayerRemoved) # reinit outLayer variables # If not, under windws remain a locking of the related file creating # an error during QgsVectorFileWriter.deleteShapeFile self.outLayer = None self.outLayerId = None if os.path.exists(newOutputLayer): if not QgsVectorFileWriter.deleteShapeFile( newOutputLayer): message = self.tr( "Error removing shape: {}".format( newOutputLayer)) iface.messageBar().pushMessage( message, QgsMessageBar.CRITICAL) return # copy input layer to the new one writeError = QgsVectorFileWriter.writeAsVectorFormat( roadLayer, newOutputLayer, 'utf-8', roadLayer.crs()) if writeError != QgsVectorFileWriter.NoError: message = self.tr( 'Error writing vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # load the layer newLayerName = os.path.splitext( os.path.basename(newOutputLayer))[0] self.outLayer = QgsVectorLayer(newOutputLayer, newLayerName, 'ogr') if not self.outLayer.isValid(): message = self.tr( 'Error loading vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return self.outLayerId = self.outLayer.id() # prepare environment try: self.alg.setProject(self.project) self.alg.setLayer(roadLayer) self.alg.initConfig() self.alg.prepareRun() except Exception as ex: traceback.print_exc() message = self.tr( 'Error preparing running contex for the algoritm: %s' % str(ex)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # run the self.alg self.thread = QtCore.QThread(self) self.thread.started.connect(self.alg.run) self.thread.finished.connect(self.threadCleanup) self.thread.terminated.connect(self.threadCleanup) self.alg.moveToThread(self.thread) self.alg.started.connect(self.manageStarted) self.alg.progress.connect(self.manageProgress) self.alg.message.connect(self.manageMessage) self.alg.error.connect(self.manageError) self.alg.finished.connect(self.manageFinished) # set wait cursor and start QgsApplication.instance().setOverrideCursor(QtCore.Qt.WaitCursor) self.thread.start() def checkOutLayerRemoved(self, layerId): ''' check when outLayer has been removed settign semaphore to True ''' if self.outLayerId == layerId: QgsMessageLog.logMessage('Completly removed outLayer', 'QTraffic', QgsMessageLog.INFO) self.outLayerRemoved = True def threadCleanup(self): ''' cleanup after thread run ''' # restore cursor QgsApplication.instance().restoreOverrideCursor() if self.alg: self.alg.deleteLater() self.alg = None self.thread.wait() self.thread.deleteLater() # remove progress bar if self.progressMessageBarItem: iface.messageBar().popWidget(self.progressMessageBarItem) self.progressMessageBarItem = None def manageStarted(self): ''' Setup GUI env to notify processing progress ''' message = self.tr('Processing started') QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.INFO) # create message bar to show progress self.progressMessageBarItem = iface.messageBar().createMessage( self.tr('Executing alg')) self.progress = QtGui.QProgressBar() self.progress.setMaximum(0) self.progress.setMinimum(0) self.progress.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.progressMessageBarItem.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBarItem, QgsMessageBar.INFO) def manageProgress(self, percentage): ''' Update progress bar basing on alg nofify ''' self.progress.setValue(percentage) def manageMessage(self, message, msgType): ''' expose alg thread messages to gui and log ''' QgsMessageLog.logMessage(message, 'QTraffic', msgType) duration = 0 if msgType == QgsMessageLog.INFO: return if msgType == QgsMessageLog.CRITICAL: msgType = QgsMessageBar.CRITICAL if msgType == QgsMessageLog.WARNING: duration = 3 msgType = QgsMessageBar.WARNING iface.messageBar().pushMessage(message, msgType, duration) def manageError(self, ex, exceptionMessage): ''' Do actions in case of alg thread error. Now only notify exception ''' QgsMessageLog.logMessage(exceptionMessage, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushMessage(exceptionMessage, QgsMessageBar.CRITICAL) def manageFinished(self, success, reason): ''' Do action after notify that alg is finished. These are the postprocessing steps 1) merge result to the output layer 2) add the layer to canvas in case it is new 3) notify edn of processing 4) terminate the thread ''' # finish the thread self.thread.quit() # check result if not success: QgsMessageLog.logMessage('Failed execution: {}'.format(reason), 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical( 'QTraffic', self.tr("Error executing the algorithm: {}".format(reason))) return # prepare result try: self.alg.addResultToLayer(self.outLayer) except Exception as ex: traceback.print_exc() QgsMessageLog.logMessage( 'Cannot add result to layer: {}'.format(str(ex)), 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical( 'QTraffic', self.tr("Cannot add result to layer")) return # add or refresh rsult vector layer addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() if not addToInputLayer: QgsMapLayerRegistry.instance().addMapLayer(self.outLayer) iface.mapCanvas().refresh() # notify the user the end of process iface.messageBar().pushSuccess('QTraffic', self.tr('Alg terminated successfully')) def validate(self): ''' pre calcluation validation related only to this tab Mandatory: At least an output parameters have to be set if "create new layer" a new layer name have to be set ''' addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if (not addToInputLayer and not newOutputLayer): message = self.tr('No output vector specified') iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False Gasoline_Consumption = self.gui.fuelEnergyConsumptionGasoline_CBox.isChecked( ) Diesel_Consumption = self.gui.fuelEnergyConsumptionDiesel_CBox.isChecked( ) LPG_Consumption = self.gui.fuelEnergyConsumptionLPG_CBox.isChecked() NewFuel_Consumption = self.gui.fuelEnergyConsumptionNewFuels_CBox.isChecked( ) Fuel_Consumption_Total = self.gui.totalFuelConsumption_CBox.isChecked() Energy_Consumption = self.gui.energyConsumption_CBox.isChecked() CO = self.gui.pollutantsCO_CBox.isChecked() NOx = self.gui.pollutantsNOx_CBox.isChecked() NMVOC = self.gui.pollutantsNMVOCs_CBox.isChecked() CO2 = self.gui.pollutantsCO2_CBox.isChecked() CH4 = self.gui.pollutantsCH4_CBox.isChecked() N2O = self.gui.pollutantsN2O_CBox.isChecked() NH3 = self.gui.pollutantsNH3_CBox.isChecked() SO2 = self.gui.pollutantsSO2_CBox.isChecked() PM25 = self.gui.pollutantsPM25_CBox.isChecked() C6H6 = self.gui.pollutantsC6H6_CBox.isChecked() if (not Gasoline_Consumption and not Diesel_Consumption and not LPG_Consumption and not NewFuel_Consumption and not Fuel_Consumption_Total and not Energy_Consumption and not CO and not NOx and not NMVOC and not CO2 and not CH4 and not N2O and not NH3 and not SO2 and not PM25 and not C6H6): message = self.tr( "Validation error: At least an output parameter have to be selected" ) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False return True def tr(self, string, context=''): if not context: context = 'QTraffic' return QtCore.QCoreApplication.translate(context, string)
def adding(self, layer_info): """Add a layer to QGIS map canvas. Take layer index, search the required information to add it in the temporary dictionnary constructed in the show_results function. It then adds it. """ # one of many add-on option if layer_info[0] == "index": combobox = self.tbl_result.cellWidget(layer_info[1], 3) layer_label = self.tbl_result.cellWidget(layer_info[1], 0).text() layer_info = combobox.itemData(combobox.currentIndex()) # the only add_on option available elif layer_info[0] == "info": layer_label = self.tbl_result.cellWidget(layer_info[2], 0).text() layer_info = layer_info[1] else: pass self.md_sync.tr = self.tr logger.info( "Adding a layer from those parameters :{}".format(layer_info)) if type(layer_info) == list: # If the layer to be added is a vector file if layer_info[0] == "vector": path = layer_info[1] name = os.path.basename(path).split(".")[0] layer = QgsVectorLayer(path, layer_label, "ogr") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) try: QgsMessageLog.logMessage( message="Data layer added: {}".format(name), tag="Isogeo", level=0, ) logger.debug("Vector layer added: {}".format(path)) except UnicodeEncodeError: QgsMessageLog.logMessage( message="Vector layer added:: {}".format( name.decode("latin1")), tag="Isogeo", level=0, ) logger.debug("Vector layer added: {}".format( name.decode("latin1"))) else: error_msg = layer.error().message() logger.warning( "Invalid vector layer: {}. QGIS says: {}".format( path, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "Vector not valid {}. QGIS says: {}", context=__class__.__name__, ).format(path, error_msg), ) # If raster file elif layer_info[0] == "raster": path = layer_info[1] name = os.path.basename(path).split(".")[0] layer = QgsRasterLayer(path, layer_label) if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) try: QgsMessageLog.logMessage( message="Data layer added: {}".format(name), tag="Isogeo", level=0, ) logger.debug("Raster layer added: {}".format(path)) except UnicodeEncodeError: QgsMessageLog.logMessage( message="Raster layer added:: {}".format( name.decode("latin1")), tag="Isogeo", level=0, ) logger.debug("Raster layer added: {}".format( name.decode("latin1"))) else: error_msg = layer.error().message() logger.warning( "Invalid raster layer: {}. QGIS says: {}".format( path, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "Raster not valid {}. QGIS says: {}", context=__class__.__name__, ).format(path, error_msg), ) # If EFS link elif layer_info[0] == "EFS": name = layer_info[1] uri = layer_info[2] layer = QgsVectorLayer(uri, layer_label, "arcgisfeatureserver") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("EFS layer added: {}".format(uri)) else: error_msg = layer.error().message() logger.warning("Invalid service: {}. QGIS says: {}".format( uri, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr("EFS not valid. QGIS says: {}", context=__class__.__name__).format(error_msg), ) # If EMS link elif layer_info[0] == "EMS": name = layer_info[1] uri = layer_info[2] layer = QgsRasterLayer(uri, layer_label, "arcgismapserver") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("EMS layer added: {}".format(uri)) else: error_msg = layer.error().message() logger.warning("Invalid service: {}. QGIS says: {}".format( uri, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr("EMS not valid. QGIS says: {}", context=__class__.__name__).format(error_msg), ) # If WFS link elif layer_info[0] == "WFS": url = layer_info[2] name = layer_info[1] layer = QgsVectorLayer(url, layer_label, "WFS") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WFS layer added: {}".format(url)) else: error_msg = layer.error().message() name_url = self.build_wfs_url(layer_info[3], layer_info[4], mode="complete") if name_url[0] != 0: layer = QgsVectorLayer(name_url[2], layer_label, "WFS") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WFS layer added: {}".format(url)) else: error_msg = layer.error().message() logger.warning( "Invalid service: {}. QGIS says: {}".format( url, error_msg)) else: QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "WFS is not valid. QGIS says: {}", context=__class__.__name__, ).format(error_msg), ) pass # If WMS link elif layer_info[0] == "WMS": url = layer_info[2] name = layer_info[1] layer = QgsRasterLayer(url, layer_label, "wms") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WMS layer added: {}".format(url)) else: error_msg = layer.error().message() name_url = self.build_wms_url(layer_info[3], layer_info[4], mode="complete") if name_url[0] != 0: layer = QgsRasterLayer(name_url[2], layer_label, "wms") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WMS layer added: {}".format(url)) else: error_msg = layer.error().message() logger.warning( "Invalid service: {}. QGIS says: {}".format( url, error_msg)) else: QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "WMS is not valid. QGIS says: {}", context=__class__.__name__, ).format(error_msg), ) # If WMTS link elif layer_info[0] == "WMTS": url = layer_info[2] name = layer_info[1] layer = QgsRasterLayer(url, layer_label, "wms") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WMTS service layer added: {}".format(url)) else: error_msg = layer.error().message() logger.warning("Invalid service: {}. QGIS says: {}".format( url, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "WMTS is not valid. QGIS says: {}", context=__class__.__name__, ).format(error_msg), ) else: pass # If the data is a PostGIS table elif isinstance(layer_info, dict): logger.debug("Data type: PostGIS") # Give aliases to the data passed as arguement base_name = layer_info.get("base_name", "") schema = layer_info.get("schema", "") table = layer_info.get("table", "") # Retrieve the database information stored in the PostGISdict uri = QgsDataSourceUri() host = self.PostGISdict[base_name]["host"] port = self.PostGISdict[base_name]["port"] user = self.PostGISdict[base_name]["username"] password = self.PostGISdict[base_name]["password"] # set host name, port, database name, username and password uri.setConnection(host, port, base_name, user, password) # Get the geometry column name from the database connexion & table # name. c = pgis_con.PostGisDBConnector(uri) dico = c.getTables() for i in dico: if i[0 == 1] and i[1] == table: geometry_column = i[8] # set database schema, table name, geometry column uri.setDataSource(schema, table, geometry_column) # Adding the layer to the map canvas layer = QgsVectorLayer(uri.uri(), table, "postgres") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("Data added: {}".format(table)) elif (not layer.isValid() and plg_tools.last_error[0] == "postgis" and "prim" in plg_tools.last_error[1]): logger.debug("PostGIS layer may be a view, " "so key column is missing. " "Trying to automatically set one...") # get layer fields to set as key column fields = layer.dataProvider().fields() fields_names = [i.name() for i in fields] # sort them by name containing id to better perf fields_names.sort(key=lambda x: ("id" not in x, x)) for field in fields_names: uri.setKeyColumn(field) layer = QgsVectorLayer(uri.uri(True), table, "postgres") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug( "PostGIS view layer added with [{}] as key column". format(field)) # filling 'QGIS Server' tab of layer Properties self.md_sync.basic_sync(layer=lyr, info=layer_info) return 1 else: continue else: logger.debug("Layer not valid. table = {}".format(table)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "The PostGIS layer is not valid." " Reason: {}", context=__class__.__name__, ).format(plg_tools.last_error), ) return 0 # filling 'QGIS Server' tab of layer Properties if layer.isValid(): try: self.md_sync.basic_sync(layer=lyr, info=layer_info) except IndexError as e: logger.debug( "Not supported 'layer_info' format causes this error : {}". format(e)) else: pass return 1
class OutputTabManager(QtCore.QObject): ''' Class to hide managing of relative tab ''' projectModified = QtCore.pyqtSignal() def __init__(self, parent=None): '''constructor''' super(OutputTabManager, self).__init__(parent) # parent is the dock widget with all graphical elements self.gui = parent self.plugin = parent.parent # init some globals self.applicationPath = os.path.dirname(os.path.realpath(__file__)) self.project = None self.projectPath = None self.outLayer = None self.outLayerId = None self.outLayerRemoved = False # retrieve the current tab index self.initTabTabIndex() # disable tab at the beginning self.gui.tabWidget.setTabEnabled(self.tabIndex, False) # add some gui events self.gui.createNewLayer_RButton.toggled.connect(self.setInputLayer) self.gui.selectOutfile_TButton.clicked.connect(self.selectNewOutFile) self.gui.calculate_PButton.clicked.connect(self.calculate) def initTabTabIndex(self): ''' Retrieve what tab index refer the current tab manager ''' for tabIndex in range(self.gui.tabWidget.count()): if self.gui.tabWidget.tabText(tabIndex) == "Output": self.tabIndex = tabIndex def setProject(self, project=None): ''' setting the new project on which the tab is based ''' self.project = project if self.project: # write everything on disk self.project.sync() # set some globals confFileName = self.project.fileName() self.projectPath = os.path.dirname(confFileName) # emit configurationLoaded with the status of loading self.setTabGUIBasingOnProject() # enable current tab because project has been loaded self.gui.tabWidget.setTabEnabled(self.tabIndex, True) else: # disable current tab because no project has been loaded yet self.gui.tabWidget.setTabEnabled(self.tabIndex, False) def selectNewOutFile(self): ''' Select the the file ''' oldOutputLayer = self.gui.outFile_LEdit.text() # get last conf to start from its path startPath = self.projectPath newOutputLayer = self.project.value('Processing.OutputFileDefinition/newOutputLayer', '') if newOutputLayer: startPath = os.path.dirname( newOutputLayer ) # ask for the new out file newOutputLayer = QtGui.QFileDialog.getSaveFileName(self.gui, "Select an autput file", startPath, self.plugin.tr("All (*)")) if not newOutputLayer: return if oldOutputLayer == newOutputLayer: return # add shp extension components = os.path.splitext(newOutputLayer) if len(components) == 1: newOutputLayer = newOutputLayer + '.shp' else: if components[1] != '.shp': newOutputLayer = components[0] + '.shp' # update gui self.gui.outFile_LEdit.setText(newOutputLayer) self.saveTabOnProject() def setInputLayer(self): ''' Set GUI basing on toggled ComboBox to set if the layer is the input one or have to select a new one ''' self.gui.outFile_LEdit.setEnabled( self.gui.createNewLayer_RButton.isChecked() ) self.gui.selectOutfile_TButton.setEnabled( self.gui.createNewLayer_RButton.isChecked() ) def setTabGUIBasingOnProject(self): '''Set tab basing on project conf ''' if not self.project: return # get conf parameters addToInputLayer = self.project.value('Processing.OutputFileDefinition/addToInputLayer', False, bool) newOutputLayer = self.project.value('Processing.OutputFileDefinition/newOutputLayer', '') Gasoline_Consumption = self.project.value('Processing.Parameters/Gasoline_Consumption', False, bool) Diesel_Consumption = self.project.value('Processing.Parameters/Diesel_Consumption', False, bool) LPG_Consumption = self.project.value('Processing.Parameters/LPG_Consumption', False, bool) NewFuel_Consumption = self.project.value('Processing.Parameters/NewFuel_Consumption', False, bool) Fuel_Consumption_Total = self.project.value('Processing.Parameters/Fuel_Consumption_Total', False, bool) Energy_Consumption = self.project.value('Processing.Parameters/Energy_Consumption', False, bool) CO = self.project.value('Processing.Parameters/CO', False, bool) NOx = self.project.value('Processing.Parameters/NOx', False, bool) NMVOC = self.project.value('Processing.Parameters/NMVOC', False, bool) CO2 = self.project.value('Processing.Parameters/CO2', False, bool) CH4 = self.project.value('Processing.Parameters/CH4', False, bool) N2O = self.project.value('Processing.Parameters/N2O', False, bool) NH3 = self.project.value('Processing.Parameters/NH3', False, bool) SO2 = self.project.value('Processing.Parameters/SO2', False, bool) PM25 = self.project.value('Processing.Parameters/PM', False, bool) C6H6 = self.project.value('Processing.Parameters/C6H6', False, bool) # avoid emitting signal in case of reset of indexes try: # to avoid add multiple listener, remove previous listener self.gui.addToOriginaLayer_RButton.toggled.disconnect(self.saveTabOnProject) self.gui.createNewLayer_RButton.toggled.disconnect(self.saveTabOnProject) self.gui.outFile_LEdit.returnPressed.disconnect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionGasoline_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionDiesel_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionLPG_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionNewFuels_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.totalFuelConsumption_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.energyConsumption_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsCO_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsNOx_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsNMVOCs_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsCO2_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsCH4_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsN2O_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsNH3_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsSO2_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsPM25_CBox.clicked.disconnect(self.saveTabOnProject) self.gui.pollutantsC6H6_CBox.clicked.disconnect(self.saveTabOnProject) except (Exception) as ex: pass # now populate interface self.gui.addToOriginaLayer_RButton.setChecked( addToInputLayer ) self.gui.createNewLayer_RButton.setChecked( not addToInputLayer ) self.gui.outFile_LEdit.setText( newOutputLayer ) self.gui.fuelEnergyConsumptionGasoline_CBox.setChecked( Gasoline_Consumption ) self.gui.fuelEnergyConsumptionDiesel_CBox.setChecked( Diesel_Consumption ) self.gui.fuelEnergyConsumptionLPG_CBox.setChecked( LPG_Consumption ) self.gui.fuelEnergyConsumptionNewFuels_CBox.setChecked( NewFuel_Consumption ) self.gui.totalFuelConsumption_CBox.setChecked( Fuel_Consumption_Total ) self.gui.energyConsumption_CBox.setChecked( Energy_Consumption ) self.gui.pollutantsCO_CBox.setChecked( CO ) self.gui.pollutantsNOx_CBox.setChecked( NOx ) self.gui.pollutantsNMVOCs_CBox.setChecked( NMVOC ) self.gui.pollutantsCO2_CBox.setChecked( CO2 ) self.gui.pollutantsCH4_CBox.setChecked( CH4 ) self.gui.pollutantsN2O_CBox.setChecked( N2O ) self.gui.pollutantsNH3_CBox.setChecked( NH3 ) self.gui.pollutantsSO2_CBox.setChecked( SO2 ) self.gui.pollutantsPM25_CBox.setChecked( PM25 ) self.gui.pollutantsC6H6_CBox.setChecked( C6H6 ) # add all modification events to notify project modification self.gui.addToOriginaLayer_RButton.toggled.connect(self.saveTabOnProject) self.gui.createNewLayer_RButton.toggled.connect(self.saveTabOnProject) self.gui.outFile_LEdit.returnPressed.connect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionGasoline_CBox.clicked.connect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionDiesel_CBox.clicked.connect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionLPG_CBox.clicked.connect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionNewFuels_CBox.clicked.connect(self.saveTabOnProject) self.gui.totalFuelConsumption_CBox.clicked.connect(self.saveTabOnProject) self.gui.energyConsumption_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCO_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNOx_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNMVOCs_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCO2_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCH4_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsN2O_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNH3_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsSO2_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsPM25_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsC6H6_CBox.clicked.connect(self.saveTabOnProject) # if and output file is specified and it's available => load it if newOutputLayer and os.path.exists(newOutputLayer): # check if layer is already loaded in layer list checking it's source found = False for layerName, layer in QgsMapLayerRegistry.instance().mapLayers().items(): if newOutputLayer == layer.publicSource(): # set the found layer as roadLayer self.outLayer = layer self.outLayerId = self.outLayer.id() found = True break if not found: # get layer name to set as public name in the legend layerName = os.path.splitext( os.path.basename(newOutputLayer) )[0] # load layer self.outLayer = QgsVectorLayer(newOutputLayer, layerName, 'ogr') if not self.outLayer.isValid(): message = self.tr("Error loading layer: %s" % self.outLayer.error().message(QgsErrorMessage.Text)) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return self.outLayerId = self.outLayer.id() # show layer in the canvas QgsMapLayerRegistry.instance().addMapLayer(self.outLayer) def saveTabOnProject(self): ''' Save tab configuration in the project basing on GUI values ''' # get values from the GUI addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() Gasoline_Consumption = self.gui.fuelEnergyConsumptionGasoline_CBox.isChecked() Diesel_Consumption = self.gui.fuelEnergyConsumptionDiesel_CBox.isChecked() LPG_Consumption = self.gui.fuelEnergyConsumptionLPG_CBox.isChecked() NewFuel_Consumption = self.gui.fuelEnergyConsumptionNewFuels_CBox.isChecked() Fuel_Consumption_Total = self.gui.totalFuelConsumption_CBox.isChecked() Energy_Consumption = self.gui.energyConsumption_CBox.isChecked() CO = self.gui.pollutantsCO_CBox.isChecked() NOx = self.gui.pollutantsNOx_CBox.isChecked() NMVOC = self.gui.pollutantsNMVOCs_CBox.isChecked() CO2 = self.gui.pollutantsCO2_CBox.isChecked() CH4 = self.gui.pollutantsCH4_CBox.isChecked() N2O = self.gui.pollutantsN2O_CBox.isChecked() NH3 = self.gui.pollutantsNH3_CBox.isChecked() SO2 = self.gui.pollutantsSO2_CBox.isChecked() PM25 = self.gui.pollutantsPM25_CBox.isChecked() C6H6 = self.gui.pollutantsC6H6_CBox.isChecked() # set conf parameters self.project.setValue('Processing.OutputFileDefinition/addToInputLayer', int(addToInputLayer)) self.project.setValue('Processing.OutputFileDefinition/newOutputLayer', newOutputLayer) self.project.setValue('Processing.Parameters/Gasoline_Consumption', int(Gasoline_Consumption)) self.project.setValue('Processing.Parameters/Diesel_Consumption', int(Diesel_Consumption)) self.project.setValue('Processing.Parameters/LPG_Consumption', int(LPG_Consumption)) self.project.setValue('Processing.Parameters/NewFuel_Consumption', int(NewFuel_Consumption)) self.project.setValue('Processing.Parameters/Fuel_Consumption_Total', int(Fuel_Consumption_Total)) self.project.setValue('Processing.Parameters/Energy_Consumption', int(Energy_Consumption)) self.project.setValue('Processing.Parameters/CO', int(CO)) self.project.setValue('Processing.Parameters/NOx', int(NOx)) self.project.setValue('Processing.Parameters/NMVOC', int(NMVOC)) self.project.setValue('Processing.Parameters/CO2', int(CO2)) self.project.setValue('Processing.Parameters/CH4', int(CH4)) self.project.setValue('Processing.Parameters/N2O', int(N2O)) self.project.setValue('Processing.Parameters/NH3', int(NH3)) self.project.setValue('Processing.Parameters/SO2', int(SO2)) self.project.setValue('Processing.Parameters/PM', int(PM25)) self.project.setValue('Processing.Parameters/C6H6', int(C6H6)) # notify project modification self.projectModified.emit() def calculate(self): ''' Prepare environment to run the alg and run it. After run, merge produced data basing on plugin configuration. Before calculation a parametere validation will be executed ''' # perform validation if not self.gui.validate(): return else: # notify successful validation message = self.tr("QTraffic: Parameters validation passed successfully") iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS) # set number of classes in the project config (that is the temporary one... but equal to the official one) fleetDistributionRoadTypes = self.gui.getRoadTypes() self.project.setValue('Processing.Parameters/maximum_type', len(fleetDistributionRoadTypes)) self.project.sync() # create the algorithm self.alg = Algorithm() roadLayer = self.gui.getRoadLayer() # prepare layer where to add result addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if addToInputLayer: self.outLayer = roadLayer self.outLayerId = self.outLayer.id() else: # if layer is present... remove it # out layer would not be the same of input road layer... in thi scase don't remove it if self.outLayer and self.outLayer.isValid(): # to be sure, remove only if roadLayer and outLayer are different if self.outLayer.publicSource() != roadLayer.publicSource(): self.outLayerRemoved = False QgsMapLayerRegistry.instance().layerRemoved.connect(self.checkOutLayerRemoved) QgsMapLayerRegistry.instance().removeMapLayer(self.outLayer.id()) # remove file when it has been removed from qgis while not self.outLayerRemoved: sleep(0.1) QgsMapLayerRegistry.instance().layerRemoved.disconnect(self.checkOutLayerRemoved) # reinit outLayer variables # If not, under windws remain a locking of the related file creating # an error during QgsVectorFileWriter.deleteShapeFile self.outLayer = None self.outLayerId = None if os.path.exists(newOutputLayer): if not QgsVectorFileWriter.deleteShapeFile(newOutputLayer): message = self.tr("Error removing shape: {}".format(newOutputLayer)) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return # copy input layer to the new one writeError = QgsVectorFileWriter.writeAsVectorFormat(roadLayer, newOutputLayer, 'utf-8', roadLayer.crs()) if writeError != QgsVectorFileWriter.NoError: message = self.tr('Error writing vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # load the layer newLayerName =os.path.splitext(os.path.basename( newOutputLayer ))[0] self.outLayer = QgsVectorLayer(newOutputLayer, newLayerName, 'ogr') if not self.outLayer.isValid(): message = self.tr('Error loading vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return self.outLayerId = self.outLayer.id() # prepare environment try: self.alg.setProject(self.project) self.alg.setLayer( roadLayer ) self.alg.initConfig() self.alg.prepareRun() except Exception as ex: traceback.print_exc() message = self.tr('Error preparing running contex for the algoritm: %s' % str(ex)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # run the self.alg self.thread = QtCore.QThread(self) self.thread.started.connect(self.alg.run) self.thread.finished.connect(self.threadCleanup) self.thread.terminated.connect(self.threadCleanup) self.alg.moveToThread(self.thread) self.alg.started.connect(self.manageStarted) self.alg.progress.connect(self.manageProgress) self.alg.message.connect(self.manageMessage) self.alg.error.connect(self.manageError) self.alg.finished.connect(self.manageFinished) # set wait cursor and start QgsApplication.instance().setOverrideCursor(QtCore.Qt.WaitCursor) self.thread.start() def checkOutLayerRemoved(self, layerId): ''' check when outLayer has been removed settign semaphore to True ''' if self.outLayerId == layerId: QgsMessageLog.logMessage('Completly removed outLayer', 'QTraffic', QgsMessageLog.INFO) self.outLayerRemoved = True def threadCleanup(self): ''' cleanup after thread run ''' # restore cursor QgsApplication.instance().restoreOverrideCursor() if self.alg: self.alg.deleteLater() self.alg = None self.thread.wait() self.thread.deleteLater() # remove progress bar if self.progressMessageBarItem: iface.messageBar().popWidget(self.progressMessageBarItem) self.progressMessageBarItem = None def manageStarted(self): ''' Setup GUI env to notify processing progress ''' message = self.tr('Processing started') QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.INFO) # create message bar to show progress self.progressMessageBarItem = iface.messageBar().createMessage(self.tr('Executing alg')) self.progress = QtGui.QProgressBar() self.progress.setMaximum(0) self.progress.setMinimum(0) self.progress.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.progressMessageBarItem.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBarItem, QgsMessageBar.INFO) def manageProgress(self, percentage): ''' Update progress bar basing on alg nofify ''' self.progress.setValue(percentage) def manageMessage(self, message, msgType): ''' expose alg thread messages to gui and log ''' QgsMessageLog.logMessage(message, 'QTraffic', msgType) duration = 0 if msgType == QgsMessageLog.INFO: return if msgType == QgsMessageLog.CRITICAL: msgType = QgsMessageBar.CRITICAL if msgType == QgsMessageLog.WARNING: duration = 3 msgType = QgsMessageBar.WARNING iface.messageBar().pushMessage(message, msgType, duration) def manageError(self, ex, exceptionMessage): ''' Do actions in case of alg thread error. Now only notify exception ''' QgsMessageLog.logMessage(exceptionMessage, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushMessage(exceptionMessage, QgsMessageBar.CRITICAL) def manageFinished(self, success, reason): ''' Do action after notify that alg is finished. These are the postprocessing steps 1) merge result to the output layer 2) add the layer to canvas in case it is new 3) notify edn of processing 4) terminate the thread ''' # finish the thread self.thread.quit() # check result if not success: QgsMessageLog.logMessage('Failed execution: {}'.format(reason), 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', self.tr("Error executing the algorithm: {}".format(reason))) return # prepare result try: self.alg.addResultToLayer(self.outLayer) except Exception as ex: traceback.print_exc() QgsMessageLog.logMessage('Cannot add result to layer: {}'.format(str(ex)), 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', self.tr("Cannot add result to layer")) return # add or refresh rsult vector layer addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() if not addToInputLayer: QgsMapLayerRegistry.instance().addMapLayer(self.outLayer) iface.mapCanvas().refresh() # notify the user the end of process iface.messageBar().pushSuccess('QTraffic', self.tr('Alg terminated successfully')) def validate(self): ''' pre calcluation validation related only to this tab Mandatory: At least an output parameters have to be set if "create new layer" a new layer name have to be set ''' addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if (not addToInputLayer and not newOutputLayer): message = self.tr('No output vector specified') iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False Gasoline_Consumption = self.gui.fuelEnergyConsumptionGasoline_CBox.isChecked() Diesel_Consumption = self.gui.fuelEnergyConsumptionDiesel_CBox.isChecked() LPG_Consumption = self.gui.fuelEnergyConsumptionLPG_CBox.isChecked() NewFuel_Consumption = self.gui.fuelEnergyConsumptionNewFuels_CBox.isChecked() Fuel_Consumption_Total = self.gui.totalFuelConsumption_CBox.isChecked() Energy_Consumption = self.gui.energyConsumption_CBox.isChecked() CO = self.gui.pollutantsCO_CBox.isChecked() NOx = self.gui.pollutantsNOx_CBox.isChecked() NMVOC = self.gui.pollutantsNMVOCs_CBox.isChecked() CO2 = self.gui.pollutantsCO2_CBox.isChecked() CH4 = self.gui.pollutantsCH4_CBox.isChecked() N2O = self.gui.pollutantsN2O_CBox.isChecked() NH3 = self.gui.pollutantsNH3_CBox.isChecked() SO2 = self.gui.pollutantsSO2_CBox.isChecked() PM25 = self.gui.pollutantsPM25_CBox.isChecked() C6H6 = self.gui.pollutantsC6H6_CBox.isChecked() if (not Gasoline_Consumption and not Diesel_Consumption and not LPG_Consumption and not NewFuel_Consumption and not Fuel_Consumption_Total and not Energy_Consumption and not CO and not NOx and not NMVOC and not CO2 and not CH4 and not N2O and not NH3 and not SO2 and not PM25 and not C6H6 ): message = self.tr("Validation error: At least an output parameter have to be selected") iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False return True def tr(self, string, context=''): if not context: context = 'QTraffic' return QtCore.QCoreApplication.translate(context, string)
def loadLayer(self): self.registry.setCrs(QgsCoordinateReferenceSystem(4326)) uri = "http://200.121.128.102:8080/geoserver/avp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=avp:vm_cofopri" uri2 = "http://200.121.128.102:8080/geoserver/avp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=avp:vm_comunidades_campesinas" uri3 = "http://200.121.128.102:8080/geoserver/avp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=avp:vm_predio_matriz" uri4 = "http://200.121.128.102:8080/geoserver/avp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=avp:vm_predio_rural" uri5 = "http://200.121.128.102:8080/geoserver/avp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=avp:vm_sitios_arqueologicos" uri6 = "http://200.121.128.102:8080/geoserver/avp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=avp:vm_sunarp_lima_psad56" uri7 = "http://200.121.128.102:8080/geoserver/avp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=avp:vm_sunarp_lima_wgs84" val = len(QgsProject.instance().mapLayersByName("Cofopri AVP")) val2 = len(QgsProject.instance().mapLayersByName("Comunidades Campesinas AVP")) val4 = len(QgsProject.instance().mapLayersByName("Predio Matriz AVP")) val5 = len(QgsProject.instance().mapLayersByName("Predio Rural AVP")) val6 = len(QgsProject.instance().mapLayersByName("Sitios Arqueologicos AVP")) val3 = len(QgsProject.instance().mapLayersByName("Anillo Vial")) val7 = len(QgsProject.instance().mapLayersByName("Sunarp Lima PSAD56 AVP")) val8 = len(QgsProject.instance().mapLayersByName("Sunarp Lima WGS84 AVP")) #verificando conexion a internet self.internet_on(uri) if val2 == 0 : vlayer = QgsVectorLayer(uri2, "Comunidades Campesinas AVP", "WFS") writer = QgsVectorFileWriter.writeAsVectorFormat(vlayer, os.path.dirname(__file__) + '/data/comunidades_campesinas_avp.geojson', "UTF-8", vlayer.crs(), "GeoJSON") #verificando algun error if writer[0] == QgsVectorFileWriter.NoError: print ("success!") self.iface.messageBar().pushMessage("Capa",'Conectando al WFS', Qgis.Info) capa = QgsVectorLayer(os.path.dirname(__file__) + '/data/comunidades_campesinas_avp.geojson',"Comunidades Campesinas AVP","ogr") self.registry.addMapLayer(capa) else: print (writer[1]) if val == 0 : vlayer = QgsVectorLayer(uri, "Cofopri AVP", "WFS") writer = QgsVectorFileWriter.writeAsVectorFormat(vlayer, os.path.dirname(__file__) + "/data/cofopri_avp.geojson", "UTF-8", vlayer.crs(), "GeoJSON") #verificando algun error if writer[0] == QgsVectorFileWriter.NoError: print ("success!") self.iface.messageBar().pushMessage("Capa",'Conectando al WFS', Qgis.Info) capa = QgsVectorLayer(os.path.dirname(__file__) + "/data/cofopri_avp.geojson","Cofopri AVP","ogr") #capa.loadSldStyle(os.path.dirname(__file__) + "/styles/style.sld") #capa.triggerRepaint() self.registry.addMapLayer(capa) else: print (writer[1]) if val4 == 0 : vlayer = QgsVectorLayer(uri3, "Predio Matriz AVP", "WFS") writer = QgsVectorFileWriter.writeAsVectorFormat(vlayer, os.path.dirname(__file__) + "/data/predio_matriz_avp.geojson", "UTF-8", vlayer.crs(), "GeoJSON") #verificando algun error if writer[0] == QgsVectorFileWriter.NoError: print ("success!") self.iface.messageBar().pushMessage("Capa",'Conectando al WFS', Qgis.Info) capa = QgsVectorLayer(os.path.dirname(__file__) + "/data/predio_matriz_avp.geojson","Predio Matriz AVP","ogr") #capa.loadSldStyle(os.path.dirname(__file__) + "/styles/style.sld") #capa.triggerRepaint() self.registry.addMapLayer(capa) else: print (writer[1]) if val5 == 0 : vlayer = QgsVectorLayer(uri4, "Predio Rural AVP", "WFS") writer = QgsVectorFileWriter.writeAsVectorFormat(vlayer, os.path.dirname(__file__) + "/data/predio_rural_avp.geojson", "UTF-8", vlayer.crs(), "GeoJSON") #verificando algun error if writer[0] == QgsVectorFileWriter.NoError: print ("success!") self.iface.messageBar().pushMessage("Capa",'Conectando al WFS', Qgis.Info) capa = QgsVectorLayer(os.path.dirname(__file__) + "/data/predio_rural_avp.geojson","Predio Rural AVP","ogr") #capa.loadSldStyle(os.path.dirname(__file__) + "/styles/style.sld") #capa.triggerRepaint() self.registry.addMapLayer(capa) else: print (writer[1]) if val6 == 0 : vlayer = QgsVectorLayer(uri5, "Sitios Arqueologicos AVP", "WFS") writer = QgsVectorFileWriter.writeAsVectorFormat(vlayer, os.path.dirname(__file__) + "/data/sitios_arqueologicos_avp.geojson", "UTF-8", vlayer.crs(), "GeoJSON") #verificando algun error if writer[0] == QgsVectorFileWriter.NoError: print ("success!") self.iface.messageBar().pushMessage("Capa",'Conectando al WFS', Qgis.Info) capa = QgsVectorLayer(os.path.dirname(__file__) + "/data/sitios_arqueologicos_avp.geojson","Sitios Arqueologicos AVP","ogr") #capa.loadSldStyle(os.path.dirname(__file__) + "/styles/style.sld") #capa.triggerRepaint() self.registry.addMapLayer(capa) else: print (writer[1]) if val7 == 0 : vlayer = QgsVectorLayer(uri6, "Sunarp Lima PSAD56 AVP", "WFS") writer = QgsVectorFileWriter.writeAsVectorFormat(vlayer, os.path.dirname(__file__) + "/data/sunarp_lima_psad56_avp.geojson", "UTF-8", vlayer.crs(), "GeoJSON") #verificando algun error if writer[0] == QgsVectorFileWriter.NoError: print ("success!") self.iface.messageBar().pushMessage("Capa",'Conectando al WFS', Qgis.Info) capa = QgsVectorLayer(os.path.dirname(__file__) + "/data/sunarp_lima_psad56_avp.geojson","Sunarp Lima PSAD56 AVP","ogr") #capa.loadSldStyle(os.path.dirname(__file__) + "/styles/style.sld") #capa.triggerRepaint() self.registry.addMapLayer(capa) else: print (writer[1]) if val8 == 0 : vlayer = QgsVectorLayer(uri7, "Sunarp Lima WGS84 AVP", "WFS") writer = QgsVectorFileWriter.writeAsVectorFormat(vlayer, os.path.dirname(__file__) + "/data/sunarp_lima_wgs84_avp.geojson", "UTF-8", vlayer.crs(), "GeoJSON") #verificando algun error if writer[0] == QgsVectorFileWriter.NoError: print ("success!") self.iface.messageBar().pushMessage("Capa",'Conectando al WFS', Qgis.Info) capa = QgsVectorLayer(os.path.dirname(__file__) + "/data/sunarp_lima_wgs84_avp.geojson","Sunarp Lima WGS84 AVP","ogr") #capa.loadSldStyle(os.path.dirname(__file__) + "/styles/style.sld") #capa.triggerRepaint() self.registry.addMapLayer(capa) else: print (writer[1]) if val3 == 0 : urlWithParams = "crs=EPSG:4326&dpiMode=7&format=image/png&layers=anillovial&styles&url=http://200.121.128.102:8080/geoserver/ddp/wms" vlayer = QgsRasterLayer(urlWithParams, 'Anillo Vial', 'wms') self.registry.addMapLayer(vlayer) if vlayer.isValid(): self.iface.messageBar().pushMessage("Capa",'Conectando al WMS', Qgis.Info) QMessageBox.information(self.iface.mainWindow(), "Mensaje", 'Su descarga fue satisfactorio') else: self.iface.messageBar().pushMessage("Error", vlayer.error().message(), level=Qgis.Critical)