def openModel(self): filename, selected_filter = QFileDialog.getOpenFileName(self, self.tr('Open Model'), ModelerUtils.modelsFolders()[0], self.tr('Processing models (*.model *.MODEL)')) if filename: try: alg = ModelerAlgorithm.fromFile(filename) self.alg = alg self.alg.setModelerView(self) self.textGroup.setText(alg._group) self.textName.setText(alg._name) self.repaintModel() self.view.centerOn(0, 0) self.hasChanged = False except WrongModelException as e: QgsMessageLog.logMessage(self.tr('Could not load model {0}\n{1}').format(filename, e.msg), self.tr('Processing'), QgsMessageLog.CRITICAL) QMessageBox.critical(self, self.tr('Could not open model'), self.tr('The selected model could not be loaded.\n' 'See the log for more information.')) except Exception as e: QgsMessageLog.logMessage(self.tr('Could not load model {0}\n{1}').format(filename, e.args[0]), self.tr('Processing'), QgsMessageLog.CRITICAL) QMessageBox.critical(self, self.tr('Could not open model'), self.tr('The selected model could not be loaded.\n' 'See the log for more information.'))
def validate(self): #self.layerList.setTitle('Layers') data_source = self.gmlas_datasource() if data_source is None: QMessageBox.critical(self, plugin_name(), self.tr('Failed to open file using OGR GMLAS driver')) return ogrMetadataLayerPrefix = '_ogr_' self.datasetsListWidget.clear() for i in range(0, data_source.GetLayerCount()): layer = data_source.GetLayer(i) layer_name = layer.GetName() if not layer_name.startswith(ogrMetadataLayerPrefix): feature_count = layer.GetFeatureCount() item = QListWidgetItem("{} ({})".format(layer_name, feature_count)) item.setData(Qt.UserRole, layer_name) self.datasetsListWidget.addItem(item) self.datasetsListWidget.sortItems() self.datasetsListWidget.selectAll()
def validate(self, ds_info): # validate common fields checks = [ (ds_info.id, self.tr('Please, enter data source id')), (ds_info.alias, self.tr('Please, enter data source alias')), (ds_info.icon, self.tr('Please, select icon for data source')), (ds_info.group, self.tr('Please, select group for data source')), (ds_info.type, self.tr('Please, select type for data source')), ] for val, comment in checks: if not val: QMessageBox.critical(self, self.tr('Error on save data source'), self.tr(comment)) return False checks_correct = [ (self.id_validator, self.tr('Please, enter correct value for data source id')), (self.alias_validator, self.tr('Please, enter correct value for data source alias')), ] for val, comment in checks_correct: if not val.is_valid(): QMessageBox.critical(self, self.tr('Error on save data source'), self.tr(comment)) return False # validate special fields if not self.DRV_WIDGETS[ds_info.type].validate(ds_info): return False return True
def blame(self, repo, tree, fid): try: path = "%s/%s" % (tree, fid) dlg = BlameDialog(repo, path) dlg.exec_() except GeoGigException as e: QMessageBox.critical(self.parent(), "Error", "%s" % e)
def on_btnLoad_clicked(self): fileName, _ = QFileDialog.getOpenFileName(None, self.tr('Import Colors and elevations from XML'), QDir.homePath(), self.tr('XML files (*.xml *.XML)')) if fileName == '': return doc = QDomDocument() with codecs.open(fileName, 'r', encoding='utf-8') as f: content = f.read() if not doc.setContent(content): QMessageBox.critical(None, self.tr('Error parsing XML'), self.tr('The XML file could not be loaded')) return self.reliefClassTree.clear() reliefColorList = doc.elementsByTagName('ReliefColor') for i in range(reliefColorList.length()): elem = reliefColorList.at(i).toElement() item = QTreeWidgetItem() item.setText(0, elem.attribute('MinElevation')) item.setText(1, elem.attribute('MaxElevation')) item.setBackground(2, QBrush(QColor(int(elem.attribute('red')), int(elem.attribute('green')), int(elem.attribute('blue'))))) self.reliefClassTree.addTopLevelItem(item)
def check_existing_id(self, group_id): gl = GroupsList() if group_id in gl.groups.keys(): QMessageBox.critical(self, self.tr('Error on save group'), self.tr('Group with such id already exists! Select new id for group!')) return False return True
def createGeomColumn(self): """ first check whether everything's fine """ if self.editName.text() == "": QMessageBox.critical(self, self.tr("DB Manager"), self.tr("field name must not be empty")) return name = self.editName.text() geom_type = self.GEOM_TYPES[self.cboType.currentIndex()] dim = self.spinDim.value() try: srid = int(self.editSrid.text()) except ValueError: srid = -1 createSpatialIndex = False # now create the geometry column QApplication.setOverrideCursor(Qt.WaitCursor) try: self.table.addGeometryColumn(name, geom_type, srid, dim, createSpatialIndex) except DbError as e: DlgDbError.showError(e, self) return finally: QApplication.restoreOverrideCursor() self.accept()
def show_api_error(self, result): if 'error' in result: QMessageBox.critical(None, "QGIS Cloud Error", "%s" % result['error']) self.status_bar.showMessage(u"Error") return True else: return False
def accept(self): try: self.setParamValues() msg = self.alg._checkParameterValuesBeforeExecuting() if msg: QMessageBox.warning( self, self.tr('Unable to execute algorithm'), msg) return description = algAsDict(self.alg) description["name"] = self.settingsPanel.txtName.text().strip() description["group"] = self.settingsPanel.txtGroup.text().strip() if not (description["name"] and description["group"]): self.tabWidget.setCurrentIndex(self.tabWidget.count() - 1) return validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:' filename = ''.join(c for c in description["name"] if c in validChars).lower() + ".json" filepath = os.path.join(preconfiguredAlgorithmsFolder(), filename) with open(filepath, "w") as f: json.dump(description, f) algList.reloadProvider('preconfigured') except AlgorithmDialogBase.InvalidParameterValue as e: try: self.buttonBox.accepted.connect(lambda: e.widget.setPalette(QPalette())) palette = e.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) e.widget.setPalette(palette) self.lblProgress.setText( self.tr('<b>Missing parameter value: %s</b>') % e.parameter.description) return except: QMessageBox.critical(self, self.tr('Unable to execute algorithm'), self.tr('Wrong or missing parameter values')) self.close()
def wkblify_raster(self, options, infile, i, previous_gt = None): """Writes given raster dataset using GDAL features into HEX-encoded of WKB for WKT Raster output.""" # Open source raster file ds = gdal.Open(infile, gdalc.GA_ReadOnly); if ds is None: QMessageBox.critical(None,'Error:','Cannot open input file: ' + str(infile)) # By default, translate all raster bands # Calculate range for single-band request if options['band'] is not None and options['band'] > 0: band_range = ( options['band'], options['band'] + 1 ) else: band_range = ( 1, ds.RasterCount + 1 ) # Compare this px size with previous one current_gt = self.get_gdal_geotransform(ds) if previous_gt is not None: if previous_gt[1] != current_gt[1] or previous_gt[5] != current_gt[5]: QMessageBox.critical(None,'Error:', 'Cannot load raster with different pixel size in the same raster table') # Generate requested overview level (base raster if level = 1) summary = self.wkblify_raster_level(options, ds, options['overview_level'], band_range, infile, i) SUMMARY.append( summary ) # Cleanup ds = None return current_gt
def check_existing_id(self, ds_id): gl = DataSourcesList() if ds_id in gl.data_sources.keys(): QMessageBox.critical(self, self.tr('Error on save group'), self.tr('Data source with such id already exists! Select new id for data source!')) return False return True
def versions(self, repo, tree, fid): try: path = tree + "/" + fid dlg = VersionViewerDialog(repo, path) dlg.exec_() except GeoGigException as e: QMessageBox.critical(self.parent(), "Error", "%s" % e)
def openModel(self): filename = unicode(QFileDialog.getOpenFileName(self, self.tr('Open Model'), ModelerUtils.modelsFolder(), self.tr('Processing models (*.model *.MODEL)'))) if filename: try: alg = ModelerAlgorithm.fromFile(filename) self.alg = alg self.alg.setModelerView(self) self.textGroup.setText(alg.group) self.textName.setText(alg.name) self.repaintModel() self.view.centerOn(0, 0) self.hasChanged = False except WrongModelException as e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not load model %s\n%s') % (filename, e.msg)) QMessageBox.critical(self, self.tr('Could not open model'), self.tr('The selected model could not be loaded.\n' 'See the log for more information.')) except Exception as e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not load model %s\n%s') % (filename, e.args[0])) QMessageBox.critical(self, self.tr('Could not open model'), self.tr('The selected model could not be loaded.\n' 'See the log for more information.'))
def export(self): """ Export the results to a CSV file """ # Remember the last location in which we saved settings = QSettings() lastFolder = str(settings.value("constraintchecker/lastSaveFolder", os.sep)) outFileName, ext_selector = QFileDialog.getSaveFileName(self, 'Save Query Results', lastFolder, 'Comma Separated Variable Files (*.csv)') # Store the path we just looked in head, tail = os.path.split(outFileName) if head != os.sep and head.lower() != 'c:\\' and head != '': settings.setValue("constraintchecker/lastSaveFolder", head) if len(outFileName) == 0: # User hit cancel return # Export the file try: csvfile = open(outFileName+'.csv', 'w') except: msg = 'Failed to open %s for writing - perhaps it is open in another application?' % outFileName QMessageBox.critical(self, 'Failed to Open File', msg) return resWriter = csv.writer(csvfile) resWriter.writerow(self.resultModel.headerNames) for i in range(self.resultModel.rowCount()): resWriter.writerow(self.resultModel.fetchRow(i)) csvfile.close()
def show_api_error(self, result): if 'error' in result: QMessageBox.critical( self, self.tr("QGIS Cloud Error"), "%s" % result['error']) self.statusBar().showMessage(self.tr("Error")) return True else: return False
def accept(self): try: self.value = float(eval(str(self.leFormula.text()))) if self.isInteger: self.value = int(round(self.value)) QDialog.accept(self) except: QMessageBox.critical(self, self.tr('Wrong expression'), self.tr('The expression entered is not correct'))
def show_error_message(parent, exception): """Generate error message to handle parameter errors :param parent: The widget as a parent of message box :type parent: QWidget :param exception: python Exception or Error :type exception: Exception """ box = QMessageBox() box.critical(parent, 'Error occured', str(exception))
def execute(self): f = os.path.join(FusionUtils.FusionPath(), 'pdq.exe') if os.path.exists(f): subprocess.Popen(f) else: QMessageBox.critical( None, self.tr('Unable to open viewer'), self.tr('The current Fusion folder does not contain the ' 'viewer executable.\nPlease check the configuration ' 'in the Processing settings dialog.'))
def validate(self, ds_info): if not ds_info.geojson_url: QMessageBox.critical(self, self.tr('Error on save data source'), self.tr('Please, enter GeoJSON url')) return False if not self.geojson_validator.is_valid(): QMessageBox.critical(self, self.tr('Error on save data source'), self.tr('Please, enter correct value for GeoJSON url')) return False return True
def onOK(self): """ first check whether everything's fine """ fld = self.getField(True) # don't change the original copy if fld.name == "": QMessageBox.critical(self, self.tr("DB Manager"), self.tr("field name must not be empty")) return if fld.dataType == "": QMessageBox.critical(self, self.tr("DB Manager"), self.tr("field type must not be empty")) return self.accept()
def createIndex(self): idx = self.getIndex() if idx.name == "": QMessageBox.critical(self, self.tr("Error"), self.tr("Please enter a name for the index.")) return # now create the index with OverrideCursor(Qt.WaitCursor): try: self.table.addIndex(idx) except DbError as e: DlgDbError.showError(e, self) return self.accept()
def runElevation(self): if mathplotlibWorks == False: QMessageBox.critical(None, "Error", QCoreApplication.translate("geopunt4Qgis" , "Deze functie kan niet geladen worden door het ontbreken van of een fout in mathplotlib") ) return 'show the dialog' if self.elevationDlg.isVisible(): self.elevationDlg.showNormal() self.elevationDlg.activateWindow() return self.elevationDlg.loadSettings() self.elevationDlg.show() # Run the dialog event loop self.elevationDlg.exec_()
def load(self): context = dataobjects.createContext() settings = QgsSettings() last_path = settings.value("/Processing/LastBatchPath", QDir.homePath()) filename, selected_filter = QFileDialog.getOpenFileName(self, self.tr('Open Batch'), last_path, self.tr('JSON files (*.json)')) if filename: last_path = QFileInfo(filename).path() settings.setValue('/Processing/LastBatchPath', last_path) with open(filename) as f: values = json.load(f) else: # If the user clicked on the cancel button. return self.tblParameters.setRowCount(0) try: for row, alg in enumerate(values): self.addRow() params = alg[self.PARAMETERS] outputs = alg[self.OUTPUTS] column = 0 for param in self.alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if param.isDestination(): continue if param.name() in params: value = eval(params[param.name()]) wrapper = self.wrappers[row][column] wrapper.setParameterValue(value, context) column += 1 for out in self.alg.destinationParameterDefinitions(): if out.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if out.name() in outputs: value = outputs[out.name()].strip("'") widget = self.tblParameters.cellWidget(row, column) widget.setValue(value) column += 1 except TypeError: QMessageBox.critical( self, self.tr('Error'), self.tr('An error occurred while reading your file.'))
def accept(self): # Set our connection preference based on the combo-box s = QSettings() if self.postgisConnectionComboBox.count() > 0: connecionName = self.postgisConnectionComboBox.currentText() s.setValue("constraintchecker/postgisConnection", connecionName) try: self.saveConfiguration() except: msg = 'An error occurred when trying to save the configuration. ' \ 'The details are:\n\n%s' % traceback.format_exc() QMessageBox.critical(self, 'Error Saving Configuration', msg) return QDialog.accept(self)
def createIndex(self): idx = self.getIndex() if idx.name == "": QMessageBox.critical(self, self.tr("Error"), self.tr("Please enter some name for the index")) return # now create the index QApplication.setOverrideCursor(Qt.WaitCursor) try: self.table.addIndex(idx) except DbError as e: DlgDbError.showError(e, self) return finally: QApplication.restoreOverrideCursor() self.accept()
def drawDMSPoint(self): point, ok = DMSDialog().getPoint() self.XYcrs = QgsCoordinateReferenceSystem(4326) if ok: if point.x() == 0 and point.y() == 0: QMessageBox.critical( self.iface.mainWindow(), self.tr('Error'), self.tr('Invalid input !')) else: self.drawPoint() self.tool.rb = QgsRubberBand( self.iface.mapCanvas(), QgsWkbTypes.PointGeometry) self.tool.rb.setColor(self.settings.getColor()) self.tool.rb.setWidth(3) self.tool.rb.addPoint(point) self.drawShape = 'XYpoint' self.draw()
def loadModel(self, filename): alg = QgsProcessingModelAlgorithm() if alg.fromFile(filename): self.model = alg self.model.setProvider(QgsApplication.processingRegistry().providerById('model')) self.textGroup.setText(alg.group()) self.textName.setText(alg.name()) self.repaintModel() self.view.centerOn(0, 0) self.hasChanged = False else: QgsMessageLog.logMessage(self.tr('Could not load model {0}').format(filename), self.tr('Processing'), Qgis.Critical) QMessageBox.critical(self, self.tr('Open Model'), self.tr('The selected model could not be loaded.\n' 'See the log for more information.'))
def constraintCheck(self, queryGeom, epsg): # Prompt the user for a reference number refDlg = ReferenceNumberDialog() result = refDlg.exec_() if result == QDialog.Rejected: # User pressed cancel return refNumber = refDlg.getRefNumber() try: c = Checker(self.iface, refNumber) c.check(queryGeom, epsg) c.display() except: msg = 'The query failed and the detailed error was:\n\n%s' % traceback.format_exc() QMessageBox.critical(self.iface.mainWindow(), 'Query Failed', msg)
def drawXYPoint(self): tuple, ok = XYDialog().getPoint( self.iface.mapCanvas().mapSettings().destinationCrs()) point = tuple[0] self.XYcrs = tuple[1] if ok: if point.x() == 0 and point.y() == 0: QMessageBox.critical( self.iface.mainWindow(), self.tr('Error'), self.tr('Invalid input !')) else: self.drawPoint() self.tool.rb = QgsRubberBand( self.iface.mapCanvas(), QgsWkbTypes.PointGeometry) self.tool.rb.setColor(self.settings.getColor()) self.tool.rb.setWidth(3) self.tool.rb.addPoint(point) self.drawShape = 'XYpoint' self.draw()
def load(self): filename, selected_filter = QFileDialog.getOpenFileName(self, self.tr('Open batch'), None, self.tr('JSON files (*.json)')) if filename: with open(filename) as f: values = json.load(f) else: # If the user clicked on the cancel button. return self.tblParameters.setRowCount(0) try: for row, alg in enumerate(values): self.addRow() params = alg[self.PARAMETERS] outputs = alg[self.OUTPUTS] column = 0 for param in self.alg.parameters: if param.hidden: continue if param.name in params: value = params[param.name] wrapper = self.wrappers[row][column] wrapper.setValue(value) column += 1 for out in self.alg.outputs: if out.hidden: continue if out.name in outputs: value = outputs[out.name] widget = self.tblParameters.cellWidget(row, column) widget.setValue(value) column += 1 except TypeError: QMessageBox.critical( self, self.tr('Error'), self.tr('An error occurred while reading your file.'))
def raster_clip(self): from PIL import Image in_filename = self.dlg.lineEdit_clip_input.text() in_filename_label = self.dlg.lineEdit_clip_input_label.text() output_path = self.dlg.lineEdit_clip_output.text() clip_width = self.dlg.lineEdit_clip_width.text() clip_height = self.dlg.lineEdit_clip_height.text() clip_step = self.dlg.lineEdit_clip_step.text() os.makedirs(output_path + "/clip/img/", exist_ok=1) os.makedirs(output_path + "/clip/label/", exist_ok=1) if in_filename is None or in_filename == '' or output_path is None or output_path == '': QMessageBox.critical(self.dlg, "错误", "参数定义错误!") return 0 name = os.path.split(in_filename)[-1] imagepath = in_filename ds = gdal.Open(imagepath) wx = ds.RasterXSize wy = ds.RasterYSize imagepath = in_filename isnot_clip_label = False if in_filename_label is not None: labelname = in_filename_label isnot_clip_label = True if isnot_clip_label: dslb = gdal.Open(labelname) stx = 0 sty = 0 step = int(clip_step) outsize = int(clip_width) nullthresh = outsize * outsize * 0.7 cx = 0 cy = 0 from PyQt5.QtWidgets import QProgressBar from PyQt5.QtCore import QBasicTimer pbar = self.dlg.progressBar_clip bar_num = 0 c = 0 while cy + outsize < wy: cx = 0 while cx + outsize < wx: c += 1 cx += step cy += step cx = 0 cy = 0 # 秦磊修改15:13 while cy + outsize < wy: cx = 0 while cx + outsize < wx: pbar.setValue(bar_num) bar_num += (100 / c) img = ds.ReadAsArray(cx, cy, outsize, outsize) img2 = img[0:3, :, :].transpose(1, 2, 0) if (img2[:, :, 0] == 0).sum() > nullthresh: cx += step continue skimage.io.imsave( output_path + "/clip/img/" + name + '_{}_{}.jpg'.format(cx, cy), img2.astype(int)) #deal with label if isnot_clip_label: img = dslb.ReadAsArray(cx, cy, outsize, outsize) img = Image.fromarray(img).convert('L') img.save(output_path + "/clip/label/" + name + '_{}_{}.jpg'.format(cx, cy)) print(cx, cy) cx += step cy += step pbar.setValue(100) QMessageBox.information(self.dlg, '训练集验证集分割图片裁剪', '完成!')
def cal_feature(self): print('计算特征') import sys #实例化列表模型,添加数据 # label_list = [ 'NDVI', 'DVI', 'RVI', 'GNDVI', 'NDWI', 'SAVI', 'MSAVI', 'EVI', 'ARVI', 'NDSI', 'Vegetation_removal', 'PCA', 'shadow_removal', 'road_removal' ] check_list = [ self.dlg.checkBox_NDVI.isChecked(), self.dlg.checkBox_DVI.isChecked(), self.dlg.checkBox_RVI.isChecked(), self.dlg.checkBox_GNDVI.isChecked(), self.dlg.checkBox_NDWI.isChecked(), self.dlg.checkBox_SAVI.isChecked(), self.dlg.checkBox_MSAVI.isChecked(), self.dlg.checkBox_EVI.isChecked(), self.dlg.checkBox_ARVI.isChecked(), self.dlg.checkBox_NDSI.isChecked(), self.dlg.checkBox_Vegetation_removal.isChecked(), self.dlg.checkBox_PCA.isChecked(), self.dlg.checkBox_shadow_removal.isChecked(), self.dlg.checkBox_road_removal.isChecked() ] labeldict = {} for i, j in zip(label_list, check_list): labeldict[i] = j in_filename = self.dlg.lineEdit_getfeature_input.text() output_path = self.dlg.lineEdit_getfeature_output.text() # print(all(check_list),check_list) if (output_path is None) or (in_filename is None) or ( output_path == '') or (in_filename == ''): print('请选择路径') QMessageBox.critical(self.dlg, "错误", "未输入文件路径!") # 一个特征提取都不选就报错 # elif ~any(check_list): # QMessageBox.critical(self.dlg, "错误","未勾选特征提取方法!") else: self.Calculation_feature_function(in_filename, output_path, labeldict) QMessageBox.information(self.dlg, '特征提取', '完成!') layers = QgsProject.instance().mapLayers().values() layer_list = [] for layer in layers: layer_list.append(layer.name()) listView = self.dlg.listView slm = QStringListModel() qList = layer_list slm.setStringList(qList) listView.setModel(slm)
def upload_data(self): if self.check_login(): if self.local_data_sources.count() == 0: return if self.db_connections.count() == 0: QMessageBox.warning(self, self.tr("No database available"), self.tr("Please create a database in the 'Account' tab.")) return if not self.ui.cbUploadDatabase.currentIndex() >= 0: QMessageBox.warning(self, self.tr("No database selected"), self.tr("Please select a database to upload data.")) return db_name = self.ui.cbUploadDatabase.currentText() if not self.db_connections.isPortOpen(db_name): uri = self.db_connections.cloud_layer_uri(db_name, "", "") host = str(uri.host()) port = uri.port() QMessageBox.critical(self, self.tr("Network Error"), self.tr("Could not connect to database server ({0}) on port {1}. Please contact your system administrator or internet provider to open port {1} in the firewall".format(host, port))) return # disable update of local data sources during upload, as there are # temporary layers added and removed self.do_update_local_data_sources = False self.statusBar().showMessage(self.tr("Uploading data...")) self.setCursor(Qt.WaitCursor) self.ui.btnUploadData.hide() self.ui.spinner.start() self.ui.progressWidget.show() # Map<data_source, {table: table, layers: layers}> data_sources_items = {} for row in range(0, self.ui.tblLocalLayers.rowCount()): data_source = unicode( self.ui.tblLocalLayers.item( row, self.COLUMN_DATA_SOURCE).text()) layers = self.local_data_sources.layers(data_source) if layers is not None: table_name = unicode( self.ui.tblLocalLayers.item( row, self.COLUMN_TABLE_NAME).text()) data_sources_items[data_source] = { u'table': unicode(table_name), u'layers': layers} login_info = self.api.check_login(version_info=self._version_info()) try: self.maxSize = login_info['max_storage'] self.maxDBs = login_info['max_dbs'] except: self.maxSize = 50 self.maxDBs = 5 try: self.data_upload.upload(self.db_connections.db(unicode(db_name)), data_sources_items, unicode(self.maxSize)) upload_ok = True except Exception as e: ErrorReportDialog(self.tr("Upload errors occurred"), self.tr("Upload errors occurred. Not all data could be uploaded."), str(e) + "\n" + traceback.format_exc(), self.user, self).exec_() upload_ok = False self.ui.spinner.stop() self.ui.progressWidget.hide() self.ui.btnUploadData.show() self.unsetCursor() self.statusBar().showMessage("") # Refresh local layers self.do_update_local_data_sources = True self.update_local_layers() # Refresh used space after upload self.db_size(self.db_connections) if upload_ok: # Show save project dialog save_dialog = QDialog(self) save_dialog.setWindowTitle(self.tr("Save Project")) save_dialog.setLayout(QVBoxLayout()) header = QWidget() header.setLayout(QVBoxLayout()) label = QLabel(self.tr("Upload complete. The local layers in the project were replaced with the layers uploaded to the qgiscloud database.")) label.setWordWrap(True) header.layout().addWidget(label) label = QLabel(self.tr("Choose were to save the modified project:")) label.setWordWrap(True) header.layout().addWidget(label) save_dialog.layout().setContentsMargins(0, 0, 0, 0) save_dialog.layout().addWidget(header) initialPath = QgsProject.instance().fileName() if not initialPath: initialPath = QSettings().value("/UI/lastProjectDir", ".") fd = QFileDialog(None, self.tr("Save Project"), initialPath, "%s (*.qgz *.qgs)" % self.tr("QGIS Project Files")) fd.setParent(save_dialog, Qt.Widget) fd.setOption(QFileDialog.DontUseNativeDialog) fd.setAcceptMode(QFileDialog.AcceptSave) save_dialog.layout().addWidget(fd) header.layout().setContentsMargins(fd.layout().contentsMargins()) fd.accepted.connect(save_dialog.accept) fd.rejected.connect(save_dialog.reject) if save_dialog.exec_() == QDialog.Accepted: files = list(fd.selectedFiles()) if files: QgsProject.instance().setFileName(files[0]) self.iface.actionSaveProject().trigger() # Switch to map tab self.ui.tabWidget.setCurrentWidget(self.ui.mapTab)
def login_error_message(e): QgsApplication.messageLog().logMessage(f"Mergin plugin: {str(e)}") msg = "<font color=red>Security token has been expired, failed to renew. Check your username and password </font>" QMessageBox.critical(None, "Login failed", msg, QMessageBox.Close)
def get_slope_from_dem(self): GA_ReadOnly = 0 output_path = self.dlg.lineEdit_dem_output.text() DEMFilename = self.dlg.lineEdit_dem_input.text() if (output_path is None) or (DEMFilename is None) or ( output_path == '') or (DEMFilename == ''): print('请选择路径') QMessageBox.critical(self.dlg, "错误", "未输入文件路径!") return 0 LandsatFilename = 'D:/data/caijian.tif' slopeFilename = output_path + '/slope_prj.tif' aspectFilename = output_path + 'aspect_prj.tif' gdal.AllRegister() data = gdal.Open(DEMFilename, GA_ReadOnly) if data is None: print('Cannot open this file:' + DEMFilename) sys.exit(1) # 投影变换 # projData = convertProjection(data, LandsatFilename) # gridNew = projData.ReadAsArray().astype(np.float) gridNew = data.ReadAsArray().astype(np.float) # 获取分辨率 dx = self.dlg.spinBox_dem_slope_resolution.value() Sx, Sy = calcFiniteSlopes(gridNew, dx) # 坡度计算 slope = np.arctan(np.sqrt(Sx**2 + Sy**2)) * 57.29578 # 坡向计算 aspect = np.ones([Sx.shape[0], Sx.shape[1]]).astype(np.float32) for i in range(Sx.shape[0]): for j in range(Sy.shape[1]): sx = float(Sx[i, j]) sy = float(Sy[i, j]) if (sx == 0.0) & (sy == 0.0): aspect[i, j] = -1 elif sx == 0.0: if sy > 0.0: aspect[i, j] = 0.0 else: aspect[i, j] = 180.0 elif sy == 0.0: if sx > 0.0: aspect[i, j] = 90.0 else: aspect[i, j] = 270.0 else: aspect[i, j] = float(math.atan2(sy, sx) * 57.29578) if aspect[i, j] < 0.0: aspect[i, j] = 90.0 - aspect[i, j] elif aspect[i, j] > 90.0: aspect[i, j] = 360.0 - aspect[i, j] + 90.0 else: aspect[i, j] = 90.0 - aspect[i, j] # 输出坡度坡向文件 driver = gdal.GetDriverByName('GTiff') if os.path.exists(slopeFilename): os.remove(slopeFilename) if os.path.exists(aspectFilename): os.remove(aspectFilename) ##########way1######## # ds1 = driver.Create(slopeFilename, slope.shape[1], slope.shape[0], 1, GDT_Float32) # band = ds1.GetRasterBand(1) # band.WriteArray(slope, 0, 0) # ds2 = driver.Create(aspectFilename, aspect.shape[1], aspect.shape[0], 1, GDT_Float32) # band = ds2.GetRasterBand(1) # band.WriteArray(aspect, 0, 0) # del ds1 # del ds2 ##########way2######## out = ga.SaveArray(slope, slopeFilename, format="GTiff", prototype=data) out = None out = ga.SaveArray(aspect, aspectFilename, format="GTiff", prototype=data) out = None data = None projData = None if self.dlg.checkBox_dem_slope_show.isChecked(): iface.addRasterLayer(slopeFilename, 'slope') iface.addRasterLayer(aspectFilename, 'aspect')
def getArguments(self): arguments = [] if self.targetSRSCheck.isChecked() and self.targetSRSEdit.text(): arguments.append("-a_srs") arguments.append(self.targetSRSEdit.text()) if self.creationOptionsGroupBox.isChecked(): for opt in self.creationOptionsWidget.options(): arguments.extend(["-co", opt]) if self.outsizeCheck.isChecked() and self.outsizeSpin.value() != 100: arguments.append("-outsize") arguments.append(self.outsizeSpin.text()) arguments.append(self.outsizeSpin.text()) if self.expandCheck.isChecked(): arguments.append("-expand") arguments.append(self.expand_method[self.expandCombo.currentIndex()]) if self.nodataCheck.isChecked(): arguments.append("-a_nodata") arguments.append(str(self.nodataSpin.value())) if self.sdsCheck.isChecked(): arguments.append("-sds") if self.srcwinCheck.isChecked() and self.srcwinEdit.text(): coordList = self.srcwinEdit.text().split() # split the string on whitespace(s) if len(coordList) == 4 and coordList[3]: try: for x in coordList: int(x) except ValueError: #print "Coordinates must be integer numbers." QMessageBox.critical(self, self.tr("Translate - srcwin"), self.tr("Image coordinates (pixels) must be integer numbers.")) else: arguments.append("-srcwin") for x in coordList: arguments.append(x) if self.prjwinCheck.isChecked() and self.prjwinEdit.text(): coordList = self.prjwinEdit.text().split() # split the string on whitespace(s) if len(coordList) == 4 and coordList[3]: try: for x in coordList: float(x) except ValueError: #print "Coordinates must be integer numbers." QMessageBox.critical(self, self.tr("Translate - prjwin"), self.tr("Image coordinates (geographic) must be numbers.")) else: arguments.append("-projwin") for x in coordList: arguments.append(x) if self.isBatchEnabled(): if self.formatCombo.currentIndex() != 0: arguments.append("-of") arguments.append(Utils.fillRasterOutputFormat(self.formatCombo.currentText())) return arguments else: return arguments outputFn = self.getOutputFileName() if outputFn: arguments.append("-of") arguments.append(self.outputFormat) arguments.append(self.getInputFileName()) arguments.append(outputFn) # set creation options filename/layer for validation if self.inSelector.layer(): self.creationOptionsWidget.setRasterLayer(self.inSelector.layer()) else: self.creationOptionsWidget.setRasterFileName(self.getInputFileName()) return arguments
def copy_published_project(self): # create publish directory if not exists if not os.path.exists(self._publish_dir): os.makedirs(self._publish_dir) def copy_project_files(link=False): project_filename, metadata_filename = self.project_files() fn = os.symlink if link else shutil.copy try: for filename in (project_filename, metadata_filename): outputname = os.path.join(self._publish_dir, os.path.basename(filename)) fn(filename, outputname) except (shutil.Error, IOError) as e: raise Exception("Copying project files failed: {0}".format(e)) def copy_data_sources(link=False): messages = [] # error messages # overwrite = [] # files to overwrite project_dir = os.path.dirname(self.plugin.project.fileName()) # collect files to be copied publish_files = {} for ds in list(self._datasources.values()): for dsfile in ds: if os.path.exists(dsfile) and os.path.isfile(dsfile): publish_path = os.path.dirname( self._publish_dir + dsfile[len(project_dir):]) if publish_path not in publish_files: publish_files[publish_path] = [] if os.path.splitext(dsfile)[1] == '.shp': # Esri Shapefile (copy all files) shpname = os.path.splitext(dsfile)[0] for shpext in ('shp', 'shx', 'dbf', 'sbn', 'sbx', 'fbn', 'fbx', 'ain', 'aih', 'atx', 'ixs', 'mxs', 'prj', 'xml', 'cpg'): shpfile = '{0}.{1}'.format(shpname, shpext) if os.path.exists(shpfile): dstfile = os.path.join( publish_path, shpfile) # if os.path.exists(dstfile): # overwrite.append(dstfile) publish_files[publish_path].append(shpfile) else: # other formats (we expect one file per datasource) dstfile = os.path.join(publish_path, os.path.basename(dsfile)) # if os.path.exists(dstfile): # overwrite.append(dstfile) publish_files[publish_path].append(dsfile) else: messages.append( "Unsupported data source: {0} is not a file". format(dsfile)) # if overwrite: # response = QMessageBox.question(self.dialog, "Overwrite", # "Files:\n{0}\nalready exists. Do you want to overwrite them?".format( # os.linesep.join(overwrite if len(overwrite) < 6 else overwrite[:5] + ['...']) # ), # QMessageBox.Yes, QMessageBox.No) # if response == QMessageBox.Yes: # overwrite = None # copy/link collected project files fn = os.symlink if link else shutil.copy for publish_dir, project_files in list(publish_files.items()): try: # create dirs if not exists if not os.path.exists(os.path.dirname(publish_path)): os.makedirs(os.path.dirname(publish_path)) for dsfile in project_files: # if overwrite: # # skip existing files # dstfile = os.path.join(publish_path, os.path.basename(dsfile)) # if dstfile in overwrite: # continue dstfile = os.path.join(publish_path, os.path.basename(dsfile)) if not os.path.exists(dstfile) or \ os.stat(dsfile).st_mtime > os.stat(dstfile).st_mtime: fn(dsfile, dstfile) except (shutil.Error, IOError) as e: messages.append( "Failed to copy data source: {0}".format(e)) if messages: raise Exception("Copying project files failed:\n{0}".format( os.linesep.join(messages))) def create_zip_project_file(): dirpath = os.path.abspath( os.path.join(self._publish_dir, os.pardir)) filename = os.path.basename(self._publish_dir) zip_out_file = os.path.join(dirpath, filename) shutil.make_archive(base_name=zip_out_file, format='zip', root_dir=dirpath, base_dir=filename) if self.plugin.run_in_gislab or self._publish_dir != self._publish_dir_default: # copy project and data files into destination folder try: copy_project_files() # link=self.plugin.run_in_gislab) copy_data_sources() # link=self.plugin.run_in_gislab) except Exception as e: QMessageBox.critical(self.dialog, "Error", "{0}".format(e)) return False if self.dialog.zip_published_project.isChecked(): # create zip archive for published project (in parrent directory) try: create_zip_project_file() except OSError as e: QMessageBox.critical(self.dialog, "Error", "Creating zip file failed. {0}".format(e)) return False return True
def _return_failure(self, reason): QApplication.restoreOverrideCursor() msg = "Failed to complete Mergin project creation.\n" + reason QMessageBox.critical(None, 'Create Project', msg, QMessageBox.Close)
def onFinishSketch(self): """ Slot raised upon selecting to finish drawing the sketch spatial unit. """ stdmLayer = self.currentVectorLayer() layerWKBType = stdmLayer.wkbType() feature = QgsFeature(stdmLayer.fields()) if self._mode == CAPTURE_POINT: feature.setGeometry(self._geometry) elif self._mode == CAPTURE_LINE or self._mode == CAPTURE_POLYGON: # Delete temporary rubber band if self._tempRubberBand is not None: self.canvas.scene().removeItem(self._tempRubberBand) del self._tempRubberBand self._tempRubberBand = None # Validate geometries using number of points if self._mode == CAPTURE_LINE and len(self._captureList) < 2: self.stopCapturing() return if self._mode == CAPTURE_POLYGON and len(self._captureList) < 3: self.stopCapturing() return if self._mode == CAPTURE_LINE: if layerWKBType == QgsWkbTypes.LineString or layerWKBType == QgsWkbTypes.LineString25D: self._geometry = QgsGeometry.fromPolyline( self._captureList) elif layerWKBType == QgsWkbTypes.MultiLineString or layerWKBType == QgsWkbTypes.MultiLineString25D: self._geometry = QgsGeometry.fromMultiPolyline( self._captureList) else: QMessageBox.critical( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "WKB Type Error"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot add feature. Unknown WKB type")) return feature.setGeometry(self._geometry) # Polygon else: if layerWKBType == QgsWkbTypes.Polygon or layerWKBType == QgsWkbTypes.Polygon25D: self._geometry = QgsGeometry.fromPolygon( [self._captureList]) elif layerWKBType == QgsWkbTypes.MultiPolygon or layerWKBType == QgsWkbTypes.MultiPolygon25D: self._geometry = QgsGeometry.fromMultiPolygon( [self._captureList]) else: QMessageBox.critical( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "WKB Type Error"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot add feature. Unknown WKB type")) return feature.setGeometry(self._geometry) avoidIntersectionsReturn = feature.geometry( ).avoidIntersections() if avoidIntersectionsReturn == 3: QMessageBox.critical( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Error"), QApplication.translate( "StdmMapToolCreateFeature", "An error was reported during intersection removal" )) polyWkb = feature.geometry().asWkb() if polyWkb is None: reason = "" if avoidIntersectionsReturn != 2: reason = QApplication.translate( "StdmMapToolCreateFeature", "The feature cannot be added because it's geometry is empty" ) else: reason = QApplication.translate( "StdmMapToolCreateFeature", "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ) QMessageBox.critical( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Error"), reason) self.stopCapturing() del feature self._resetGeometry() return stdmLayer.beginEditCommand( QApplication.translate("StdmMapToolCreateFeature", "Feature Added")) if self.addFeature(stdmLayer, feature): stdmLayer.endEditCommand() else: del feature self._resetGeometry() stdmLayer.destroyEditCommand() self.stopCapturing() self.canvas.refresh()
def accept(self): if self.mode == self.ASK_FOR_INPUT_MODE: # create the input layer (if not already done) and # update available options self.reloadInputLayer() # sanity checks if self.inLayer is None: QMessageBox.critical(self, self.tr("Import to Database"), self.tr("Input layer missing or not valid.")) return if self.cboTable.currentText() == "": QMessageBox.critical(self, self.tr("Import to Database"), self.tr("Output table name is required.")) return if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): if not self.widgetSourceSrid.crs().isValid(): QMessageBox.critical( self, self.tr("Import to Database"), self.tr("Invalid source srid: must be a valid crs.")) return if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): if not self.widgetTargetSrid.crs().isValid(): QMessageBox.critical( self, self.tr("Import to Database"), self.tr("Invalid target srid: must be a valid crs.")) return with OverrideCursor(Qt.WaitCursor): # store current input layer crs and encoding, so I can restore it prevInCrs = self.inLayer.crs() prevInEncoding = self.inLayer.dataProvider().encoding() try: schema = self.outUri.schema() if not self.cboSchema.isEnabled( ) else self.cboSchema.currentText() table = self.cboTable.currentText() # get pk and geom field names from the source layer or use the # ones defined by the user srcUri = QgsDataSourceUri(self.inLayer.source()) pk = srcUri.keyColumn() if not self.chkPrimaryKey.isChecked( ) else self.editPrimaryKey.text() if not pk: pk = self.default_pk if self.inLayer.isSpatial() and self.chkGeomColumn.isEnabled(): geom = srcUri.geometryColumn( ) if not self.chkGeomColumn.isChecked( ) else self.editGeomColumn.text() if not geom: geom = self.default_geom else: geom = None options = {} if self.chkLowercaseFieldNames.isEnabled( ) and self.chkLowercaseFieldNames.isChecked(): pk = pk.lower() if geom: geom = geom.lower() options['lowercaseFieldNames'] = True # get output params, update output URI self.outUri.setDataSource(schema, table, geom, "", pk) typeName = self.db.dbplugin().typeName() providerName = self.db.dbplugin().providerName() if typeName == 'gpkg': uri = self.outUri.database() options['update'] = True options['driverName'] = 'GPKG' options['layerName'] = table else: uri = self.outUri.uri(False) if self.chkDropTable.isChecked(): options['overwrite'] = True if self.chkSinglePart.isEnabled( ) and self.chkSinglePart.isChecked(): options['forceSinglePartGeometryType'] = True outCrs = QgsCoordinateReferenceSystem() if self.chkTargetSrid.isEnabled( ) and self.chkTargetSrid.isChecked(): outCrs = self.widgetTargetSrid.crs() # update input layer crs and encoding if self.chkSourceSrid.isEnabled( ) and self.chkSourceSrid.isChecked(): inCrs = self.widgetSourceSrid.crs() self.inLayer.setCrs(inCrs) if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked( ): enc = self.cboEncoding.currentText() self.inLayer.setProviderEncoding(enc) onlySelected = self.chkSelectedFeatures.isChecked() # do the import! ret, errMsg = QgsVectorLayerExporter.exportLayer( self.inLayer, uri, providerName, outCrs, onlySelected, options) except Exception as e: ret = -1 errMsg = str(e) finally: # restore input layer crs and encoding self.inLayer.setCrs(prevInCrs) self.inLayer.setProviderEncoding(prevInEncoding) if ret != 0: output = QgsMessageViewer() output.setTitle(self.tr("Import to Database")) output.setMessageAsPlainText( self.tr("Error {0}\n{1}").format(ret, errMsg)) output.showMessage() return # create spatial index if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked( ): self.db.connector.createSpatialIndex((schema, table), geom) self.db.connection().reconnect() self.db.refresh() QMessageBox.information(self, self.tr("Import to Database"), self.tr("Import was successful.")) return QDialog.accept(self)
def doWork(self): #Defining layer type for testLayer in self.iface.mapCanvas().layers(): if testLayer.type() == QgsMapLayer.VectorLayer: workFeature = list(testLayer.getSelectedFeatures()) workCrs = testLayer.crs() if not workFeature: QMessageBox.critical(self, u"Erro", u"Nenhuma feição selecionada. Selecione ao menos uma feição vetorial.") return workGeometries = [] for i in range(len(workFeature)): workGeometries.append(workFeature[i].geometry()) centr = QgsGeometry().collectGeometry(workGeometries).centroid() listElem = QgsFeature() listElem.setGeometry(centr) centrList = [] centrList.append(listElem) centr = centr.asPoint() #Opening UTM Zones layer and finding intersections utmZone = DimensionsVFDialog(self.iface).UTMcheck(centrList, workCrs)[0] decl = GeoMag().GeoMag(centr.y(), centr.x()).dec conv = DeclConvDockWidget(self.iface).calcConvergence(centr) if not utmZone: QMessageBox.critical(self, u"Erro", u"Feição selecionada fora do Brasil. Escolha uma feição dentro.") return pontos = {} pointList=[] for f in workGeometries: for i in f.vertices(): pointList.append(i) pontos[f] = pointList pointList=[] pontos_conv = {} pointList=[] zoneDict = {'18S':31978,'19N':31973, '19S':31979, '20N':31974, '20S':31980,'21N':31975, '21S':31981, '22N':31976, '22S':31982, '23S':31983, '24S':31984, '25S':31985, '26S':31986} transformer = QgsCoordinateTransform(workCrs, QgsCoordinateReferenceSystem(zoneDict[utmZone[0]], QgsCoordinateReferenceSystem.EpsgCrsId), QgsProject.instance()) for f in workGeometries: for i in range(len(list(f.vertices()))): pointList.append(pontos[f][i]) pointList[i].transform(transformer) pontos_conv[f] = pointList pointList=[] self.convEdit.setText(str(conv)) self.declEdit.setText(str(decl)) self.final_list = [] ponto_inicial = pontos[0] for idx in range(0,len(pontos)-1): pt1 = pontos_conv[idx] pt2 = pontos_conv[idx+1] crs1 = pontos[idx][1] azim = pt1.azimuth(pt2) - decl if azim < 0: azim = azim + 360 d = QgsDistanceArea() dist = format( d.measureLine(pt1,pt2), '.3f' ) #VERIFICAR UNIDADES DO MAPA if crs1.mapUnits in [QGis.Degrees, QGis.DecimalDegrees]: #GERAR GRAU, MINUTOS E SEGUNDOS PARA X E Y x = self.gerarGMS( pontos[idx][0].x() ) y = self.gerarGMS( pontos[idx][0].y() ) else: x = str( pontos[idx][0].x() ) y = str( pontos[idx][0].y() ) a = self.gerarGMS( azim ) am = format( self.converterParaMilesimos( azim - decl ), '.3f' ) self.final_list.append( (x, y, a, am, dist, crs1) ) ponto_final = pontos_conv[len(pontos)-1] crsFinal = pontos[len(pontos)-1][1] x = self.gerarGMS( pontos[len(pontos)-1][0].x() ) if crsFinal.mapUnits() in [QGis.Degrees, QGis.DecimalDegrees] else str( pontos[len(pontos)-1][0].x() ) y = self.gerarGMS( pontos[len(pontos)-1][0].y() ) if crsFinal.mapUnits() in [QGis.Degrees, QGis.DecimalDegrees] else str( pontos[len(pontos)-1][0].y() ) self.final_list.append( (x, y, u"Final", u"Final", u"Final") ) #CRIAR A TABELA DA INTERFACE self.exportDialog.fillTable(self.final_list, decl, conv, ponto_inicial)
def execImport(self): # Initiate the import process success = False matchCols = self.getSrcDestPairs() # Specify geometry column geom_column = None if self.field("typeSpatial"): geom_column = self.field("geomCol") # Ensure that user has selected at least one column if it is a # non-spatial table if len(matchCols) == 0: self.ErrorInfoMessage("Please select at least one source column.") return success value_translator_manager = self._trans_widget_mgr.translator_manager() try: if self.field("optOverwrite"): entity = self.curr_profile.entity_by_name(self.targetTab) dependencies = entity.dependencies() view_dep = dependencies['views'] entity_dep = [e.name for e in entity.children()] entities_dep_str = ', '.join(entity_dep) views_dep_str = ', '.join(view_dep) if len(entity_dep) > 0 or len(view_dep) > 0: del_msg = QApplication.translate( 'ImportData', "Overwriting existing records will permanently \n" "remove records from other tables linked to the \n" "records. The following tables will be affected." "\n{}\n{}" "\nClick Yes to proceed importing or No to cancel.". format(entities_dep_str, views_dep_str)) del_result = QMessageBox.critical( self, QApplication.translate( "ImportData", "Overwrite Import Data Warning"), del_msg, QMessageBox.Yes | QMessageBox.No) if del_result == QMessageBox.Yes: self.dataReader.featToDb( self.targetTab, matchCols, False, self, geom_column, translator_manager=value_translator_manager) # Update directory info in the registry setVectorFileDir(self.field("srcFile")) self.InfoMessage( "All features have been imported successfully!") success = True else: success = False else: self.dataReader.featToDb( self.targetTab, matchCols, True, self, geom_column, translator_manager=value_translator_manager) self.InfoMessage( "All features have been imported successfully!") # Update directory info in the registry setVectorFileDir(self.field("srcFile")) success = True except: self.ErrorInfoMessage(str(sys.exc_info()[1])) return success
def accept(self): self.settings.setValue("/Processing/dialogBase", self.saveGeometry()) checkCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_CRS) try: self.setParamValues() if checkCRS and not self.alg.checkInputCRS(): reply = QMessageBox.question( self, self.tr("Unmatching CRS's"), self.tr('Layers do not all use the same CRS. This can ' 'cause unexpected results.\nDo you want to ' 'continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return msg = self.alg._checkParameterValuesBeforeExecuting() if msg: QMessageBox.warning(self, self.tr('Unable to execute algorithm'), msg) return self.btnRun.setEnabled(False) self.btnClose.setEnabled(False) buttons = self.mainWidget.iterateButtons self.iterateParam = None for i in range(len(buttons.values())): button = buttons.values()[i] if button.isChecked(): self.iterateParam = buttons.keys()[i] break self.progressBar.setMaximum(0) self.lblProgress.setText(self.tr('Processing algorithm...')) # Make sure the Log tab is visible before executing the algorithm try: self.tabWidget.setCurrentIndex(1) self.repaint() except: pass QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.setInfo( self.tr('<b>Algorithm %s starting...</b>') % self.alg.name) if self.iterateParam: if runalgIterating(self.alg, self.iterateParam, self): self.finish() else: QApplication.restoreOverrideCursor() self.resetGUI() else: command = self.alg.getAsCommand() if command: ProcessingLog.addToLog(ProcessingLog.LOG_ALGORITHM, command) if runalg(self.alg, self): self.finish() else: QApplication.restoreOverrideCursor() self.resetGUI() except AlgorithmDialogBase.InvalidParameterValue as e: try: self.buttonBox.accepted.connect( lambda: e.widget.setPalette(QPalette())) palette = e.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) e.widget.setPalette(palette) self.lblProgress.setText( self.tr('<b>Missing parameter value: %s</b>') % e.parameter.description) return except: QMessageBox.critical( self, self.tr('Unable to execute algorithm'), self.tr('Wrong or missing parameter values'))
def error(self, text): QMessageBox.critical(self, "Error", text) ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, text)
def executeCropRowsClipProcessing(self): """Execute Crop Rows STEP 1""" QgsMessageLog.logMessage( 'Excecute Task1: Clip Raster Mosaic by Vector Mask') strMosaicRasterFileSelected = self.dlg.comboBoxInputRaster.currentText( ) strMaskVectorFileSelected = self.dlg.comboBoxInputVector.currentText() seedValue = 0 QgsMessageLog.logMessage('Get Seed from user selection') if self.dlg.radioButtonSeed1.isChecked() == True: seedValue = 1 elif self.dlg.radioButtonSeed2.isChecked() == True: seedValue = 2 elif self.dlg.radioButtonSeed3.isChecked() == True: seedValue = 3 elif self.dlg.radioButtonSeed4.isChecked() == True: seedValue = 4 if (seedValue == 0): QgsMessageLog.logMessage('You must be set a seed value !') QMessageBox.critical(None, 'Error!', "You must be set a <b>seed</b> value !", QMessageBox.Ok) pass else: QgsMessageLog.logMessage('Seed value: ' + str(seedValue)) #Start Crop Rows processing if strMosaicRasterFileSelected != '' and strMaskVectorFileSelected != '' and seedValue > 0 and self.flagClipTaskDone == 0: if self.flagNoCropRaster == False: msgboxCrop = "Are you sure that you want to start a <b>Mosaic Clip by Mask</b> process?<br>Keep in mind this task can take a few minutes, even several hours." else: msgboxCrop = "Are you sure that you want to copy a raster <b>Mosaic</b> into a selected shared folder?<br>Keep in mind this process can take a few minutes, even several hours." ret = QMessageBox.question(None, "Mosaic Data Preprocessing", (msgboxCrop), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if ret == QMessageBox.Yes: #hide step1 button self.dlg.btnExecuteClippingTask.setVisible(False) QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) self.dlg.statusBarProcessing.setGeometry(10, 281, 631, 31) self.dlg.statusBarProcessing.setValue(1) QgsMessageLog.logMessage('Processing Raster ') #urlSourceRasterMosaic = QgsMapLayerRegistry.instance().mapLayersByName(strMosaicRasterFileSelected)[0].dataProvider().dataSourceUri() urlSourceRasterMosaic = QgsProject.instance().mapLayersByName( strMosaicRasterFileSelected)[0].dataProvider( ).dataSourceUri() self.dlg.statusBarProcessing.setValue(5) #urlSourceVectorMask = QgsMapLayerRegistry.instance().mapLayersByName(strMaskVectorFileSelected)[0].dataProvider().dataSourceUri() urlSourceVectorMask = QgsProject.instance().mapLayersByName( strMaskVectorFileSelected)[0].dataProvider().dataSourceUri( ) self.dlg.statusBarProcessing.setValue(10) urlSourceVectorMaskSplit = urlSourceVectorMask.split("|")[0] self.dlg.statusBarProcessing.setValue(20) temporalPath = self.dlg.inputSharedFolderPath.text().replace( "/", "\\") rasterLyr = QgsRasterLayer(urlSourceRasterMosaic, "masklayer") pixelSizeX = rasterLyr.rasterUnitsPerPixelX() pixelSizeY = rasterLyr.rasterUnitsPerPixelY() self.dlg.statusBarProcessing.setValue(25) QgsMessageLog.logMessage(str(urlSourceRasterMosaic)) QgsMessageLog.logMessage(str(urlSourceVectorMaskSplit)) QgsMessageLog.logMessage('GDAL Clipper') QgsMessageLog.logMessage(str(pixelSizeX)) QgsMessageLog.logMessage(str(pixelSizeY)) gdalOSGeoPath = self.dlg.inputGdalOsgeoPath.text().replace( "/", "\\") #temporalPath = self.dlg.inputSharedFolderPath.text().replace("/", "\\") self.dlg.statusBarProcessing.setValue(30) timestr = time.strftime("%Y%m%d-%H%M%S") ouputFilenameRasterClip = 'clipfile_' + timestr + '.tif' ouputFilenameVectorMask = 'maskfile_' + timestr + '.shp' ouputFilenamePrj = 'croprows_' + timestr ouputFilenameCropRowsProjectXML = 'croprows_' + timestr + '.xml' ouputclipfile_path = os.path.join(temporalPath, ouputFilenameRasterClip) #temporalPath.replace("/", "\\") + ouputFilenameRasterClip self.dlg.statusBarProcessing.setValue(35) if self.flagNoCropRaster == True: QgsMessageLog.logMessage( 'No Crop option selected - Copy file directly') shutil.copyfile( urlSourceRasterMosaic, os.path.join(ouputclipfile_path[:-4] + '.tif')) self.dlg.statusBarProcessing.setValue(40) else: QgsMessageLog.logMessage( 'Crop raster by mask option selected - Cliping using GDAL' ) #print('C:/Program Files/QGIS 2.14/bin/gdalwarp') gdalWarpSubProcessCommand = '"' + gdalOSGeoPath + "\\" + 'gdalwarp.exe" -dstnodata -9999 -q -cutline ' + urlSourceVectorMaskSplit.replace( "/", "\\") + ' -crop_to_cutline -tr ' + str( pixelSizeX) + ' ' + str( pixelSizeX ) + ' -of GTiff ' + urlSourceRasterMosaic.replace( "/", "\\") + ' ' + ouputclipfile_path QgsMessageLog.logMessage(str(gdalWarpSubProcessCommand)) self.dlg.statusBarProcessing.setValue(40) p = subprocess.Popen(gdalWarpSubProcessCommand, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for line in p.stdout.readlines(): print(line), retval = p.wait() self.dlg.statusBarProcessing.setValue(50) QgsMessageLog.logMessage( 'Clipper process done check result file ' + ouputclipfile_path) #Load result file into map environment rasterLayerClipped = QgsRasterLayer( ouputclipfile_path, ouputFilenameRasterClip[:-4]) pixelSizeXClip = rasterLayerClipped.rasterUnitsPerPixelX() pixelSizeYClip = rasterLayerClipped.rasterUnitsPerPixelY() imageWClip = rasterLayerClipped.width() imageHClip = rasterLayerClipped.height() providerRasterLayerClipped = rasterLayerClipped.dataProvider() extentRasterLayerClipped = rasterLayerClipped.extent() #print(providerRasterLayerClipped) #xmin,ymax,xmax,ymin imageXminClip = (extentRasterLayerClipped.xMinimum()) imageYminClip = (extentRasterLayerClipped.yMinimum()) imageXmaxClip = (extentRasterLayerClipped.xMaximum()) imageYmaxClip = (extentRasterLayerClipped.yMaximum()) #origin imageXOriginClip = int( round(extentRasterLayerClipped.xMinimum())) imageYOriginClip = int( round(extentRasterLayerClipped.yMinimum())) #epsg proj4crs = rasterLayerClipped.crs() QgsMessageLog.logMessage(str(proj4crs.srsid())) QgsMessageLog.logMessage(str(proj4crs.toProj4())) QgsMessageLog.logMessage(str(proj4crs.authid())) QgsMessageLog.logMessage(str(proj4crs.description())) QgsMessageLog.logMessage(str(proj4crs.ellipsoidAcronym())) QgsMessageLog.logMessage(str(proj4crs.findMatchingProj())) QgsMessageLog.logMessage(str(proj4crs.postgisSrid())) QgsMessageLog.logMessage(str(proj4crs.toWkt())) epsgClip = proj4crs.postgisSrid() epsgWKTClip = proj4crs.toWkt() #QgsMapLayerRegistry.instance().addMapLayer(rasterLayerClipped) QgsProject.instance().addMapLayer(rasterLayerClipped) #pass self.dlg.statusBarProcessing.setValue(75) #copy vector mask outputFileMaskPath = os.path.join(temporalPath, ouputFilenameVectorMask) #temporalPath.replace("/", "\\") + ouputFilenameVectorMask temporalVectorLayer = QgsVectorLayer(urlSourceVectorMaskSplit, "tmp_polygon", "ogr") shutil.copyfile(urlSourceVectorMaskSplit[:-4] + '.shp', os.path.join(outputFileMaskPath[:-4] + '.shp')) shutil.copyfile(urlSourceVectorMaskSplit[:-4] + '.dbf', os.path.join(outputFileMaskPath[:-4] + '.dbf')) shutil.copyfile(urlSourceVectorMaskSplit[:-4] + '.shx', os.path.join(outputFileMaskPath[:-4] + '.shx')) temporalVectorLayerDataProvider = temporalVectorLayer.dataProvider( ) temporalVectorLayerCrs = temporalVectorLayerDataProvider.crs() temporalVectorLayerCrsString = temporalVectorLayerCrs.authid() temporalVectorLayerEPSGInt = int( temporalVectorLayerCrsString[5:]) QgsMessageLog.logMessage(str(temporalVectorLayerEPSGInt)) maskVectorLayerExported = QgsVectorLayer( outputFileMaskPath, ouputFilenameVectorMask[:-4], "ogr") crs = maskVectorLayerExported.crs() crs.createFromId(temporalVectorLayerEPSGInt) maskVectorLayerExported.setCrs(crs) maskVectorLayerExported.setCrs( QgsCoordinateReferenceSystem( temporalVectorLayerEPSGInt, QgsCoordinateReferenceSystem.EpsgCrsId)) styleBoundary = os.path.join( (os.path.dirname(os.path.abspath(__file__))), 'styles', 'croprows_style_boundary.qml') maskVectorLayerExported.loadNamedStyle(styleBoundary) #QgsMapLayerRegistry.instance().addMapLayer(maskVectorLayerExported) QgsProject.instance().addMapLayer(maskVectorLayerExported) #end copy vector mask #TODO: try not to simulate process status, make it real for i in range(76, 90): self.dlg.statusBarProcessing.setValue(i) #show step2 button self.dlg.btnExecuteProcessingFromApi.setVisible(True) self.dlg.statusBarProcessing.setValue(95) arrXMLOptions = [ str(seedValue), str(ouputFilenameRasterClip), str(ouputFilenameVectorMask), str(pixelSizeXClip) + ',-' + str(pixelSizeYClip), str(imageWClip) + ',' + str(imageHClip), str(imageXminClip) + ',' + str(imageYminClip) + ',' + str(imageXmaxClip) + ',' + str(imageYmaxClip), str(imageXOriginClip) + ',' + str(imageYOriginClip), str(epsgClip), str(epsgWKTClip), str(ouputFilenamePrj) ] #Write XML file self.writeXMLFile(ouputFilenameCropRowsProjectXML, arrXMLOptions) self.dlg.xmlCoreFile.setText( str(ouputFilenameCropRowsProjectXML)) self.dlg.statusBarProcessing.setValue(100) QApplication.setOverrideCursor(QtCore.Qt.ArrowCursor) self.flagClipTaskDone = 1 toStep2Msg = QMessageBox.question( None, "Crop Rows processing task start", ("Are you sure that you want to start a <b>Crop Rows</b> processing task ?<br>Keep in mind this process can take a few minutes, even several hours.<br><br>Make sure that <b>Crop Rows - API Server is Running before continue.</b>" ), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if toStep2Msg == QMessageBox.Yes: QgsMessageLog.logMessage('Run Step 2') self.executeCropRowsProcessingFromAPI() pass else: QMessageBox.information( None, 'Message !', "You must be run the processing task by manually way !<br>Just click on the button <b>Processing Task (manual)</b>", QMessageBox.Ok) pass else: QgsMessageLog.logMessage('No Mosaic Clip Process Selected') pass else: QgsMessageLog.logMessage('Missing Required Parameters') QgsMessageLog.logMessage('strMosaicRasterFileSelected: ' + strMosaicRasterFileSelected) QgsMessageLog.logMessage('strMaskVectorFileSelected: ' + strMaskVectorFileSelected) QgsMessageLog.logMessage('seedValue: ' + str(seedValue)) QgsMessageLog.logMessage('flagClipTaskDone: ' + str(self.flagClipTaskDone)) QMessageBox.critical(None, 'Error!', "Missing Required Parameter !", QMessageBox.Ok)
def classFactory(iface): """Load pat_toolbar class from file pat_toolbar. :param iface: A QGIS interface instance. :type iface: QgsInterface """ if platform.system() != 'Windows': message = 'PAT is only available for Windows' iface.messageBar().pushMessage("ERROR", message, level=Qgis.Critical, duration=0) QMessageBox.critical(None, 'Error', message) sys.exit(message) if not os.path.exists(TEMPDIR): os.mkdir(TEMPDIR) from .util.settings import read_setting, write_setting if read_setting(PLUGIN_NAME + "/DISP_TEMP_LAYERS") is None: write_setting(PLUGIN_NAME + "/DISP_TEMP_LAYERS", False) if read_setting(PLUGIN_NAME + "/DEBUG") is None: write_setting(PLUGIN_NAME + "/DEBUG", False) try: from pyprecag import config config.set_debug_mode(read_setting(PLUGIN_NAME + "/DEBUG", bool)) except ImportError: # pyprecag is not yet installed pass # the custom logging import requires qgis_config so leave it here from .util.custom_logging import setup_logger # Call the logger pyprecag so it picks up the module debugging as well. setup_logger(LOGGER_NAME) LOGGER = logging.getLogger(LOGGER_NAME) LOGGER.addHandler(logging.NullHandler()) # logging.StreamHandler() from .util.check_dependencies import (check_pat_symbols, check_R_dependency, check_gdal_dependency, check_python_dependencies) meta_version = pluginMetadata('pat', 'version') plugin_state = '\nPAT Plugin:\n' plugin_state += ' {:25}\t{}\n'.format('QGIS Version:', Qgis.QGIS_VERSION) plugin_state += ' {:25}\t{}\n'.format('Python Version:', sys.version) plugin_state += ' {:25}\t{} {}'.format( 'PAT:', pluginMetadata('pat', 'version'), pluginMetadata('pat', 'update_date')) LOGGER.info(plugin_state) # if not check_gdal: # LOGGER.critical('QGIS Version {} and GDAL {} is are not currently supported.'.format(Qgis.QGIS_VERSION, gdal_ver)) # # message = ('QGIS Version {} and GDAL {} are not currently supported. ' # 'Downgrade QGIS to an earlier version. If required email [email protected] ' # 'for assistance.'.format(Qgis.QGIS_VERSION, gdal_ver)) # # iface.messageBar().pushMessage("ERROR Failed Dependency Check", message, # level= Qgis.Critical, duration=0) # QMessageBox.critical(None, 'Failed Dependency Check', message) # sys.exit(message) gdal_ver = check_gdal_dependency() check_py = check_python_dependencies(PLUGIN_DIR, iface) if len(check_py) > 0: sys.exit(check_py) check_pat_symbols() # check_R_dependency() #iface.messageBar().pushMessage("ERROR Failed Dependency Check", result, level= Qgis.Critical, duration=0) from .pat_toolbar import pat_toolbar return pat_toolbar(iface)
def canvasReleaseEvent(self, e): """ Base class override. """ stdmLayer = self.currentVectorLayer() # Try to set mode from layer type if self._mode == CAPTURE_NONE: self.setCaptureMode(stdmLayer) if not isinstance(stdmLayer, QgsVectorLayer): self.notifyNotVectorLayer() return layerWKBType = stdmLayer.wkbType() provider = stdmLayer.dataProvider() if not (provider.capabilities() & QgsVectorDataProvider.AddFeatures): QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Cannot add to layer"), QApplication.translate( "StdmMapToolCreateFeature", "The data provider for this layer does not support the addition of features." )) return if not stdmLayer.isEditable(): self.notifyNotEditableLayer() return # Spatial unit point capture if self._mode == CAPTURE_POINT: if stdmLayer.geometryType() != QgsWkbTypes.PointGeometry: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Wrong create tool"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot apply the 'Create Point Feature' tool on this vector layer" )) return self.startCapturing() # Point in map coordinates mapPoint = None snapResults = [] # Point in layer coordinates layerPoint = None opResult, snapResults = self._snapper.snapToBackgroundLayers( e.pos()) if len(snapResults) > 0: mapPoint = self.snapPointFromResults(snapResults, e.pos()) else: mapPoint = self.toMapCoordinates(e.pos()) try: layerPoint = self.toLayerCoordinates(stdmLayer, mapPoint) except QgsCsException: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Coordinate transform error"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot transform the point to the layer's coordinate system" )) self._capturing = False return if layerWKBType == QgsWkbTypes.Point or layerWKBType == QgsWkbTypes.Point25D: self._geometry = QgsGeometry.fromPoint(layerPoint) elif layerWKBType == QgsWkbTypes.MultiPoint or layerWKBType == QgsWkbTypes.MultiPoint25D: self._geometry = QgsGeometry.fromMultiPoint(layerPoint) # Line and polygon capturing elif self._mode == CAPTURE_LINE or self._mode == CAPTURE_POLYGON: if self._mode == CAPTURE_LINE and stdmLayer.geometryType( ) != QgsWkbTypes.LineGeometry: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Wrong create tool"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot apply the 'Create Line Feature' tool on this vector layer" )) return if self._mode == CAPTURE_POLYGON and stdmLayer.geometryType( ) != QgsWkbTypes.PolygonGeometry: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Wrong create tool"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot apply the 'Create Polygon Feature' tool on this vector layer" )) return if e.button() == Qt.LeftButton: error = self.addVertex(e.pos()) if error == 2: QMessageBox.critical( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Coordinate transform error"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot transform the point to the layer's coordinate system" )) return self.startCapturing()
def accept(self): try: nodata = self.ui.IDC_tbNoDataExport.text() self.settings.nodata_value = int(nodata) if nodata != "" else None QgsMessageLog.logMessage( "Maindlg: nodata: {0}".format(self.settings.nodata_value), "VoGis", Qgis.Info) if self.settings.onlyHektoMode is True and self.settings.mapData.rasters.count( ) > 0: self.settings.onlyHektoMode = False if self.settings.onlyHektoMode is False: if self.settings.mapData.rasters.count() < 1: retVal = QMessageBox.warning( self.iface.mainWindow(), "VoGIS-Profiltool", QApplication.translate( "code", "Keine Rasterebene vorhanden oder sichtbar! Nur hektometrieren?" ), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if retVal == QMessageBox.No: return else: self.settings.onlyHektoMode = True self.settings.createHekto = True if self.__getSettingsFromGui() is False: return if self.settings.onlyHektoMode is False: if len(self.settings.mapData.rasters.selectedRasters()) < 1: QMessageBox.warning( self.iface.mainWindow(), "VoGIS-Profiltool", QApplication.translate("code", "Kein Raster selektiert!")) return QgsMessageLog.logMessage( "modeLine!=line: {0}".format( self.settings.modeLine != enumModeLine.line), "VoGis", Qgis.Info) QgsMessageLog.logMessage( "customLine is None: {0}".format( self.settings.mapData.customLine is None), "VoGis", Qgis.Info) if self.settings.modeLine != enumModeLine.line and self.settings.mapData.customLine is None: QMessageBox.warning( self.iface.mainWindow(), "VoGIS-Profiltool", QApplication.translate("code", "Keine Profillinie vorhanden!")) return if len(self.settings.mapData.polygons.selected_polygons() ) > 0 and len( self.settings.mapData.rasters.selectedRasters()) > 1: raster_names = list( raster.name for raster in self.settings.mapData.rasters.selectedRasters()) sel_raster, ok_clicked = QInputDialog.getItem( self.iface.mainWindow(), "DHM?", "Welches DHM soll zur Flächenverschneidung verwendet werden?", raster_names, 0, False) if ok_clicked is False: return self.settings.intersection_dhm_idx = raster_names.index( sel_raster) QApplication.setOverrideCursor(Qt.WaitCursor) create_profile = CreateProfile(self.iface, self.settings) thread = QThread(self) create_profile.moveToThread(thread) create_profile.finished.connect(self.profiles_finished) create_profile.error.connect(self.profiles_error) create_profile.progress.connect(self.profiles_progress) thread.started.connect(create_profile.create) thread.start(QThread.LowestPriority) self.thread = thread self.create_profile = create_profile self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) except: QApplication.restoreOverrideCursor() ex = "{0}".format(traceback.format_exc()) msg = "Unexpected ERROR:\n\n{0}".format(ex[:2000]) QMessageBox.critical(self.iface.mainWindow(), "VoGIS-Profiltool", msg)
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 = NewRaptorDialog() self.dlg.cmbSpecies.currentTextChanged.connect( self.evt_cmbSpecies_changed) mc = self.iface.mapCanvas() self.dlg.spbLatitude.setValue(mc.center().y()) self.dlg.spbLongitude.setValue(mc.center().x()) self.dlg.dteLast.setDate(QDate.currentDate()) map_layers = [] for lyr in mc.layers(): map_layers.append(lyr.name()) missing_layers = [] if not "Raptor Nests" in map_layers: missing_layers.append("Raptor Nests") if not "Raptor Buffer" in map_layers: missing_layers.append("Raptor Buffer") if not "Linear Buffer" in map_layers: missing_layers.append("Linear Buffer") if missing_layers: msg = "The following layers are misisng from this project\n" for lyr in missing_layers: msg += "\n{}".format(lyr) QMessageBox.critical(self.dlg, "Missing layers", msg) return # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. lyrNests = QgsProject.instance().mapLayersByName("Raptor Nests")[0] lyrBuffer = QgsProject.instance().mapLayersByName( "Raptor Buffer")[0] lyrLinear = QgsProject.instance().mapLayersByName( "Linear Buffer")[0] idxNestID = lyrNests.fields().indexOf("Nest_ID") valNestID = lyrNests.maximumValue(idxNestID) + 1 valLat = self.dlg.spbLatitude.value() valLng = self.dlg.spbLongitude.value() valSpecies = self.dlg.cmbSpecies.currentText() valBuffer = self.dlg.spbBuffer.value() valStatus = self.dlg.cmbStatus.currentText() valLast = self.dlg.dteLast.date() QMessageBox.information( self.dlg, "Message", "New Nest ID: {}\n\nLatitude: {}\nLongitude: {}\nSpecies: {}\nBuffer: {}\nStatus: {}\nLast Survey: {}" .format(valNestID, valLat, valLng, valSpecies, valBuffer, valStatus, valLast)) ftrNest = QgsFeature(lyrNests.fields()) ftrNest.setAttribute("lat_y_dd", valLat) ftrNest.setAttribute("long_x_dd", valLng) ftrNest.setAttribute("recentspec", valSpecies) ftrNest.setAttribute("buf_dist", valBuffer) ftrNest.setAttribute("recentstat", valStatus) ftrNest.setAttribute("lastsurvey", valLast) ftrNest.setAttribute("Nest_ID", valNestID) geom = QgsGeometry(QgsPoint(valLng, valLat)) ftrNest.setGeometry(geom) pr = lyrNests.dataProvider() pr.addFeatures([ftrNest]) lyrNests.reload() pr = lyrBuffer.dataProvider() buffer = geom.buffer(valBuffer, 10) ftrNest.setGeometry(buffer) pr.addFeatures([ftrNest]) lyrBuffer.reload() dlgTable = DlgTable() dlgTable.setWindowTitle( "Impacts Table for Nest {}".format(valNestID)) # Find linear projects that will be impacted and report them in the table bb = buffer.boundingBox() linears = lyrLinear.getFeatures(bb) for linear in linears: valID = linear.attribute("Project") valType = linear.attribute("type") valDistance = linear.geometry().distance(geom) if valDistance < valBuffer: # Populate table with linear data row = dlgTable.tblImpacts.rowCount() dlgTable.tblImpacts.insertRow(row) dlgTable.tblImpacts.setItem(row, 0, QTableWidgetItem(str(valID))) dlgTable.tblImpacts.setItem(row, 1, QTableWidgetItem(valType)) twi = QTableWidgetItem("{:4.5f}".format(valDistance)) twi.setTextAlignment(QtCore.Qt.AlignRight) dlgTable.tblImpacts.setItem(row, 2, twi) dlgTable.tblImpacts.sortItems(2) dlgTable.show() dlgTable.exec_() else: QMessageBox.information(self.dlg, "Message", "Should only run if cancelled")
def onAddXY(self): """ Slot raised to show the coordinates point editor for manually entering the X, Y coordinate values. """ stdmLayer = self.currentVectorLayer() # Try to set mode from layer type if self._mode == CAPTURE_NONE: self.setCaptureMode(stdmLayer) if not isinstance(stdmLayer, QgsVectorLayer): self.notifyNotVectorLayer() return layerWKBType = stdmLayer.wkbType() provider = stdmLayer.dataProvider() if not (provider.capabilities() & QgsVectorDataProvider.AddFeatures): QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Cannot add to layer"), QApplication.translate( "StdmMapToolCreateFeature", "The data provider for this layer does not support the addition of features." )) return if not stdmLayer.isEditable(): self.notifyNotEditableLayer() return coordsEditor = SpatialCoordinatesEditor(self.iface.mainWindow()) ret = coordsEditor.exec_() if ret == QDialog.Accepted: layerPoint = coordsEditor.qgsPoint() # Spatial unit point capture if self._mode == CAPTURE_POINT: if stdmLayer.geometryType() != QgsWkbTypes.PointGeometry: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Wrong create tool"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot apply the 'Create Point Feature' tool on this vector layer" )) return self.startCapturing() if layerWKBType == QgsWkbTypes.Point or layerWKBType == QgsWkbTypes.Point25D: self._geometry = QgsGeometry.fromPoint(layerPoint) elif layerWKBType == QgsWkbTypes.MultiPoint or layerWKBType == QgsWkbTypes.MultiPoint25D: self._geometry = QgsGeometry.fromMultiPoint(layerPoint) elif self._mode == CAPTURE_LINE or self._mode == CAPTURE_POLYGON: if self._mode == CAPTURE_LINE and stdmLayer.geometryType( ) != QgsWkbTypes.LineGeometry: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Wrong create tool"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot apply the 'Create Line Feature' tool on this vector layer" )) return if self._mode == CAPTURE_POLYGON and stdmLayer.geometryType( ) != QgsWkbTypes.PolygonGeometry: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Wrong create tool"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot apply the 'Create Polygon Feature' tool on this vector layer" )) return error = self.addVertex(layerPoint, True) if error == 2: QMessageBox.critical( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Coordinate transform error"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot transform the point to the layer's coordinate system" )) return elif error == 3: QMessageBox.critical( self.iface.mainWindow(), QApplication.translate("StdmMapToolCreateFeature", "Coordinate transform error"), QApplication.translate( "StdmMapToolCreateFeature", "Cannot transform the layer point to the map's coordinate system" )) return self.startCapturing()
def error(self, msg): QMessageBox.critical(None, self.menu, msg)
def error(self, text): QMessageBox.critical(self, "Error", text) QgsMessageLog.logMessage(text, self.tr('Processing'), Qgis.Critical)
def error(self, msg): QMessageBox.critical(None, WINDOW_TITLE, msg)
def _persistModel(self, save_and_new): """ Saves the model to the database and shows a success message. :param save_and_new: A Boolean indicating it is triggered by save and new button. :type save_and_new: Boolean """ try: # Persist the model to its corresponding store. if self._mode == SAVE: self._model.save() if not save_and_new: QMessageBox.information( self, QApplication.translate( "MappedDialog", "Record Saved" ), QApplication.translate( "MappedDialog", "New record has been successfully saved." ) ) else: self._model.update() QMessageBox.information( self, QApplication.translate("MappedDialog", "Record Updated"), QApplication.translate( "MappedDialog", "Record has been successfully updated.") ) STDMDb.instance().session.flush() for attrMapper in self._attrMappers: control = attrMapper.valueHandler().control if isinstance(control, ExpressionLineEdit): value = control.on_expression_triggered() print((attrMapper._attrName, value)) setattr(self.model(), attrMapper._attrName, value) self._model.update() # STDMDb.instance().session.flush() except DummyException as ex: QMessageBox.critical( self, QApplication.translate( "MappedDialog", "Data Operation Error" ), QApplication.translate( "MappedDialog", 'The data could not be saved due to ' 'the error: \n{}'.format(ex.args[0]) ) ) self.is_valid = False # Close the dialog if isinstance(self, QDialog) and self.is_valid: self.postSaveUpdate(self._model) if not save_and_new: self.accept()
def initData(self, result, status): if not result: self.close() # Save original data from optimization self.originalData = result # result properties: cable line, optSTA, force, optLen, optLen_arr, # duration self.result = result # Algorithm was skipped, no optimized solution if status in ['jumpedOver', 'savedFile']: try: params = self.confHandler.params.getSimpleParameterDict() cableline, force, \ seil_possible = preciseCable(params, self.poles, self.result['optSTA']) self.result['cableline'] = cableline self.result['force'] = force except Exception as e: QMessageBox.critical( self, self.tr('Unerwarteter Fehler ' 'bei Berechnung der Seillinie'), str(e), QMessageBox.Ok) return self.cableline = self.result['cableline'] self.profile.updateProfileAnalysis(self.cableline) self.updateRecalcStatus(status) # Draw profile in diagram self.plot.initData(self.profile.di_disp, self.profile.zi_disp, self.profile.peakLoc_x, self.profile.peakLoc_z, self.profile.surveyPnts) self.plot.updatePlot(self.poles.getAsArray(), self.cableline) # Create layout to modify poles lowerDistRange = floor(-1 * self.anchorBuffer[0]) upperDistRange = floor(self.profile.profileLength + self.anchorBuffer[1]) self.poleLayout.setInitialGui([lowerDistRange, upperDistRange]) # Fill in cable parameters self.paramLayout.fillInParams() # Fill in Threshold data self.thdUpdater.update( [ self.cableline['groundclear_rel'], # Distance cable - terrain self.result['force']['MaxSeilzugkraft'] [0], # Max force on cable self.result['force']['Sattelkraft_Total'] [0], # Max force on pole self.result['force'] ['Lastseilknickwinkel'], # Cable angle on pole self.result['force']['Leerseilknickwinkel'] ], # Cable angle on pole self.confHandler.params, self.poles, (self.status in ['jumpedOver', 'savedFile'])) # Mark profile line and poles on map self.updateLineOnMap() self.addMarkerToMap() # Fill in project header data self.fillInPrHeaderData() # Start Thread to recalculate cable line every 300 milliseconds self.timer.timeout.connect(self.recalculate) self.timer.start(300) self.plot.zoomOut()
def commit_str(self): """ Slot raised when the user clicks on Finish button in order to create a new STR entry. """ isValid = True # Create a progress dialog try: progress = STDMProgressDialog(iface.mainWindow()) progress.show() if not self.str_edit_node: QApplication.processEvents() progress.setRange(0, len(self.data_store)) progress.overall_progress('Creating a STR...', ) for i, str_store in enumerate(self.data_store.values()): progress.progress_message('Saving STR {}'.format(i + 1), '') progress.setValue(i + 1) self.on_add_str(str_store) # ==> progress.deleteLater() progress = None strMsg = QApplication.translate( "STRDBHandler", "The social tenure relationship has " "been successfully created!") QMessageBox.information( iface.mainWindow(), QApplication.translate("STRDBHandler", "Social Tenure Relationship"), strMsg) else: QApplication.processEvents() progress.setRange(0, 1) progress.setValue(0) progress.overall_progress('Editing a STR...', ) progress.progress_message('Updating STR', '') updated_str_obj = self.on_edit_str(self.data_store[1]) # ===> progress.deleteLater() progress = None strMsg = QApplication.translate( "STRDBHandler", "The social tenure relationship has " "been successfully updated!") QMessageBox.information( iface.mainWindow(), QApplication.translate("STRDBHandler", "Social Tenure Relationship"), strMsg) return updated_str_obj except exc.OperationalError as oe: errMsg = str(oe) QMessageBox.critical( iface.mainWindow(), QApplication.translate("STRDBHandler", "Unexpected Error"), errMsg) progress.deleteLater() progress = None isValid = False STDMDb.instance().session.rollback() LOGGER.debug(str(oe)) except exc.IntegrityError as ie: errMsg = str(ie) QMessageBox.critical( iface.mainWindow(), QApplication.translate("STRDBHandler", "Duplicate Relationship Error"), errMsg) progress.deleteLater() progress = None isValid = False STDMDb.instance().session.rollback() LOGGER.debug(str(ie)) except exc.InternalError as ie: QMessageBox.critical( iface.mainWindow(), QApplication.translate('STRDBHandler', 'InternalError Error'), QApplication.translate( 'STRDBHandler', 'Sorry, there is an internal error. \n' 'Restart QGIS to fix the issue.')) LOGGER.debug(str(ie)) progress.deleteLater() progress = None isValid = False STDMDb.instance().session.rollback() except DummyException as e: errMsg = str(e) QMessageBox.critical( iface.mainWindow(), QApplication.translate('STRDBHandler', 'Unexpected Error'), errMsg) LOGGER.debug(str(e)) isValid = False STDMDb.instance().session.rollback() progress.deleteLater() progress = None finally: STDMDb.instance().session.rollback() if progress is not None: progress.deleteLater() progress = None return isValid
def check_login(self): version_ok = True if not self.api.check_auth(): self._qgis3_info() login_dialog = QDialog(self) login_dialog.ui = Ui_LoginDialog() login_dialog.ui.setupUi(login_dialog) login_dialog.ui.editUser.setText(self.user) login_ok = False while not login_ok and version_ok: self.api.set_url(self.api_url()) if not login_dialog.exec_(): self.api.set_auth( user=login_dialog.ui.editUser.text(), password=None) return login_ok self.api.set_auth( user=login_dialog.ui.editUser.text(), password=login_dialog.ui.editPassword.text()) try: login_info = self.api.check_login( version_info=self._version_info()) # QGIS private Cloud has no tos_accepted try: if not login_info['tos_accepted']: result = QMessageBox.information( None, self.tr("Accept new Privacy Policy"), self.tr("""Due to the GDPR qgiscloud.com has a new <a href='http://qgiscloud.com/en/pages/privacy'> Privacy Policy </a>. To continue using qgiscloud.com, you must accept the new policy. """), QMessageBox.StandardButtons( QMessageBox.No | QMessageBox.Yes)) if result == QMessageBox.No: login_ok = False return else: result = self.api.accept_tos() except: pass self.user = login_dialog.ui.editUser.text() self._update_clouddb_mode(login_info['clouddb']) version_ok = StrictVersion(self.version) >= StrictVersion(login_info['current_plugin']) if not version_ok: self.ui.lblVersionPlugin.setPalette(self.palette_red) QMessageBox.information(None, self.tr('New Version'), self.tr('New plugin release {version} is available! Please upgrade the QGIS Cloud plugin.').format(version=login_info['current_plugin'])) self.store_settings() self.ui.btnLogin.hide() self.ui.lblSignup.hide() self.ui.btnLogout.show() self.ui.widgetDatabases.setEnabled(True) self.ui.widgetMaps.setEnabled(True) self.ui.lblLoginStatus.setText( self.tr("Logged in as {0} ({1})").format(self.user, login_info['plan'])) self.ui.lblLoginStatus.show() self._push_message( self.tr("QGIS Cloud"), self.tr("Logged in as {0}").format(self.user), level=0, duration=2) self.refresh_databases() self.refresh_maps() if not version_ok: self._push_message(self.tr("QGIS Cloud"), self.tr( "Unsupported versions detected. Please check your versions first!"), level=1) version_ok = False self.ui.tabWidget.setCurrentWidget(self.ui.aboutTab) login_ok = True self.update_local_layers() except ForbiddenError: QMessageBox.critical( self, self.tr("Account Disabled"), self.tr("Account {username} is disabled! Please contact [email protected]").format(username=login_dialog.ui.editUser.text())) login_ok = False except UnauthorizedError: QMessageBox.critical( self, self.tr("Login for user {username} failed").format(username=login_dialog.ui.editUser.text()), self.tr("Wrong user name or password")) login_ok = False except (TokenRequiredError, ConnectionException) as e: QMessageBox.critical( self, self.tr("Login failed"), self.tr("Login failed: %s") % str(e)) login_ok = False return version_ok
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 = NewRaptorDialog() # self.dlg.cmbSpecies.currentTextChanged.connect( self.evt_cmbSpecies_changed) mc = self.iface.mapCanvas() self.dlg.spbLatitude.setValue(mc.center().y()) self.dlg.spbLongitude.setValue(mc.center().x()) self.dlg.dteLast.setDate(QDate.currentDate()) # Lista de camada do mapa map_layers = [] for lyr in mc.layers(): map_layers.append(lyr.name()) # Coloca o nome dos layrs em uma caixa de mensagem, com o titulo camadas #QMessageBox.information(self.dlg, "Layers", str(map_layers)) # cria uma caixa de mensagem caso não achar alguams das layrs descritas abaixo missing_layers = [] if not 'Raptor Nests' in map_layers: missing_layers.append('Raptor Nests') if not 'Raptor Buffer' in map_layers: missing_layers.append('Raptor Buffer') if not 'Linear Buffer' in map_layers: missing_layers.append('Linear Buffer') if missing_layers: msg = 'The following layres are missing from ths project\n' for lyr in missing_layers: msg += f'\n {lyr}' QMessageBox.critical(self.dlg, 'Missing layers', msg) # o return barra a execução das demais linhas de códigos return # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. # irá retornar uma lista com o as camdas com nome Raptor Nests, mas iremos pegar apenas a primeira camadd lyrNests = QgsProject.instance().mapLayersByName('Raptor Nests')[0] lyrBuffer = QgsProject.instance().mapLayersByName( 'Raptor Buffer')[0] lyrLinear = QgsProject.instance().mapLayersByName( 'Linear Buffer')[0] # Irá pegar o ultimo valor de índice idxNestID = lyrNests.fields().indexOf('Nest_ID') valNestID = lyrNests.maximumValue(idxNestID) + 1 # Irá pegar os valores que foram digitados na caixa de texto valLat = self.dlg.spbLatitude.value() valLng = self.dlg.spbLongitude.value() valSpecies = self.dlg.cmbSpecies.currentText() valBuffer = self.dlg.spbBuffer.value() valStatus = self.dlg.cmbStatus.currentText() valLast = self.dlg.dteLast.date() QMessageBox.information( self.dlg, 'Message', f'New Nest ID: {valNestID}\n \nLatitude: {valLat} ' f'\nLongitude: {valLng} \nSpecies: {valSpecies} ' f'\nBuffer: {valBuffer} \nStatus: {valStatus} \nLast: {valLast}' ) # cria um novo objeto da classe QgsFeature, no qual a classe terá os mesmoa campos do lyrnet.fildes # (objeto da Layer Raptor Nests) ftrNest = QgsFeature(lyrNests.fields()) # Irá começar a adicoanr atributos de acordo com o nome dos campos da layer Raptor Nests ftrNest.setAttribute('lat_y_dd', valLat) ftrNest.setAttribute('long_x_dd', valLng) ftrNest.setAttribute('recentspec', valSpecies) ftrNest.setAttribute('buf_dist', valBuffer) ftrNest.setAttribute('recentstat', valStatus) ftrNest.setAttribute('lastsurvey', valLast) ftrNest.setAttribute('Nest_ID', valNestID) # colcoando o tipo de geometria geom = QgsGeometry(QgsPoint(valLng, valLat)) ftrNest.setGeometry(geom) # Cada tipo de dados pode ter um provedor diferente, o qgis tem extensões para varios tipos de provedor, # a função abaixo pega o provedor e inclui os dados de acordo com o proveor pr = lyrNests.dataProvider() pr.addFeatures([ftrNest]) lyrNests.reload() # Adiconando a camada de buffer pr = lyrBuffer.dataProvider() buffer = geom.buffer(valBuffer, 10) ftrNest.setGeometry(buffer) pr.addFeatures([ftrNest]) lyrBuffer.reload() dlgTable = DlgTable() dlgTable.setWindowTitle(f"Impacts Table for Nest {valNestID}") # Find linear projects that will impacted and report then in the table bb = buffer.boundingBox() linears = lyrLinear.getFeatures(bb) for linear in linears: valID = linear.attribute('Project') valType = linear.attribute('type') valDistance = linear.geometry().distance(geom) if valDistance < valBuffer: #populate table with Linear data row = dlgTable.tblImpacts.rowCount() dlgTable.tblImpacts.insertRow(row) dlgTable.tblImpacts.setItem(row, 0, QTableWidgetItem(str(valID))) dlgTable.tblImpacts.setItem(row, 1, QTableWidgetItem(valType)) twi = QTableWidgetItem(f"{valDistance:4.5f}") twi.setTextAlignment(QtCore.Qt.AlignRight) dlgTable.tblImpacts.setItem(row, 2, twi) dlgTable.tblImpacts.sortItems(2) dlgTable.show() dlgTable.exec_() else: QMessageBox.information(self.dlg, "Message", "Should only run if cancelled")
def load_stdm_form(self, feature_id, spatial_column): """ Loads STDM Form and collects the model added into the form so that it is saved later. :param feature_id: the ID of a feature that is last added :type feature_id: Integer :param spatial_column: The spatial column name of the layer :type spatial_column: String :return: None :rtype:NoneType """ srid = None self.current_feature = feature_id # If the digitizing save button is clicked, # the featureAdded signal is called but the # feature ids value is over 0. Return to prevent # the dialog from popping up for every feature. if feature_id > 0: return # if the feature is already in the OrderedDict don't # show the form as the model of the feature is # already populated by the form if feature_id in self.feature_models.keys(): return # If the feature is removed by the undo button, don't # load the form for it but add it # back to feature_models and don't show the form. # This happens when redo button(add feature back) is # clicked after an undo button(remove feature) if feature_id in self.removed_feature_models.keys(): self.feature_models[feature_id] = \ self.removed_feature_models[feature_id] return # If the feature is not valid, geom_wkt will be None # So don't launch form for invalid feature and delete feature geom_wkt = self.get_wkt(spatial_column, feature_id) if geom_wkt is None: title = QApplication.translate( 'STDMFieldWidget', 'Spatial Entity Form Error', None ) msg = QApplication.translate( 'STDMFieldWidget', 'The feature you have added is invalid. \n' 'To fix this issue, check if the feature ' 'is digitized correctly. \n' 'Make sure you have added a base layer to digitize on.', None ) # Message: Spatial column information # could not be found QMessageBox.critical( iface.mainWindow(), title, msg ) return # init form feature_model, col_with_data = self.feature_to_model(feature_id) if col_with_data == 0: feature_model = None self.editor = EntityEditorDialog( self.entity, model=feature_model, parent=iface.mainWindow(), manage_documents=True, collect_model=True, plugin=self.plugin ) self.model = self.editor.model() self.editor.addedModel.connect(self.on_form_saved) # get srid with EPSG text full_srid = self.layer.crs().authid().split(':') if len(full_srid) > 0: # Only extract the number srid = full_srid[1] if not geom_wkt is None: # add geometry into the model setattr( self.model, spatial_column, 'SRID={};{}'.format(srid, geom_wkt) ) # open editor result = self.editor.exec_() if result < 1: self.removed_feature_models[feature_id] = None self.layer.deleteFeature(feature_id)
def on_add_to_canvas_button_clicked(self): """ Add STDM layer to map canvas. """ if self.stdm_layers_combo.count() == 0: return sp_col_info = self.stdm_layers_combo.itemData( self.stdm_layers_combo.currentIndex()) if sp_col_info is None: title = QApplication.translate('SpatialUnitManagerDockWidget', 'Spatial Unit Manager') msg = QApplication.translate( 'SpatialUnitManagerDockWidget', 'Spatial Column Layer Could not be found') # Message: Spatial column information # could not be found QMessageBox.warning(self.iface.mainWindow(), title, msg) table_name, spatial_column = sp_col_info["table_name"], \ sp_col_info["column_name"] # Check if the layer has already been layer_item = sp_col_info.get('item', None) layer_name = self.geom_col_layer_name(table_name, layer_item) if layer_name in self._map_registry_layer_names(): layer = QgsProject.instance().mapLayersByName(layer_name)[0] self.iface.setActiveLayer(layer) return self.curr_lyr_table = table_name self.curr_lyr_sp_col = spatial_column if layer_item is not None: if isinstance(layer_item, str): layer_name = layer_item else: layer_name = layer_item.layer_display() entity = self._curr_profile.entity_by_name(table_name) if entity is not None: geom_col_obj = entity.columns[spatial_column] srid = None if geom_col_obj.srid >= 100000: srid = geom_col_obj.srid curr_layer = vector_layer(table_name, geom_column=spatial_column, layer_name=layer_name, proj_wkt=srid) else: curr_layer = vector_layer(table_name, geom_column=spatial_column, layer_name=layer_name, proj_wkt=None) # for lookup layer. else: curr_layer = vector_layer(table_name, geom_column=spatial_column) if curr_layer.isValid(): if curr_layer.name() in self._map_registry_layer_names(): return QgsProject.instance().addMapLayer(curr_layer) self.zoom_to_layer() self.onLayerAdded.emit(spatial_column, curr_layer) self.toggle_entity_multi_layers(curr_layer) self.set_canvas_crs(curr_layer) # Required in order for the layer name to be set if layer_name is not None: QTimer.singleShot( 100, lambda: self._set_layer_display_name( curr_layer, layer_name)) entity = self._curr_profile.entity_by_name(self.curr_lyr_table) fk_fields = self.join_fk_layer(curr_layer, entity) if entity is not None: self.sort_joined_columns(curr_layer, fk_fields) self.set_field_alias(curr_layer, entity, fk_fields) else: msg = QApplication.translate( "Spatial Unit Manager", "'{0}.{1}' layer is invalid, it cannot " "be added to the map view.".format(table_name, spatial_column)) QMessageBox.critical(self.iface.mainWindow(), 'Spatial Unit Manager', msg)