def crs_text_element(crs, feature, parent): """Retrieve coordinate reference system text string from definitions. Example usage: crs_text_element('EPSG:3857'). """ _ = feature, parent # NOQA crs_definition = QgsCoordinateReferenceSystem(crs) crs_description = crs_definition.description() text = crs_text['string_format'].format(crs=crs_description) return text
def crs_text_element(crs, feature, parent): """Retrieve coordinate reference system text string from definitions. Example usage: crs_text_element('EPSG:3857'). """ _ = feature, parent # NOQA crs_definition = QgsCoordinateReferenceSystem(crs) crs_description = crs_definition.description() text = crs_text['string_format'].format(crs=crs_description) return text
def setDatabase(self, index): self.activeDatabase.setCurrentIndex(index) if self.activeDatabase.currentText(): self.proj.writeEntry("QGYF", "activeDataBase", self.activeDatabase.currentText()) crs_id = self.getCRS( self.proj.readEntry("QGYF", "activeDataBase")[0]) self.proj.writeEntry("QGYF", "CRS", crs_id) crs = QgsCoordinateReferenceSystem(int(float(crs_id))) self.crs.setText(crs.description()) else: self.proj.writeEntry("QGYF", "activeDataBase", 'qgyf.sqlite')
def on_srsButton_clicked(self): projSelector = QgsGenericProjectionSelector() message = self.tr('Select the Spatial Reference System!') projSelector.setMessage(theMessage=message) if not projSelector.exec_(): QMessageBox.warning(self, self.tr("Warning!"), message) return else: self.epsg = int(projSelector.selectedAuthId().split(':')[-1]) srs = QgsCoordinateReferenceSystem( self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) self.srLineEdit.setText(srs.description())
def on_srsButton_clicked(self): ''' Opens the dialog to select CRS ''' projSelector = QgsGenericProjectionSelector() message = self.tr('Select the Spatial Reference System!') projSelector.setMessage(theMessage=message) if not projSelector.exec_(): QMessageBox.warning(self, self.tr("Warning!"), message) return else: self.epsg = int(projSelector.selectedAuthId().split(':')[-1]) srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) self.srLineEdit.setText(srs.description())
def on_srsButton_clicked(self): projSelector = QgsGenericProjectionSelector() message = 'Select the Spatial Reference System!' projSelector.setMessage(theMessage=message) projSelector.exec_() try: self.epsg = int(projSelector.selectedAuthId().split(':')[-1]) srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if srs: self.srsEdit.setText(srs.description()) else: self.epsg = 4326 except: QMessageBox.warning(self, self.tr("Warning!"), self.tr(message))
def __init__(self, iface): """Constructor.""" super(ProcessingTools, self).__init__() # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface self.tabWidget.removeTab(1) self.epsg = 4326 srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) self.srLineEdit.setText(srs.description())
def __init__(self, iface): """Constructor.""" super(ProcessingTools, self).__init__() # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface self.tabWidget.removeTab(1) self.epsg = 4326 srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) self.srLineEdit.setText(srs.description())
def init(self, config): # called from tool try: self.debug = config.get('debug', False) if self.debug: self.info.log("init") #status self.layer = self.iface.activeLayer() self.prj = QgsProject.instance() self.cboCoordSystems.clear() # tooldata self.coords = config.get('coordinatereferences', self.coords) self.pointScale = config.get('point_scale', self.pointScale) self.buffer_scale = config.get("buffer_scale", self.buffer_scale) self.minimum_scale = config.get("minimum_scale", self.minimum_scale) if not self.coords: self.cboCoordSystems.setHidden(True) self.projectWid.setHidden(False) self.projectWid.setCrs(self.prj.crs()) cbos = self.projectWid.findChildren(QComboBox) for cbo in cbos: cbo.setMaximumHeight(self.iface.iconSize().height()) else: self.projectWid.setHidden(True) self.cboCoordSystems.setHidden(False) crs = self.prj.crs() self.cboCoordSystems.addItem( "Project CRS: " + crs.authid() + " - " + crs.description(), crs) for crsID in self.coords: try: crs = QgsCoordinateReferenceSystem(crsID) self.cboCoordSystems.addItem( crs.authid() + " - " + crs.description(), crs) except Exception as e: self.info.err(e) #ui stuff btns = self.findChildren(QToolButton) for btn in btns: btn.setIconSize(self.iface.iconSize()) #start self.fillCombo(self.layer) self.fillTable(True) except Exception as e: self.info.err(e)
def sdbinfo(self, filename): """Populate dialog with current values""" self.sdbname.setText(filename) try: sdb = SDB(filename) crs = QgsCoordinateReferenceSystem() crs.createFromUserInput(sdb.meta("crs")) self.sdb_info_basic.setPlainText( sdb.info(report='basic') + '\nCRS parsed by QGIS:\n{}'.format(crs.description())) self.sdb_info_data.setPlainText(sdb.info(report='data')) self.sdb_info_tags.setPlainText(sdb.info(report='tags')) self.dbok = True except: self.sdb_info_basic.clear() self.sdb_info_data.clear() self.sdb_info_tags.clear() self.sdbname.clear() self.dbok = False
def define_crs_if_not_exist(): __logger.debug('Check if CQFS CRS is defined...') config = __config['global'] name = config['crs_name'] proj4 = config['crs_proj4'] crs = QgsCoordinateReferenceSystem() crs.createFromProj4(proj4) description = str(crs.description()) if description == '': success = crs.saveAsUserCRS(name) if success: __logger.debug('CRS defined successfully.') else: __logger.warning('Fail to save CRS "{}".'.format(name)) else: __logger.debug('CRS "{}" already exists.'.format(description))
def added(self): # widget was added to parent try: self.crs_transform = self.prj.crs() self.crs_layer = self.iface.activeLayer().crs() # set crs widget if self.coordinatereferences is None: # qgis transform self.cboCoordSys.setHidden(True) self.cboCoordSystems = self.mQgsProjectionSelectionWidget self.cboCoordSystems.setMinimumWidth(460) self.cboCoordSystems.setOptionVisible(QgsProjectionSelectionWidget.ProjectCrs, True) self.cboCoordSystems.setCrs(self.prj.crs()) self.setCrs(self.cboCoordSystems.crs()) self.cboCoordSystems.crsChanged.connect(self.setCrs) else: # custom transform self.mQgsProjectionSelectionWidget.setHidden(True) self.cboCoordSystems = self.cboCoordSys self.cboCoordSystems.setMinimumWidth(400) self.cboCoordSystems.currentIndexChanged.connect( lambda: self.setCrs(self.cboCoordSystems.currentData())) self.cboCoordSystems.addItem( "Projekt CRS: " + self.crs_transform.authid() + " - " + self.crs_transform.description(), self.crs_transform) for crsID in self.coordinatereferences: try: crs = QgsCoordinateReferenceSystem(crsID) self.cboCoordSystems.addItem(crs.authid() + " - " + crs.description(), crs) except Exception as e: self.info.err(e) self.cboCoordSystems.setCurrentIndex(0) # here we know which type is cboCoordSystems! self.setIconSizes() except Exception as e: self.info.err(e)
def __init__(self, dockwidget, model, plugin_dir, layerSelectorDialog, parent=None, parentWidget=None): super(SettingsDialog, self).__init__(parent) self.setupUi(self) self.proj = QgsProject.instance() modelGyf = model self.switch = SwitchGYFs(dockwidget, plugin_dir) self.populate() self.populateGYF() self.dataPath.setText(self.proj.readEntry("QGYF", "dataPath")[0]) if self.proj.readEntry("QGYF", "CRS")[0]: crs = QgsCoordinateReferenceSystem( int(self.proj.readEntry("QGYF", "CRS")[0])) self.crs.setText(crs.description()) self.selectPathButton.clicked.connect(self.openFileDialog) self.clearDatabaseButton.clicked.connect( lambda: self.clearDataBase(dockwidget)) self.activeDatabase.currentIndexChanged.connect(self.setDatabase) self.parent = parentWidget self.selectCRSButton.clicked.connect(self.setCRS) updateDockwidget = lambda: self.updateDockwidget( dockwidget, layerSelectorDialog) self.db = Db() self.quality = QualityTable() if self.db.checkClass(): self.currentGyf.setEnabled(True) self.currentGyf.currentIndexChanged.connect(self.setGYF) if dockwidget.isVisible(): self.currentGyf.currentIndexChanged.connect(updateDockwidget) else: self.currentGyf.setEnabled(False)
def getSpatialRefInfo(self, srid): crs = QgsCoordinateReferenceSystem(srid) return crs.description()
class LoadByClass(QtGui.QDialog, load_by_class_base.Ui_LoadByClass): def __init__(self, parent=None): """Constructor.""" super(LoadByClass, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.selectedClasses = [] #Sql factory generator self.isSpatialite = True self.setupUi(self) self.tabWidget.setCurrentIndex(0) self.factory = SqlGeneratorFactory() self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.utils = Utils() self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0,0,0,0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0,0,1,1) #Objects Connections QtCore.QObject.connect(self.pushButtonOpenFile, QtCore.SIGNAL(("clicked()")), self.loadDatabase) QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel) QtCore.QObject.connect(self.selectAllCheck, QtCore.SIGNAL(("stateChanged(int)")), self.selectAll) QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected) QtCore.QObject.connect(self.tabWidget,QtCore.SIGNAL(("currentChanged(int)")), self.restoreInitialState) self.db = None #populating the postgis combobox self.populatePostGISConnectionsCombo() def __del__(self): self.closeDatabase() def closeDatabase(self): if self.db: self.db.close() self.db = None def restoreInitialState(self): self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.selectedClasses = [] self.spatialiteFileEdit.setText(self.filename) self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) tam = self.classesListWidget.__len__() for i in range(tam+1,1,-1): item = self.classesListWidget.takeItem(i-2) self.selectAllCheck.setCheckState(0) #Setting the database type if self.tabWidget.currentIndex() == 0: self.isSpatialite = True else: self.isSpatialite = False #getting the sql generator according to the database type self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.comboBoxPostgis.setCurrentIndex(0) def updateBDField(self): if self.dbLoaded == True: self.spatialiteFileEdit.setText(self.filename) else: self.filename = "" self.spatialiteFileEdit.setText(self.filename) def getDatabaseVersion(self): self.dbVersion = self.utils.getDatabaseVersion(self.db) self.qmlPath = self.utils.getQmlDir(self.db) def listClassesFromDatabase(self): self.classesListWidget.clear() self.getDatabaseVersion() sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) while query.next(): if self.isSpatialite: tableName = query.value(0) layerName = tableName else: tableSchema = query.value(0) tableName = query.value(1) layerName = tableSchema+'.'+tableName if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" \ or tableName.split("_")[-1] == "a": item = QtGui.QListWidgetItem(layerName) self.classesListWidget.addItem(item) self.classesListWidget.sortItems() self.setCRS() def setCRS(self): try: self.epsg = self.utils.findEPSG(self.db) if self.epsg == -1: self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): if self.comboBoxPostgis.currentIndex() > 0: self.loadDatabase() def loadDatabase(self): self.closeDatabase() if self.isSpatialite: (self.filename, self.db) = self.utils.getSpatialiteDatabase() if self.filename: self.spatialiteFileEdit.setText(self.filename) else: self.db = self.utils.getPostGISDatabase(self.comboBoxPostgis.currentText()) try: if not self.db.open(): QgsMessageLog.logMessage(self.db.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL) else: self.dbLoaded = True self.listClassesFromDatabase() except: pass def populatePostGISConnectionsCombo(self): self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem(self.tr("Select Database")) self.comboBoxPostgis.addItems(self.utils.getPostGISConnections()) def cancel(self): self.restoreInitialState() self.close() def selectAll(self): if self.selectAllCheck.isChecked(): tam = self.classesListWidget.__len__() for i in range(tam+1): item = self.classesListWidget.item(i-1) self.classesListWidget.setItemSelected(item,2) else: tam = self.classesListWidget.__len__() for i in range(tam+1): item = self.classesListWidget.item(i-1) self.classesListWidget.setItemSelected(item,0) def getSelectedItems(self): lista = self.classesListWidget.selectedItems() self.selectedClasses = [] tam = len(lista) for i in range(tam): self.selectedClasses.append(lista[i].text()) self.selectedClasses.sort() def okSelected(self): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.isSpatialite: self.loadSpatialiteLayers() else: self.loadPostGISLayers() QApplication.restoreOverrideCursor() except: QApplication.restoreOverrideCursor() def loadPostGISLayers(self): self.getSelectedItems() (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText()) uri = QgsDataSourceURI() uri.setConnection(str(host),str(port), str(database), str(user), str(password)) if len(self.selectedClasses)>0: try: geom_column = 'geom' for layer in self.selectedClasses: split = layer.split('.') schema = split[0] layerName = split[1] sql = self.gen.loadLayerFromDatabase(layer) uri.setDataSource(schema, layerName, geom_column, sql,'id') uri.disableSelectAtId(True) self.loadEDGVLayer(uri, layerName, 'postgres') self.restoreInitialState() self.close() except: self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the selected classes!"), level=QgsMessageBar.CRITICAL) else: self.bar.pushMessage(self.tr("Warning!"), self.tr("Please, select at least one class!"), level=QgsMessageBar.WARNING) def loadSpatialiteLayers(self): self.getSelectedItems() uri = QgsDataSourceURI() uri.setDatabase(self.filename) schema = '' geom_column = 'GEOMETRY' if len(self.selectedClasses)>0: try: for layer_name in self.selectedClasses: uri.setDataSource(schema, layer_name, geom_column) self.loadEDGVLayer(uri, layer_name, 'spatialite') self.restoreInitialState() self.close() except: self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the layer(s)!"), level=QgsMessageBar.CRITICAL) else: self.bar.pushMessage(self.tr("Warning!"), self.tr("Please select at least one layer!"), level=QgsMessageBar.WARNING) 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)
class StripTrialPointsDialog(QtGui.QDialog, FORM_CLASS): """Extract statistics from a list of rasters at set locations.""" toolKey = 'StripTrialPointsDialog' def __init__(self, iface, parent=None): super(StripTrialPointsDialog, self).__init__(parent) # Set up the user interface from Designer. self.setupUi(self) self.iface = iface self.DISP_TEMP_LAYERS = read_setting(PLUGIN_NAME + '/DISP_TEMP_LAYERS', bool) self.DEBUG = config.get_debug_mode() # Catch and redirect python errors directed at the log messages python error tab. QgsMessageLog.instance().messageReceived.connect(errorCatcher) if not os.path.exists(TEMPDIR): os.mkdir(TEMPDIR) # Setup for validation messagebar on gui----------------------------- self.messageBar = QgsMessageBar( self) # leave this message bar for bailouts self.validationLayout = QtGui.QFormLayout(self) # new layout to gui if isinstance(self.layout(), (QtGui.QFormLayout, QtGui.QGridLayout)): # create a validation layout so multiple messages can be added and cleaned up. self.layout().insertRow(0, self.validationLayout) self.layout().insertRow(0, self.messageBar) else: self.layout().insertWidget( 0, self.messageBar) # for use with Vertical/horizontal layout box self.outQgsCRS = None self.exclude_map_layers() # self.updateUseSelected() self.autoSetCoordinateSystem() # GUI Runtime Customisation ----------------------------------------------- self.setWindowIcon( QtGui.QIcon(':/plugins/pat/icons/icon_stripTrialPoints.svg')) self.chkUseSelected.setChecked(False) self.chkUseSelected.hide() self.chkSaveLinesFile.setChecked(False) def cleanMessageBars(self, AllBars=True): """Clean Messages from the validation layout. Args: AllBars (bool): Remove All bars including those which haven't timed-out. Defaults to True """ layout = self.validationLayout for i in reversed(range(layout.count())): # when it timed out the row becomes empty.... if layout.itemAt(i).isEmpty(): # .removeItem doesn't always work. so takeAt(pop) it instead item = layout.takeAt(i) elif AllBars: # ie remove all item = layout.takeAt(i) # also have to remove any widgets associated with it. if item.widget() is not None: item.widget().deleteLater() def send_to_messagebar(self, message, title='', level=QgsMessageBar.INFO, duration=5, exc_info=None, core_QGIS=False, addToLog=False, showLogPanel=False): """ Add a message to the forms message bar. Args: message (str): Message to display title (str): Title of message. Will appear in bold. Defaults to '' level (QgsMessageBarLevel): The level of message to log. Defaults to QgsMessageBar.INFO duration (int): Number of seconds to display message for. 0 is no timeout. Defaults to 5 core_QGIS (bool): Add to QGIS interface rather than the dialog addToLog (bool): Also add message to Log. Defaults to False showLogPanel (bool): Display the log panel exc_info () : Information to be used as a traceback if required """ if core_QGIS: newMessageBar = self.iface.messageBar() else: newMessageBar = QgsMessageBar(self) widget = newMessageBar.createMessage(title, message) if showLogPanel: button = QPushButton(widget) button.setText('View') button.setContentsMargins(0, 0, 0, 0) button.setFixedWidth(35) button.pressed.connect(openLogPanel) widget.layout().addWidget(button) newMessageBar.pushWidget(widget, level, duration=duration) if not core_QGIS: rowCount = self.validationLayout.count() self.validationLayout.insertRow(rowCount + 1, newMessageBar) if addToLog: if level == 1: # 'WARNING': LOGGER.warning(message) elif level == 2: # 'CRITICAL': # Add a traceback to log only for bailouts only if exc_info is not None: exc_type, exc_value, exc_traceback = sys.exc_info() mess = str(traceback.format_exc()) message = message + '\n' + mess LOGGER.critical(message) else: # INFO = 0 LOGGER.info(message) def exclude_map_layers(self): """ Run through all loaded layers to find ones which should be excluded. In this case exclude services.""" exVlayer_list = [] for layer in self.iface.legendInterface().layers(): if layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() != 'ogr': exVlayer_list.append(layer) if len(exVlayer_list) > 0: self.mcboLineLayer.setExceptedLayerList(exVlayer_list) def updateUseSelected(self): """Update use selected checkbox if active layer has a feature selection""" self.chkUseSelected.setChecked(False) if self.mcboLineLayer.count() == 0: return line_lyr = self.mcboLineLayer.currentLayer() self.mFieldComboBox.setLayer(line_lyr) if len(line_lyr.selectedFeatures()) > 0: self.chkUseSelected.setText( 'Use the {} selected feature(s) ?'.format( len(line_lyr.selectedFeatures()))) self.chkUseSelected.setEnabled(True) else: self.chkUseSelected.setText('No features selected') self.chkUseSelected.setEnabled(False) def autoSetCoordinateSystem(self): if self.mcboLineLayer.count() == 0: return self.cleanMessageBars() line_lyr = self.mcboLineLayer.currentLayer() line_utm_crs = crs.getProjectedCRSForXY( line_lyr.extent().xMinimum(), line_lyr.extent().yMinimum(), int(line_lyr.crs().authid().replace('EPSG:', ''))) self.outQgsCRS = None if line_utm_crs is not None: line_crs = QgsCoordinateReferenceSystem('EPSG:{}'.format( line_utm_crs.epsg_number)) self.outQgsCRS = line_crs if self.outQgsCRS is not None: self.lblOutCRS.setText('{} - {}'.format( self.outQgsCRS.description(), self.outQgsCRS.authid())) self.lblOutCRSTitle.setStyleSheet('color:black') self.lblOutCRS.setStyleSheet('color:black') else: self.lblOutCRSTitle.setStyleSheet('color:red') self.lblOutCRS.setStyleSheet('color:red') self.lblOutCRS.setText('Unspecified') self.send_to_messagebar( 'Auto detect coordinate system Failed. Check coordinate system of input raster layer', level=QgsMessageBar.CRITICAL, duration=5) return def on_mcboLineLayer_layerChanged(self): # self.updateUseSelected() self.autoSetCoordinateSystem() @QtCore.pyqtSlot(int) def on_chkUseSelected_stateChanged(self, state): if self.chkUseSelected.isChecked(): self.chkUsePoly.setChecked(True) @QtCore.pyqtSlot(name='on_cmdOutCRS_clicked') def on_cmdOutCRS_clicked(self): dlg = QgsGenericProjectionSelector(self) dlg.setMessage(self.tr('Select coordinate system')) if dlg.exec_(): if dlg.selectedAuthId() != '': self.outQgsCRS = QgsCoordinateReferenceSystem( dlg.selectedAuthId()) if self.outQgsCRS.geographicFlag(): self.outQgsCRS = None self.send_to_messagebar(unicode( self. tr("Geographic coordinate systems are not allowed. Resetting to default.." )), level=QgsMessageBar.WARNING, duration=5) else: self.outQgsCRS = None if self.outQgsCRS is None: self.autoSetCoordinateSystem() self.lblOutCRSTitle.setStyleSheet('color:black') self.lblOutCRS.setStyleSheet('color:black') self.lblOutCRS.setText( self.tr('{} - {}'.format(self.outQgsCRS.description(), self.outQgsCRS.authid()))) @QtCore.pyqtSlot(name='on_cmdSavePointsFile_clicked') def on_cmdSavePointsFile_clicked(self): self.messageBar.clearWidgets() lastFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder") if lastFolder is None or not os.path.exists(lastFolder): lastFolder = read_setting(PLUGIN_NAME + "/BASE_OUT_FOLDER") filename = self.mcboLineLayer.currentText() + '_strip-trial-points' s = save_as_dialog(self, self.tr("Save As"), self.tr("ESRI Shapefile") + " (*.shp);;", default_name=os.path.join(lastFolder, filename)) if s == '' or s is None: return s = os.path.normpath(s) write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder", os.path.dirname(s)) self.lneSavePointsFile.setText(s) self.lblSavePointsFile.setStyleSheet('color:black') self.lneSavePointsFile.setStyleSheet('color:black') @QtCore.pyqtSlot(int) def on_chkSaveLinesFile_stateChanged(self, state): self.lneSaveLinesFile.setEnabled(state) if state: lastFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder") if lastFolder is None or not os.path.exists(lastFolder): lastFolder = read_setting(PLUGIN_NAME + "/BASE_OUT_FOLDER") if self.lneSavePointsFile.text() == '': filename = os.path.join( lastFolder, self.mcboLineLayer.currentText() + '_strip-trial-lines.shp') else: path, file = os.path.split(self.lneSavePointsFile.text()) file, ext = os.path.splitext(file) filename = os.path.join( path, file.replace('-points', '') + '-lines' + ext) self.lneSaveLinesFile.setText(filename) self.chkSaveLinesFile.setStyleSheet('color:black') self.lneSaveLinesFile.setStyleSheet('color:black') else: self.lneSaveLinesFile.setText('') @QtCore.pyqtSlot(name='on_cmdSaveLinesFile_clicked') def on_cmdSaveLinesFile_clicked(self): self.messageBar.clearWidgets() lastFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder") if lastFolder is None or not os.path.exists(lastFolder): lastFolder = read_setting(PLUGIN_NAME + "/BASE_OUT_FOLDER") if self.lneSaveLinesFile.text() != '': filename = self.lneSaveLinesFile.text() elif self.lneSavePointsFile.text() == '': filename = os.path.join( lastFolder, self.mcboLineLayer.currentText() + '_strip-trial-lines') else: path, file = os.path.split(self.lneSavePointsFile.text()) file, ext = os.path.splitext(file) filename = os.path.join( path, file.replace('-points', '') + '-lines' + ext) s = save_as_dialog(self, self.tr("Save As"), self.tr("ESRI Shapefile") + " (*.shp);;", default_name=os.path.join(lastFolder, filename)) if s == '' or s is None: return s = os.path.normpath(s) write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder", os.path.dirname(s)) self.chkSaveLinesFile.setChecked(True) self.lneSaveLinesFile.setText(s) self.chkSaveLinesFile.setStyleSheet('color:black') self.lneSaveLinesFile.setStyleSheet('color:black') def validate(self): """Check to see that all required gui elements have been entered and are valid.""" self.messageBar.clearWidgets() self.cleanMessageBars(AllBars=True) try: errorList = [] if self.mcboLineLayer.currentLayer() is None: self.lblLineLayer.setStyleSheet('color:red') errorList.append(self.tr("Input line layer required.")) else: self.lblLineLayer.setStyleSheet('color:black') if self.dsbDistBtwnPoints.value() <= 0: self.lblDistBtwnPoints.setStyleSheet('color:red') errorList.append( self.tr("Distance between points must be greater than 0.")) else: self.lblDistBtwnPoints.setStyleSheet('color:black') if self.dsbLineOffsetDist.value() <= 0: self.lblLineOffsetDist.setStyleSheet('color:red') errorList.append( self.tr("Line offset distance must be greater than 0")) else: self.lblLineOffsetDist.setStyleSheet('color:black') if self.outQgsCRS is None: self.lblOutCRSTitle.setStyleSheet('color:red') self.lblOutCRS.setStyleSheet('color:red') errorList.append( self.tr("Select output projected coordinate system")) else: if self.outQgsCRS.geographicFlag(): self.lblOutCRSTitle.setStyleSheet('color:red') self.lblOutCRS.setStyleSheet('color:red') errorList.append( self. tr("Output projected coordinate system (not geographic) required" )) else: self.lblOutCRSTitle.setStyleSheet('color:black') self.lblOutCRS.setStyleSheet('color:black') if self.lneSavePointsFile.text() == '': self.lblSavePointsFile.setStyleSheet('color:red') errorList.append(self.tr("Save points shapefile")) elif not os.path.exists( os.path.dirname(self.lneSavePointsFile.text())): self.lneSavePointsFile.setStyleSheet('color:red') self.lblSavePointsFile.setStyleSheet('color:red') errorList.append( self.tr("Output shapefile folder cannot be found")) else: self.lblSavePointsFile.setStyleSheet('color:black') self.lneSavePointsFile.setStyleSheet('color:black') if self.chkSaveLinesFile.isChecked(): if self.lneSaveLinesFile.text() == '': self.chkSaveLinesFile.setStyleSheet('color:red') errorList.append(self.tr("Save lines shapefile")) elif not os.path.exists( os.path.dirname(self.lneSaveLinesFile.text())): self.lneSaveLinesFile.setStyleSheet('color:red') errorList.append( self.tr("Output shapefile folder cannot be found")) else: self.chkSaveLinesFile.setStyleSheet('color:black') self.lneSaveLinesFile.setStyleSheet('color:black') else: self.chkSaveLinesFile.setStyleSheet('color:black') self.lneSaveLinesFile.setStyleSheet('color:black') if len(errorList) > 0: raise ValueError(errorList) except ValueError as e: self.cleanMessageBars(True) if len(errorList) > 0: for i, ea in enumerate(errorList): self.send_to_messagebar(unicode(ea), level=QgsMessageBar.WARNING, duration=(i + 1) * 5) return False return True def accept(self, *args, **kwargs): try: if not self.validate(): return False # disable form via a frame, this will still allow interaction with the message bar self.fraMain.setDisabled(True) # clean gui and Qgis messagebars self.cleanMessageBars(True) # Change cursor to Wait cursor QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor)) self.iface.mainWindow().statusBar().showMessage( 'Processing {}'.format(self.windowTitle())) LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(), st='*' * 50)) self.send_to_messagebar( "Please wait.. QGIS will be locked... See log panel for progress.", level=QgsMessageBar.WARNING, duration=0, addToLog=False, core_QGIS=False, showLogPanel=True) # Add settings to log settingsStr = 'Parameters:---------------------------------------' settingsStr += '\n {:20}\t{}'.format( 'Line layer:', self.mcboLineLayer.currentLayer().name()) settingsStr += '\n {:20}\t{}'.format( 'Distance between points (m):', self.dsbDistBtwnPoints.value()) settingsStr += '\n {:20}\t{}'.format( 'Line offset distance (m):', self.dsbLineOffsetDist.value()) if self.chkUseSelected.isChecked(): settingsStr += '\n {:20}\t{} with {} selected features'.format( 'Layer:', self.mcboLineLayer.currentLayer().name(), len(self.mcboLineLayer.currentLayer().selectedFeatures())) settingsStr += '\n {:30}\t{}'.format( 'Output coordinate system:', self.lblOutCRS.text()) settingsStr += '\n {:30}\t{}'.format( 'Output points :', self.lneSavePointsFile.text()) if self.chkSaveLinesFile.isChecked(): settingsStr += '\n {:30}\t{}\n'.format( 'Output points :', self.chkSaveLinesFile.text()) LOGGER.info(settingsStr) lyr_line = self.mcboLineLayer.currentLayer() if self.chkUseSelected.isChecked(): line_shapefile = os.path.join(TEMPDIR, lyr_line.name() + '_lines.shp') if os.path.exists(line_shapefile): removeFileFromQGIS(line_shapefile) QgsVectorFileWriter.writeAsVectorFormat(lyr_line, line_shapefile, "utf-8", self.outQgsCRS, "ESRI Shapefile", onlySelected=True) if self.DISP_TEMP_LAYERS: addVectorFileToQGIS( line_shapefile, layer_name=os.path.splitext( os.path.basename(line_shapefile))[0], group_layer_name='DEBUG', atTop=True) else: line_shapefile = lyr_line.source() lines_desc = describe.VectorDescribe(line_shapefile) gdf_lines = lines_desc.open_geo_dataframe() epsgOut = int(self.outQgsCRS.authid().replace('EPSG:', '')) out_lines = None if self.chkSaveLinesFile.isChecked(): out_lines = self.lneSaveLinesFile.text() _ = create_points_along_line( gdf_lines, lines_desc.crs, self.dsbDistBtwnPoints.value(), self.dsbLineOffsetDist.value(), epsgOut, out_points_shapefile=self.lneSavePointsFile.text(), out_lines_shapefile=out_lines) out_lyr_points = addVectorFileToQGIS( self.lneSavePointsFile.text(), atTop=True, layer_name=os.path.splitext( os.path.basename(self.lneSavePointsFile.text()))[0]) vector_apply_unique_value_renderer(out_lyr_points, 'Strip_Name') if self.chkSaveLinesFile.isChecked(): out_lyr_lines = addVectorFileToQGIS( self.lneSaveLinesFile.text(), atTop=True, layer_name=os.path.splitext( os.path.basename(self.lneSaveLinesFile.text()))[0]) vector_apply_unique_value_renderer(out_lyr_lines, 'Strip_Name') self.cleanMessageBars(True) self.fraMain.setDisabled(False) self.iface.mainWindow().statusBar().clearMessage() self.iface.messageBar().popWidget() QtGui.qApp.restoreOverrideCursor() return super(StripTrialPointsDialog, self).accept(*args, **kwargs) except Exception as err: QtGui.qApp.restoreOverrideCursor() self.iface.mainWindow().statusBar().clearMessage() self.cleanMessageBars(True) self.fraMain.setDisabled(False) self.send_to_messagebar(str(err), level=QgsMessageBar.CRITICAL, duration=0, addToLog=True, core_QGIS=False, showLogPanel=True, exc_info=sys.exc_info()) return False # leave dialog open
class vectorLayerPropertyDlg(QDialog): ''' classdocs ''' def __init__(self, parent, layer): ''' Constructor ''' QDialog.__init__(self, parent) self.ui = Ui_VectorLayerProPertyDialog() self.ui.setupUi(self) self.ui.txtLayerName.setText(layer.name()) self.ui.txtLayerSource.setText(layer.source()) self.ui.txtCrs.setText(layer.crs().authid() + " - " + layer.crs().description()) self.ui.btnCrsSelect.clicked.connect(self.selectCrs) self.mCrs = layer.crs() self.vLayer = layer self.ui.mOptionsListWidget.currentRowChanged.connect( self.changeStackWidget) ''' init RenderV2 Widget''' self.mRendererDialog = QgsRendererV2PropertiesDialog( self.vLayer, QgsStyleV2.defaultStyle(), True) self.ui.stackedWidget.insertWidget(1, self.mRendererDialog) self.ui.buttonBox.accepted.connect(self.OK) frame_Label = QFrame() verticalLayout_Label = QVBoxLayout(frame_Label) self.mLabelWidget = QgsFieldExpressionWidget() self.mLabelWidget.setLayer(layer) verticalLayout_Label.addWidget(self.mLabelWidget) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) verticalLayout_Label.addItem(spacerItem) frame_Label.setLayout(verticalLayout_Label) self.ui.stackedWidget.insertWidget(2, frame_Label) # self.ui.buttonBox.accepted.connect(self.OK) def selectCrs(self): projectionDlg = QgsGenericProjectionSelector(self) projectionDlg.setSelectedAuthId(self.mCrs.authid()) if projectionDlg.exec_(): self.mCrs = QgsCoordinateReferenceSystem( projectionDlg.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId) self.ui.txtCrs.setText(self.mCrs.authid() + " - " + self.mCrs.description()) def changeStackWidget(self, index): self.ui.stackedWidget.setCurrentIndex(index) def OK(self): self.vLayer.setCrs(self.mCrs) self.mRendererDialog.apply() self.vLayer.triggerRepaint() if self.ui.stackedWidget.currentIndex( ) == 2 and self.mLabelWidget.currentText() != "": self.vLayer.setCustomProperty("labeling", "pal") self.vLayer.setCustomProperty("labeling/enabled", "true") self.vLayer.setCustomProperty("labeling/fontFamily", "Arial") self.vLayer.setCustomProperty("labeling/fontSize", "8") self.vLayer.setCustomProperty("labeling/fieldName", self.mLabelWidget.currentText()) # palLayerSetting = QgsPalLayerSettings() # palLayerSetting.readFromLayer(self.vLayer) # palLayerSetting.enabled = True # palLayerSetting.fieldName = self.mLabelWidget.currentText() # palLayerSetting.isExpression = True if self.vLayer.geometryType() == QGis.Line: self.vLayer.setCustomProperty("labeling/placement", "2") self.vLayer.setCustomProperty( "labeling/placementFlags", str(QgsPalLayerSettings.AboveLine)) # palLayerSetting.placement = QgsPalLayerSettings.Line # palLayerSetting.placementFlags = QgsPalLayerSettings.AboveLine elif self.vLayer.geometryType() == QGis.Point: self.vLayer.setCustomProperty("labeling/placement", "0") self.vLayer.setCustomProperty( "labeling/placementFlags", str(QgsPalLayerSettings.AroundPoint)) # self.vLayer.setCustomProperty("labeling/placementFlags", "0") # palLayerSetting.placement = QgsPalLayerSettings.Points # palLayerSetting.placementFlags = QgsPalLayerSettings.AroundPoint else: self.vLayer.setCustomProperty("labeling/placement", "3") self.vLayer.setCustomProperty( "labeling/placementFlags", str(QgsPalLayerSettings.AboveLine)) # palLayerSetting.placement = QgsPalLayerSettings.PolygonBoundary # palLayerSetting.placementFlags = QgsPalLayerSettings.AboveLine # palLayerSetting.setDataDefinedProperty(QgsPalLayerSettings.Size, True, True, '8', "") # palLayerSetting.writeToLayer(self.vLayer) elif self.ui.stackedWidget.currentIndex( ) == 2 and self.mLabelWidget.currentText() == "": self.vLayer.setCustomProperty("labeling", "") QgsProject.instance().dirty(True) QDialog.accept(self)
class LoadByCategory(QtGui.QDialog, FORM_CLASS): def __init__(self, codeList, parent=None): """Constructor.""" super(LoadByCategory, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.categories = [] self.selectedClasses = [] self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] self.parentTreeNode = None self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0, 0, 1, 1) #Objects Connections self.widget.connectionChanged.connect(self.listCategoriesFromDatabase) self.widget.problemOccurred.connect(self.pushMessage) self.pushButtonCancel.clicked.connect(self.cancel) self.pushButtonOk.clicked.connect(self.okSelected) self.pushButtonSelectAll.clicked.connect(self.selectAll) self.pushButtonDeselectAll.clicked.connect(self.deselectAll) self.pushButtonSelectOne.clicked.connect(self.selectOne) self.pushButtonDeselectOne.clicked.connect(self.deselectOne) self.checkBoxAll.stateChanged.connect(self.setAllGroup) self.widget.tabWidget.currentChanged.connect(self.restoreInitialState) self.codeList = codeList self.layerFactory = LayerFactory() def restoreInitialState(self): self.categories = [] self.selectedClasses = [] self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] self.parentTreeNode = None self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) def listCategoriesFromDatabase(self): self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() self.dbVersion = self.widget.getDBVersion() self.qmlPath = self.widget.getQmlPath() classes = self.widget.abstractDb.listGeomClassesFromDatabase() for table in classes: schema, layerName = self.widget.abstractDb.getTableSchema(table) category = layerName.split('_')[0] categoryName = schema + '.' + category if layerName.split("_")[-1] == "p": self.point.append(table) if layerName.split("_")[-1] == "l": self.line.append(table) if layerName.split("_")[-1] == "a": self.polygon.append(table) self.insertIntoListView(categoryName) self.listWidgetCategoryFrom.sortItems() self.setCRS() def insertIntoListView(self, item_name): found = self.listWidgetCategoryFrom.findItems(item_name, Qt.MatchExactly) if len(found) == 0: item = QtGui.QListWidgetItem(item_name) self.listWidgetCategoryFrom.addItem(item) def selectAll(self): tam = self.listWidgetCategoryFrom.__len__() for i in range(tam + 1, 1, -1): item = self.listWidgetCategoryFrom.takeItem(i - 2) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectAll(self): tam = self.listWidgetCategoryTo.__len__() for i in range(tam + 1, 1, -1): item = self.listWidgetCategoryTo.takeItem(i - 2) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def selectOne(self): listedItems = self.listWidgetCategoryFrom.selectedItems() for i in listedItems: item = self.listWidgetCategoryFrom.takeItem( self.listWidgetCategoryFrom.row(i)) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectOne(self): listedItems = self.listWidgetCategoryTo.selectedItems() for i in listedItems: item = self.listWidgetCategoryTo.takeItem( self.listWidgetCategoryTo.row(i)) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def setAllGroup(self): if self.checkBoxAll.isChecked(): self.checkBoxPoint.setCheckState(2) self.checkBoxLine.setCheckState(2) self.checkBoxPolygon.setCheckState(2) else: self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) def pushMessage(self, msg): self.bar.pushMessage('', msg, level=QgsMessageBar.WARNING) def setCRS(self): try: self.epsg = self.utils.findEPSG(self.db) if self.epsg == -1: self.bar.pushMessage( "", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING) else: self.crs = QgsCoordinateReferenceSystem( self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass def cancel(self): self.restoreInitialState() self.close() def getSelectedItems(self): lista = self.classesListWidget.selectedItems() self.selectedClasses = [] tam = len(lista) for i in range(tam): self.selectedClasses.append(lista[i].text()) self.selectedClasses.sort() def okSelected(self): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.checkBoxOnlyWithElements.isChecked(): self.setLayersWithElements() ponto = self.pointWithElement linha = self.lineWithElement area = self.polygonWithElement else: ponto = self.point linha = self.line area = self.polygon if len(self.listWidgetCategoryTo) > 0: categoriasSelecionadas = [] for i in range(self.listWidgetCategoryTo.__len__()): categoriasSelecionadas.append( self.listWidgetCategoryTo.item(i).text()) if self.checkBoxPoint.isChecked(): self.loadLayers('p', categoriasSelecionadas, ponto) if self.checkBoxLine.isChecked(): self.loadLayers('l', categoriasSelecionadas, linha) if self.checkBoxPolygon.isChecked(): self.loadLayers('a', categoriasSelecionadas, area) if self.checkBoxPoint.isChecked( ) == False and self.checkBoxLine.isChecked( ) == False and self.checkBoxPolygon.isChecked() == False: self.bar.pushMessage( self.tr("WARNING!"), self.tr("Please, select at least one type of layer!"), level=QgsMessageBar.WARNING) else: self.restoreInitialState() self.close() else: if self.widget.db and not self.widget.crs: self.bar.pushMessage( self.tr("CRITICAL!"), self. tr("Could not determine the coordinate reference system!" ), level=QgsMessageBar.CRITICAL) if not self.widget.db and not self.widget.crs: self.bar.pushMessage( self.tr("CRITICAL!"), self.tr("Database not loaded properly!"), level=QgsMessageBar.CRITICAL) self.bar.pushMessage( self.tr("CRITICAL!"), self. tr("Could not determine the coordinate reference system!" ), level=QgsMessageBar.CRITICAL) if len(self.listWidgetCategoryTo) == 0: self.bar.pushMessage( self.tr("WARNING!"), self.tr("Please, select at least one category!"), level=QgsMessageBar.WARNING) categoriasSelecionadas = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] QApplication.restoreOverrideCursor() except: QApplication.restoreOverrideCursor() def setLayersWithElements(self): self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] pontoAux = self.widget.abstractDb.countElements(self.point) linhaAux = self.widget.abstractDb.countElements(self.line) areaAux = self.widget.abstractDb.countElements(self.polygon) for i in pontoAux: if i[1] > 0: self.pointWithElement.append(i[0]) for i in linhaAux: if i[1] > 0: self.lineWithElement.append(i[0]) for i in areaAux: if i[1] > 0: self.polygonWithElement.append(i[0]) def loadLayers(self, type, categories, table_names): dbName = self.widget.abstractDb.getDatabaseName() groupList = qgis.utils.iface.legendInterface().groups() groupRelationshipList = qgis.utils.iface.legendInterface( ).groupLayerRelationship() if dbName not in groupList: self.parentTreeNode = qgis.utils.iface.legendInterface().addGroup( dbName, -1) else: self.parentTreeNode = groupList.index(dbName) if type == 'p': if len(groupList[self.parentTreeNode::]) == 0: idGrupo = qgis.utils.iface.legendInterface().addGroup( self.tr('Point'), True, self.parentTreeNode) elif self.tr('Point') not in groupRelationshipList[ self.parentTreeNode][1]: idGrupo = qgis.utils.iface.legendInterface().addGroup( self.tr('Point'), True, self.parentTreeNode) else: idGrupo = groupList[self.parentTreeNode::].index( self.tr('Point')) for category in categories: self.prepareLayer(category, table_names, idGrupo) if type == 'l': if len(groupList[self.parentTreeNode::]) == 0: idGrupo = qgis.utils.iface.legendInterface().addGroup( self.tr('Line'), True, self.parentTreeNode) elif self.tr('Line') not in groupRelationshipList[ self.parentTreeNode][1]: idGrupo = qgis.utils.iface.legendInterface().addGroup( self.tr('Line'), True, self.parentTreeNode) else: idGrupo = groupList[self.parentTreeNode::].index( self.tr('Line')) for category in categories: self.prepareLayer(category, table_names, idGrupo) if type == 'a': if len(groupList[self.parentTreeNode::]) == 0: idGrupo = qgis.utils.iface.legendInterface().addGroup( self.tr('Area'), True, self.parentTreeNode) elif self.tr('Area') not in groupRelationshipList[ self.parentTreeNode][1]: idGrupo = qgis.utils.iface.legendInterface().addGroup( self.tr('Area'), True, self.parentTreeNode) else: idGrupo = groupList[self.parentTreeNode::].index( self.tr('Area')) for category in categories: self.prepareLayer(category, table_names, idGrupo) def prepareLayer(self, category, table_names, idGrupo): idSubgrupo = qgis.utils.iface.legendInterface().addGroup( category, True, idGrupo) table_names.sort(reverse=True) for table_name in table_names: schema, layerName = self.widget.abstractDb.getTableSchema( table_name) if (category.split('.')[1] == layerName.split('_')[0]) and (category.split('.')[0] == schema): edgvLayer = self.layerFactory.makeLayer( self.widget.abstractDb, self.codeList, table_name) edgvLayer.load(self.widget.crs, idSubgrupo)
class QGISRedLayerManagementDialog(QDialog, FORM_CLASS): # Common variables iface = None NetworkName = "" ProjectDirectory = "" def __init__(self, parent=None): """Constructor.""" super(QGISRedLayerManagementDialog, self).__init__(parent) self.setupUi(self) self.btAccept.clicked.connect(self.accept) self.btSelectCRS.clicked.connect(self.selectCRS) self.btPipes.clicked.connect(lambda: self.createElement("Pipes")) self.btJunctions.clicked.connect( lambda: self.createElement("Junctions")) self.btTanks.clicked.connect(lambda: self.createElement("Tanks")) self.btReservoirs.clicked.connect( lambda: self.createElement("Reservoirs")) self.btValves.clicked.connect(lambda: self.createElement("Valves")) self.btPumps.clicked.connect(lambda: self.createElement("Pumps")) self.btDemands.clicked.connect( lambda: self.createElement("Demands", True)) self.btSources.clicked.connect( lambda: self.createElement("Sources", True)) self.btIsolatedValves.clicked.connect( lambda: self.createElement("IsolationValves", True)) self.btHydrants.clicked.connect( lambda: self.createElement("Hydrants", True)) self.btPurgeValves.clicked.connect( lambda: self.createElement("WashoutValves", True)) self.btAirReleases.clicked.connect( lambda: self.createElement("AirReleaseValves", True)) self.btConnections.clicked.connect( lambda: self.createElement("ServiceConnections", True)) self.btMeters.clicked.connect( lambda: self.createElement("Meters", True)) def config(self, ifac, direct, netw, parent): self.iface = ifac self.parent = parent utils = QGISRedUtils(direct, netw, ifac) self.crs = utils.getProjectCrs() self.originalCrs = self.crs self.tbCRS.setText(self.crs.description()) self.NetworkName = netw self.ProjectDirectory = direct self.setProperties() def setProperties(self): dirList = os.listdir(self.ProjectDirectory) # Visibilities self.btPipes.setVisible(not self.NetworkName + "_Pipes.shp" in dirList) self.btJunctions.setVisible(not self.NetworkName + "_Junctions.shp" in dirList) self.btTanks.setVisible(not self.NetworkName + "_Tanks.shp" in dirList) self.btReservoirs.setVisible(not self.NetworkName + "_Reservoirs.shp" in dirList) self.btValves.setVisible(not self.NetworkName + "_Valves.shp" in dirList) self.btPumps.setVisible(not self.NetworkName + "_Pumps.shp" in dirList) self.btDemands.setVisible(not self.NetworkName + "_Demands.shp" in dirList) self.btSources.setVisible(not self.NetworkName + "_Sources.shp" in dirList) self.btIsolatedValves.setVisible(not self.NetworkName + "_IsolationValves.shp" in dirList) self.btHydrants.setVisible(not self.NetworkName + "_Hydrants.shp" in dirList) self.btPurgeValves.setVisible(not self.NetworkName + "_WashoutValves.shp" in dirList) self.btAirReleases.setVisible(not self.NetworkName + "_AirReleaseValves.shp" in dirList) self.btConnections.setVisible(not self.NetworkName + "_ServiceConnections.shp" in dirList) self.btMeters.setVisible(not self.NetworkName + "_Meters.shp" in dirList) # Enables self.cbDemands.setEnabled(self.NetworkName + "_Demands.shp" in dirList) self.cbSources.setEnabled(self.NetworkName + "_Sources.shp" in dirList) self.cbIsolatedValves.setEnabled(self.NetworkName + "_IsolationValves.shp" in dirList) self.cbHydrants.setEnabled(self.NetworkName + "_Hydrants.shp" in dirList) self.cbPurgeValves.setEnabled(self.NetworkName + "_WashoutValves.shp" in dirList) self.cbAirReleases.setEnabled(self.NetworkName + "_AirReleaseValves.shp" in dirList) self.cbConnections.setEnabled(self.NetworkName + "_ServiceConnections.shp" in dirList) self.cbMeters.setEnabled(self.NetworkName + "_Meters.shp" in dirList) # Los básicos: Enables and checked utils = QGISRedUtils(self.ProjectDirectory, self.NetworkName, self.iface) hasLayer = utils.isLayerOpened("Pipes") self.cbPipes.setChecked(hasLayer) self.cbPipes.setEnabled(self.NetworkName + "_Pipes.shp" in dirList and not hasLayer) hasLayer = utils.isLayerOpened("Junctions") self.cbJunctions.setChecked(hasLayer) self.cbJunctions.setEnabled( self.NetworkName + "_Junctions.shp" in dirList and not hasLayer) hasLayer = utils.isLayerOpened("Tanks") self.cbTanks.setChecked(hasLayer) self.cbTanks.setEnabled(self.NetworkName + "_Tanks.shp" in dirList and not hasLayer) hasLayer = utils.isLayerOpened("Reservoirs") self.cbReservoirs.setChecked(hasLayer) self.cbReservoirs.setEnabled( self.NetworkName + "_Reservoirs.shp" in dirList and not hasLayer) hasLayer = utils.isLayerOpened("Valves") self.cbValves.setChecked(hasLayer) self.cbValves.setEnabled(self.NetworkName + "_Valves.shp" in dirList and not hasLayer) hasLayer = utils.isLayerOpened("Pumps") self.cbPumps.setChecked(hasLayer) self.cbPumps.setEnabled(self.NetworkName + "_Pumps.shp" in dirList and not hasLayer) # Checked self.cbDemands.setChecked(utils.isLayerOpened("Demands")) self.cbSources.setChecked(utils.isLayerOpened("Sources")) self.cbIsolatedValves.setChecked( utils.isLayerOpened("IsolationValves")) self.cbHydrants.setChecked(utils.isLayerOpened("Hydrants")) self.cbPurgeValves.setChecked(utils.isLayerOpened("WashoutValves")) self.cbAirReleases.setChecked(utils.isLayerOpened("AirReleaseValves")) self.cbConnections.setChecked( utils.isLayerOpened("ServiceConnections")) self.cbMeters.setChecked(utils.isLayerOpened("Meters")) def selectCRS(self): projSelector = QgsGenericProjectionSelector() if projSelector.exec_(): crsId = projSelector.crs().srsid() if not crsId == 0: self.crs = QgsCoordinateReferenceSystem() self.crs.createFromId( crsId, QgsCoordinateReferenceSystem.InternalCrsId) self.tbCRS.setText(self.crs.description()) def getLayerPath(self, layer): return QGISRedUtils().getLayerPath(layer) def generatePath(self, folder, fileName): return QGISRedUtils().generatePath(folder, fileName) def getLayers(self): return QGISRedUtils().getLayers() def isInLegend(self, layerName): openedLayers = self.getLayers() for layer in openedLayers: layerPath = self.generatePath( self.ProjectDirectory, self.NetworkName + "_" + layerName + ".shp") if self.getLayerPath(layer) == layerPath: return True return False def createElementsList(self): if self.cbPipes.isChecked(): self.layers.append("Pipes") if self.cbJunctions.isChecked(): self.layers.append("Junctions") if self.cbTanks.isChecked(): self.layers.append("Tanks") if self.cbReservoirs.isChecked(): self.layers.append("Reservoirs") if self.cbValves.isChecked(): self.layers.append("Valves") if self.cbPumps.isChecked(): self.layers.append("Pumps") def createComplementaryList(self): if self.cbDemands.isChecked(): self.layers.append("Demands") if self.cbSources.isChecked(): self.layers.append("Sources") if self.cbIsolatedValves.isChecked(): self.layers.append("Isolation Valves") if self.cbHydrants.isChecked(): self.layers.append("Hydrants") if self.cbPurgeValves.isChecked(): self.layers.append("Washout Valves") if self.cbAirReleases.isChecked(): self.layers.append("AirRelease Valves") if self.cbConnections.isChecked(): self.layers.append("Service Connections") if self.cbMeters.isChecked(): self.layers.append("Meters") def createElement(self, layerName, complementary=False): layer = "" if complementary else layerName complLayer = layerName if complementary else "" # Process QApplication.setOverrideCursor(Qt.WaitCursor) resMessage = GISRed.CreateLayer(self.ProjectDirectory, self.NetworkName, layer, complLayer) QApplication.restoreOverrideCursor() if resMessage == "True": self.parent.openElementLayer(layerName) elif resMessage == "False": self.iface.messageBar().pushMessage( "Warning", "Some issues occurred in the process", level=1, duration=5) else: self.iface.messageBar().pushMessage("Error", resMessage, level=2, duration=5) self.close() def accept(self): self.layers = [] self.createElementsList() self.createComplementaryList() epsg = None if not self.crs.srsid() == self.originalCrs.srsid(): epsg = self.crs.authid().replace("EPSG:", "") self.parent.openRemoveSpecificLayers(self.layers, epsg) self.close()
class SurvexImport: """QGIS Plugin Implementation.""" # The following are some dictionaries for flags in the .3d file station_attr = { 0x01: 'SURFACE', 0x02: 'UNDERGROUND', 0x04: 'ENTRANCE', 0x08: 'EXPORTED', 0x10: 'FIXED', 0x20: 'ANON' } leg_attr = {0x01: 'SURFACE', 0x02: 'DUPLICATE', 0x04: 'SPLAY'} style_type = { 0x00: 'NORMAL', 0x01: 'DIVING', 0x02: 'CARTESIAN', 0x03: 'CYLPOLAR', 0x04: 'NOSURVEY', 0xff: 'NOSTYLE' } # lists of keys of above, sorted to restore ordering station_flags = sorted(station_attr.keys()) leg_flags = sorted(leg_attr.keys()) # field names if there is error data error_fields = ('ERROR_VERT', 'ERROR_HORIZ', 'ERROR', 'LENGTH') # main data structures leg_list = [] # accumulates legs + metadata station_list = [] # ditto stations xsect_list = [] # ditto for cross sections for walls station_xyz = {} # map station names to xyz coordinates crs = None # used to set layer CRS in memory provider crs_source = None # records the origin of the CRS title = '' # used to set layer title in memory provider path_3d = '' # to remember the path to the survex .3d file path_gpkg = '' # ditto for path to save GeoPackage (.gpkg) def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'SurvexImport_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Import .3d file') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('SurvexImport', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToVectorMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/survex_import/icon.png' self.add_action(icon_path, text=self.tr(u'.3d import'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginVectorMenu(self.tr(u'&Import .3d file'), action) self.iface.removeToolBarIcon(action) def crs_from_file(self): """Enforce consistent CRS selector state""" if self.dlg.CRSFromFile.isChecked(): self.dlg.CRSFromProject.setChecked(False) def crs_from_project(self): """Enforce consistent CRS selector state""" if self.dlg.CRSFromProject.isChecked(): self.dlg.CRSFromFile.setChecked(False) def select_3d_file(self): """Select 3d file""" file_3d, _filter_3d = QFileDialog.getOpenFileName( self.dlg, "Select .3d file ", self.path_3d, '*.3d') self.dlg.selectedFile.setText(file_3d) self.path_3d = QFileInfo(file_3d).path() # memorise path selection def select_gpkg(self): """Select GeoPackage (.gpkg)""" file_gpkg, _filter_gpkg = QFileDialog.getSaveFileName( self.dlg, "Enter or select existing .gpkg file ", self.path_gpkg, '*.gpkg') self.dlg.selectedGPKG.setText(file_gpkg) self.path_gpkg = QFileInfo(file_gpkg).path() # memorise path selection def set_crs(self, s): """Figure out the CRS for layer creation, from the selected options and/or string""" if self.dlg.CRSFromProject.isChecked(): self.crs_source = 'from project' self.crs = QgsProject.instance().crs() elif self.dlg.CRSFromFile.isChecked() and s: self.crs_source = 'from .3d file' self.crs = QgsCoordinateReferenceSystem() match = search('epsg:([0-9]*)', s) # check for epsg in proj string if match: # if found, use the EPSG number explicitly self.crs.createFromString('EPSG:{}'.format(int( match.group(1)))) else: # fall back to proj4 self.crs.createFromProj4(s) else: # fall back to raising a CRS selection dialog self.crs_source = 'from dialog' dialog = QgsProjectionSelectionDialog() dialog.setMessage('define the CRS for the imported layers') dialog.exec() # run the dialog .. self.crs = dialog.crs() # .. and recover the user input if self.crs.isValid(): msg = 'CRS {} : {}'.format(self.crs_source, self.crs.authid()) QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) QgsMessageLog.logMessage(self.crs.description(), tag='Import .3d', level=Qgis.Info) else: # hopefully never happens msg = "CRS invalid!" QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) self.crs = None def all_checked(self): """ ensures the import all check box is consistent""" check = self.dlg.Legs.isChecked() check = check and self.dlg.Stations.isChecked() check = check and self.dlg.Polygons.isChecked() check = check and self.dlg.Walls.isChecked() check = check and self.dlg.XSections.isChecked() check = check and self.dlg.Traverses.isChecked() check = check and self.dlg.LegsSurface.isChecked() check = check and self.dlg.LegsSplay.isChecked() check = check and self.dlg.LegsDuplicate.isChecked() check = check and self.dlg.StationsSurface.isChecked() self.dlg.ImportAll.setChecked(check) def toggle_import_all(self): """toggle import all possible data""" checked = self.dlg.ImportAll.isChecked() self.dlg.Legs.setChecked(checked) self.dlg.Stations.setChecked(checked) self.dlg.Polygons.setChecked(checked) self.dlg.Walls.setChecked(checked) self.dlg.XSections.setChecked(checked) self.dlg.Traverses.setChecked(checked) self.dlg.LegsSurface.setChecked(checked) self.dlg.LegsSplay.setChecked(checked) self.dlg.LegsDuplicate.setChecked(checked) self.dlg.StationsSurface.setChecked(checked) def add_layer(self, subtitle, geom): """Add a memory layer with title(subtitle) and geom""" name = '%s(%s)' % (self.title, subtitle) if self.title else subtitle layer = QgsVectorLayer(geom, name, 'memory') if self.crs: # this should have been set by now layer.setCrs(self.crs) if not layer.isValid(): raise Exception("Invalid layer with %s" % geom) msg = "Memory layer '%s' called '%s' added" % (geom, name) QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) return layer # The next three routines are to do with reading .3d binary file format def read_xyz(self, fp): """Read xyz as integers, according to .3d spec""" return unpack('<iii', fp.read(12)) def read_len(self, fp): """Read a number as a length according to .3d spec""" byte = ord(fp.read(1)) if byte != 0xff: return byte else: return unpack('<I', fp.read(4))[0] def read_label(self, fp, current_label): """Read a string as a label, or part thereof, according to .3d spec""" byte = ord(fp.read(1)) if byte != 0x00: ndel = byte >> 4 nadd = byte & 0x0f else: ndel = self.read_len(fp) nadd = self.read_len(fp) oldlen = len(current_label) return current_label[:oldlen - ndel] + fp.read(nadd).decode('ascii') def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = SurvexImportDialog() self.dlg.selectedFile.clear() self.dlg.fileSelector.clicked.connect(self.select_3d_file) self.dlg.selectedGPKG.clear() self.dlg.GPKGSelector.clicked.connect(self.select_gpkg) self.dlg.CRSFromProject.setChecked(False) self.dlg.CRSFromFile.clicked.connect(self.crs_from_file) self.dlg.CRSFromFile.setChecked(False) self.dlg.CRSFromProject.clicked.connect(self.crs_from_project) self.dlg.ImportAll.clicked.connect(self.toggle_import_all) self.dlg.Legs.clicked.connect(self.all_checked) self.dlg.Stations.clicked.connect(self.all_checked) self.dlg.Polygons.clicked.connect(self.all_checked) self.dlg.Walls.clicked.connect(self.all_checked) self.dlg.XSections.clicked.connect(self.all_checked) self.dlg.Traverses.clicked.connect(self.all_checked) self.dlg.LegsSurface.clicked.connect(self.all_checked) self.dlg.LegsSplay.clicked.connect(self.all_checked) self.dlg.LegsDuplicate.clicked.connect(self.all_checked) self.dlg.StationsSurface.clicked.connect(self.all_checked) self.dlg.show() # show the dialog result = self.dlg.exec_() # Run the dialog event loop if result: # The user pressed OK, and this is what happened next! survex_3d = self.dlg.selectedFile.text() gpkg_file = self.dlg.selectedGPKG.text() include_legs = self.dlg.Legs.isChecked() include_stations = self.dlg.Stations.isChecked() include_polygons = self.dlg.Polygons.isChecked() include_walls = self.dlg.Walls.isChecked() include_xsections = self.dlg.XSections.isChecked() include_traverses = self.dlg.Traverses.isChecked() exclude_surface_legs = not self.dlg.LegsSurface.isChecked() exclude_splay_legs = not self.dlg.LegsSplay.isChecked() exclude_duplicate_legs = not self.dlg.LegsDuplicate.isChecked() exclude_surface_stations = not self.dlg.StationsSurface.isChecked() use_clino_wgt = self.dlg.UseClinoWeights.isChecked() include_up_down = self.dlg.IncludeUpDown.isChecked() discard_features = not self.dlg.KeepFeatures.isChecked() if not os.path.exists(survex_3d): raise Exception("File '%s' doesn't exist" % survex_3d) if discard_features: self.leg_list = [] self.station_list = [] self.station_xyz = {} self.xsect_list = [] # Read .3d file as binary, parse, and save data structures with open(survex_3d, 'rb') as fp: line = fp.readline().rstrip() # File ID check if not line.startswith(b'Survex 3D Image File'): raise IOError('Not a survex .3d file: ' + survex_3d) line = fp.readline().rstrip() # File format version if not line.startswith(b'v'): raise IOError('Unrecognised survex .3d version in ' + survex_3d) version = int(line[1:]) if version < 8: raise IOError('Survex .3d version >= 8 required in ' + survex_3d) line = fp.readline().rstrip( ) # Metadata (title and coordinate system) fields = line.split(b'\x00') previous_title = '' if discard_features else self.title if previous_title: self.title = previous_title + ' + ' + fields[0].decode( 'ascii') else: self.title = fields[0].decode('ascii') self.set_crs( fields[1].decode('ascii') if len(fields) > 1 else None) line = fp.readline().rstrip( ) # Timestamp, unused in present application if not line.startswith(b'@'): raise IOError('Unrecognised timestamp in ' + survex_3d) # timestamp = int(line[1:]) flag = ord(fp.read(1)) # file-wide flag if flag & 0x80: # abort if extended elevation raise IOError("Can't deal with extended elevation in " + survex_3d) # All file-wide header data read in, now read byte-wise # according to .3d spec. Note that all elements must # be processed, in order, otherwise we get out of sync. # We first define some baseline dates date0 = QDate(1900, 1, 1) date1 = QDate(1900, 1, 1) date2 = QDate(1900, 1, 1) label, style = '', 0xff # initialise label and style legs = [] # will be used to capture leg data between MOVEs xsect = [] # will be used to capture XSECT data nlehv = None # .. remains None if there isn't any error data... while True: # start of byte-gobbling while loop char = fp.read(1) if not char: # End of file (reached prematurely?) raise IOError('Premature end of file in ' + survex_3d) byte = ord(char) if byte <= 0x05: # STYLE if byte == 0x00 and style == 0x00: # this signals end of data if legs: # there may be a pending list of legs to save self.leg_list.append((legs, nlehv)) break # escape from byte-gobbling while loop else: style = byte elif byte <= 0x0e: # Reserved continue elif byte == 0x0f: # MOVE xyz = self.read_xyz(fp) if legs: self.leg_list.append((legs, nlehv)) legs = [] elif byte == 0x10: # DATE (none) date1 = date2 = date0 elif byte == 0x11: # DATE (single date) days = unpack('<H', fp.read(2))[0] date1 = date2 = date0.addDays(days) elif byte == 0x12: # DATE (date range, short format) days, extra = unpack('<HB', fp.read(3)) date1 = date0.addDays(days) date2 = date0.addDays(days + extra + 1) elif byte == 0x13: # DATE (date range, long format) days1, days2 = unpack('<HH', fp.read(4)) date1 = date0.addDays(days1) date2 = date0.addDays(days2) elif byte <= 0x1e: # Reserved continue elif byte == 0x1f: # Error info nlehv = unpack('<iiiii', fp.read(20)) elif byte <= 0x2f: # Reserved continue elif byte <= 0x33: # XSECT label = self.read_label(fp, label) if byte & 0x02: lrud = unpack('<iiii', fp.read(16)) else: lrud = unpack('<hhhh', fp.read(8)) xsect.append((label, lrud)) if byte & 0x01: # XSECT_END self.xsect_list.append(xsect) xsect = [] elif byte <= 0x3f: # Reserved continue elif byte <= 0x7f: # LINE flag = byte & 0x3f if not (flag & 0x20): label = self.read_label(fp, label) xyz_prev = xyz xyz = self.read_xyz(fp) while (True): # code pattern to implement logic if exclude_surface_legs and flag & 0x01: break if exclude_duplicate_legs and flag & 0x02: break if exclude_splay_legs and flag & 0x04: break legs.append(((xyz_prev, xyz), label, style, date1, date2, flag)) break elif byte <= 0xff: # LABEL (or NODE) flag = byte & 0x7f label = self.read_label(fp, label) xyz = self.read_xyz(fp) while (True): # code pattern to implement logic if exclude_surface_stations and flag & 0x01 and not flag & 0x02: break self.station_list.append((xyz, label, flag)) break self.station_xyz[label] = xyz # End of byte-gobbling while loop # file closes automatically, with open(survex_3d, 'rb') as fp: layers = [] # used to keep a list of the created layers if include_stations and self.station_list: # station layer station_layer = self.add_layer('stations', 'PointZ') attrs = [ QgsField(self.station_attr[k], QVariant.Int) for k in self.station_flags ] attrs.insert(0, QgsField('ELEVATION', QVariant.Double)) attrs.insert(0, QgsField('NAME', QVariant.String)) station_layer.dataProvider().addAttributes(attrs) station_layer.updateFields() features = [] for (xyz, label, flag) in self.station_list: xyz = [0.01 * v for v in xyz] attrs = [1 if flag & k else 0 for k in self.station_flags] attrs.insert(0, round(xyz[2], 2)) # elevation attrs.insert(0, label) feat = QgsFeature() geom = QgsGeometry(QgsPoint(*xyz)) feat.setGeometry(geom) feat.setAttributes(attrs) features.append(feat) station_layer.dataProvider().addFeatures(features) layers.append(station_layer) if include_legs and self.leg_list: # leg layer leg_layer = self.add_layer('legs', 'LineStringZ') attrs = [ QgsField(self.leg_attr[k], QVariant.Int) for k in self.leg_flags ] if nlehv: [ attrs.insert(0, QgsField(s, QVariant.Double)) for s in self.error_fields ] attrs.insert(0, QgsField('NLEGS', QVariant.Int)) attrs.insert(0, QgsField('DATE2', QVariant.Date)) attrs.insert(0, QgsField('DATE1', QVariant.Date)) attrs.insert(0, QgsField('STYLE', QVariant.String)) attrs.insert(0, QgsField('ELEVATION', QVariant.Double)) attrs.insert(0, QgsField('NAME', QVariant.String)) leg_layer.dataProvider().addAttributes(attrs) leg_layer.updateFields() features = [] for legs, nlehv in self.leg_list: for (xyz_pair, label, style, from_date, to_date, flag) in legs: elev = 0.5 * sum([0.01 * xyz[2] for xyz in xyz_pair]) points = [] for xyz in xyz_pair: xyz = [0.01 * v for v in xyz] points.append(QgsPoint(*xyz)) attrs = [1 if flag & k else 0 for k in self.leg_flags] if nlehv: [ attrs.insert(0, 0.01 * v) for v in reversed(nlehv[1:5]) ] attrs.insert(0, nlehv[0]) attrs.insert(0, to_date) attrs.insert(0, from_date) attrs.insert(0, self.style_type[style]) attrs.insert(0, round(elev, 2)) attrs.insert(0, label) linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) features.append(feat) leg_layer.dataProvider().addFeatures(features) layers.append(leg_layer) # Now do wall features if asked if (include_traverses or include_xsections or include_walls or include_polygons) and self.xsect_list: trav_features = [] wall_features = [] xsect_features = [] quad_features = [] for xsect in self.xsect_list: if len(xsect) < 2: # if there's only one station .. continue # .. give up as we don't know which way to face centerline = [ ] # will contain the station position and LRUD data for label, lrud in xsect: xyz = self.station_xyz[ label] # look up coordinates from label lrud_or_zero = tuple([max(0, v) for v in lrud ]) # deal with missing data centerline.append( xyz + lrud_or_zero) # and collect as 7-uple direction = [ ] # will contain the corresponding direction vectors # The calculations below use integers for xyz and lrud, and # conversion to metres is left to the end. Then dh2 is an # integer and the test for a plumb is safely dh2 = 0. # The directions are unit vectors optionally weighted by # cos(inclination) = dh/dl where dh^2 = dx^2 + dy^2 (note, no dz^2), # and dl^2 = dh^2 + dz^2. The normalisation is correspondingly # either 1/dh, or 1/dh * dh/dl = 1/dl. for i, xyzlrud in enumerate(centerline): x, y, z = xyzlrud[0:3] if i > 0: dx, dy, dz = x - xp, y - yp, z - zp dh2 = dx * dx + dy * dy # integer horizontal displacement (mm^2) norm = sqrt(dh2 + dz * dz) if use_clino_wgt else sqrt(dh2) dx, dy = (dx / norm, dy / norm) if dh2 > 0 and norm > 0 else (0, 0) direction.append((dx, dy)) xp, yp, zp = x, y, z left_wall = [] right_wall = [] up_down = [] # We build the walls by walking through the list # of stations and directions, with simple defaults # for the start and end stations for i, (x, y, z, l, r, u, d) in enumerate(centerline): d1x, d1y = direction[i - 1] if i > 0 else (0, 0) d2x, d2y = direction[i] if i + 1 < len( centerline) else (0, 0) dx, dy = d1x + d2x, d1y + d2y # mean (sum of) direction vectors norm = sqrt(dx * dx + dy * dy) # normalise to unit vector ex, ey = (dx / norm, dy / norm) if norm > 0 else (0, 0) # Convert to metres when saving the points left_wall.append((0.01 * (x - l * ey), 0.01 * (y + l * ex), 0.01 * z)) right_wall.append((0.01 * (x + r * ey), 0.01 * (y - r * ex), 0.01 * z)) up_down.append((0.01 * u, 0.01 * d)) # Mean elevation of centerline, used for elevation attribute elev = 0.01 * sum([xyzlrud[2] for xyzlrud in centerline ]) / len(centerline) attrs = [round(elev, 2)] # Now create the feature sets - first the centerline traverse points = [] for xyzlrud in centerline: xyz = [0.01 * v for v in xyzlrud[0:3] ] # These were mm, convert to metres points.append(QgsPoint(*xyz)) linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) trav_features.append(feat) # The walls as line strings for wall in (left_wall, right_wall): points = [QgsPoint(*xyz) for xyz in wall] linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) wall_features.append(feat) # Slightly more elaborate, pair up points on left # and right walls, and build a cross section as a # 2-point line string, and a quadrilateral polygon # with a closed 5-point line string for the # exterior ring. Note that QGIS polygons are # supposed to have their points ordered clockwise. for i, xyz_pair in enumerate(zip(left_wall, right_wall)): elev = 0.01 * centerline[i][ 2] # elevation of station in centerline attrs = [round(elev, 2)] points = [QgsPoint(*xyz) for xyz in xyz_pair] linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) xsect_features.append(feat) if i > 0: elev = 0.5 * (prev_xyz_pair[0][2] + xyz_pair[0][2] ) # average elevation attrs = [round(elev, 2)] if include_up_down: # average up / down attrs += [ 0.5 * (v1 + v2) for (v1, v2) in zip(up_down[i - 1], up_down[i]) ] points = [ ] # will contain the exterior 5-point ring, as follows... for xyz in tuple( reversed(prev_xyz_pair)) + xyz_pair + ( prev_xyz_pair[1], ): points.append(QgsPoint(*xyz)) linestring = QgsLineString() linestring.setPoints(points) polygon = QgsPolygon() polygon.setExteriorRing(linestring) feat = QgsFeature() geom = QgsGeometry(polygon) feat.setGeometry(geom) feat.setAttributes(attrs) quad_features.append(feat) prev_xyz_pair = xyz_pair # End of processing xsect_list - now add features to requested layers attrs = [QgsField('ELEVATION', QVariant.Double)] # common to all if include_traverses and trav_features: # traverse layer travs_layer = self.add_layer('traverses', 'LineStringZ') travs_layer.dataProvider().addAttributes(attrs) travs_layer.updateFields() travs_layer.dataProvider().addFeatures(trav_features) layers.append(travs_layer) if include_xsections and xsect_features: # xsection layer xsects_layer = self.add_layer('xsections', 'LineStringZ') xsects_layer.dataProvider().addAttributes(attrs) xsects_layer.updateFields() xsects_layer.dataProvider().addFeatures(xsect_features) layers.append(xsects_layer) if include_walls and wall_features: # wall layer walls_layer = self.add_layer('walls', 'LineStringZ') walls_layer.dataProvider().addAttributes(attrs) walls_layer.updateFields() walls_layer.dataProvider().addFeatures(wall_features) layers.append(walls_layer) if include_up_down: # add fields if requested for polygons attrs += [ QgsField(s, QVariant.Double) for s in ('MEAN_UP', 'MEAN_DOWN') ] if include_polygons and quad_features: # polygon layer quads_layer = self.add_layer('polygons', 'PolygonZ') quads_layer.dataProvider().addAttributes(attrs) quads_layer.updateFields() quads_layer.dataProvider().addFeatures(quad_features) layers.append(quads_layer) # All layers have been created, now update extents and add to QGIS registry if layers: [layer.updateExtents() for layer in layers] QgsProject.instance().addMapLayers(layers) # Write to GeoPackage if requested if gpkg_file: opts = [ QgsVectorFileWriter.CreateOrOverwriteFile, QgsVectorFileWriter.CreateOrOverwriteLayer ] for i, layer in enumerate(layers): options = QgsVectorFileWriter.SaveVectorOptions() options.actionOnExistingFile = opts[int( i > 0)] # create file or layer layer_name = layer.name() match = search( ' - ([a-z]*)', layer_name) # ie, extract 'legs', 'stations', etc options.layerName = str( match.group(1)) if match else layer_name writer = QgsVectorFileWriter.writeAsVectorFormat( layer, gpkg_file, options) if writer: msg = "'{}' -> {} in {}".format( layer_name, options.layerName, gpkg_file) QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) options, writer = None, None
def build_layer_table(layer_list=None, only_raster_boundingbox=True): """Build a table of layer properties. Can be used in conjunction with selecting layers to exclude from mapcomboboxes Layer_list: default None if None then it will build the table from all layers in the QGIS project otherwise it will use the list. only_raster_boundingbox: default False create a bounding box from the raster data ie removing nodata from polygon. This will slow it down if large numbers of rasters are present. """ dest_crs = QgsProject.instance().crs() gdf_layers = gpd.GeoDataFrame(columns=[ 'layer', 'layer_name', 'layer_id', 'layer_type', 'source', 'format', 'epsg', 'crs_name', 'is_projected', 'extent', 'provider', 'geometry' ], geometry='geometry', crs=dest_crs.authid()) # pd.DataFrame() if layer_list is None or len(layer_list) == 0: layermap = QgsProject.instance().mapLayers().values() else: layermap = layer_list new_rows = [] for layer in layermap: if layer.type() not in [ QgsMapLayer.VectorLayer, QgsMapLayer.RasterLayer ]: continue if layer.providerType() not in ['ogr', 'gdal', 'delimitedtext']: continue if layer.type() == QgsMapLayer.VectorLayer: format = layer.dataProvider().storageType() else: format = None if layer.crs().isValid() and layer.crs().authid() == '': # Try and convert older style coordinates systems # were correctly definied in QGIS 2 as GDA94 / MGA zone 54 # but get interpreted in QGIS 3 as Unknown CRS: BOUNDCRS[SOURCECRS[PROJCRS["GDA94 / MGA zone 54",..... layer_crs = QgsCoordinateReferenceSystem() if not layer_crs.createFromProj(layer.crs().toWkt()): #print('Could not match a coordinate system for {}'.format(layer.id())) layer_crs = layer.crs() # could apply to the layer, but what if it's wrong.... #layer.setCrs(layer_crs) else: layer_crs = layer.crs() # project the bounding box extents to be the same as the qgis project. if layer_crs.authid() != dest_crs.authid(): transform = QgsCoordinateTransform(layer_crs, dest_crs, QgsProject.instance()) prj_ext = transform.transformBoundingBox(layer.extent()) else: prj_ext = layer.extent() row_dict = { 'layer': layer, 'layer_name': layer.name(), 'layer_id': layer.id(), 'layer_type': layerTypes[layer.type()], 'format': format, 'source': get_layer_source(layer), 'epsg': layer_crs.authid(), 'crs_name': layer_crs.description(), 'is_projected': not layer_crs.isGeographic(), 'provider': layer.providerType(), 'geometry': wkt.loads(prj_ext.asWktPolygon()) } # 'extent': prj_ext.asWktPolygon(), if layer.type() == QgsMapLayer.RasterLayer: pixel_size = get_pixel_size(layer) if not only_raster_boundingbox: with rasterio.open(get_layer_source(layer)) as src: msk = src.dataset_mask() # 0 = nodata 255=valid rast_shapes = rasterio.features.shapes( np.ma.masked_equal(np.where(msk > 0, 1, 0), 0), transform=src.transform) try: results = ({ 'properties': { 'raster_val': v }, 'geometry': s } for i, (s, v) in enumerate(rast_shapes)) geoms = list(results) gpd_rPoly = gpd.GeoDataFrame.from_features( geoms, crs=layer.crs().authid()) dest_crs.authid().replace('epgs:', '') gpd_rPoly.to_crs(dest_crs.authid().replace('epgs:', ''), inplace=True) row_dict.update({'geometry': gpd_rPoly.unary_union}) del gpd_rPoly, results, msk, rast_shapes except: pass row_dict.update({ 'bandcount': layer.bandCount(), 'datatype': dataTypes[layer.dataProvider().dataType(1)], 'pixel_size': pixel_size[0], 'pixel_text': '{} {}'.format(*pixel_size), }) new_rows.append(row_dict) # gdf_layers = gpd.GeoDataFrame(new_rows, geometry='extent') if len(new_rows) == 0: return gdf_layers # for pandas 0.23.4 add sort=False to prevent row and column orders to change. try: gdf_layers = gdf_layers.append(new_rows, ignore_index=True, sort=False) except: gdf_layers = gdf_layers.append(new_rows, ignore_index=True) #df_layers.set_geometry('geometry') return gdf_layers
class ResampleImageToBlockDialog(QtGui.QDialog, FORM_CLASS): """Extract statistics from a list of rasters at set locations.""" toolKey = 'ResampleImageBandDialog' def __init__(self, iface, parent=None): super(ResampleImageToBlockDialog, self).__init__(parent) # Set up the user interface from Designer. self.setupUi(self) self.iface = iface self.DISP_TEMP_LAYERS = read_setting(PLUGIN_NAME + '/DISP_TEMP_LAYERS', bool) self.DEBUG = config.get_debug_mode() # Catch and redirect python errors directed at the log messages python error tab. QgsMessageLog.instance().messageReceived.connect(errorCatcher) if not os.path.exists(TEMPDIR): os.mkdir(TEMPDIR) # Setup for validation messagebar on gui----------------------------- self.messageBar = QgsMessageBar( self) # leave this message bar for bailouts self.validationLayout = QtGui.QFormLayout(self) # new layout to gui if isinstance(self.layout(), (QtGui.QFormLayout, QtGui.QGridLayout)): # create a validation layout so multiple messages can be added and cleaned up. self.layout().insertRow(0, self.validationLayout) self.layout().insertRow(0, self.messageBar) else: self.layout().insertWidget( 0, self.messageBar) # for use with Vertical/horizontal layout box self.outQgsCRS = None self.exclude_map_layers() self.updateRaster() self.updateUseSelected() self.autoSetCoordinateSystem() # GUI Runtime Customisation ----------------------------------------------- self.setWindowIcon( QtGui.QIcon(':/plugins/pat/icons/icon_resampleToBlock.svg')) self.chkAddToDisplay.setChecked(False) self.add_blank_field_to_cbo() # self.chkAddToDisplay.hide() def cleanMessageBars(self, AllBars=True): """Clean Messages from the validation layout. Args: AllBars (bool): Remove All bars including those which haven't timed-out. Defaults to True """ layout = self.validationLayout for i in reversed(range(layout.count())): # when it timed out the row becomes empty.... if layout.itemAt(i).isEmpty(): # .removeItem doesn't always work. so takeAt(pop) it instead item = layout.takeAt(i) elif AllBars: # ie remove all item = layout.takeAt(i) # also have to remove any widgets associated with it. if item.widget() is not None: item.widget().deleteLater() def send_to_messagebar(self, message, title='', level=QgsMessageBar.INFO, duration=5, exc_info=None, core_QGIS=False, addToLog=False, showLogPanel=False): """ Add a message to the forms message bar. Args: message (str): Message to display title (str): Title of message. Will appear in bold. Defaults to '' level (QgsMessageBarLevel): The level of message to log. Defaults to QgsMessageBar.INFO duration (int): Number of seconds to display message for. 0 is no timeout. Defaults to 5 core_QGIS (bool): Add to QGIS interface rather than the dialog addToLog (bool): Also add message to Log. Defaults to False showLogPanel (bool): Display the log panel exc_info () : Information to be used as a traceback if required """ if core_QGIS: newMessageBar = self.iface.messageBar() else: newMessageBar = QgsMessageBar(self) widget = newMessageBar.createMessage(title, message) if showLogPanel: button = QPushButton(widget) button.setText('View') button.setContentsMargins(0, 0, 0, 0) button.setFixedWidth(35) button.pressed.connect(openLogPanel) widget.layout().addWidget(button) newMessageBar.pushWidget(widget, level, duration=duration) if not core_QGIS: rowCount = self.validationLayout.count() self.validationLayout.insertRow(rowCount + 1, newMessageBar) if addToLog: if level == 1: # 'WARNING': LOGGER.warning(message) elif level == 2: # 'CRITICAL': # Add a traceback to log only for bailouts only if exc_info is not None: exc_type, exc_value, exc_traceback = sys.exc_info() mess = str(traceback.format_exc()) message = message + '\n' + mess LOGGER.critical(message) else: # INFO = 0 LOGGER.info(message) def exclude_map_layers(self): """ Run through all loaded layers to find ones which should be excluded. In this case exclude services.""" exVlayer_list = [] exRlayer_list = [] for layer in self.iface.legendInterface().layers(): if layer.type() == QgsMapLayer.RasterLayer: if layer.providerType() != 'gdal': exRlayer_list.append(layer) elif layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() != 'ogr': exVlayer_list.append(layer) self.mcboRasterLayer.setExceptedLayerList(exRlayer_list) if len(exRlayer_list) > 0: pass if len(exVlayer_list) > 0: self.mcboPolygonLayer.setExceptedLayerList(exVlayer_list) def updateRaster(self): if self.mcboRasterLayer.currentLayer() is None: return layer = self.mcboRasterLayer.currentLayer() provider = layer.dataProvider() if provider.srcHasNoDataValue(1): self.spnNoDataVal.setValue(provider.srcNoDataValue(1)) elif len(provider.userNoDataValues(1)) > 0: self.spnNoDataVal.setValue(provider.userNoDataValues(1)[0].min()) else: self.spnNoDataVal.setValue(0) # add a band list to the drop down box bandCount = self.mcboRasterLayer.currentLayer().bandCount() band_list = ['Band {: >2}'.format(i) for i in range(1, bandCount + 1)] self.cboBand.setMaxCount(bandCount + 1) self.cboBand.clear() self.cboBand.addItems([u''] + sorted(band_list)) def updateUseSelected(self): """Update use selected checkbox if active layer has a feature selection""" self.chkUseSelected.setChecked(False) if self.mcboPolygonLayer.count() == 0: return polygon_lyr = self.mcboPolygonLayer.currentLayer() self.mFieldComboBox.setLayer(polygon_lyr) if len(polygon_lyr.selectedFeatures()) > 0: self.chkUseSelected.setText( 'Use the {} selected feature(s) ?'.format( len(polygon_lyr.selectedFeatures()))) self.chkUseSelected.setEnabled(True) else: self.chkUseSelected.setText('No features selected') self.chkUseSelected.setEnabled(False) def autoSetCoordinateSystem(self): if self.mcboRasterLayer.count() == 0: return self.cleanMessageBars() raster_lyr = self.mcboRasterLayer.currentLayer() raster_utm_crs = crs.getProjectedCRSForXY( raster_lyr.extent().xMinimum(), raster_lyr.extent().yMinimum(), int(raster_lyr.crs().authid().replace('EPSG:', ''))) self.outQgsCRS = None if raster_utm_crs is not None: raster_crs = QgsCoordinateReferenceSystem('EPSG:{}'.format( raster_utm_crs.epsg_number)) self.outQgsCRS = raster_crs if self.outQgsCRS is not None: self.lblOutCRS.setText('{} - {}'.format( self.outQgsCRS.description(), self.outQgsCRS.authid())) self.lblOutCRSTitle.setStyleSheet('color:black') self.lblOutCRS.setStyleSheet('color:black') else: self.lblOutCRSTitle.setStyleSheet('color:red') self.lblOutCRS.setStyleSheet('color:red') self.lblOutCRS.setText('Unspecified') self.send_to_messagebar( 'Auto detect coordinate system Failed. Check coordinate system of input raster layer', level=QgsMessageBar.CRITICAL, duration=5) return def add_blank_field_to_cbo(self, set=True): """ Add a blank string to the field combo box. Fixed in qgis 3""" if self.mFieldComboBox.findText('', QtCore.Qt.MatchFixedString) == -1: self.mFieldComboBox.addItem(u'') if set == True: self.mFieldComboBox.setField(u'') def on_mcboRasterLayer_layerChanged(self): self.updateRaster() self.autoSetCoordinateSystem() def on_mcboPolygonLayer_layerChanged(self): self.updateUseSelected() self.autoSetCoordinateSystem() # ToDo: QGIS 3 implement QgsMapLayerComboBox.allowEmptyLayer() instead of chkUsePoly checkbox self.chkUsePoly.setChecked(True) self.add_blank_field_to_cbo() @QtCore.pyqtSlot(int) def on_chkUsePoly_stateChanged(self, state): self.add_blank_field_to_cbo() self.mFieldComboBox.setEnabled(state) self.lblGroupByField.setEnabled(state) # def on_mFieldComboBox_fieldChanged(self, field): # # Problem : after selecting a field, the blank is removed from the pick list. # # Solution: Add it again.... but this doesn't work. # if self.mFieldComboBox.findText('', QtCore.Qt.MatchFixedString) == -1: # # work around for not having a physical blank in the list. Fixed in qgis 3 # self.mFieldComboBox.addItem(u'') def on_chkUseSelected_stateChanged(self, state): if self.chkUseSelected.isChecked(): self.chkUsePoly.setChecked(True) @QtCore.pyqtSlot(name='on_cmdOutCRS_clicked') def on_cmdOutCRS_clicked(self): dlg = QgsGenericProjectionSelector(self) dlg.setMessage(self.tr('Select coordinate system')) if dlg.exec_(): if dlg.selectedAuthId() != '': self.outQgsCRS = QgsCoordinateReferenceSystem( dlg.selectedAuthId()) if self.outQgsCRS.geographicFlag(): self.outQgsCRS = None self.send_to_messagebar(unicode( self. tr("Geographic coordinate systems are not allowed. Resetting to default.." )), level=QgsMessageBar.WARNING, duration=5) else: self.outQgsCRS = None if self.outQgsCRS is None: self.autoSetCoordinateSystem() self.lblOutCRSTitle.setStyleSheet('color:black') self.lblOutCRS.setStyleSheet('color:black') self.lblOutCRS.setText( self.tr('{} - {}'.format(self.outQgsCRS.description(), self.outQgsCRS.authid()))) @QtCore.pyqtSlot(name='on_cmdOutputFolder_clicked') def on_cmdOutputFolder_clicked(self): self.messageBar.clearWidgets() if self.lneOutputFolder.text() is None: outFolder = '' else: outFolder = self.lneOutputFolder.text() if outFolder == '': outFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder") if outFolder is None or not os.path.exists(outFolder): outFolder = read_setting(PLUGIN_NAME + '/BASE_OUT_FOLDER') s = QtGui.QFileDialog.getExistingDirectory( self, self. tr("Save output files to a folder. A sub-folder will be created from the image name" ), outFolder, QtGui.QFileDialog.ShowDirsOnly) self.cleanMessageBars(self) if s == '' or s is None: return s = os.path.normpath(s) self.lblOutputFolder.setStyleSheet('color:black') self.lneOutputFolder.setStyleSheet('color:black') self.lneOutputFolder.setText(s) write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder", s) def validate(self): """Check to see that all required gui elements have been entered and are valid.""" self.messageBar.clearWidgets() self.cleanMessageBars(AllBars=True) try: errorList = [] if self.mcboRasterLayer.currentLayer() is None: self.lblRasterLayer.setStyleSheet('color:red') errorList.append(self.tr("Input image layer required.")) else: self.lblRasterLayer.setStyleSheet('color:black') if self.cboBand.currentText() == '': self.lblBand.setStyleSheet('color:red') errorList.append(self.tr("Input band selection required.")) else: self.lblBand.setStyleSheet('color:black') if self.dsbPixelSize.value() <= 0: self.lblPixelSize.setStyleSheet('color:red') errorList.append(self.tr("Pixel size must be greater than 0.")) else: self.lblPixelSize.setStyleSheet('color:black') if self.outQgsCRS is None: self.lblOutCRSTitle.setStyleSheet('color:red') self.lblOutCRS.setStyleSheet('color:red') errorList.append( self.tr("Select output projected coordinate system")) else: if self.outQgsCRS.geographicFlag(): self.lblOutCRSTitle.setStyleSheet('color:red') self.lblOutCRS.setStyleSheet('color:red') errorList.append( self. tr("Output projected coordinate system (not geographic) required" )) else: self.lblOutCRSTitle.setStyleSheet('color:black') self.lblOutCRS.setStyleSheet('color:black') if self.lneOutputFolder.text() == '': self.lblOutputFolder.setStyleSheet('color:red') errorList.append(self.tr("Select output data folder")) elif not os.path.exists(self.lneOutputFolder.text()): self.lneOutputFolder.setStyleSheet('color:red') self.lblOutputFolder.setStyleSheet('color:red') errorList.append(self.tr("Output data folder does not exist")) else: self.lblOutputFolder.setStyleSheet('color:black') self.lneOutputFolder.setStyleSheet('color:black') if len(errorList) > 0: raise ValueError(errorList) except ValueError as e: self.cleanMessageBars(True) if len(errorList) > 0: for i, ea in enumerate(errorList): self.send_to_messagebar(unicode(ea), level=QgsMessageBar.WARNING, duration=(i + 1) * 5) return False return True def accept(self, *args, **kwargs): try: if not self.validate(): return False # disable form via a frame, this will still allow interaction with the message bar self.fraMain.setDisabled(True) # clean gui and Qgis messagebars self.cleanMessageBars(True) # Change cursor to Wait cursor QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor)) self.iface.mainWindow().statusBar().showMessage( 'Processing {}'.format(self.windowTitle())) LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(), st='*' * 50)) self.send_to_messagebar( "Please wait.. QGIS will be locked... See log panel for progress.", level=QgsMessageBar.WARNING, duration=0, addToLog=False, core_QGIS=False, showLogPanel=True) # Add settings to log settingsStr = 'Parameters:---------------------------------------' settingsStr += '\n {:20}\t{}'.format( 'Image layer:', self.mcboRasterLayer.currentLayer().name()) settingsStr += '\n {:20}\t{}'.format('Image Band:', self.cboBand.currentText()) settingsStr += '\n {:20}\t{}'.format('Image nodata value:', self.spnNoDataVal.value()) if self.chkUsePoly.isChecked(): if self.chkUseSelected.isChecked(): settingsStr += '\n {:20}\t{} with {} selected features'.format( 'Layer:', self.mcboPolygonLayer.currentLayer().name(), len(self.mcboPolygonLayer.currentLayer(). selectedFeatures())) else: settingsStr += '\n {:20}\t{}'.format( 'Boundary layer:', self.mcboPolygonLayer.currentLayer().name()) if self.mFieldComboBox.currentField(): settingsStr += '\n {:20}\t{}'.format( 'Block ID field:', self.mFieldComboBox.currentField()) else: settingsStr += '\n {:20}\t{}'.format('Boundary layer:', '') settingsStr += '\n {:20}\t{}'.format('Block ID field:', '') settingsStr += '\n {:20}\t{}'.format('Resample pixel size: ', self.dsbPixelSize.value()) settingsStr += '\n {:30}\t{}'.format( 'Output Coordinate System:', self.lblOutCRS.text()) settingsStr += '\n {:30}\t{}\n'.format( 'Output Folder:', self.lneOutputFolder.text()) LOGGER.info(settingsStr) lyrRaster = self.mcboRasterLayer.currentLayer() if self.chkUsePoly.isChecked(): lyrBoundary = self.mcboPolygonLayer.currentLayer() if self.chkUseSelected.isChecked(): savePlyName = lyrBoundary.name() + '_poly.shp' filePoly = os.path.join(TEMPDIR, savePlyName) if os.path.exists(filePoly): removeFileFromQGIS(filePoly) QgsVectorFileWriter.writeAsVectorFormat(lyrBoundary, filePoly, "utf-8", lyrBoundary.crs(), "ESRI Shapefile", onlySelected=True) if self.DISP_TEMP_LAYERS: addVectorFileToQGIS(filePoly, layer_name=os.path.splitext( os.path.basename(filePoly))[0], group_layer_name='DEBUG', atTop=True) else: filePoly = lyrBoundary.source() band_num = [int(self.cboBand.currentText().replace('Band ', ''))] files = resample_bands_to_block( lyrRaster.source(), self.dsbPixelSize.value(), self.lneOutputFolder.text(), band_nums=band_num, image_epsg=int(lyrRaster.crs().authid().replace('EPSG:', '')), image_nodata=self.spnNoDataVal.value(), polygon_shapefile=filePoly if self.chkUsePoly.isChecked() else None, groupby=self.mFieldComboBox.currentField() if self.mFieldComboBox.currentField() else None, out_epsg=int(self.outQgsCRS.authid().replace('EPSG:', ''))) if self.chkAddToDisplay.isChecked(): for ea_file in files: removeFileFromQGIS(ea_file) addRasterFileToQGIS(ea_file, group_layer_name=os.path.basename( os.path.dirname(ea_file)), atTop=False) self.cleanMessageBars(True) self.fraMain.setDisabled(False) self.iface.mainWindow().statusBar().clearMessage() self.iface.messageBar().popWidget() QtGui.qApp.restoreOverrideCursor() return super(ResampleImageToBlockDialog, self).accept(*args, **kwargs) except Exception as err: QtGui.qApp.restoreOverrideCursor() self.iface.mainWindow().statusBar().clearMessage() self.cleanMessageBars(True) self.fraMain.setDisabled(False) self.send_to_messagebar(str(err), level=QgsMessageBar.CRITICAL, duration=0, addToLog=True, core_QGIS=False, showLogPanel=True, exc_info=sys.exc_info()) return False # leave dialog open
class ConnectionWidget(QtGui.QWidget, FORM_CLASS): connectionChanged = pyqtSignal() problemOccurred = pyqtSignal(str) dbChanged = pyqtSignal(AbstractDb) styleChanged = pyqtSignal(dict) def __init__(self, parent = None): """Constructor.""" super(ConnectionWidget, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.setInitialState() self.serverWidget.populateServersCombo() self.serverWidget.abstractDbLoaded.connect(self.getDatabasesFromServer) self.serverWidget.clearWidgets.connect(self.clearAll) def __del__(self): """ Closes the database """ self.closeDatabase() def closeDatabase(self): """ Closes the current database """ if self.abstractDb: del self.abstractDb self.abstractDb = None def clearAll(self): """ Resets the initial state """ self.filename = '' self.dbLoaded = False self.epsg = 0 self.crs = None self.abstractDb = None self.isSpatialite = False self.abstractDbFactory = DbFactory() self.utils = Utils() #populating the postgis combobox self.comboBoxPostgis.clear() self.spatialiteFileEdit.setReadOnly(True) self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setReadOnly(True) def setInitialState(self): """ Sets the initial state """ self.filename = '' self.dbLoaded = False self.epsg = 0 self.crs = None self.abstractDb = None self.isSpatialite = False self.tabWidget.setCurrentIndex(0) self.abstractDbFactory = DbFactory() self.utils = Utils() self.serverWidget.serversCombo.setCurrentIndex(0) #populating the postgis combobox self.comboBoxPostgis.clear() self.spatialiteFileEdit.setReadOnly(True) self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setReadOnly(True) @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): """ Updates database information when the combo box changes """ if self.comboBoxPostgis.currentIndex() > 0: self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setText('') self.edgvPostgisVersionEdit.setReadOnly(True) self.loadDatabase() self.connectionChanged.emit() @pyqtSlot(bool) def on_pushButtonOpenFile_clicked(self): """ Loads a spatialite database """ self.loadDatabase() if self.isDBConnected(): self.connectionChanged.emit() @pyqtSlot(int) def on_tabWidget_currentChanged(self): """ Changes the tab to work with spatialite or postgis databases """ self.filename = '' self.comboBoxPostgis.clear() self.dbLoaded = False self.epsg = 0 self.crs = None self.dbVersion = '' self.serverWidget.serversCombo.setCurrentIndex(0) self.spatialiteFileEdit.setReadOnly(True) self.spatialiteFileEdit.setText(self.filename) self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setText('') self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setText('') self.edgvPostgisVersionEdit.setReadOnly(True) self.mGroupBox.setTitle(self.tr('Database connection')) #Setting the database type if self.tabWidget.currentIndex() == 1: self.isSpatialite = True else: self.isSpatialite = False def loadDatabase(self): """ Loads the selected database """ self.closeDatabase() try: if self.isSpatialite: self.abstractDb = self.abstractDbFactory.createDbFactory('QSQLITE') self.abstractDb.connectDatabase() self.spatialiteFileEdit.setText(self.abstractDb.db.databaseName()) self.edgvSpatialiteVersionEdit.setText(self.abstractDb.getDatabaseVersion()) else: self.abstractDb = self.abstractDbFactory.createDbFactory('QPSQL') (host, port, user, password) = self.serverWidget.getServerParameters() dbName = self.comboBoxPostgis.currentText() self.abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password) self.edgvPostgisVersionEdit.setText(self.abstractDb.getDatabaseVersion()) serverName = self.serverWidget.serversCombo.currentText() newText = dbName + self.tr(' on ') + serverName self.mGroupBox.setToolTip(newText) # self.mGroupBox.setTitle(newText) self.abstractDb.checkAndOpenDb() self.dbLoaded = True self.dbVersion = self.abstractDb.getDatabaseVersion() self.abstractDb.checkAndCreateStyleTable() self.styles = self.abstractDb.getStyleDict(self.dbVersion) self.styleChanged.emit(self.styles) self.dbChanged.emit(self.abstractDb) if self.dbVersion == '-1': self.problemOccurred.emit(self.tr('This is not a valid DsgTools database!')) else: self.setCRS() except Exception as e: self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) def setCRS(self): """ Sets the CRS information """ try: self.epsg = self.abstractDb.findEPSG() if self.epsg == -1: self.problemOccurred.emit(self.tr('Coordinate Reference System not set or invalid!')) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except Exception as e: self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) def isDBConnected(self): """ Checks if the database is already loaded """ return self.dbLoaded def getDBVersion(self): """ Gets the database version """ ret = '' try: ret = self.abstractDb.getDatabaseVersion() except Exception as e: self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) return ret def getQmlPath(self): """ Gets the QML path """ ret = '' try: ret = self.abstractDb.getQmlDir() except Exception as e: self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) return ret def getDatabasesFromServer(self): """ Gets databases from server """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: if self.serverWidget.abstractDb: dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(parentWidget = self) dbList.sort() self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem(self.tr('Select Database')) for db, version in dbList: self.comboBoxPostgis.addItem(db) else: self.setInitialState() return except Exception as e: QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) self.setInitialState() self.setInitialState() QApplication.restoreOverrideCursor()
class PreVesperDialog(QtGui.QDialog, FORM_CLASS): """Dialog to prepare data and run vesper kriging""" toolKey = 'PreVesperDialog' def __init__(self, iface, parent=None): super(PreVesperDialog, self).__init__(iface.mainWindow()) # Set up the user interface from Designer. self.setupUi(self) # The qgis interface self.iface = iface self.DISP_TEMP_LAYERS = read_setting( PLUGIN_NAME + '/DISP_TEMP_LAYERS', bool) self.DEBUG = config.get_debug_mode() # Catch and redirect python errors directed at the log messages python # error tab. QgsMessageLog.instance().messageReceived.connect(errorCatcher) if not os.path.exists(TEMPDIR): os.mkdir(TEMPDIR) # Setup for validation messagebar on gui----------------------------- self.setWindowIcon(QtGui.QIcon( ':/plugins/pat/icons/icon_vesperKriging.svg')) self.validationLayout = QtGui.QFormLayout(self) # source: https://nathanw.net/2013/08/02/death-to-the-message-box-use-the-qgis-messagebar/ # Add the error messages to top of form via a message bar. # leave this message bar for bailouts self.messageBar = QgsMessageBar(self) if isinstance(self.layout(), (QtGui.QFormLayout, QtGui.QGridLayout)): # create a validation layout so multiple messages can be added and # cleaned up. self.layout().insertRow(0, self.validationLayout) self.layout().insertRow(0, self.messageBar) else: # for use with Vertical/horizontal layout box self.layout().insertWidget(0, self.messageBar) # Set Class default variables ------------------------------------- self.vesp_dict = None self.in_qgscrs = None self.dfCSV = None # this is a validation flag self.OverwriteCtrlFile = False self.cboMethod.addItems( ['High Density Kriging', 'Low Density Kriging (Advanced)']) # To allow only integers for the min number of pts. self.onlyInt = QIntValidator() self.lneMinPoint.setValidator(self.onlyInt) self.vesper_exe = check_vesper_dependency() if self.vesper_exe is None or self.vesper_exe == '': self.gbRunVesper.setTitle( 'WARNING:Vesper not found please configure using the about dialog.') self.gbRunVesper.setChecked(False) self.gbRunVesper.setCheckable(False) self.gbRunVesper.setEnabled(False) def cleanMessageBars(self, AllBars=True): """Clean Messages from the validation layout. Args: AllBars (bool): Remove All bars including. Defaults to True """ layout = self.validationLayout for i in reversed(range(layout.count())): # when it timed out the row becomes empty.... if layout.itemAt(i).isEmpty(): # .removeItem doesn't always work. so takeAt(pop) it instead item = layout.takeAt(i) elif AllBars: # ie remove all item = layout.takeAt(i) # also have to remove any widgets associated with it. if item.widget() is not None: item.widget().deleteLater() def send_to_messagebar(self, message, title='', level=QgsMessageBar.INFO, duration=5, exc_info=None, core_QGIS=False, addToLog=False, showLogPanel=False): """ Add a message to the forms message bar. Args: message (str): Message to display title (str): Title of message. Will appear in bold. Defaults to '' level (QgsMessageBarLevel): The level of message to log. Defaults to QgsMessageBar.INFO duration (int): Number of seconds to display message for. 0 is no timeout. Defaults to 5 core_QGIS (bool): Add to QGIS interface rather than the dialog addToLog (bool): Also add message to Log. Defaults to False showLogPanel (bool): Display the log panel exc_info () : Information to be used as a traceback if required """ if core_QGIS: newMessageBar = self.iface.messageBar() else: newMessageBar = QgsMessageBar(self) widget = newMessageBar.createMessage(title, message) if showLogPanel: button = QPushButton(widget) button.setText('View') button.setContentsMargins(0, 0, 0, 0) button.setFixedWidth(35) button.pressed.connect(openLogPanel) widget.layout().addWidget(button) newMessageBar.pushWidget(widget, level, duration=duration) if not core_QGIS: rowCount = self.validationLayout.count() self.validationLayout.insertRow(rowCount + 1, newMessageBar) if addToLog: if level == 1: # 'WARNING': LOGGER.warning(message) elif level == 2: # 'CRITICAL': # Add a traceback to log only for bailouts only if exc_info is not None: exc_type, exc_value, exc_traceback = sys.exc_info() mess = str(traceback.format_exc()) message = message + '\n' + mess LOGGER.critical(message) else: # INFO = 0 LOGGER.info(message) def updateCtrlFileName(self): if self.chkAutoCtrlFileName.isChecked(): ctrl_name = os.path.splitext( os.path.basename(self.lneInCSVFile.text()))[0] ctrl_name = ctrl_name.replace('_normtrimmed', '') fld = '' if self.cboKrigColumn.currentText() != '': # convert field name to something meaningful if it contains # invalid chars, ie degC fld = unidecode(self.cboKrigColumn.currentText()) # remove field from filename, then add it according to the naming # convention to avoid duplications. # flags=re.I is for a case insensitive find and replace ctrl_name = re.sub(fld, '', ctrl_name, flags=re.I) # and again with invalid characters removed. Only allow # alpha-numeric Underscores and hyphens fld = re.sub('[^A-Za-z0-9_-]+', '', fld) ctrl_name = re.sub(fld, '', ctrl_name, flags=re.I) # and again with the field truncated to 10 chars fld = fld[:10] ctrl_name = re.sub(fld, '', ctrl_name, flags=re.I) if self.cboMethod.currentText() == 'High Density Kriging': krig_type = 'HighDensity' else: krig_type = 'LowDensity' # add the chosen field name to the control filename ctrl_name = '{}_{}_{}_control'.format(ctrl_name[:20], krig_type, fld) # only allow alpha-numeric Underscores and hyphens ctrl_name = re.sub('[^A-Za-z0-9_-]+', '', ctrl_name) # replace more than one instance of underscore with a single one. # ie'file____norm__control___yield_h__' to # 'file_norm_control_yield_h_' ctrl_name = re.sub(r"_+", "_", ctrl_name) self.lneCtrlFile.setText(ctrl_name + '.txt') @QtCore.pyqtSlot(int) def on_cboKrigColumn_currentIndexChanged(self, index): if self.cboKrigColumn.currentText() != '': self.lblKrigColumn.setStyleSheet('color:black') if self.chkAutoCtrlFileName.isChecked(): self.updateCtrlFileName() @QtCore.pyqtSlot(name='on_cmdInCSVFile_clicked') def on_cmdInCSVFile_clicked(self): self.lneInCSVFile.clear() self.messageBar.clearWidgets() self.cboMethod.setCurrentIndex(0) self.dfCSV = None inFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastCSVFolder") if inFolder is None or not os.path.exists(inFolder): inFolder = read_setting(PLUGIN_NAME + '/BASE_IN_FOLDER') s = QtGui.QFileDialog.getOpenFileName(self, caption=self.tr("Select a CSV file to krige"), directory=inFolder, filter='{} (*.csv);;{} (*.*);;'.format( self.tr("Comma delimited files"), self.tr("All Files")) ) self.cleanMessageBars(self) self.lneInCSVFile.clear() # validate files first overlaps, message = self.validate_csv_grid_files(s, self.lneInGridFile.text()) if not overlaps or message is not None: self.lblInCSVFile.setStyleSheet('color:red') self.lneInCSVFile.setStyleSheet('color:red') self.send_to_messagebar(message, level=QgsMessageBar.CRITICAL, duration=0, addToLog=True, showLogPanel=True, exc_info=sys.exc_info()) return s = os.path.normpath(s) self.lblInCSVFile.setStyleSheet('color:black') self.lneInCSVFile.setStyleSheet('color:black') self.lneInCSVFile.setText(s) descCSV = describe.CsvDescribe(s) self.dfCSV = descCSV.open_pandas_dataframe(nrows=150) if len(self.dfCSV) <= 100: self.lneMinPoint.clear() QMessageBox.warning(self, 'Cannot Krige', 'Kriging is not advised for less ' 'than 100 points') self.lneMinPoint.clear() self.cboKrigColumn.clear() coord_cols = predictCoordinateColumnNames(self.dfCSV.columns) epsgcols = [col for col in self.dfCSV.columns if 'EPSG' in col.upper()] field_names = list(self.dfCSV.drop(coord_cols + epsgcols, axis=1) .select_dtypes(include=[np.number]).columns.values) self.cboKrigColumn.addItems([''] + field_names) # To set a coordinate system for vesper2raster, try and get it from # a column in the data. epsg = 0 if len(epsgcols) > 0: for col in epsgcols: if self.dfCSV.iloc[0][col] > 0: epsg = int(self.dfCSV.iloc[0][col]) break if epsg > 0: self.in_qgscrs = QgsCoordinateReferenceSystem("EPSG:{}".format(epsg)) self.lblInCRS.setText('{} - {}'.format(self.in_qgscrs.description(), self.in_qgscrs.authid())) else: self.lblInCRS.setText('Unspecified') write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastCSVFolder", os.path.dirname(s)) del descCSV self.updateCtrlFileName() @QtCore.pyqtSlot(name='on_cmdInGridFile_clicked') def on_cmdInGridFile_clicked(self): self.lneInGridFile.clear() self.messageBar.clearWidgets() inFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastVesperGridFolder") if inFolder is None or not os.path.exists(inFolder): inFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastCSVFolder") if inFolder is None or not os.path.exists(inFolder): inFolder = read_setting(PLUGIN_NAME + '/BASE_IN_FOLDER') s = QtGui.QFileDialog.getOpenFileName(self, caption=self.tr("Choose the Vesper Grid File"), directory=inFolder, filter='{} (*_v.txt);;{} (*.*);;'.format( self.tr("Vesper Grid File(s)"), self.tr("All Files")) ) self.cleanMessageBars(self) s = os.path.normpath(s) self.lneInGridFile.clear() self.lneInGridFile.setStyleSheet('color:red') self.lblInGridFile.setStyleSheet('color:red') overlaps, message = self.validate_csv_grid_files(self.lneInCSVFile.text(), s) if overlaps or message is None: self.lneInGridFile.setStyleSheet('color:black') self.lblInGridFile.setStyleSheet('color:black') if overlaps: self.lneInGridFile.setText(s) write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastVesperGridFolder", os.path.dirname(s)) else: self.send_to_messagebar(message, level=QgsMessageBar.CRITICAL, duration=0, addToLog=True, showLogPanel=True, exc_info=sys.exc_info()) @QtCore.pyqtSlot(name='on_cmdVariogramFile_clicked') def on_cmdVariogramFile_clicked(self): self.lneVariogramFile.clear() self.messageBar.clearWidgets() inFolder = read_setting( PLUGIN_NAME + "/" + self.toolKey + "/LastVariogramFolder") if inFolder is None or not os.path.exists(inFolder): inFolder = read_setting( PLUGIN_NAME + "/" + self.toolKey + "/LastVariogramFolder") if inFolder is None or not os.path.exists(inFolder): inFolder = read_setting(PLUGIN_NAME + '/BASE_IN_FOLDER') s = QtGui.QFileDialog.getOpenFileName(self, caption=self.tr("Choose the Vesper Variogram File"), directory=inFolder, filter='{} (*.txt);;{} (*.*);;'.format( self.tr("Variogram Text File(s)"), self.tr("All Files")) ) self.cleanMessageBars(self) if s == '': self.lneVariogramFile.setStyleSheet('color:red') self.lblVariogramFile.setStyleSheet('color:red') return if 'Variogram Model' not in open(s).read(): self.lneVariogramFile.setStyleSheet('color:red') self.lblVariogramFile.setStyleSheet('color:red') self.send_to_messagebar("Invalid Variogram File", level=QgsMessageBar.CRITICAL, duration=0, addToLog=True, showLogPanel=True, exc_info=sys.exc_info()) # self.lneVariogramFile.clear() return s = os.path.normpath(s) self.lblVariogramFile.setStyleSheet('color:black') self.lneVariogramFile.setStyleSheet('color:black') self.lneVariogramFile.setText(s) write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastVariogramFolder", os.path.dirname(s)) @QtCore.pyqtSlot(name='on_cmdVesperFold_clicked') def on_cmdVesperFold_clicked(self): self.messageBar.clearWidgets() if self.lneVesperFold.text() is None: outFolder = '' else: outFolder = self.lneVesperFold.text() if outFolder == '': outFolder = read_setting( PLUGIN_NAME + "/" + self.toolKey + "/LastVesperOutFolder") if outFolder is None or not os.path.exists(outFolder): outFolder = read_setting(PLUGIN_NAME + '/BASE_OUT_FOLDER') s = QtGui.QFileDialog.getExistingDirectory(self, self.tr( "Vesper processing folder. A Vesper sub-folder will be created."), outFolder, QtGui.QFileDialog.ShowDirsOnly) self.cleanMessageBars(self) if s == '' or s is None: return s = os.path.normpath(s) self.lblVesperFold.setStyleSheet('color:black') self.lneVesperFold.setStyleSheet('color:black') self.lneVesperFold.setText(s) write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastVesperOutFolder", s) @QtCore.pyqtSlot(int) def on_chkAutoCtrlFileName_stateChanged(self, state): self.updateCtrlFileName() @QtCore.pyqtSlot(name='on_cmdInCRS_clicked') def on_cmdInCRS_clicked(self): self.messageBar.clearWidgets() dlg = QgsGenericProjectionSelector(self) dlg.setMessage('Select coordinate system for the Vesper raster files') if dlg.exec_(): if dlg.selectedAuthId() != '': self.in_qgscrs = QgsCoordinateReferenceSystem(dlg.selectedAuthId()) if self.in_qgscrs == 'Unspecified' or self.in_qgscrs == '': self.lblInCRS.setText('Unspecified') self.lblOutCRS.setText('Unspecified') else: self.lblInCRS.setText('{} - {}'.format(self.in_qgscrs.description(), self.in_qgscrs.authid())) self.lblInCRS.setStyleSheet('color:black;background:transparent;') self.lblInCRSTitle.setStyleSheet('color:black') self.cleanMessageBars(self) @QtCore.pyqtSlot(int) def on_cboMethod_currentIndexChanged(self, index): self.stackedWidget.setCurrentIndex(index) self.updateCtrlFileName() if self.dfCSV is None: return if len(self.dfCSV) <= 100: self.cleanMessageBars(self) self.lneMinPoint.clear() QMessageBox.warning( self, 'Cannot Krige', 'Kriging is not advised for less than 100 points') if 'Low Density Kriging' in self.cboMethod.currentText(): if len(self.dfCSV) <= 150: # only partial file opened so open it all descCSV = describe.CsvDescribe(self.lneInCSVFile.text()) self.dfCSV = descCSV.open_pandas_dataframe() self.lblRowCount.setText("The maximum number of points is {}.".format(len(self.dfCSV))) self.lneMinPoint.setText(str(len(self.dfCSV) - 2)) else: self.lneMinPoint.clear() self.lblRowCount.setText('') def parse_variogram_file(self): vario_values = {} for line in open(self.lneVariogramFile.text()): # reset some text to control file tags line = line.replace('C0', 'CO') line = line.replace('Variogram Model', 'modtyp').strip() if set(':=.').intersection(set(line)): for ea in ['=', ':', ' ']: if ea in line: key, val = line.split(ea, 1) break # sort out the numerics from the strings try: key = int(float(key)) if int( float(key)) == float(key) else float(key) except ValueError: key = key.strip() try: val = int(float(val)) if int( float(val)) == float(val) else float(val) except ValueError: val = val.strip() # only return keys required for the control file. # and key in VESPER_OPTIONS.keys(): if isinstance(key, basestring): vario_values[key] = val return vario_values def validate_csv_grid_files(self, csv_file, grid_file, show_msgbox=True): """ validate the csv and grid files and check for overlap assuming that they are of the same coordinate system if True then message will be blank else a message will be generated """ overlaps = False if csv_file != '': if not os.path.exists(csv_file): return False, 'CSV file does not exist' else: try: df_csv = pd.read_csv(csv_file) csvX, csvY = predictCoordinateColumnNames(df_csv.columns) csv_bbox = box(df_csv[csvX].min(), df_csv[csvY].min(), df_csv[csvX].max(), df_csv[csvY].max()) except Exception as err: self.lblInCSVFile.setStyleSheet('color:red') self.lneInCSVFile.setStyleSheet('color:red') return False, 'Invalid CSV file' if grid_file != '': if not os.path.exists(grid_file): return False, 'Grid file does not exist' else: try: df_grid = pd.read_table(grid_file, names=['X', 'Y'], delimiter=' ', skipinitialspace=True) grid_bbox = box(df_grid['X'].min(), df_grid['Y'].min(), df_grid['X'].max(), df_grid['Y'].max()) except Exception as err: self.lblInGridFile.setStyleSheet('color:red') self.lneInGridFile.setStyleSheet('color:red') return False, 'Invalid VESPER grid file' # only continue if both inputs aren't blank if csv_file == '' or grid_file == '': # if one or the other is blank keep validate as true or it wont write to the GUI return True, None if csv_file == grid_file: return False, "VESPER grid file and CSV file cannot be the same file" # now we can check for overlap if self.in_qgscrs: epsg = self.in_qgscrs.authid() else: epsg = '' overlaps = check_for_overlap(csv_bbox.to_wkt(), grid_bbox.to_wkt(), epsg, epsg) if not overlaps: message = 'There is no overlap between the VESPER Grid file and the CSV file.\n' \ 'Please check input files and coordinate systems' if show_msgbox: QMessageBox.warning(self, 'No Overlap', message) self.lblInGridFile.setStyleSheet('color:red') self.lneInGridFile.setStyleSheet('color:red') self.lblInCSVFile.setStyleSheet('color:red') self.lneInCSVFile.setStyleSheet('color:red') else: message = None self.lblInGridFile.setStyleSheet('color:black') self.lneInGridFile.setStyleSheet('color:black') self.lblInCSVFile.setStyleSheet('color:black') self.lneInCSVFile.setStyleSheet('color:black') return overlaps, message def validate(self): """Check to see that all required gui elements have been entered and are valid.""" try: self.messageBar.clearWidgets() self.cleanMessageBars(AllBars=True) errorList = [] if self.lneInCSVFile.text() is None or self.lneInCSVFile.text() == '': self.lblInCSVFile.setStyleSheet('color:red') self.lneInCSVFile.setStyleSheet('color:red') errorList.append(self.tr("Select an input csv data file")) elif not os.path.exists(self.lneInCSVFile.text()): self.lblInCSVFile.setStyleSheet('color:red') self.lneInCSVFile.setStyleSheet('color:red') errorList.append(self.tr("Input csv data file does not exist")) else: self.lblInCSVFile.setStyleSheet('color:black') self.lneInCSVFile.setStyleSheet('color:black') if self.lneInGridFile.text() is None or self.lneInGridFile.text() == '': self.lblInGridFile.setStyleSheet('color:red') self.lneInGridFile.setStyleSheet('color:red') errorList.append(self.tr("Select a Vesper grid file")) elif not os.path.exists(self.lneInGridFile.text()): self.lblInGridFile.setStyleSheet('color:red') self.lneInGridFile.setStyleSheet('color:red') errorList.append(self.tr("Vesper grid file does not exists.")) else: self.lblInGridFile.setStyleSheet('color:black') self.lneInGridFile.setStyleSheet('color:black') if self.in_qgscrs is None: self.lblInCRSTitle.setStyleSheet('color:red') self.lblInCRS.setStyleSheet('color:red;background:transparent;') errorList.append(self.tr("Select a coordinate system")) else: self.lblInCRSTitle.setStyleSheet('color:black') self.lblInCRS.setStyleSheet('color:black;background:transparent;') pass_check, message = self.validate_csv_grid_files(self.lneInCSVFile.text(), self.lneInGridFile.text()) if not pass_check: errorList.append(self.tr(message)) # errorList.append(self.tr("Input csv file and grid file do not overlap. Could be " # "due to differing coordinate systems or invalid files")) if self.cboKrigColumn.currentText() == '': self.lblKrigColumn.setStyleSheet('color:red') errorList.append(self.tr("Select a column to krige")) else: self.lblKrigColumn.setStyleSheet('color:black') if self.cboMethod.currentText() != 'High Density Kriging': if self.lneVariogramFile.text() is None or self.lneVariogramFile.text() == '': self.lblVariogramFile.setStyleSheet('color:red') self.lneVariogramFile.setStyleSheet('color:red') errorList.append(self.tr("Select a variogram text file")) elif not os.path.exists(self.lneVariogramFile.text()): self.lblVariogramFile.setStyleSheet('color:red') self.lneVariogramFile.setStyleSheet('color:red') errorList.append(self.tr("Variogram text file does not exists.")) else: self.lblVariogramFile.setStyleSheet('color:black') self.lneVariogramFile.setStyleSheet('color:black') if int(self.lneMinPoint.text()) >= len(self.dfCSV): self.lneMinPoint.setStyleSheet('color:red') self.lneMinPoint.setStyleSheet('color:red') errorList.append( self.tr("Minimum number of points should be at least " "2 less than the dataset count")) else: self.lneMinPoint.setStyleSheet('color:black') self.lneMinPoint.setStyleSheet('color:black') if self.lneVesperFold.text() == '': self.lblVesperFold.setStyleSheet('color:red') errorList.append(self.tr("Select output Vesper data folder")) elif not os.path.exists(self.lneVesperFold.text()): self.lneVesperFold.setStyleSheet('color:red') errorList.append( self.tr("Output Vesper data folder does not exist")) else: self.lblVesperFold.setStyleSheet('color:black') self.lneVesperFold.setStyleSheet('color:black') ctrl_file = os.path.join(self.lneVesperFold.text(), self.lneCtrlFile.text()) if os.path.exists(ctrl_file): message = 'Vesper Control File {} already exists. Do you want to' \ ' overwrite?'.format(self.lneCtrlFile.text()) reply = QMessageBox.question( self, 'Control File', message, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: self.overwrite_ctrl_file = True self.lblVesperFold.setStyleSheet('color:black') else: self.overwrite_ctrl_file = False self.lblCtrlFile.setStyleSheet('color:red') errorList.append( self.tr("Output control file exists please choose a different name")) if len(errorList) > 0: raise ValueError(errorList) except ValueError as e: self.cleanMessageBars(True) if len(errorList) > 0: for i, ea in enumerate(errorList): self.send_to_messagebar( unicode(ea), level=QgsMessageBar.WARNING, duration=(i + 1) * 5) return False return True def accept(self, *args, **kwargs): if not self.validate(): return False try: self.cleanMessageBars(True) message = '- and run VESPER' if self.gbRunVesper.isChecked() else '' LOGGER.info('{st}\nProcessing {} {}'.format( self.windowTitle(), message, st='*' * 50)) # Add settings to log settingsStr = 'Parameters:---------------------------------------' settingsStr += '\n {:30}\t{}'.format('Data File:', self.lneInCSVFile.text()) settingsStr += '\n {:30}\t{}'.format('Krige Column:', self.cboKrigColumn.currentText()) settingsStr += '\n {:30}\t{}'.format('Grid File:', self.lneInGridFile.text()) settingsStr += '\n {:30}\t{}'.format('Output Vesper Folder:', self.lneVesperFold.text()) settingsStr += '\n {:30}\t{}'.format(self.cboMethod.currentText(), '') if self.cboMethod.currentText() == 'High Density Kriging': settingsStr += '\n {:30}\t{}'.format('Block Kriging Size:', int(self.dsbBlockKrigSize.value())) else: settingsStr += '\n {:30}\t{}'.format('Variogram File:', self.lneVariogramFile.text()) settingsStr += '\n {:30}\t{}'.format('Min Point Number:', self.lneMinPoint.text()) settingsStr += '\n {:30}\t{}'.format( 'Display Vesper Graphics:', self.chkDisplayGraphics.isChecked()) settingsStr += '\n {:30}\t{}'.format( 'Run Vesper Now:', self.gbRunVesper.isChecked()) if self.gbRunVesper.isChecked(): settingsStr += '\n {:30}\t{}'.format('Import Vesper Files to Rasters:', self.chkVesper2Raster.isChecked()) if self.chkVesper2Raster.isChecked(): settingsStr += '\n {:30}\t{}'.format( 'Vesper Files Coordinate System:', self.lblInCRS.text()) LOGGER.info(settingsStr) # get a fresh dataframe for the input csv file self.dfCSV = pd.read_csv(self.lneInCSVFile.text()) vc = VesperControl() if self.cboMethod.currentText() == 'High Density Kriging': vc.update(xside=int(self.dsbBlockKrigSize.value()), yside=int(self.dsbBlockKrigSize.value())) else: # from the variogram text file find and update the control file keys vario = self.parse_variogram_file() vesp_keys = {key: val for key, val in vario.items() if key in vc} vc.update(vesp_keys) # apply the other keys. vc.update({'jpntkrg': 1, 'jlockrg': 0, 'minpts': int(self.lneMinPoint.text()), 'maxpts': len(self.dfCSV), 'jcomvar': 0, }) epsg = int(self.in_qgscrs.authid().replace('EPSG:', '')) bat_file, ctrl_file = prepare_for_vesper_krige(self.dfCSV, self.cboKrigColumn.currentText(), self.lneInGridFile.text(), self.lneVesperFold.text(), control_textfile=self.lneCtrlFile.text(), coord_columns=[], epsg=epsg, display_graphics=self.chkDisplayGraphics.isChecked(), control_options=vc) epsg = 0 if self.in_qgscrs is not None and self.chkVesper2Raster.isChecked(): epsg = int(self.in_qgscrs.authid().replace('EPSG:', '')) if self.gbRunVesper.isChecked(): # Add to vesper queue self.vesp_dict = {'control_file': ctrl_file, 'epsg': epsg} else: message = 'Successfully created files for Vesper kriging. ' \ 'The control file is {}'.format(ctrl_file) self.send_to_messagebar(message, level=QgsMessageBar.SUCCESS, duration=0, addToLog=True, core_QGIS=True) LOGGER.info('Successfully created files for Vesper kriging') QtGui.qApp.restoreOverrideCursor() return super(PreVesperDialog, self).accept(*args, **kwargs) except Exception as err: QtGui.qApp.restoreOverrideCursor() self.cleanMessageBars(True) self.send_to_messagebar(str(err), level=QgsMessageBar.CRITICAL, duration=0, addToLog=True, showLogPanel=True, exc_info=sys.exc_info()) return False
class Dialog(QDialog, Ui_Dialog): def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.iface = iface self.setupUi(self) self.toolOut.setEnabled(False) self.toolOut.setVisible(False) self.outShape.setEnabled(False) self.outShape.setVisible(False) self.label_2.setVisible(False) self.label_2.setEnabled(False) self.setWindowTitle(self.tr("Define current projection")) self.buttonOk = self.buttonBox_2.button(QDialogButtonBox.Ok) QObject.connect(self.btnProjection, SIGNAL("clicked()"), self.outProjFile) QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.updateProj1) QObject.connect(self.cmbLayer, SIGNAL("currentIndexChanged(QString)"), self.updateProj2) # populate layer list self.progressBar.setValue(0) layers = ftools_utils.getLayerNames( [QGis.Point, QGis.Line, QGis.Polygon]) self.inShape.addItems(layers) self.cmbLayer.addItems(layers) self.crs = None def updateProj1(self, layerName): self.inRef.clear() tempLayer = ftools_utils.getVectorLayerByName(layerName) crs = tempLayer.dataProvider().crs() if crs.isValid(): self.inRef.insert(crs.authid() + " - " + crs.description()) else: self.inRef.insert(self.tr("Missing or invalid CRS")) def updateProj2(self, layerName): self.outRef.clear() tempLayer = ftools_utils.getVectorLayerByName(layerName) crs = tempLayer.dataProvider().crs() if crs.isValid(): self.outRef.insert(crs.authid() + " - " + crs.description()) else: self.outRef.insert(self.tr("Missing or invalid CRS")) def accept(self): self.buttonOk.setEnabled(False) if self.inShape.currentText() == "": QMessageBox.information(self, self.tr("Define current projection"), self.tr("No input shapefile specified")) elif self.txtProjection.text() == "" and self.rdoProjection.isChecked( ): QMessageBox.information( self, self.tr("Define current projection"), self.tr("Please specify spatial reference system")) elif self.cmbLayer.currentText() == "" and self.rdoLayer.isChecked(): QMessageBox.information( self, self.tr("Define current projection"), self.tr("Please specify spatial reference system")) else: self.progressBar.setValue(5) inName = self.inShape.currentText() self.progressBar.setValue(10) vLayer = ftools_utils.getVectorLayerByName(inName) self.progressBar.setValue(30) if vLayer == "Error": QMessageBox.information( self, self.tr("Define current projection"), self.tr( "Cannot define projection for PostGIS data...yet!")) else: srsDefine = None if self.rdoProjection.isChecked(): srsDefine = self.crs else: destLayer = ftools_utils.getVectorLayerByName( self.cmbLayer.currentText()) srsDefine = destLayer.crs() if srsDefine == vLayer.crs(): responce = QMessageBox.question( self, self.tr("Define current projection"), self. tr("Identical output spatial reference system chosen\n\nAre you sure you want to proceed?" ), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton) if responce == QMessageBox.No: self.progressBar.setValue(0) self.buttonOk.setEnabled(True) return provider = vLayer.dataProvider() self.progressBar.setValue(35) inPath = provider.dataSourceUri() p = re.compile("\|.*") inPath = p.sub("", inPath) self.progressBar.setValue(40) if inPath.endswith(".shp"): inPath = inPath[:-4] self.progressBar.setValue(55) if not srsDefine.isValid(): QMessageBox.information( self, self.tr("Define current projection"), self.tr( "Output spatial reference system is not valid")) else: self.progressBar.setValue(60) outputWkt = srsDefine.toWkt() self.progressBar.setValue(65) outputFile = QFile(inPath + ".prj") outputFile.open(QIODevice.WriteOnly | QIODevice.Text) outputPrj = QTextStream(outputFile) outputPrj << outputWkt outputPrj.flush() outputFile.close() self.progressBar.setValue(70) checkFile = QFile(inPath + ".qpj") if checkFile.exists(): checkFile.open(QIODevice.WriteOnly | QIODevice.Text) outputPrj = QTextStream(checkFile) outputPrj << outputWkt outputPrj.flush() checkFile.close() self.progressBar.setValue(95) vLayer.setCrs(srsDefine) self.progressBar.setValue(100) QMessageBox.information( self, self.tr("Define current projection"), self.tr("Defined Projection For:\n%s.shp") % (inPath)) self.progressBar.setValue(0) self.buttonOk.setEnabled(True) def outProjFile(self): header = "Define layer CRS:" sentence1 = self.tr( "Please select the projection system that defines the current layer." ) sentence2 = self.tr( "Layer CRS information will be updated to the selected CRS.") projSelector = QgsGenericProjectionSelector(self) projSelector.setMessage("<h2>%s</h2>%s <br/> %s" % (header, sentence1, sentence2)) if projSelector.exec_(): self.crs = QgsCoordinateReferenceSystem( projSelector.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId) print "AUTHID", projSelector.selectedAuthId() if len(projSelector.selectedAuthId()) == 0: QMessageBox.information(self, self.tr("Export to new projection"), self.tr("No Valid CRS selected")) return else: self.txtProjection.clear() self.txtProjection.insert(self.crs.authid() + " - " + self.crs.description()) else: return
class rasterLayerPropertyDlg(QDialog): ''' classdocs ''' def __init__(self, parent, layer): ''' Constructor ''' QDialog.__init__(self, parent) self.resize(200, 200) self.rasterLayer = layer sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) verticalLayout = QVBoxLayout(self) verticalLayout.setObjectName("verticalLayout") stackedWidget = QStackedWidget(self) stackedWidget.setObjectName("stackedWidget") pageRender = QWidget(stackedWidget) pageRender.setObjectName("pageRender") sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(pageRender.sizePolicy().hasHeightForWidth()) pageRender.setSizePolicy(sizePolicy) horizontalLayout = QHBoxLayout(pageRender) horizontalLayout.setObjectName("horizontalLayout") frameRender = QFrame(pageRender) frameRender.setObjectName("frameRender") frameRender.setFrameShape(QFrame.StyledPanel) frameRender.setFrameShadow(QFrame.Raised) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(frameRender.sizePolicy().hasHeightForWidth()) frameRender.setSizePolicy(sizePolicy) self.vLayoutFrameRender = QVBoxLayout(frameRender) self.vLayoutFrameRender.setObjectName("vLayoutFrameRender") horizontalLayout.addWidget(frameRender) self.cmbRendererType = ComboBoxPanel(frameRender) self.cmbRendererType.Caption = "Render Type" self.cmbRendererType.LabelWidth = 70 self.cmbRendererType.Items = ["Mutiband color", "Paletted", "Singleband gray", "Singleband pseudocolor"] self.connect(self.cmbRendererType, SIGNAL("Event_0"), self.cmbRendererType_currentIndexChanged) self.vLayoutFrameRender.addWidget(self.cmbRendererType) self.gbRenderer = GroupBox(frameRender) self.gbRenderer.Caption = self.cmbRendererType.SelectedItem self.vLayoutFrameRender.addWidget(self.gbRenderer) self.qgsMultiBandColorRendererWidget = QgsMultiBandColorRendererWidget(self.rasterLayer) self.qgsPalettedRendererWidget = QgsPalettedRendererWidget(self.rasterLayer) self.qgsSingleBandGrayRendererWidget = QgsSingleBandGrayRendererWidget(self.rasterLayer) self.qgsSingleBandPseudoColorRendererWidget = QgsSingleBandPseudoColorRendererWidget(self.rasterLayer) self.gbRenderer.Add = self.qgsMultiBandColorRendererWidget self.gbRenderer.Add = self.qgsPalettedRendererWidget self.gbRenderer.Add = self.qgsSingleBandGrayRendererWidget self.gbRenderer.Add = self.qgsSingleBandPseudoColorRendererWidget self.qgsPalettedRendererWidget.setVisible(False) self.qgsSingleBandGrayRendererWidget.setVisible(False) self.qgsSingleBandPseudoColorRendererWidget.setVisible(False) stackedWidget.addWidget(pageRender) # page_2 = QWidget() # page_2.setObjectName("page_2") # stackedWidget.addWidget(page_2) verticalLayout.addWidget(stackedWidget) buttonBox = QDialogButtonBox(self) buttonBox.setObjectName("buttonBox") buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Apply) btnApply = buttonBox.button(QDialogButtonBox.Apply) btnApply.clicked.connect(self.btnApply_clicked) verticalLayout.addWidget(buttonBox) # retranslateUi(Dialog) buttonBox.accepted.connect(self.OK) buttonBox.rejected.connect(self.reject) if self.rasterLayer.renderer().bandCount() == 1: self.cmbRendererType.SelectedIndex = 2 elif self.rasterLayer.renderer().bandCount() > 1: self.cmbRendererType.SelectedIndex = 0 # QObject.connect(buttonBox, SIGNAL("accepted()"), self, SLOT(accept())) # QObject.connect(buttonBox, SIGNAL("rejected()"), self, SLOT(reject())) def cmbRendererType_currentIndexChanged(self): if self.cmbRendererType.SelectedIndex == 0: self.qgsPalettedRendererWidget.setVisible(False) self.qgsSingleBandGrayRendererWidget.setVisible(False) self.qgsSingleBandPseudoColorRendererWidget.setVisible(False) # self.resize(200, 200) self.qgsMultiBandColorRendererWidget.setVisible(True) elif self.cmbRendererType.SelectedIndex == 1: self.qgsMultiBandColorRendererWidget.setVisible(False) self.qgsSingleBandGrayRendererWidget.setVisible(False) self.qgsSingleBandPseudoColorRendererWidget.setVisible(False) # self.resize(200, 200) self.qgsPalettedRendererWidget.setVisible(True) elif self.cmbRendererType.SelectedIndex == 2: self.qgsMultiBandColorRendererWidget.setVisible(False) self.qgsPalettedRendererWidget.setVisible(False) self.qgsSingleBandPseudoColorRendererWidget.setVisible(False) # self.resize(200, 200) self.qgsSingleBandGrayRendererWidget.setVisible(True) else: self.qgsMultiBandColorRendererWidget.setVisible(False) self.qgsPalettedRendererWidget.setVisible(False) self.qgsSingleBandGrayRendererWidget.setVisible(False) self.qgsSingleBandPseudoColorRendererWidget.setVisible(True) self.resize(200, 200) self.gbRenderer.Caption = self.cmbRendererType.SelectedItem def selectCrs(self): projectionDlg = QgsGenericProjectionSelector(self) projectionDlg.setSelectedAuthId(self.mCrs.authid()) if projectionDlg.exec_(): self.mCrs = QgsCoordinateReferenceSystem(projectionDlg.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId) self.ui.txtCrs.setText(self.mCrs.authid() + " - " + self.mCrs.description()) def changeStackWidget(self, index): self.ui.stackedWidget.setCurrentIndex(index) def btnApply_clicked(self): if self.cmbRendererType.SelectedIndex == 0: self.rasterLayer.setRenderer(self.qgsMultiBandColorRendererWidget.renderer()) elif self.cmbRendererType.SelectedIndex == 1: self.rasterLayer.setRenderer(self.qgsPalettedRendererWidget.renderer()) elif self.cmbRendererType.SelectedIndex == 2: self.rasterLayer.setRenderer(self.qgsSingleBandGrayRendererWidget.renderer()) else: self.rasterLayer.setRenderer(self.qgsSingleBandPseudoColorRendererWidget.renderer()) self.rasterLayer.triggerRepaint() def OK(self): self.btnApply_clicked() QDialog.accept(self)
def initializeExistingGeoreferencing(self, dataset, georef): # georef can have scaling, rotation or translation rotation = 180 / math.pi * -math.atan2(georef[4], georef[1]) sx = math.sqrt(georef[1] ** 2 + georef[4] ** 2) sy = math.sqrt(georef[2] ** 2 + georef[5] ** 2) i_center_x = self.image.width() / 2 i_center_y = self.image.height() / 2 center = QgsPointXY( georef[0] + georef[1] * i_center_x + georef[2] * i_center_y, georef[3] + georef[4] * i_center_x + georef[5] * i_center_y, ) qDebug(repr(rotation) + " " + repr((sx, sy)) + " " + repr(center)) self.setRotation(rotation) self.setCenter(center) # keep yScale positive self.setScale(sx, sy) self.commitTransformParameters() crs_wkt = dataset.GetProjection() message_shown = False if crs_wkt: qcrs = QgsCoordinateReferenceSystem(crs_wkt) # TODO check change if qcrs.description() != self.crs().description(): # reproject try: self.reprojectTransformParameters(qcrs, self.crs()) self.commitTransformParameters() self.showBarMessage( "Transform parameters changed: ", "Found existing georeferencing in raster but " "its CRS does not match the CRS of the map. " "Reprojected the extent.", Qgis.Warning, 25, ) message_shown = True except Exception as ex: QgsMessageLog.logMessage(repr(ex)) self.showBarMessage( "CRS does not match", "Found existing georeferencing in raster but " "its CRS does not match the CRS of the map. " "Unable to reproject.", Qgis.Warning, 5, ) message_shown = True # if no projection info, assume it is the same CRS # as the map and no warning if not message_shown: self.showBarMessage( "Georeferencing loaded", "Found existing georeferencing in raster", Qgis.Info, 3, ) # zoom (assume the user wants to work on the image) self.iface.mapCanvas().setExtent(self.extent())
class layerSaveAsDlg(QDialog): ''' classdocs ''' def __init__(self, parent, layer): ''' Constructor ''' QDialog.__init__(self, parent) self.ui = ui_layerSaveAsDlg() self.ui.setupUi(self) # self.layerSet = layerSet self.baseLayer = layer self.shpFormats = ["ESRI Shapefile", "GeoJSON"] self.fileTypes = ["ESRI Shape file(*.shp )", "GeoJSON(*.geojson)"] self.crsList = ["Layer CRS", "Project CRS", "Selected CRS"] self.ui.cmbFormat.addItems(self.shpFormats) self.ui.cmbCrs.addItems(self.crsList) self.ui.btnBrowse.clicked.connect(self.browse) self.ui.txtCrs.setText("WGS 84") self.ui.txtCrs.setEnabled(False) # self.ui.cmbFormat.currentIndexChanged.connect(self.enableTxtAPV) self.ui.cmbCrs.currentIndexChanged.connect(self.crsSelectChange) self.ui.btnChange.clicked.connect(self.crsChange) self.ui.buttonBox.accepted.connect(self.saveLayer) self.crs = QgsCoordinateReferenceSystem( 4326, QgsCoordinateReferenceSystem.EpsgCrsId) def browse(self): type1 = self.fileTypes[self.ui.cmbFormat.currentIndex()] filePath = QFileDialog.getSaveFileName( self, "Save layer as...", QCoreApplication.applicationDirPath(), type1) self.ui.txtSavePath.setText(filePath) def crsSelectChange(self): if self.ui.cmbCrs.currentIndex() == 2: self.ui.txtCrs.setEnabled(True) else: self.ui.txtCrs.setEnabled(False) def crsChange(self): projectionDlg = QgsGenericProjectionSelector(self) projectionDlg.exec_() # print projectionDlg.selectedCrsId() srs = QgsCoordinateReferenceSystem( projectionDlg.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId) self.mCRS = srs.srsid() self.crs = QgsCoordinateReferenceSystem() self.crs.createFromId(self.mCRS, QgsCoordinateReferenceSystem.InternalCrsId) # authId = projectionDlg.selectedAuthId() # crsId = projectionDlg.selectedCrsId() # if authId != "": # if authId[:4] != "EPSG": # self.crs = QgsCoordinateReferenceSystem(crsId, QgsCoordinateReferenceSystem.InternalCrsId) # else: # self.crs = QgsCoordinateReferenceSystem(crsId, QgsCoordinateReferenceSystem.EpsgCrsId) self.ui.cmbCrs.setCurrentIndex(2) self.ui.txtCrs.setText(self.crs.description()) def saveLayer(self): destCrs = None ct = QgsCoordinateTransform() if self.ui.txtSavePath.text() == "": QMessageBox.warning(self, "Error", "Please input save file path") return else: if self.ui.cmbCrs.currentIndex() == 0: if self.baseLayer.crs() is None: destCrs = QgsCoordinateReferenceSystem( 4326, QgsCoordinateReferenceSystem.EpsgCrsId) # er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs, self.ui.cmbFormat.currentText()) else: destCrs = self.baseLayer.crs() print destCrs.authid() # er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", self.baseLayer.crs(), self.ui.cmbFormat.currentText()) elif self.ui.cmbCrs.currentIndex() == 1: destCrs = define._canvas.mapSettings().destinationCrs() if destCrs is None: destCrs = QgsCoordinateReferenceSystem( 4326, QgsCoordinateReferenceSystem.EpsgCrsId) # er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs, self.ui.cmbFormat.currentText()) # else: # er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs, self.ui.cmbFormat.currentText()) else: destCrs = QgsCoordinateReferenceSystem( self.mCRS, QgsCoordinateReferenceSystem.InternalCrsId) if destCrs != self.baseLayer.crs(): ct = QgsCoordinateTransform(self.baseLayer.crs(), destCrs) er = QgsVectorFileWriter.writeAsVectorFormat( self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs, self.ui.cmbFormat.currentText()) # er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", self.crs, self.ui.cmbFormat.currentText()) QMessageBox.information( self, "Successful", "Export to vector file has been completed. ") QDialog.accept(self)
class LoadByCategory(QtGui.QDialog, load_by_category_dialog.Ui_LoadByCategory): def __init__(self, parent=None): """Constructor.""" super(LoadByCategory, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.categories = [] self.selectedClasses = [] self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] #Sql factory generator self.isSpatialite = True self.setupUi(self) self.tabWidget.setCurrentIndex(0) self.factory = SqlGeneratorFactory() self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.utils = Utils() self.parentTreeNode = None self.comboBoxPostgis.setCurrentIndex(0) self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0,0,0,0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0,0,1,1) #Objects Connections QtCore.QObject.connect(self.pushButtonOpenFile, QtCore.SIGNAL(("clicked()")), self.loadDatabase) QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel) QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected) QtCore.QObject.connect(self.tabWidget,QtCore.SIGNAL(("currentChanged(int)")), self.restoreInitialState) QtCore.QObject.connect(self.pushButtonSelectAll, QtCore.SIGNAL(("clicked()")), self.selectAll) QtCore.QObject.connect(self.pushButtonDeselectAll, QtCore.SIGNAL(("clicked()")), self.deselectAll) QtCore.QObject.connect(self.pushButtonSelectOne, QtCore.SIGNAL(("clicked()")), self.selectOne) QtCore.QObject.connect(self.pushButtonDeselectOne, QtCore.SIGNAL(("clicked()")), self.deselectOne) QtCore.QObject.connect(self.checkBoxAll, QtCore.SIGNAL(("stateChanged(int)")), self.setAllGroup) self.db = None #populating the postgis combobox self.populatePostGISConnectionsCombo() def __del__(self): self.closeDatabase() def closeDatabase(self): if self.db: self.db.close() self.db = None def restoreInitialState(self): self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.categories = [] self.selectedClasses = [] self.spatialiteFileEdit.setText(self.filename) self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] self.parentTreeNode = None #Setting the database type if self.tabWidget.currentIndex() == 0: self.isSpatialite = True else: self.isSpatialite = False #getting the sql generator according to the database type self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.comboBoxPostgis.setCurrentIndex(0) self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) def updateBDField(self): if self.dbLoaded == True: self.spatialiteFileEdit.setText(self.filename) else: self.filename = "" self.spatialiteFileEdit.setText(self.filename) def getDatabaseVersion(self): self.dbVersion = self.utils.getDatabaseVersion(self.db) self.qmlPath = self.utils.getQmlDir(self.db) def listCategoriesFromDatabase(self): self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) self.getDatabaseVersion() while query.next(): if self.isSpatialite: tableName = query.value(0) layerName = tableName split = tableName.split('_') if len(split) < 2: continue if self.dbVersion == '3.0' or self.dbVersion == '2.1.3': schema = split[0] category = split[1] categoryName = schema+'.'+category else: categoryName = split[0] #done this way to have back compatibility with spatialites already in production else: tableSchema = query.value(0) tableName = query.value(1) split = tableName.split('_') category = split[0] categoryName = tableSchema+'.'+category layerName = tableSchema+'.'+tableName if layerName.split("_")[-1] == "p": self.point.append(layerName) if layerName.split("_")[-1] == "l": self.line.append(layerName) if layerName.split("_")[-1] == "a": self.polygon.append(layerName) if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" \ or tableName.split("_")[-1] == "a": self.insertIntoListView(categoryName) self.listWidgetCategoryFrom.sortItems() self.setCRS() def insertIntoListView(self, item_name): found = self.listWidgetCategoryFrom.findItems(item_name, Qt.MatchExactly) if len(found) == 0: item = QtGui.QListWidgetItem(item_name) self.listWidgetCategoryFrom.addItem(item) def selectAll(self): tam = self.listWidgetCategoryFrom.__len__() for i in range(tam+1,1,-1): item = self.listWidgetCategoryFrom.takeItem(i-2) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectAll(self): tam = self.listWidgetCategoryTo.__len__() for i in range(tam+1,1,-1): item = self.listWidgetCategoryTo.takeItem(i-2) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def selectOne(self): listedItems = self.listWidgetCategoryFrom.selectedItems() for i in listedItems: item = self.listWidgetCategoryFrom.takeItem(self.listWidgetCategoryFrom.row(i)) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectOne(self): listedItems = self.listWidgetCategoryTo.selectedItems() for i in listedItems: item = self.listWidgetCategoryTo.takeItem(self.listWidgetCategoryTo.row(i)) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def setAllGroup(self): if self.checkBoxAll.isChecked(): self.checkBoxPoint.setCheckState(2) self.checkBoxLine.setCheckState(2) self.checkBoxPolygon.setCheckState(2) else: self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) def setCRS(self): try: self.epsg = self.utils.findEPSG(self.db) if self.epsg == -1: self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): if self.comboBoxPostgis.currentIndex() > 0: self.loadDatabase() def loadDatabase(self): self.closeDatabase() if self.isSpatialite: (self.filename, self.db) = self.utils.getSpatialiteDatabase() if self.filename: self.spatialiteFileEdit.setText(self.filename) else: self.db = self.utils.getPostGISDatabase(self.comboBoxPostgis.currentText()) try: if not self.db.open(): QgsMessageLog.logMessage(self.db.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL) else: self.dbLoaded = True self.listCategoriesFromDatabase() except: pass def populatePostGISConnectionsCombo(self): self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem("Select Database") self.comboBoxPostgis.addItems(self.utils.getPostGISConnections()) def cancel(self): self.restoreInitialState() self.close() def getSelectedItems(self): lista = self.classesListWidget.selectedItems() self.selectedClasses = [] tam = len(lista) for i in range(tam): self.selectedClasses.append(lista[i].text()) self.selectedClasses.sort() def okSelected(self): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.checkBoxOnlyWithElements.isChecked(): self.setLayersWithElements() ponto = self.pointWithElement linha = self.lineWithElement area = self.polygonWithElement else: ponto = self.point linha = self.line area = self.polygon if self.db and self.crs and len(self.listWidgetCategoryTo)>0: categoriasSelecionadas = [] for i in range(self.listWidgetCategoryTo.__len__()): categoriasSelecionadas.append(self.listWidgetCategoryTo.item(i).text()) try: if self.checkBoxPoint.isChecked(): self.loadLayers('p',categoriasSelecionadas,ponto) if self.checkBoxLine.isChecked(): self.loadLayers('l',categoriasSelecionadas,linha) if self.checkBoxPolygon.isChecked(): self.loadLayers('a',categoriasSelecionadas,area) if self.checkBoxPoint.isChecked()== False and self.checkBoxLine.isChecked() == False and self.checkBoxPolygon.isChecked() == False: self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one type of layer!"), level=QgsMessageBar.WARNING) else: self.restoreInitialState() self.close() except: qgis.utils.iface.messageBar().pushMessage(self.tr("CRITICAL!"), self.tr("Problem loading the categories!"), level=QgsMessageBar.CRITICAL) pass else: if self.db and not self.crs: self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL) if not self.db and not self.crs: self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Database not loaded properly!"), level=QgsMessageBar.CRITICAL) self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL) if len(self.listWidgetCategoryTo)==0: self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one category!"), level=QgsMessageBar.WARNING) categoriasSelecionadas = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] QApplication.restoreOverrideCursor() except: QApplication.restoreOverrideCursor() def loadLayers(self, type, categories, layer_names): if self.isSpatialite: self.loadSpatialiteLayers(type, categories, layer_names) else: self.loadPostGISLayers(type, categories, layer_names) def setLayersWithElements(self): self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] pontoAux = self.countElements(self.point) linhaAux = self.countElements(self.line) areaAux = self.countElements(self.polygon) for i in pontoAux: if i[1] > 0: self.pointWithElement.append(i[0]) for i in linhaAux: if i[1] > 0: self.lineWithElement.append(i[0]) for i in areaAux: if i[1] > 0: self.polygonWithElement.append(i[0]) def countElements(self, layers): listaQuantidades = [] for layer in layers: sql = self.gen.getElementCountFromLayer(layer) query = QSqlQuery(sql,self.db) query.next() number = query.value(0) if not query.exec_(sql): QgsMessageLog.logMessage(self.tr("Problem counting elements: ")+query.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL) listaQuantidades.append([layer, number]) return listaQuantidades def loadPostGISLayers(self, type, categories, layer_names): (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText()) uri = QgsDataSourceURI() uri.setConnection(str(host),str(port), str(database), str(user), str(password)) geom_column = 'geom' if self.parentTreeNode is None: self.parentTreeNode = qgis.utils.iface.legendInterface (). addGroup (database, -1) if type == 'p': idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Ponto", True,self.parentTreeNode) for categoria in categories: self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'l': idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Linha", True,self.parentTreeNode) for categoria in categories: self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'a': idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Area", True,self.parentTreeNode) for categoria in categories: self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column) def preparePostGISToLoad(self, uri, categoria, layer_names, idGrupo, geom_column): idSubgrupo = qgis.utils.iface.legendInterface().addGroup(categoria, True, idGrupo) layer_names.sort(reverse=True) for layer_name in layer_names: split = layer_name.split('_') category = split[0] schema = category.split('.')[0] name = layer_name.replace(schema+'.', '') if category == categoria: sql = self.gen.loadLayerFromDatabase(layer_name) uri.setDataSource(schema, name, geom_column, sql, 'id') uri.disableSelectAtId(True) self.loadEDGVLayer(uri, name, 'postgres', idSubgrupo) def prepareSpatialiteToLoad(self, uri, categoria, layer_names, idGrupo, geom_column): idSubgrupo = qgis.utils.iface.legendInterface().addGroup(categoria, True, idGrupo) layer_names.sort(reverse=True) for layer_name in layer_names: split = layer_name.split('_') if self.dbVersion == '3.0' or self.dbVersion == '2.1.3': category = split[0]+'.'+split[1] else: category = split[0] if category == categoria: uri.setDataSource('', layer_name, geom_column) self.loadEDGVLayer(uri, layer_name, 'spatialite', idSubgrupo) def loadSpatialiteLayers(self, type, categories, layer_names): uri = QgsDataSourceURI() uri.setDatabase(self.filename) geom_column = 'GEOMETRY' if self.parentTreeNode is None: self.parentTreeNode = qgis.utils.iface.legendInterface(). addGroup(self.filename.split('.sqlite')[0].split('/')[-1], -1) if type == 'p': idGrupo = qgis.utils.iface.legendInterface(). addGroup("Ponto", True, self.parentTreeNode) for categoria in categories: self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'l': idGrupo = qgis.utils.iface.legendInterface(). addGroup("Linha", True, self.parentTreeNode) for categoria in categories: self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'a': idGrupo = qgis.utils.iface.legendInterface(). addGroup("Area", True, self.parentTreeNode) for categoria in categories: self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column) def loadEDGVLayer(self, uri, layer_name, provider, idSubgrupo): 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) qgis.utils.iface.legendInterface().moveLayer(vlayer, idSubgrupo) if not vlayer.isValid(): QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
class LoadByCategory(QtGui.QDialog, FORM_CLASS): def __init__(self, codeList, parent=None): """Constructor.""" super(LoadByCategory, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.categories = [] self.selectedClasses = [] self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] self.parentTreeNode = None self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0,0,0,0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0,0,1,1) #Objects Connections self.widget.connectionChanged.connect(self.listCategoriesFromDatabase) self.widget.problemOccurred.connect(self.pushMessage) self.pushButtonCancel.clicked.connect(self.cancel) self.pushButtonOk.clicked.connect(self.okSelected) self.pushButtonSelectAll.clicked.connect(self.selectAll) self.pushButtonDeselectAll.clicked.connect(self.deselectAll) self.pushButtonSelectOne.clicked.connect(self.selectOne) self.pushButtonDeselectOne.clicked.connect(self.deselectOne) self.checkBoxAll.stateChanged.connect(self.setAllGroup) self.widget.tabWidget.currentChanged.connect(self.restoreInitialState) self.codeList = codeList self.layerFactory = LayerFactory() def restoreInitialState(self): self.categories = [] self.selectedClasses = [] self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] self.parentTreeNode = None self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) def listCategoriesFromDatabase(self): self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() self.dbVersion = self.widget.getDBVersion() self.qmlPath = self.widget.getQmlPath() classes = self.widget.abstractDb.listGeomClassesFromDatabase() for table in classes: schema, layerName = self.widget.abstractDb.getTableSchema(table) category = layerName.split('_')[0] categoryName = schema+'.'+category if layerName.split("_")[-1] == "p": self.point.append(table) if layerName.split("_")[-1] == "l": self.line.append(table) if layerName.split("_")[-1] == "a": self.polygon.append(table) self.insertIntoListView(categoryName) self.listWidgetCategoryFrom.sortItems() self.setCRS() def insertIntoListView(self, item_name): found = self.listWidgetCategoryFrom.findItems(item_name, Qt.MatchExactly) if len(found) == 0: item = QtGui.QListWidgetItem(item_name) self.listWidgetCategoryFrom.addItem(item) def selectAll(self): tam = self.listWidgetCategoryFrom.__len__() for i in range(tam+1,1,-1): item = self.listWidgetCategoryFrom.takeItem(i-2) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectAll(self): tam = self.listWidgetCategoryTo.__len__() for i in range(tam+1,1,-1): item = self.listWidgetCategoryTo.takeItem(i-2) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def selectOne(self): listedItems = self.listWidgetCategoryFrom.selectedItems() for i in listedItems: item = self.listWidgetCategoryFrom.takeItem(self.listWidgetCategoryFrom.row(i)) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectOne(self): listedItems = self.listWidgetCategoryTo.selectedItems() for i in listedItems: item = self.listWidgetCategoryTo.takeItem(self.listWidgetCategoryTo.row(i)) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def setAllGroup(self): if self.checkBoxAll.isChecked(): self.checkBoxPoint.setCheckState(2) self.checkBoxLine.setCheckState(2) self.checkBoxPolygon.setCheckState(2) else: self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) def pushMessage(self, msg): self.bar.pushMessage('', msg, level=QgsMessageBar.WARNING) def setCRS(self): try: self.epsg = self.utils.findEPSG(self.db) if self.epsg == -1: self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass def cancel(self): self.restoreInitialState() self.close() def getSelectedItems(self): lista = self.classesListWidget.selectedItems() self.selectedClasses = [] tam = len(lista) for i in range(tam): self.selectedClasses.append(lista[i].text()) self.selectedClasses.sort() def okSelected(self): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.checkBoxOnlyWithElements.isChecked(): self.setLayersWithElements() ponto = self.pointWithElement linha = self.lineWithElement area = self.polygonWithElement else: ponto = self.point linha = self.line area = self.polygon if len(self.listWidgetCategoryTo)>0: categoriasSelecionadas = [] for i in range(self.listWidgetCategoryTo.__len__()): categoriasSelecionadas.append(self.listWidgetCategoryTo.item(i).text()) if self.checkBoxPoint.isChecked(): self.loadLayers('p', categoriasSelecionadas, ponto) if self.checkBoxLine.isChecked(): self.loadLayers('l', categoriasSelecionadas, linha) if self.checkBoxPolygon.isChecked(): self.loadLayers('a', categoriasSelecionadas, area) if self.checkBoxPoint.isChecked()== False and self.checkBoxLine.isChecked() == False and self.checkBoxPolygon.isChecked() == False: self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one type of layer!"), level=QgsMessageBar.WARNING) else: self.restoreInitialState() self.close() else: if self.widget.db and not self.widget.crs: self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL) if not self.widget.db and not self.widget.crs: self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Database not loaded properly!"), level=QgsMessageBar.CRITICAL) self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL) if len(self.listWidgetCategoryTo)==0: self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one category!"), level=QgsMessageBar.WARNING) categoriasSelecionadas = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] QApplication.restoreOverrideCursor() except: QApplication.restoreOverrideCursor() def setLayersWithElements(self): self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] pontoAux = self.widget.abstractDb.countElements(self.point) linhaAux = self.widget.abstractDb.countElements(self.line) areaAux = self.widget.abstractDb.countElements(self.polygon) for i in pontoAux: if i[1] > 0: self.pointWithElement.append(i[0]) for i in linhaAux: if i[1] > 0: self.lineWithElement.append(i[0]) for i in areaAux: if i[1] > 0: self.polygonWithElement.append(i[0]) def loadLayers(self, type, categories, table_names): dbName = self.widget.abstractDb.getDatabaseName() groupList = qgis.utils.iface.legendInterface().groups() groupRelationshipList = qgis.utils.iface.legendInterface().groupLayerRelationship() if dbName not in groupList: self.parentTreeNode = qgis.utils.iface.legendInterface (). addGroup (dbName, -1) else: self.parentTreeNode = groupList.index(dbName) if type == 'p': if len(groupList[self.parentTreeNode::]) == 0: idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Point'), True,self.parentTreeNode) elif self.tr('Point') not in groupRelationshipList[self.parentTreeNode][1]: idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Point'), True,self.parentTreeNode) else: idGrupo = groupList[self.parentTreeNode::].index(self.tr('Point')) for category in categories: self.prepareLayer(category, table_names, idGrupo) if type == 'l': if len(groupList[self.parentTreeNode::]) == 0: idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Line'), True,self.parentTreeNode) elif self.tr('Line') not in groupRelationshipList[self.parentTreeNode][1]: idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Line'), True,self.parentTreeNode) else: idGrupo = groupList[self.parentTreeNode::].index(self.tr('Line')) for category in categories: self.prepareLayer(category, table_names, idGrupo) if type == 'a': if len(groupList[self.parentTreeNode::]) == 0: idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Area'), True,self.parentTreeNode) elif self.tr('Area') not in groupRelationshipList[self.parentTreeNode][1]: idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Area'), True,self.parentTreeNode) else: idGrupo = groupList[self.parentTreeNode::].index(self.tr('Area')) for category in categories: self.prepareLayer(category, table_names, idGrupo) def prepareLayer(self, category, table_names, idGrupo): idSubgrupo = qgis.utils.iface.legendInterface().addGroup(category, True, idGrupo) table_names.sort(reverse=True) for table_name in table_names: schema, layerName = self.widget.abstractDb.getTableSchema(table_name) if (category.split('.')[1] == layerName.split('_')[0]) and (category.split('.')[0] == schema): edgvLayer = self.layerFactory.makeLayer(self.widget.abstractDb, self.codeList, table_name) edgvLayer.load(self.widget.crs, idSubgrupo)
"""" https://docs.qgis.org/2.18/en/docs/pyqgis_developer_cookbook/crs.html """ from qgis.core import QgsCoordinateReferenceSystem from osgeo import osr if __name__ == '__console__': print("-----------------------------------------------\n\n") # PostGIS SRID 4326 is allocated for WGS84 # If not specified otherwise in second parameter, PostGIS SRID is used by default. crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.PostgisCrsId) print("Valid: ", crs.isValid()) print("QGIS CRS ID:", crs.srsid()) print("EPSG ID:", crs.authid()) print("Description:", crs.description()) print("Projection Acronym:", crs.projectionAcronym()) print("Ellipsoid Acronym:", crs.ellipsoidAcronym()) print("Proj4 String:", crs.toProj4()) # check whether it's geographic or projected coordinate system print("Is geographic:", crs.geographicFlag()) # check type of map units in this CRS (values defined in QGis::units enum) print("Map units:", crs.mapUnits()) print("-----------------------------------------------\n\n") wkt = '''GEOGCS["WGS84", DATUM["WGS84", SPHEROID["WGS84", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]''' crs = QgsCoordinateReferenceSystem(wkt) print("Valid: ", crs.isValid())
class CriaSpatialiteDialog(QtGui.QDialog, FORM_CLASS): def __init__(self, parent=None): """Constructor.""" super(CriaSpatialiteDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.filepath = "" self.carregado = False self.coordSysDefinido = False self.epsgCriaSpatialite = 0 self.srsCriaSpatialite = '' self.sqliteFileName = '' self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0,0,0,0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0,0,1,1) QtCore.QObject.connect(self.pushButtonBuscarPastaDestinoCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.definePastaDestino) QtCore.QObject.connect(self.pushButtonBuscarSistCoordCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.setaSistCoordCriaSpatialite) QtCore.QObject.connect(self.pushButtonOkCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.okselecionadoCriaSpatialite) def getTemplateLocation(self): currentPath = os.path.dirname(__file__) if self.versionComboBox.currentText() == '2.1.3': edgvPath = os.path.join(currentPath, 'template', '213', 'seed_edgv213.sqlite') elif self.versionComboBox.currentText() == 'FTer_2a_Ed': edgvPath = os.path.join(currentPath, 'template', 'FTer_2a_Ed', 'seed_edgvfter_2a_ed.sqlite') return edgvPath def restauraInicio(self): self.filepath = "" self.carregado = False self.coordSysDefinido = False self.epsgCriaSpatialite = 0 self.srsCriaSpatialite = '' self.sqliteFileName = '' self.pastaDestinoCriaSpatialiteLineEdit.setText("") self.coordSysCriaSpatialiteLineEdit.setText("") self.nomeLineEdit.setText("") def definePastaDestino(self): fd = QtGui.QFileDialog() self.filepath = fd.getExistingDirectory() if self.filepath <> "": self.carregado = True self.pastaDestinoCriaSpatialiteLineEdit.setText(self.filepath) def setaSistCoordCriaSpatialite(self): projSelector = QgsGenericProjectionSelector() projSelector.setMessage(theMessage=self.tr('Please, select the coordinate system')) projSelector.exec_() try: self.epsgCriaSpatialite = int(projSelector.selectedAuthId().split(':')[-1]) self.srsCriaSpatialite = QgsCoordinateReferenceSystem(self.epsgCriaSpatialite, QgsCoordinateReferenceSystem.EpsgCrsId) if self.srsCriaSpatialite <> "": self.coordSysDefinido = True self.coordSysCriaSpatialiteLineEdit.setText(self.srsCriaSpatialite.description()) except: self.bar.pushMessage("", self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING) pass def copiaSemente(self,destino,srid): f = open(self.getTemplateLocation(),'rb') g = open(destino,'wb') x = f.readline() while x: g.write(x) x = f.readline() g.close() con = sqlite3.connect(destino) cursor = con.cursor() srid_sql = (srid,) cursor.execute("UPDATE geometry_columns SET srid=?",srid_sql) con.commit() con.close() def okselecionadoCriaSpatialite(self): if self.carregado and self.coordSysDefinido and len(self.nomeLineEdit.text()) > 0: try: self.sqliteFileName = self.filepath+'/'+self.nomeLineEdit.text()+'.sqlite' destino = self.sqliteFileName self.copiaSemente(destino,self.epsgCriaSpatialite) self.close() self.restauraInicio() QtGui.QMessageBox.information(self, self.tr('Information'), self.tr('Spatialite created successfully!')) except: qgis.utils.iface.messageBar().pushMessage(self.tr("Error!"), self.tr("Problem creating the database!"), level=QgsMessageBar.CRITICAL) self.restauraInicio() pass else: if self.coordSysDefinido == False: self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING) if self.carregado == False: self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select a folder to save the database'), level=QgsMessageBar.CRITICAL) if len(self.nomeLineEdit.text()) == 0: self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, fill the file name.'), level=QgsMessageBar.CRITICAL)
def getSpatialRefInfo(self, srid): crs = QgsCoordinateReferenceSystem(srid) return crs.description()
class ConnectionWidget(QtGui.QWidget, FORM_CLASS): connectionChanged = pyqtSignal() problemOccurred = pyqtSignal(str) def __init__(self, parent = None): """Constructor.""" super(ConnectionWidget, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.setInitialState() def __del__(self): self.closeDatabase() def closeDatabase(self): if self.abstractDb: del self.abstractDb self.abstractDb = None def setInitialState(self): self.filename = '' self.dbLoaded = False self.epsg = 0 self.crs = None self.abstractDb = None self.isSpatialite = True self.tabWidget.setCurrentIndex(0) self.abstractDbFactory = DbFactory() self.utils = Utils() #populating the postgis combobox self.comboBoxPostgis.setCurrentIndex(0) self.populatePostGISConnectionsCombo() self.spatialiteFileEdit.setReadOnly(True) self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setReadOnly(True) @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): if self.comboBoxPostgis.currentIndex() > 0: self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setText('') self.edgvPostgisVersionEdit.setReadOnly(True) self.loadDatabase() self.connectionChanged.emit() @pyqtSlot(bool) def on_pushButtonOpenFile_clicked(self): self.loadDatabase() if self.isDBConnected(): self.connectionChanged.emit() @pyqtSlot(int) def on_tabWidget_currentChanged(self): self.filename = '' self.comboBoxPostgis.setCurrentIndex(0) self.dbLoaded = False self.epsg = 0 self.crs = None self.dbVersion = '' self.spatialiteFileEdit.setReadOnly(True) self.spatialiteFileEdit.setText(self.filename) self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setText('') self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setText('') self.edgvPostgisVersionEdit.setReadOnly(True) #Setting the database type if self.tabWidget.currentIndex() == 0: self.isSpatialite = True else: self.isSpatialite = False def loadDatabase(self): self.closeDatabase() if self.isSpatialite: self.abstractDb = self.abstractDbFactory.createDbFactory('QSQLITE') self.abstractDb.connectDatabase() self.spatialiteFileEdit.setText(self.abstractDb.db.databaseName()) self.edgvSpatialiteVersionEdit.setText(self.abstractDb.getDatabaseVersion()) else: self.abstractDb = self.abstractDbFactory.createDbFactory('QPSQL') self.abstractDb.connectDatabase(self.comboBoxPostgis.currentText()) self.edgvPostgisVersionEdit.setText(self.abstractDb.getDatabaseVersion()) try: self.abstractDb.checkAndOpenDb() self.dbLoaded = True self.dbVersion = self.abstractDb.getDatabaseVersion() if self.dbVersion == '-1': self.problemOccurred.emit(self.tr('This is not a valid DsgTools database!')) else: self.setCRS() except Exception as e: QgsMessageLog.logMessage(e.args[0], "DSG Tools Plugin", QgsMessageLog.CRITICAL) def setCRS(self): try: self.epsg = self.abstractDb.findEPSG() if self.epsg == -1: self.problemOccurred.emit(self.tr('Coordinate Reference System not set or invalid!')) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass def populatePostGISConnectionsCombo(self): self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem(self.tr('Select Database')) self.comboBoxPostgis.addItems(self.getPostGISConnections()) def isDBConnected(self): return self.dbLoaded def getDBVersion(self): return self.abstractDb.getDatabaseVersion() def getQmlPath(self): return self.abstractDb.getQmlDir() @pyqtSlot(bool) def on_addConnectionButton_clicked(self): newConnectionDialog = ServerDBExplorer(self) retvalue = newConnectionDialog.exec_() self.populatePostGISConnectionsCombo() return retvalue def getPostGISConnections(self): settings = QSettings() settings.beginGroup('PostgreSQL/connections') currentConnections = settings.childGroups() settings.endGroup() return currentConnections
def processAlgorithm(self, parameters, context, feedback): pasta = self.parameterAsFile(parameters, self.FOLDER, context) if not pasta: raise QgsProcessingException( self.invalidSourceError(parameters, self.FOLDER)) subpasta = self.parameterAsBool(parameters, self.SUBFOLDER, context) formato = self.parameterAsString(parameters, self.FORMAT, context) geometria = self.parameterAsEnum(parameters, self.GEOMETRY, context) crs = self.parameterAsCrs(parameters, self.CRS, context) # OUTPUT GeomType = QgsWkbTypes.Point if geometria == 1 else QgsWkbTypes.Polygon Fields = QgsFields() itens = { self.tr('name', 'nome'): QVariant.String, self.tr('extension', 'extensão'): QVariant.String, self.tr('path', 'caminho'): QVariant.String, self.tr('resX'): QVariant.Double, self.tr('resY'): QVariant.Double, self.tr('n_cols'): QVariant.Int, self.tr('n_rows', 'n_lin'): QVariant.Int, self.tr('crs', 'src'): QVariant.String, self.tr('n_bands', 'n_bandas'): QVariant.Int, self.tr('dataType', 'tipoDado'): QVariant.String, } for item in itens: Fields.append(QgsField(item, itens[item])) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, Fields, GeomType, crs) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) # Listar Arquivos feedback.pushInfo( self.tr('Checking files in the folder...', 'Checando arquivos na pasta...')) lista = [] if subpasta: for root, dirs, files in os.walk(pasta, topdown=True): for name in files: if name[-1 * len(formato):] == formato: lista += [os.path.join(root, name)] else: for item in os.listdir(pasta): if item[-1 * len(formato):] == formato: lista += [os.path.join(pasta, item)] total = 100.0 / len(lista) if len(lista) > 0 else 0 # Obter dados dos arquivos listados feedback.pushInfo( self.tr('Creating raster files...', 'Criando inventário de arquivos raster...')) for current, file_path in enumerate(lista): image = gdal.Open(file_path) # https://gdal.org/python/ prj = image.GetProjection() # wkt ulx, xres, xskew, uly, yskew, yres = image.GetGeoTransform() GDT = image.GetRasterBand(1).DataType n_bands = image.RasterCount cols = image.RasterXSize # Number of columns rows = image.RasterYSize # Number of rows CRS = QgsCoordinateReferenceSystem(prj) # Create CRS image = None # Close image # Creating BBox coord = [[ QgsPointXY(ulx, uly), QgsPointXY(ulx + cols * xres, uly), QgsPointXY(ulx + cols * xres, uly + rows * yres), QgsPointXY(ulx, uly + rows * yres), QgsPointXY(ulx, uly) ]] geom = QgsGeometry.fromPolygonXY(coord) # CRS transformation coordinateTransformer = QgsCoordinateTransform() coordinateTransformer.setDestinationCrs(crs) coordinateTransformer.setSourceCrs(CRS) geom_transf = self.reprojectPoints(geom, coordinateTransformer) # Attributes path, file = os.path.split(file_path) name = os.path.splitext(file)[0] extension = os.path.splitext(file)[1] att = [ name, extension, path, abs(xres), abs(yres), cols, rows, CRS.description(), n_bands, gdal.GetDataTypeName(GDT) ] # Saving feature feat = QgsFeature() feat.setGeometry(geom_transf.centroid() ) if geometria == 1 else feat.setGeometry( geom_transf) # centroid or polygon feat.setAttributes(att) sink.addFeature(feat, QgsFeatureSink.FastInsert) if feedback.isCanceled(): break feedback.setProgress(int((current + 1) * total)) feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo('Leandro França - Eng Cart') return {self.OUTPUT: dest_id}
class ConnectionWidget(QtGui.QWidget, FORM_CLASS): connectionChanged = pyqtSignal() problemOccurred = pyqtSignal(str) dbChanged = pyqtSignal(AbstractDb) styleChanged = pyqtSignal(dict) def __init__(self, parent=None): """Constructor.""" super(ConnectionWidget, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.setInitialState() self.serverWidget.populateServersCombo() self.serverWidget.abstractDbLoaded.connect(self.getDatabasesFromServer) self.serverWidget.clearWidgets.connect(self.clearAll) def __del__(self): """ Closes the database """ self.closeDatabase() def closeDatabase(self): """ Closes the current database """ if self.abstractDb: del self.abstractDb self.abstractDb = None def clearAll(self): """ Resets the initial state """ self.filename = '' self.dbLoaded = False self.epsg = 0 self.crs = None self.abstractDb = None self.isSpatialite = False self.abstractDbFactory = DbFactory() self.utils = Utils() #populating the postgis combobox self.comboBoxPostgis.clear() self.spatialiteFileEdit.setReadOnly(True) self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setReadOnly(True) def setInitialState(self): """ Sets the initial state """ self.filename = '' self.dbLoaded = False self.epsg = 0 self.crs = None self.abstractDb = None self.isSpatialite = False self.tabWidget.setCurrentIndex(0) self.abstractDbFactory = DbFactory() self.utils = Utils() self.serverWidget.serversCombo.setCurrentIndex(0) #populating the postgis combobox self.comboBoxPostgis.clear() self.spatialiteFileEdit.setReadOnly(True) self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setReadOnly(True) @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): """ Updates database information when the combo box changes """ if self.comboBoxPostgis.currentIndex() > 0: self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setText('') self.edgvPostgisVersionEdit.setReadOnly(True) self.loadDatabase() self.connectionChanged.emit() @pyqtSlot(bool) def on_pushButtonOpenFile_clicked(self): """ Loads a spatialite database """ self.loadDatabase() if self.isDBConnected(): self.connectionChanged.emit() @pyqtSlot(int) def on_tabWidget_currentChanged(self): """ Changes the tab to work with spatialite or postgis databases """ self.filename = '' self.comboBoxPostgis.clear() self.dbLoaded = False self.epsg = 0 self.crs = None self.dbVersion = '' self.serverWidget.serversCombo.setCurrentIndex(0) self.spatialiteFileEdit.setReadOnly(True) self.spatialiteFileEdit.setText(self.filename) self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setText('') self.edgvSpatialiteVersionEdit.setReadOnly(True) self.edgvPostgisVersionEdit.setText('') self.edgvPostgisVersionEdit.setReadOnly(True) self.mGroupBox.setTitle(self.tr('Database connection')) #Setting the database type if self.tabWidget.currentIndex() == 1: self.isSpatialite = True else: self.isSpatialite = False def loadDatabase(self): """ Loads the selected database """ self.closeDatabase() try: if self.isSpatialite: self.abstractDb = self.abstractDbFactory.createDbFactory( 'QSQLITE') self.abstractDb.connectDatabase() self.spatialiteFileEdit.setText( self.abstractDb.db.databaseName()) self.edgvSpatialiteVersionEdit.setText( self.abstractDb.getDatabaseVersion()) else: self.abstractDb = self.abstractDbFactory.createDbFactory( 'QPSQL') (host, port, user, password) = self.serverWidget.getServerParameters() dbName = self.comboBoxPostgis.currentText() self.abstractDb.connectDatabaseWithParameters( host, port, dbName, user, password) self.edgvPostgisVersionEdit.setText( self.abstractDb.getDatabaseVersion()) serverName = self.serverWidget.serversCombo.currentText() newText = dbName + self.tr(' on ') + serverName self.mGroupBox.setToolTip(newText) # self.mGroupBox.setTitle(newText) self.abstractDb.checkAndOpenDb() self.dbLoaded = True self.dbVersion = self.abstractDb.getDatabaseVersion() self.abstractDb.checkAndCreateStyleTable() self.styles = self.abstractDb.getStyleDict(self.dbVersion) self.styleChanged.emit(self.styles) self.dbChanged.emit(self.abstractDb) if self.dbVersion == '-1': self.problemOccurred.emit( self.tr('This is not a valid DsgTools database!')) else: self.setCRS() except Exception as e: self.problemOccurred.emit( self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) def setCRS(self): """ Sets the CRS information """ try: self.epsg = self.abstractDb.findEPSG() if self.epsg == -1: self.problemOccurred.emit( self.tr('Coordinate Reference System not set or invalid!')) else: self.crs = QgsCoordinateReferenceSystem( self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except Exception as e: self.problemOccurred.emit( self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) def isDBConnected(self): """ Checks if the database is already loaded """ return self.dbLoaded def getDBVersion(self): """ Gets the database version """ ret = '' try: ret = self.abstractDb.getDatabaseVersion() except Exception as e: self.problemOccurred.emit( self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) return ret def getQmlPath(self): """ Gets the QML path """ ret = '' try: ret = self.abstractDb.getQmlDir() except Exception as e: self.problemOccurred.emit( self.tr('A problem occurred! Check log for details.')) QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) return ret def getDatabasesFromServer(self): """ Gets databases from server """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: if self.serverWidget.abstractDb: dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer( parentWidget=self) dbList.sort() self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem(self.tr('Select Database')) for db, version in dbList: self.comboBoxPostgis.addItem(db) else: self.setInitialState() return except Exception as e: QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) self.setInitialState() self.setInitialState() QApplication.restoreOverrideCursor()
class QGISRedCreateProjectDialog(QDialog, FORM_CLASS): # Common variables iface = None NetworkName = "" ProjectDirectory = "" gplFile = "" TemporalFolder = "Temporal folder" def __init__(self, parent=None): """Constructor.""" super(QGISRedCreateProjectDialog, self).__init__(parent) self.setupUi(self) self.btCreateProject.clicked.connect(self.createProject) self.btSelectDirectory.clicked.connect(self.selectDirectory) self.btSelectCRS.clicked.connect(self.selectCRS) # Variables: gplFolder = os.path.join(os.getenv('APPDATA'), "QGISRed") try: # create directory if does not exist os.stat(gplFolder) except Exception: os.mkdir(gplFolder) self.gplFile = os.path.join(gplFolder, "qgisredprojectlist.gpl") def config(self, ifac, direct, netw, parent): self.iface = ifac self.parent = parent utils = QGISRedUtils(direct, netw, ifac) self.crs = utils.getProjectCrs() self.tbCRS.setText(self.crs.description()) self.NetworkName = netw self.ProjectDirectory = direct self.tbNetworkName.setText(netw) self.tbProjectDirectory.setText(direct) self.tbProjectDirectory.setCursorPosition(0) def selectDirectory(self): selected_directory = QFileDialog.getExistingDirectory() if not selected_directory == "": self.tbProjectDirectory.setText(selected_directory) self.tbProjectDirectory.setCursorPosition(0) self.ProjectDirectory = selected_directory self.NetworkName = self.tbNetworkName.text() def selectCRS(self): projSelector = QgsGenericProjectionSelector() if projSelector.exec_(): crsId = projSelector.crs().srsid() if not crsId == 0: self.crs = QgsCoordinateReferenceSystem() self.crs.createFromId(crsId, QgsCoordinateReferenceSystem.InternalCrsId) self.tbCRS.setText(self.crs.description()) def validationsCreateProject(self): self.NetworkName = self.tbNetworkName.text() if len(self.NetworkName) == 0: self.iface.messageBar().pushMessage("Validations", "The network's name is not valid", level=1) return False self.ProjectDirectory = self.tbProjectDirectory.text() if len(self.ProjectDirectory) == 0 or self.ProjectDirectory == self.TemporalFolder: self.ProjectDirectory = tempfile._get_default_tempdir() + "\\" + next(tempfile._get_candidate_names()) else: if not os.path.exists(self.ProjectDirectory): self.iface.messageBar().pushMessage("Validations", "The project directory does not exist", level=1) return False else: dirList = os.listdir(self.ProjectDirectory) layers = ["Pipes", "Junctions", "Tanks", "Reservoirs", "Valves", "Pumps", "IsolationValves", "Hydrants", "WashoutValves", "AirReleaseValves", "ServiceConnections", "Manometers", "Flowmeters", "Countermeters", "LevelSensors"] for layer in layers: if self.NetworkName + "_" + layer + ".shp" in dirList: message = "The project directory has some file to selected network's name" self.iface.messageBar().pushMessage("Validations", message, level=1) return False return True def createProject(self): # Validations isValid = self.validationsCreateProject() if isValid is True: epsg = self.crs.authid().replace("EPSG:", "") # Process QApplication.setOverrideCursor(Qt.WaitCursor) resMessage = GISRed.CreateProject(self.ProjectDirectory, self.NetworkName, epsg) QApplication.restoreOverrideCursor() # Message if resMessage == "True": self.iface.messageBar().pushMessage("Information", "Process successfully completed", level=3, duration=5) # Project manager list file = open(self.gplFile, "a+") QGISRedUtils().writeFile(file, self.NetworkName + ";" + self.ProjectDirectory + '\n') file.close() # open layers self.parent.openElementLayers(None, self.NetworkName, self.ProjectDirectory) elif resMessage == "False": self.iface.messageBar().pushMessage("Warning", "Some issues occurred in the process", level=1, duration=5) else: self.iface.messageBar().pushMessage("Error", resMessage, level=2, duration=5) self.close()
class Dialog(QDialog, Ui_Dialog): def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.iface = iface self.setupUi(self) self.toolOut.setEnabled(False) self.toolOut.setVisible(False) self.outShape.setEnabled(False) self.outShape.setVisible(False) self.label_2.setVisible(False) self.label_2.setEnabled(False) self.setWindowTitle(self.tr("Define current projection")) self.buttonOk = self.buttonBox_2.button(QDialogButtonBox.Ok) QObject.connect(self.btnProjection, SIGNAL("clicked()"), self.outProjFile) QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.updateProj1) QObject.connect(self.cmbLayer, SIGNAL("currentIndexChanged(QString)"), self.updateProj2) # populate layer list self.progressBar.setValue(0) layers = ftools_utils.getLayerNames([QGis.Point, QGis.Line, QGis.Polygon]) self.inShape.addItems(layers) self.cmbLayer.addItems(layers) self.crs = None def updateProj1(self, layerName): self.inRef.clear() tempLayer = ftools_utils.getVectorLayerByName(layerName) crs = tempLayer.dataProvider().crs() if crs.isValid(): self.inRef.insert(crs.authid() + " - " + crs.description()) else: self.inRef.insert(self.tr("Missing or invalid CRS")) def updateProj2(self, layerName): self.outRef.clear() tempLayer = ftools_utils.getVectorLayerByName(layerName) crs = tempLayer.dataProvider().crs() if crs.isValid(): self.outRef.insert(crs.authid() + " - " + crs.description()) else: self.outRef.insert(self.tr("Missing or invalid CRS")) def accept(self): self.buttonOk.setEnabled(False) if self.inShape.currentText() == "": QMessageBox.information(self, self.tr("Define current projection"), self.tr("No input shapefile specified")) elif self.txtProjection.text() == "" and self.rdoProjection.isChecked(): QMessageBox.information(self, self.tr("Define current projection"), self.tr("Please specify spatial reference system")) elif self.cmbLayer.currentText() == "" and self.rdoLayer.isChecked(): QMessageBox.information(self, self.tr("Define current projection"), self.tr("Please specify spatial reference system")) else: self.progressBar.setValue(5) inName = self.inShape.currentText() self.progressBar.setValue(10) vLayer = ftools_utils.getVectorLayerByName(inName) self.progressBar.setValue(30) if vLayer == "Error": QMessageBox.information(self, self.tr("Define current projection"), self.tr("Cannot define projection for PostGIS data...yet!")) else: srsDefine = None if self.rdoProjection.isChecked(): srsDefine = self.crs else: destLayer = ftools_utils.getVectorLayerByName(self.cmbLayer.currentText()) srsDefine = destLayer.crs() if srsDefine == vLayer.crs(): responce = QMessageBox.question(self, self.tr("Define current projection"), self.tr("Identical output spatial reference system chosen\n\nAre you sure you want to proceed?"), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton) if responce == QMessageBox.No: self.progressBar.setValue(0) self.buttonOk.setEnabled(True) return provider = vLayer.dataProvider() self.progressBar.setValue(35) inPath = provider.dataSourceUri() p = re.compile("\|.*") inPath = p.sub("", inPath) self.progressBar.setValue(40) if inPath.endswith(".shp"): inPath = inPath[:-4] self.progressBar.setValue(55) if not srsDefine.isValid(): QMessageBox.information(self, self.tr("Define current projection"), self.tr("Output spatial reference system is not valid")) else: self.progressBar.setValue(60) outputWkt = srsDefine.toWkt() self.progressBar.setValue(65) outputFile = QFile(inPath + ".prj") outputFile.open(QIODevice.WriteOnly | QIODevice.Text) outputPrj = QTextStream(outputFile) outputPrj << outputWkt outputPrj.flush() outputFile.close() self.progressBar.setValue(70) checkFile = QFile(inPath + ".qpj") if checkFile.exists(): checkFile.open(QIODevice.WriteOnly | QIODevice.Text) outputPrj = QTextStream(checkFile) outputPrj << outputWkt outputPrj.flush() checkFile.close() self.progressBar.setValue(95) vLayer.setCrs(srsDefine) self.progressBar.setValue(100) QMessageBox.information(self, self.tr("Define current projection"), self.tr("Defined Projection For:\n%s.shp") % (inPath)) self.progressBar.setValue(0) self.buttonOk.setEnabled(True) def outProjFile(self): header = "Define layer CRS:" sentence1 = self.tr("Please select the projection system that defines the current layer.") sentence2 = self.tr("Layer CRS information will be updated to the selected CRS.") projSelector = QgsGenericProjectionSelector(self) projSelector.setMessage("<h2>%s</h2>%s <br/> %s" % (header, sentence1, sentence2)) if projSelector.exec_(): self.crs = QgsCoordinateReferenceSystem(projSelector.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId) print "AUTHID", projSelector.selectedAuthId() if len(projSelector.selectedAuthId()) == 0: QMessageBox.information(self, self.tr("Export to new projection"), self.tr("No Valid CRS selected")) return else: self.txtProjection.clear() self.txtProjection.insert(self.crs.authid() + " - " + self.crs.description()) else: return
class QGISRedImportDialog(QDialog, FORM_CLASS): # Common variables iface = None NewProject = True NetworkName = "" ProjectDirectory = "" InpFile = "" gplFile = "" TemporalFolder = "Temporal folder" ownMainLayers = ["Pipes", "Valves", "Pumps", "Junctions", "Tanks", "Reservoirs", "Demands", "Sources"] ownFiles = ["DefaultValues", "Options", "Rules", "Controls", "Curves", "Patterns"] def __init__(self, parent=None): """Constructor.""" super(QGISRedImportDialog, self).__init__(parent) self.setupUi(self) gplFolder = os.path.join(os.getenv('APPDATA'), "QGISRed") try: # create directory if does not exist os.stat(gplFolder) except Exception: os.mkdir(gplFolder) self.gplFile = os.path.join(gplFolder, "qgisredprojectlist.gpl") # INP self.btImportInp.clicked.connect(self.importInpProject) self.btSelectDirectory.clicked.connect(self.selectDirectory) self.btSelectCRS.clicked.connect(self.selectCRS) self.btSelectInp.clicked.connect(self.selectINP) # SHPs self.btSelectSHPDirectory.clicked.connect(self.selectSHPDirectory) self.cbPipeLayer.currentIndexChanged.connect(self.pipeLayerChanged) self.cbValveLayer.currentIndexChanged.connect(self.valveLayerChanged) self.cbPumpLayer.currentIndexChanged.connect(self.pumpLayerChanged) self.cbTankLayer.currentIndexChanged.connect(self.tankLayerChanged) self.cbReservoirLayer.currentIndexChanged.connect(self.reservoirLayerChanged) self.cbJunctionLayer.currentIndexChanged.connect(self.junctionLayerChanged) self.cbServiceConnectionLayer.currentIndexChanged.connect(self.serviceConnectionLayerChanged) self.btImportShps.clicked.connect(self.importShpProject) def config(self, ifac, direct, netw, parent): self.parent = parent self.iface = ifac utils = QGISRedUtils(direct, netw, ifac) self.crs = utils.getProjectCrs() self.tbCRS.setText(self.crs.description()) self.ProcessDone = False self.InpFile = "" self.NetworkName = netw self.tbNetworkName.setText(netw) self.ProjectDirectory = direct self.tbProjectDirectory.setText(direct) self.tbProjectDirectory.setCursorPosition(0) self.tbTolerance.setText(str(0)) self.NewProject = self.ProjectDirectory == self.TemporalFolder if not self.NewProject: self.setWindowTitle("QGISRed: Add data") icon_path = ':/plugins/QGISRed/images/iconAddData.png' self.setWindowIcon(QIcon(icon_path)) self.lbProject.setVisible(False) self.tbProjectDirectory.setVisible(False) self.btSelectDirectory.setVisible(False) self.lbName.setVisible(False) self.tbNetworkName.setVisible(False) self.lbCrs.setVisible(False) self.tbCRS.setVisible(False) self.btSelectCRS.setVisible(False) self.tabWidget.removeTab(0) self.label_14.setVisible(False) self.label_15.setVisible(False) self.cbUnits.setVisible(False) self.cbHeadloss.setVisible(False) def selectDirectory(self): selected_directory = QFileDialog.getExistingDirectory() if not selected_directory == "": self.tbProjectDirectory.setText(selected_directory) self.tbProjectDirectory.setCursorPosition(0) self.ProjectDirectory = selected_directory self.NetworkName = self.tbNetworkName.text() dirList = os.listdir(self.ProjectDirectory) self.NewProject = True for name in self.ownMainLayers: if self.NetworkName + "_" + name + ".shp" in dirList: self.NewProject = False break def selectCRS(self): projSelector = QgsGenericProjectionSelector() if projSelector.exec_(): crsId = projSelector.crs().srsid() if not crsId == 0: self.crs = QgsCoordinateReferenceSystem() self.crs.createFromId(crsId, QgsCoordinateReferenceSystem.InternalCrsId) self.tbCRS.setText(self.crs.description()) def validationsCreateProject(self): self.NetworkName = self.tbNetworkName.text() if len(self.NetworkName) == 0: self.iface.messageBar().pushMessage("Validations", "The network's name is not valid", level=1) return False self.ProjectDirectory = self.tbProjectDirectory.text() if len(self.ProjectDirectory) == 0 or self.ProjectDirectory == self.TemporalFolder: self.ProjectDirectory = tempfile._get_default_tempdir() + "\\" + next(tempfile._get_candidate_names()) else: if not os.path.exists(self.ProjectDirectory): self.iface.messageBar().pushMessage("Validations", "The project directory does not exist", level=1) return False return True def createProject(self): epsg = self.crs.authid().replace("EPSG:", "") units = self.cbUnits.currentText() headloss = self.cbHeadloss.currentText() # Process QApplication.setOverrideCursor(Qt.WaitCursor) resMessage = GISRed.CreateProject(self.ProjectDirectory, self.NetworkName, epsg, units, headloss) QApplication.restoreOverrideCursor() # Message if not resMessage == "True": if resMessage == "False": self.iface.messageBar().pushMessage("Warning", "Some issues occurred in the process", level=1, duration=5) else: self.iface.messageBar().pushMessage("Error", resMessage, level=2, duration=5) self.close() return False # Write .gql file file = open(self.gplFile, "a+") QGISRedUtils().writeFile(file, self.NetworkName + ";" + self.ProjectDirectory + '\n') file.close() return True def getInputGroup(self): inputGroup = QgsProject.instance().layerTreeRoot().findGroup("Inputs") if inputGroup is None: netGroup = QgsProject.instance().layerTreeRoot().findGroup(self.NetworkName) if netGroup is None: root = QgsProject.instance().layerTreeRoot() netGroup = root.insertGroup(0, self.NetworkName) inputGroup = netGroup.addGroup("Inputs") return inputGroup def setZoomExtent(self, exception=None, result=None): self.iface.mapCanvas().zoomToFullExtent() self.iface.mapCanvas().refresh() """INP SECTION""" def selectINP(self): qfd = QFileDialog() path = "" filter = "inp(*.inp)" f = QFileDialog.getOpenFileName(qfd, "Select INP file", path, filter) f = f[0] if not f == "": self.InpFile = f self.tbInpFile.setText(f) self.tbInpFile.setCursorPosition(0) def importInpProject(self): # Common validations isValid = self.validationsCreateProject() if isValid: # Validations INP self.InpFile = self.tbInpFile.text() if len(self.InpFile) == 0: self.iface.messageBar().pushMessage("Validations", "INP file is not valid", level=1) return else: if not os.path.exists(self.InpFile): self.iface.messageBar().pushMessage("Validations", "INP file does not exist", level=1) return self.close() # Process self.parent.zoomToFullExtent = True epsg = self.crs.authid().replace("EPSG:", "") QApplication.setOverrideCursor(Qt.WaitCursor) resMessage = GISRed.ImportFromInp(self.ProjectDirectory, self.NetworkName, self.parent.tempFolder, self.InpFile, epsg) QApplication.restoreOverrideCursor() self.parent.ProjectDirectory = self.ProjectDirectory self.parent.NetworkName = self.NetworkName # Write .gql file file = open(self.gplFile, "a+") QGISRedUtils().writeFile(file, self.NetworkName + ";" + self.ProjectDirectory + '\n') file.close() # Open files self.parent.processCsharpResult(resMessage, "") """SHPS SECTION""" def selectSHPDirectory(self): selected_directory = QFileDialog.getExistingDirectory() if selected_directory == "": return self.tbShpDirectory.setText(selected_directory) self.tbShpDirectory.setCursorPosition(0) dirList = os.listdir(selected_directory) self.cbPipeLayer.clear() self.cbPipeLayer.addItem("None") self.cbValveLayer.clear() self.cbValveLayer.addItem("None") self.cbPumpLayer.clear() self.cbPumpLayer.addItem("None") self.cbTankLayer.clear() self.cbTankLayer.addItem("None") self.cbReservoirLayer.clear() self.cbReservoirLayer.addItem("None") self.cbJunctionLayer.clear() self.cbJunctionLayer.addItem("None") self.cbServiceConnectionLayer.clear() self.cbServiceConnectionLayer.addItem("None") for file in dirList: if ".shp" in file: layerPath = os.path.join(self.tbShpDirectory.text(), file) vlayer = QgsVectorLayer(layerPath, "layer", "ogr") if not vlayer.isValid(): continue features = vlayer.getFeatures() # only check first feature for feature in features: featureType = feature.geometry().type() name = os.path.splitext(os.path.basename(file))[0] if featureType == QgsWkbTypes.LineGeometry: self.cbPipeLayer.addItem(name) self.cbServiceConnectionLayer.addItem(name) if featureType == QgsWkbTypes.LineGeometry or featureType == QgsWkbTypes.PointGeometry: self.cbValveLayer.addItem(name) self.cbPumpLayer.addItem(name) if featureType == QgsWkbTypes.PointGeometry: self.cbTankLayer.addItem(name) self.cbReservoirLayer.addItem(name) self.cbJunctionLayer.addItem(name) break vlayer = None def selectComboBoxItem(self, combobox, options): for i in range(combobox.count()): fieldName = combobox.itemText(i).lower() if fieldName in options: combobox.setCurrentIndex(i) return def pipeLayerChanged(self): newItem = self.cbPipeLayer.currentText() self.cbPipe_Id.clear() self.cbPipe_Length.clear() self.cbPipe_Diameter.clear() self.cbPipe_LossCoef.clear() self.cbPipe_Tag.clear() self.cbPipe_Descr.clear() if newItem == "None": self.gbPipes.setEnabled(False) return self.gbPipes.setEnabled(True) pipeLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp") vlayer = QgsVectorLayer(pipeLayer, "Pipes layer", "ogr") if not vlayer.isValid(): return field_names = [field.name() for field in vlayer.fields()] field_names.insert(0, "None") self.cbPipe_Id.addItems(field_names) self.cbPipe_Length.addItems(field_names) self.cbPipe_Diameter.addItems(field_names) self.cbPipe_LossCoef.addItems(field_names) self.cbPipe_Material.addItems(field_names) self.cbPipe_InstDate.addItems(field_names) self.cbPipe_Tag.addItems(field_names) self.cbPipe_Descr.addItems(field_names) self.selectComboBoxItem(self.cbPipe_Id, ["id"]) self.selectComboBoxItem(self.cbPipe_Length, ["length", "longitud"]) self.selectComboBoxItem(self.cbPipe_Diameter, ["diameter", "diam", "diametro", "diámetro"]) self.selectComboBoxItem(self.cbPipe_LossCoef, ["losscoeff"]) self.selectComboBoxItem(self.cbPipe_Material, ["material"]) self.selectComboBoxItem(self.cbPipe_InstDate, ["instdate", "date", "fecha", "fecha_de_i"]) self.selectComboBoxItem(self.cbPipe_Tag, ["tag"]) self.selectComboBoxItem(self.cbPipe_Descr, ["descrip", "descr", "description", "descripcion", "descripción"]) def valveLayerChanged(self): newItem = self.cbValveLayer.currentText() self.cbValve_Id.clear() self.cbValve_Diameter.clear() self.cbValve_Type.clear() self.cbValve_InitStat.clear() self.cbValve_Orient.clear() self.cbValve_Tag.clear() self.cbValve_Descr.clear() if newItem == "None": self.gbValves.setEnabled(False) return self.gbValves.setEnabled(True) valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp") vlayer = QgsVectorLayer(valveLayer, "Valves layer", "ogr") if not vlayer.isValid(): return field_names = [field.name() for field in vlayer.fields()] field_names.insert(0, "None") self.cbValve_Id.addItems(field_names) self.cbValve_Diameter.addItems(field_names) self.cbValve_Type.addItems(field_names) self.cbValve_InitStat.addItems(field_names) self.cbValve_Orient.addItems(field_names) self.cbValve_Tag.addItems(field_names) self.cbValve_Descr.addItems(field_names) self.selectComboBoxItem(self.cbValve_Id, ["id"]) self.selectComboBoxItem(self.cbValve_Diameter, ["diameter", "diam", "diametro", "diámetro"]) self.selectComboBoxItem(self.cbValve_Type, ["type", "tipo"]) self.selectComboBoxItem(self.cbValve_InitStat, ["inistatus"]) self.selectComboBoxItem(self.cbValve_Orient, ["orientatio"]) self.selectComboBoxItem(self.cbValve_Tag, ["tag"]) self.selectComboBoxItem(self.cbValve_Descr, ["descrip", "descr", "description", "descripcion", "descripción"]) def pumpLayerChanged(self): newItem = self.cbPumpLayer.currentText() self.cbPump_Id.clear() self.cbPump_Power.clear() self.cbPump_InitStat.clear() self.cbPump_Orient.clear() self.cbPump_Tag.clear() self.cbPump_Descr.clear() if newItem == "None": self.gbPumps.setEnabled(False) return self.gbPumps.setEnabled(True) valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp") vlayer = QgsVectorLayer(valveLayer, "Pumps layer", "ogr") if not vlayer.isValid(): return field_names = [field.name() for field in vlayer.fields()] field_names.insert(0, "None") self.cbPump_Id.addItems(field_names) self.cbPump_Power.addItems(field_names) self.cbPump_InitStat.addItems(field_names) self.cbPump_Orient.addItems(field_names) self.cbPump_Tag.addItems(field_names) self.cbPump_Descr.addItems(field_names) self.selectComboBoxItem(self.cbPump_Id, ["id"]) self.selectComboBoxItem(self.cbPump_Power, ["power", "potencia"]) self.selectComboBoxItem(self.cbPump_InitStat, ["inistatus"]) self.selectComboBoxItem(self.cbPump_Orient, ["orientatio"]) self.selectComboBoxItem(self.cbPump_Tag, ["tag"]) self.selectComboBoxItem(self.cbPump_Descr, ["descrip", "descr", "description", "descripcion", "descripción"]) def tankLayerChanged(self): newItem = self.cbTankLayer.currentText() self.cbTank_Id.clear() self.cbTank_Elevat.clear() self.cbTank_MinLevel.clear() self.cbTank_MaxLevel.clear() self.cbTank_Diameter.clear() self.cbTank_ReactCoeff.clear() self.cbTank_Tag.clear() self.cbTank_Descr.clear() if newItem == "None": self.gbTanks.setEnabled(False) return self.gbTanks.setEnabled(True) valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp") vlayer = QgsVectorLayer(valveLayer, "Tanks layer", "ogr") if not vlayer.isValid(): return field_names = [field.name() for field in vlayer.fields()] field_names.insert(0, "None") self.cbTank_Id.addItems(field_names) self.cbTank_Elevat.addItems(field_names) self.cbTank_MinLevel.addItems(field_names) self.cbTank_MaxLevel.addItems(field_names) self.cbTank_Diameter.addItems(field_names) self.cbTank_ReactCoeff.addItems(field_names) self.cbTank_Tag.addItems(field_names) self.cbTank_Descr.addItems(field_names) self.selectComboBoxItem(self.cbTank_Id, ["id"]) self.selectComboBoxItem(self.cbTank_Elevat, ["elevation"]) self.selectComboBoxItem(self.cbTank_MinLevel, ["minlevel"]) self.selectComboBoxItem(self.cbTank_MaxLevel, ["maxlevel"]) self.selectComboBoxItem(self.cbTank_Diameter, ["diameter", "diam", "diametro", "diámetro"]) self.selectComboBoxItem(self.cbTank_ReactCoeff, ["reactcoef"]) self.selectComboBoxItem(self.cbTank_Tag, ["tag"]) self.selectComboBoxItem(self.cbTank_Descr, ["descrip", "descr", "description", "descripcion", "descripción"]) def reservoirLayerChanged(self): newItem = self.cbReservoirLayer.currentText() self.cbReservoir_Id.clear() self.cbReservoir_TotHead.clear() self.cbReservoir_Tag.clear() self.cbReservoir_Descr.clear() if newItem == "None": self.gbReservoirs.setEnabled(False) return self.gbReservoirs.setEnabled(True) valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp") vlayer = QgsVectorLayer(valveLayer, "Reservoirs layer", "ogr") if not vlayer.isValid(): return field_names = [field.name() for field in vlayer.fields()] field_names.insert(0, "None") self.cbReservoir_Id.addItems(field_names) self.cbReservoir_TotHead.addItems(field_names) self.cbReservoir_Tag.addItems(field_names) self.cbReservoir_Descr.addItems(field_names) self.selectComboBoxItem(self.cbReservoir_Id, ["id"]) self.selectComboBoxItem(self.cbReservoir_TotHead, ["totalhead"]) self.selectComboBoxItem(self.cbReservoir_Tag, ["tag"]) self.selectComboBoxItem(self.cbReservoir_Descr, ["descrip", "descr", "description", "descripcion", "descripción"]) def junctionLayerChanged(self): newItem = self.cbJunctionLayer.currentText() self.cbJunction_Id.clear() self.cbJunction_Elevation.clear() self.cbJunction_BaseDem.clear() self.cbJunction_Tag.clear() self.cbJunction_Descr.clear() if newItem == "None": self.gbJunctions.setEnabled(False) return self.gbJunctions.setEnabled(True) valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp") vlayer = QgsVectorLayer(valveLayer, "Juntions layer", "ogr") if not vlayer.isValid(): return field_names = [field.name() for field in vlayer.fields()] field_names.insert(0, "None") self.cbJunction_Id.addItems(field_names) self.cbJunction_Elevation.addItems(field_names) self.cbJunction_BaseDem.addItems(field_names) self.cbJunction_Tag.addItems(field_names) self.cbJunction_Descr.addItems(field_names) self.selectComboBoxItem(self.cbJunction_Id, ["id"]) self.selectComboBoxItem(self.cbJunction_Elevation, ["elevation"]) self.selectComboBoxItem(self.cbJunction_BaseDem, ["basedem"]) self.selectComboBoxItem(self.cbJunction_Tag, ["tag"]) self.selectComboBoxItem(self.cbJunction_Descr, ["descrip", "descr", "description", "descripcion", "descripción"]) def serviceConnectionLayerChanged(self): newItem = self.cbServiceConnectionLayer.currentText() self.cbServiceConnection_Id.clear() self.cbServiceConnection_Length.clear() self.cbServiceConnection_Diameter.clear() self.cbServiceConnection_Material.clear() self.cbServiceConnection_InstDate.clear() self.cbServiceConnection_Tag.clear() self.cbServiceConnection_Descr.clear() if newItem == "None": self.gbServiceConnection.setEnabled(False) return self.gbServiceConnection.setEnabled(True) valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp") vlayer = QgsVectorLayer(valveLayer, "Pumps layer", "ogr") if not vlayer.isValid(): return field_names = [field.name() for field in vlayer.fields()] field_names.insert(0, "None") self.cbServiceConnection_Id.addItems(field_names) self.cbServiceConnection_Length.addItems(field_names) self.cbServiceConnection_Diameter.addItems(field_names) self.cbServiceConnection_Material.addItems(field_names) self.cbServiceConnection_InstDate.addItems(field_names) self.cbServiceConnection_Tag.addItems(field_names) self.cbServiceConnection_Descr.addItems(field_names) self.selectComboBoxItem(self.cbServiceConnection_Id, ["id"]) self.selectComboBoxItem(self.cbServiceConnection_Length, ["length", "longitud"]) self.selectComboBoxItem(self.cbServiceConnection_Diameter, ["diameter", "diam", "diametro", "diámetro"]) self.selectComboBoxItem(self.cbServiceConnection_Material, ["material"]) self.selectComboBoxItem(self.cbServiceConnection_InstDate, ["instdate", "date", "fecha", "fecha_de_i"]) self.selectComboBoxItem(self.cbServiceConnection_Tag, ["tag"]) self.selectComboBoxItem(self.cbServiceConnection_Descr, ["descrip", "descr", "description", "descripcion", "descripción"]) def createShpsNames(self): shpFolder = self.tbShpDirectory.text() shpNames = "" name = self.cbPipeLayer.currentText() if not name == "None": shpNames = shpNames + "[PIPES]" + os.path.join(shpFolder, name) + "," name = self.cbValveLayer.currentText() if not name == "None": shpNames = shpNames + "[VALVES]" + os.path.join(shpFolder, name) + "," name = self.cbPumpLayer.currentText() if not name == "None": shpNames = shpNames + "[PUMPS]" + os.path.join(shpFolder, name) + "," name = self.cbTankLayer.currentText() if not name == "None": shpNames = shpNames + "[TANKS]" + os.path.join(shpFolder, name) + "," name = self.cbReservoirLayer.currentText() if not name == "None": shpNames = shpNames + "[RESERVOIRS]" + os.path.join(shpFolder, name) + "," name = self.cbJunctionLayer.currentText() if not name == "None": shpNames = shpNames + "[JUNCTIONS]" + os.path.join(shpFolder, name) + "," name = self.cbServiceConnectionLayer.currentText() if not name == "None": shpNames = shpNames + "[SERVICECONNECTIONS]" + os.path.join(shpFolder, name) + "," return shpNames def createShpFields(self): fields = "" name = self.cbPipeLayer.currentText() if not name == "None": fields = "[PIPES]" name = self.cbPipe_Id.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbPipe_Length.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbPipe_Diameter.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # RougCoeff name = self.cbPipe_Material.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbPipe_InstDate.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbPipe_LossCoef.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # InitStat fields = fields + ";" # BulkCoef fields = fields + ";" # WallCoef name = self.cbPipe_Tag.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbPipe_Descr.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + "," # To separate layers name = self.cbValveLayer.currentText() if not name == "None": fields = fields + "[VALVES]" name = self.cbValve_Id.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbValve_Diameter.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbValve_Type.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # Setting fields = fields + ";" # IdHeadLoss fields = fields + ";" # LossCoef name = self.cbValve_InitStat.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbValve_Tag.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbValve_Descr.currentText() if not name == "None": fields = fields + name fields = fields + ";" # fields = fields + ";" #Sector name = self.cbValve_Orient.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + "," # To separate layers name = self.cbPumpLayer.currentText() if not name == "None": fields = fields + "[PUMPS]" name = self.cbPump_Id.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # IdHFCurve name = self.cbPump_Power.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # Speed fields = fields + ";" # IdSpeedPat name = self.cbPump_InitStat.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # IdEfficCur fields = fields + ";" # EnergPrice fields = fields + ";" # IdPricePat name = self.cbPump_Tag.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbPump_Descr.currentText() if not name == "None": fields = fields + name fields = fields + ";" # fields = fields + ";" #Sector name = self.cbPump_Orient.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + "," # To separate layers name = self.cbTankLayer.currentText() if not name == "None": fields = fields + "[TANKS]" name = self.cbTank_Id.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbTank_Elevat.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # IniLevel name = self.cbTank_MinLevel.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbTank_MaxLevel.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbTank_Diameter.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # MinVolum fields = fields + ";" # IdVolCur fields = fields + ";" # MixMod fields = fields + ";" # MixFrac name = self.cbTank_ReactCoeff.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # InitialQuality name = self.cbTank_Tag.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbTank_Descr.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + "," # To separate layers name = self.cbReservoirLayer.currentText() if not name == "None": fields = fields + "[RESERVOIRS]" name = self.cbReservoir_Id.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbReservoir_TotHead.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # IdHeadPat fields = fields + ";" # IniQual name = self.cbReservoir_Tag.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbReservoir_Descr.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + "," # To separate layers name = self.cbJunctionLayer.currentText() if not name == "None": fields = fields + "[JUNCTIONS]" name = self.cbJunction_Id.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbJunction_Elevation.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbJunction_BaseDem.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + ";" # IdDemPat fields = fields + ";" # EmitCoef fields = fields + ";" # IniQual name = self.cbJunction_Tag.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbJunction_Descr.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + "," # To separate layers name = self.cbServiceConnectionLayer.currentText() if not name == "None": fields = fields + "[SERVICECONNECTIONS]" name = self.cbServiceConnection_Id.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbServiceConnection_Length.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbServiceConnection_Diameter.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbServiceConnection_Material.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbServiceConnection_InstDate.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbServiceConnection_Tag.currentText() if not name == "None": fields = fields + name fields = fields + ";" name = self.cbServiceConnection_Descr.currentText() if not name == "None": fields = fields + name fields = fields + ";" fields = fields + "," # To separate layers return fields def importShpProject(self): # Common validations isValid = self.validationsCreateProject() if isValid: # Validations SHP's if not os.path.exists(self.tbShpDirectory.text()): self.iface.messageBar().pushMessage("Validations", "The SHPs folder is not valid or does not exist", level=1) return # Tolerance tolerance = self.tbTolerance.text() try: t = float(tolerance) if t < 0: self.iface.messageBar().pushMessage("Validations", "Not valid Tolerance", level=1) return except Exception: self.iface.messageBar().pushMessage("Validations", "Not numeric Tolerance", level=1) return # Fields fields = self.createShpFields() if fields == "": self.iface.messageBar().pushMessage("Validations", "Any SHP selected for importing", level=1) return # Process if self.NewProject: if not self.createProject(): return self.close() self.parent.zoomToFullExtent = True epsg = self.crs.authid().replace("EPSG:", "") shapes = self.createShpsNames() # fields = self.createShpFields() # Process QApplication.setOverrideCursor(Qt.WaitCursor) resMessage = GISRed.ImportFromShps(self.ProjectDirectory, self.NetworkName, self.parent.tempFolder, shapes, fields, epsg, tolerance) QApplication.restoreOverrideCursor() self.parent.ProjectDirectory = self.ProjectDirectory self.parent.NetworkName = self.NetworkName name = self.cbServiceConnectionLayer.currentText() if not name == "None": self.parent.complementaryLayers = ["ServiceConnections"] self.parent.processCsharpResult(resMessage, "")
class CriaSpatialiteDialog(QtGui.QDialog, FORM_CLASS): def __init__(self, parent=None): """Constructor.""" super(CriaSpatialiteDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.filepath = "" self.carregado = False self.coordSysDefinido = False self.epsgCriaSpatialite = 0 self.srsCriaSpatialite = '' self.sqliteFileName = '' self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0,0,0,0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0,0,1,1) QtCore.QObject.connect(self.pushButtonBuscarPastaDestinoCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.definePastaDestino) QtCore.QObject.connect(self.pushButtonBuscarSistCoordCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.setaSistCoordCriaSpatialite) QtCore.QObject.connect(self.pushButtonOkCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.okselecionadoCriaSpatialite) def getTemplateLocation(self): """ gets the template location """ currentPath = os.path.dirname(__file__) if self.versionComboBox.currentText() == '2.1.3': edgvPath = os.path.join(currentPath, 'template', '213', 'seed_edgv213.sqlite') elif self.versionComboBox.currentText() == 'FTer_2a_Ed': edgvPath = os.path.join(currentPath, 'template', 'FTer_2a_Ed', 'seed_edgvfter_2a_ed.sqlite') elif self.versionComboBox.currentText() == '3.0': edgvPath = os.path.join(currentPath, 'template', '3', 'seed_edgv3.sqlite') return edgvPath def restauraInicio(self): """ Stes the initial state """ self.filepath = "" self.carregado = False self.coordSysDefinido = False self.epsgCriaSpatialite = 0 self.srsCriaSpatialite = '' self.sqliteFileName = '' self.pastaDestinoCriaSpatialiteLineEdit.setText("") self.coordSysCriaSpatialiteLineEdit.setText("") self.nomeLineEdit.setText("") def definePastaDestino(self): """ Defines destination folder """ fd = QtGui.QFileDialog() self.filepath = fd.getExistingDirectory() if self.filepath <> "": self.carregado = True self.pastaDestinoCriaSpatialiteLineEdit.setText(self.filepath) def setaSistCoordCriaSpatialite(self): """ Opens the CRS selector """ projSelector = QgsGenericProjectionSelector() projSelector.setMessage(theMessage=self.tr('Please, select the coordinate system')) projSelector.exec_() try: self.epsgCriaSpatialite = int(projSelector.selectedAuthId().split(':')[-1]) self.srsCriaSpatialite = QgsCoordinateReferenceSystem(self.epsgCriaSpatialite, QgsCoordinateReferenceSystem.EpsgCrsId) if self.srsCriaSpatialite <> "": self.coordSysDefinido = True self.coordSysCriaSpatialiteLineEdit.setText(self.srsCriaSpatialite.description()) except: self.bar.pushMessage("", self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING) pass def copiaSemente(self, destino, srid): """ Copies the spatialite seed template """ f = open(self.getTemplateLocation(),'rb') g = open(destino,'wb') x = f.readline() while x: g.write(x) x = f.readline() g.close() con = sqlite3.connect(destino) cursor = con.cursor() srid_sql = (srid,) cursor.execute("UPDATE geometry_columns SET srid=?",srid_sql) con.commit() con.close() def okselecionadoCriaSpatialite(self): """ Performs the database creation """ if self.carregado and self.coordSysDefinido and len(self.nomeLineEdit.text()) > 0: try: self.sqliteFileName = self.filepath+'/'+self.nomeLineEdit.text()+'.sqlite' destino = self.sqliteFileName self.copiaSemente(destino,self.epsgCriaSpatialite) self.close() self.restauraInicio() QtGui.QMessageBox.information(self, self.tr('Information'), self.tr('Spatialite created successfully!')) except: qgis.utils.iface.messageBar().pushMessage(self.tr("Error!"), self.tr("Problem creating the database!"), level=QgsMessageBar.CRITICAL) self.restauraInicio() pass else: if self.coordSysDefinido == False: self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING) if self.carregado == False: self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select a folder to save the database'), level=QgsMessageBar.CRITICAL) if len(self.nomeLineEdit.text()) == 0: self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, fill the file name.'), level=QgsMessageBar.CRITICAL)