def testOwnership(self): """ Test that registered color schemes do not require that a reference to them is kept. They should be parented to the registry (on transfer) and even if there's no reference to the registry around (see the `del` below) this childship should continue to exist. """ class TestColorScheme(QgsColorScheme): def schemeName(self): return "TestScheme" def fetchColors(self, context, baseColors): return None def clone(self): return TestColorScheme() def flags(self): return 1 reg = QgsApplication.instance().colorSchemeRegistry() reg.addColorScheme(TestColorScheme()) del reg reg = QgsApplication.instance().colorSchemeRegistry() self.assertIn('TestScheme', [scheme.schemeName() for scheme in reg.schemes()])
def start_app(cleanup=True): """ Will start a QgsApplication and call all initialization code like registering the providers and other infrastructure. It will not load any plugins. You can always get the reference to a running app by calling `QgsApplication.instance()`. The initialization will only happen once, so it is safe to call this method repeatedly. Parameters ---------- cleanup: Do cleanup on exit. Defaults to true. Returns ------- QgsApplication A QgsApplication singleton """ global QGISAPP try: QGISAPP except NameError: myGuiFlag = True # All test will run qgis in gui mode try: sys.argv except: sys.argv = [''] # In python3 we need to convert to a bytes object (or should # QgsApplication accept a QString instead of const char* ?) try: argvb = list(map(os.fsencode, sys.argv)) except AttributeError: argvb = sys.argv # Note: QGIS_PREFIX_PATH is evaluated in QgsApplication - # no need to mess with it here. QGISAPP = QgsApplication(argvb, myGuiFlag) QGISAPP.initQgis() print(QGISAPP.showSettings()) def debug_log_message(message, tag, level): print('{}({}): {}'.format(tag, level, message)) QgsApplication.instance().messageLog().messageReceived.connect(debug_log_message) if cleanup: import atexit @atexit.register def exitQgis(): QGISAPP.exitQgis() return QGISAPP
def load(self): success = super().load() if success: self.parameterTypeFieldsMapping = FieldsMapper.ParameterFieldsMappingType() QgsApplication.instance().processingRegistry().addParameterType(self.parameterTypeFieldsMapping) return success
def threadCleanup(self): ''' cleanup after thread run ''' # restore cursor QgsApplication.instance().restoreOverrideCursor() if self.alg: self.alg.deleteLater() self.alg = None self.thread.wait() self.thread.deleteLater() # remove progress bar if self.progressMessageBarItem: iface.messageBar().popWidget(self.progressMessageBarItem) self.progressMessageBarItem = None
def unmodalWidget(objectName, repeatTimes=10, repeatInterval=500, step=0): """Look for a widget in the QGIS hierarchy to set it as not modal. If the widget is not found try agail after a "repeatInterval" and repeat no more that "repeatTimes" """ if not objectName: return l = QgsApplication.instance().topLevelWidgets() for d in l: for dd in d.findChildren(QDialog): if dd.objectName() != objectName: continue dd.setWindowModality(False) return if repeatTimes == step: return # if here => not found QTimer.singleShot(repeatInterval, lambda: unmodalWidget(objectName, repeatTimes, repeatInterval, step + 1))
def __init__(self, parent=None): super().__init__(parent) self.setObjectName("PythonConsole") self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console")) # self.setAllowedAreas(Qt.BottomDockWidgetArea) self.console = PythonConsoleWidget(self) self.setWidget(self.console) self.setFocusProxy(self.console) # try to restore position from stored main window state if iface and not iface.mainWindow().restoreDockWidget(self): iface.mainWindow().addDockWidget(Qt.BottomDockWidgetArea, self) # closeEvent is not always called for this widget -- so we also trigger a settings # save on application exit QgsApplication.instance().aboutToQuit.connect(self.console.saveSettingsConsole)
def qgis_excepthook(type, value, tb): # detect if running in the main thread in_main_thread = True if QThread.currentThread() != QgsApplication.instance().thread(): in_main_thread = False # only use messagebar if running in main thread - otherwise it will crash! showException(type, value, tb, None, messagebar=in_main_thread)
def fetchFiles(self, urls, renderContext): downloader = Downloader(None, self.maxConnections, self.cacheExpiry, self.userAgent) downloader.moveToThread(QgsApplication.instance().thread()) downloader.timer.moveToThread(QgsApplication.instance().thread()) self.logT("TileLayer.fetchFiles() starts") # create a QEventLoop object that belongs to the current worker thread eventLoop = QEventLoop() downloader.allRepliesFinished.connect(eventLoop.quit) if self.iface: # for download progress downloader.replyFinished.connect(self.networkReplyFinished) self.downloader = downloader # create a timer to watch whether rendering is stopped watchTimer = QTimer() watchTimer.timeout.connect(eventLoop.quit) # fetch files QMetaObject.invokeMethod(self.downloader, "fetchFilesAsync", Qt.QueuedConnection, Q_ARG(list, urls), Q_ARG(int, self.plugin.downloadTimeout)) # wait for the fetch to finish tick = 0 interval = 500 timeoutTick = self.plugin.downloadTimeout * 1000 / interval watchTimer.start(interval) while tick < timeoutTick: # run event loop for 0.5 seconds at maximum eventLoop.exec_() if downloader.unfinishedCount() == 0 or renderContext.renderingStopped(): break tick += 1 watchTimer.stop() if downloader.unfinishedCount() > 0: downloader.abort(False) if tick == timeoutTick: downloader.errorStatus = Downloader.TIMEOUT_ERROR self.log("fetchFiles(): timeout") # watchTimer.timeout.disconnect(eventLoop.quit) # downloader.allRepliesFinished.disconnect(eventLoop.quit) self.logT("TileLayer.fetchFiles() ends") return downloader.fetchedFiles
def __run_test(): """ Run the test specified as last argument in the command line. """ # Disable modal handler for bad layers QgsProject.instance().setBadLayerHandler(QgsProjectBadLayerDefaultHandler()) eprint("QGIS Test Runner Inside - starting the tests ...") try: test_module_name = QgsApplication.instance().arguments()[-1] function_name = __get_test_function(test_module_name) eprint("QGIS Test Runner Inside - executing function %s" % function_name) function_name() except Exception as e: eprint("QGIS Test Runner Inside - [FAILED] Exception: %s" % e) # Print tb traceback.print_exc(file=sys.stdout) app = QgsApplication.instance() os.kill(app.applicationPid(), signal.SIGTERM)
def setUpClass(cls): """Run before all tests""" QCoreApplication.setOrganizationName("QGIS_Test") QCoreApplication.setOrganizationDomain( "QGIS_TestPyQgsProcessingInPlace.com") QCoreApplication.setApplicationName("QGIS_TestPyQgsProcessingInPlace") QgsSettings().clear() Processing.initialize() QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms()) cls.registry = QgsApplication.instance().processingRegistry()
def setUp(self): self.ran_errored = False self.ran_finished = False self.ran_progress = False self.qgs = None # Duh... there can only be one QApplication at a time # http://stackoverflow.com/questions/10888045/simple-ipython-example-raises-exception-on-sys-exit # if you do create >1 QgsApplications (QtApplications) then you will have non exit code 0 self.qgs = QgsApplication.instance() # checks if QApplication already exists if not self.qgs: # create QApplication if it doesnt exist self.qgs = QgsApplication(sys.argv, False) self.qgs.initQgis() # nessecary for opening auth db etc etc
def _dropEvent(event): if event.mimeData().hasText(): itemId = event.mimeData().text() if itemId in [param.id() for param in QgsApplication.instance().processingRegistry().parameterTypes()]: self.addInputOfType(itemId, event.pos()) else: alg = QgsApplication.processingRegistry().createAlgorithmById(itemId) if alg is not None: self._addAlgorithm(alg, event.pos()) event.accept() else: event.ignore()
def run(self): geojson = self.geojson() projestions = [] if geojson: try: projestions = projestions_api.get_projestions(geojson) except URLError as e: msg = 'URLError while loading projestions: %s' % str(e) QgsApplication.instance().messageLog().logMessage(msg, tag="Projestions", level=Qgis.MessageLevel(1)) self.warningSent.emit('Failed to get projestions from API. ' 'Please try again and see the error log ' 'for details.') except Exception as e: msg = '%s while loading projections' % type(e).__name__ QgsApplication.instance().messageLog().logMessage(msg, tag="Projestions", level=Qgis.MessageLevel(1)) QgsApplication.instance().messageLog().logMessage(traceback.format_exc(), tag="Projestions", level=Qgis.MessageLevel(1)) self.warningSent.emit('Failed to get projestions from API. ' 'Please try again and see the error log ' 'for details.') self.taskFinished.emit(projestions) self.quit()
def run(self): """Run method that performs all the real work""" self.dlg.show() if settings.DEBUG: def writelogmessage(message, tag, level): with open('/home/eric/tmp/qgis.log', 'a') as logfile: logfile.write('{}({}): {}'.format(tag, level, message)) QgsApplication.instance().messageLog().messageReceived.connect(writelogmessage) if self.dlg.exec_(): try: item = self.dlg.crsTableView.selectionModel().selectedRows()[0] row = item.row() data = item.data() new_crs = QgsCoordinateReferenceSystem( data, QgsCoordinateReferenceSystem.EpsgCrsId ) QgsProject.instance().setCrs(new_crs) except IndexError: pass
def __run_test(): """ Run the test specified as last argument in the command line. """ eprint("QGIS Test Runner Inside - starting the tests ...") try: test_module_name = QgsApplication.instance().argv()[-1] function_name = __get_test_function(test_module_name) if function_name is None: eprint("QGIS Test Runner Inside - [ERROR] cannot load test function from %s" % test_module_name) function_name() except Exception, e: eprint("QGIS Test Runner Inside - [ERROR] Exception: %s" % e)
def setUpClass(cls): """Run before all tests""" QCoreApplication.setOrganizationName("QGIS_Test") QCoreApplication.setOrganizationDomain( "QGIS_TestPyQgsExportToPostgis.com") QCoreApplication.setApplicationName("QGIS_TestPyQgsExportToPostgis") QgsSettings().clear() Processing.initialize() QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms()) cls.registry = QgsApplication.instance().processingRegistry() # Create DB connection in the settings settings = QgsSettings() settings.beginGroup('/PostgreSQL/connections/qgis_test') settings.setValue('service', 'qgis_test') settings.setValue('database', 'qgis_test')
def loop_qgis(kernel): """QGIS event loop for IPython kernels. Based on loop_qt in IPython.zmq.eventloops, but uses the special QGIS main application instance and avoids trying to launch a new instance. Using loop_qt will cause starting the kernel to hang QGIS with IPython 0.12 or later. """ from qgis.core import QgsApplication from PyQt4 import QtCore kernel.app = QgsApplication.instance() kernel.timer = QtCore.QTimer() kernel.timer.timeout.connect(kernel.do_one_iteration) # Units for the timer are in milliseconds kernel.timer.start(1000*kernel._poll_interval)
def fillInputsTree(self): icon = QIcon(os.path.join(pluginPath, 'images', 'input.svg')) parametersItem = QTreeWidgetItem() parametersItem.setText(0, self.tr('Parameters')) sortedParams = sorted(QgsApplication.instance().processingRegistry().parameterTypes(), key=lambda pt: pt.name()) for param in sortedParams: if param.flags() & QgsProcessingParameterType.ExposeToModeler: paramItem = QTreeWidgetItem() paramItem.setText(0, param.name()) paramItem.setData(0, Qt.UserRole, param.id()) paramItem.setIcon(0, icon) paramItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) paramItem.setToolTip(0, param.description()) parametersItem.addChild(paramItem) self.inputsTree.addTopLevelItem(parametersItem) parametersItem.setExpanded(True)
def _dropEvent(event): if event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'): data = event.mimeData().data('application/x-vnd.qgis.qgis.algorithmid') stream = QDataStream(data, QIODevice.ReadOnly) algorithm_id = stream.readQString() alg = QgsApplication.processingRegistry().createAlgorithmById(algorithm_id) if alg is not None: self._addAlgorithm(alg, event.pos()) else: assert False, algorithm_id elif event.mimeData().hasText(): itemId = event.mimeData().text() if itemId in [param.id() for param in QgsApplication.instance().processingRegistry().parameterTypes()]: self.addInputOfType(itemId, event.pos()) event.accept() else: event.ignore()
def setUpClass(cls): """Run before all tests""" QCoreApplication.setOrganizationName("QGIS_Test") QCoreApplication.setOrganizationDomain( "QGIS_TestPyQgsProcessingInPlace.com") QCoreApplication.setApplicationName("QGIS_TestPyQgsProcessingInPlace") QgsSettings().clear() Processing.initialize() QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms()) cls.registry = QgsApplication.instance().processingRegistry() fields = QgsFields() fields.append(QgsField('int_f', QVariant.Int)) cls.vl = QgsMemoryProviderUtils.createMemoryLayer( 'mylayer', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(4326)) f1 = QgsFeature(cls.vl.fields()) f1['int_f'] = 1 f1.setGeometry(QgsGeometry.fromWkt('Point(9 45)')) f2 = QgsFeature(cls.vl.fields()) f2['int_f'] = 2 f2.setGeometry(QgsGeometry.fromWkt('Point(9.5 45.6)')) cls.vl.dataProvider().addFeatures([f1, f2]) assert cls.vl.isValid() assert cls.vl.featureCount() == 2 # Multipolygon layer cls.multipoly_vl = QgsMemoryProviderUtils.createMemoryLayer( 'mymultiplayer', fields, QgsWkbTypes.MultiPolygon, QgsCoordinateReferenceSystem(4326)) f3 = QgsFeature(cls.multipoly_vl.fields()) f3.setGeometry(QgsGeometry.fromWkt('MultiPolygon (((2.81856297539240419 41.98170998812887689, 2.81874467773035464 41.98167537995160359, 2.81879535908157752 41.98154066615795443, 2.81866433873670452 41.98144056064155905, 2.81848263699778379 41.98147516865246587, 2.81843195500470811 41.98160988234612034, 2.81856297539240419 41.98170998812887689)),((2.81898589063455907 41.9815711567298635, 2.81892080450418803 41.9816030048432367, 2.81884192631866437 41.98143737613141724, 2.8190679469505846 41.98142270931093378, 2.81898589063455907 41.9815711567298635)))')) f4 = QgsFeature(cls.multipoly_vl.fields()) f4.setGeometry(QgsGeometry.fromWkt('MultiPolygon (((2.81823679385631332 41.98133290154246566, 2.81830770255185703 41.98123540208609228, 2.81825871989355159 41.98112524362621656, 2.81813882853970243 41.98111258462271422, 2.81806791984415872 41.98121008407908761, 2.81811690250246416 41.98132024253896333, 2.81823679385631332 41.98133290154246566)),((2.81835835162010895 41.98123286963267731, 2.8183127674586852 41.98108725356146209, 2.8184520523963692 41.98115436357689134, 2.81835835162010895 41.98123286963267731)))')) cls.multipoly_vl.dataProvider().addFeatures([f3, f4]) assert cls.multipoly_vl.isValid() assert cls.multipoly_vl.featureCount() == 2 QgsProject.instance().addMapLayers([cls.vl, cls.multipoly_vl])
def createBaseMapLayer(self, map_theme, layer, tile_size, map_units_per_pixel): """ Create a basemap from map layer(s) :param dataPath: The path where the basemap should be writtent to :param extent: The extent rectangle in which data shall be fetched :param map_theme: The name of the map theme to be rendered :param layer: A layer id to be rendered. Will only be used if map_theme is None. :param tile_size: The extent rectangle in which data shall be fetched :param map_units_per_pixel: Number of map units per pixel (1: 1 m per pixel, 10: 10 m per pixel...) """ extent_string = '{},{},{},{}'.format(self.extent.xMinimum(), self.extent.xMaximum(), self.extent.yMinimum(), self.extent.yMaximum()) alg = QgsApplication.instance().processingRegistry().createAlgorithmById('qgis:rasterize') params = { 'EXTENT': extent_string, 'MAP_THEME': map_theme, 'LAYER': layer, 'MAP_UNITS_PER_PIXEL': map_units_per_pixel, 'TILE_SIZE': tile_size, 'MAKE_BACKGROUND_TRANSPARENT': False, 'OUTPUT': os.path.join(self.export_folder, 'basemap.gpkg') } feedback = QgsProcessingFeedback() context = QgsProcessingContext() context.setProject(QgsProject.instance()) results, ok = alg.run(params, context, feedback) new_layer = QgsRasterLayer(results['OUTPUT'], self.tr('Basemap')) resample_filter = new_layer.resampleFilter() resample_filter.setZoomedInResampler(QgsCubicRasterResampler()) resample_filter.setZoomedOutResampler(QgsBilinearRasterResampler()) self.project_configuration.project.addMapLayer(new_layer, False) layer_tree = QgsProject.instance().layerTreeRoot() layer_tree.insertLayer(len(layer_tree.children()), new_layer)
def testConcurrency(self): """ The connection pool has a maximum of 4 connections defined (+2 spare connections) Make sure that if we exhaust those 4 connections and force another connection it is actually using the spare connections and does not freeze. This situation normally happens when (at least) 4 rendering threads are active in parallel and one requires an expression to be evaluated. """ # Acquire the maximum amount of concurrent connections iterators = list() for i in range(QgsApplication.instance().maxConcurrentConnectionsPerPool()): iterators.append(self.vl.getFeatures()) # Run an expression that will also do a request and should use a spare # connection. It just should not deadlock here. feat = next(iterators[0]) context = QgsExpressionContext() context.setFeature(feat) exp = QgsExpression('get_feature(\'{layer}\', \'pk\', 5)'.format(layer=self.vl.id())) exp.evaluate(context)
def accept(self): """Handler for when OK is clicked.""" input_path = self.input_path.text() input_title = self.line_edit_title.text() input_source = self.line_edit_source.text() output_path = self.output_path.text() if not output_path.endswith('.tif'): # noinspection PyArgumentList,PyCallByClass,PyTypeChecker QMessageBox.warning( self, tr('InaSAFE'), tr('Output file name must be tif file')) if not os.path.exists(input_path): # noinspection PyArgumentList,PyCallByClass,PyTypeChecker QMessageBox.warning( self, tr('InaSAFE'), tr('Input file does not exist')) return algorithm = 'nearest' if self.nearest_mode.isChecked(): algorithm = 'nearest' elif self.inverse_distance_mode.isChecked(): algorithm = 'invdist' elif self.use_ascii_mode.isChecked(): algorithm = 'use_ascii' # Smoothing smoothing_method = NONE_SMOOTHING if self.numpy_smoothing.isChecked(): smoothing_method = NUMPY_SMOOTHING if self.scipy_smoothing.isChecked(): smoothing_method = SCIPY_SMOOTHING # noinspection PyUnresolvedReferences QgsApplication.instance().setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor) ) extra_keywords = {} if self.check_box_custom_shakemap_id.isChecked(): event_id = self.line_edit_shakemap_id.text() extra_keywords[extra_keyword_earthquake_event_id['key']] = event_id current_index = self.combo_box_source_type.currentIndex() source_type = self.combo_box_source_type.itemData(current_index) if source_type: extra_keywords[ extra_keyword_earthquake_source['key']] = source_type file_name = convert_mmi_data( input_path, input_title, input_source, output_path, algorithm=algorithm, algorithm_filename_flag=True, smoothing_method=smoothing_method, extra_keywords=extra_keywords ) file_info = QFileInfo(file_name) base_name = file_info.baseName() self.output_layer = QgsRasterLayer(file_name, base_name) # noinspection PyUnresolvedReferences QgsApplication.instance().restoreOverrideCursor() if self.load_result.isChecked(): # noinspection PyTypeChecker mmi_ramp_roman(self.output_layer) self.output_layer.saveDefaultStyle() if not self.output_layer.isValid(): LOGGER.debug("Failed to load") else: # noinspection PyArgumentList QgsProject.instance().addMapLayer(self.output_layer) iface.zoomToActiveLayer() if (self.keyword_wizard_checkbox.isChecked() and self.keyword_wizard_checkbox.isEnabled()): self.launch_keyword_wizard() self.done(self.Accepted)
def accept(self): description = self.nameTextBox.text() if description.strip() == '': QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Invalid parameter name')) return if self.param is None: validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeName = ''.join(c for c in description if c in validChars) name = safeName.lower() i = 2 while self.alg.parameterDefinition(name): name = safeName.lower() + str(i) i += 1 else: name = self.param.name() # Destination parameter if (isinstance(self.param, QgsProcessingParameterFeatureSink)): self.param = QgsProcessingParameterFeatureSink( name=name, description=self.param.description(), type=self.param.dataType(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFileDestination)): self.param = QgsProcessingParameterFileDestination( name=name, description=self.param.description(), fileFilter=self.param.fileFilter(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFolderDestination)): self.param = QgsProcessingParameterFolderDestination( name=name, description=self.param.description(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterRasterDestination)): self.param = QgsProcessingParameterRasterDestination( name=name, description=self.param.description(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterVectorDestination)): self.param = QgsProcessingParameterVectorDestination( name=name, description=self.param.description(), type=self.param.dataType(), defaultValue=self.defaultWidget.value()) else: if self.paramType: typeId = self.paramType else: typeId = self.param.type() paramTypeDef = QgsApplication.instance().processingRegistry( ).parameterType(typeId) if not paramTypeDef: msg = self.tr( 'The parameter `{}` is not registered, are you missing a required plugin?' .format(typeId)) raise UndefinedParameterException(msg) self.param = paramTypeDef.create(name) self.param.setDescription(description) self.param.setMetadata(paramTypeDef.metadata()) if not self.requiredCheck.isChecked(): self.param.setFlags( self.param.flags() | QgsProcessingParameterDefinition.FlagOptional) else: self.param.setFlags( self.param.flags() & ~QgsProcessingParameterDefinition.FlagOptional) if self.advancedCheck.isChecked(): self.param.setFlags( self.param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) else: self.param.setFlags( self.param.flags() & ~QgsProcessingParameterDefinition.FlagAdvanced) settings = QgsSettings() settings.setValue( "/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.accept(self)
* the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ """ from __future__ import absolute_import # Import the PyQt and QGIS libraries from builtins import object from qgis.PyQt.QtCore import QSettings, QTranslator, QObject from qgis.PyQt.QtWidgets import QApplication, QAction from qgis.PyQt.QtGui import QIcon from qgis.core import QgsApplication # Initialize Qt resources from file resources.py from . import qrc_resources # Add translations to translator application = QgsApplication.instance() localeName = QSettings().value("locale/userLocale", type=str) translator = QTranslator() translator.load("B4UdigNL_"+localeName, ":/") # Add translator to application application.installTranslator(translator) # Import the code for the dialog from .B4UdigNLDialog import B4UdigNLDialog class B4UdigNL(object): def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface self.dialog = None
def __init__(self): super(Screenshot, self).__init__() self._screen = QgsApplication.instance().primaryScreen() self.iscreenshot = 0
def __init__(self, parent, c, view): Ui_QgsCompositionWidgetBase.__init__(self, parent) # s = ["a", "b"] # i = s.index().__contains__("b") # o = s.__contains__("n") self.mComposition = c self.mPaperMap = dict() self.mMapItems = [] self.timeStart = 0 self.timeEnd = 0 self.blockSignals( True ) self.createPaperEntries() #unit self.mPaperUnitsComboBox.addItem( QString( "mm" ) ) self.mPaperUnitsComboBox.addItem( QString( "inch" ) ) #orientation self.mPaperOrientationComboBox.insertItem( 0, QString( "Landscape" ) ) self.mPaperOrientationComboBox.insertItem( 1, QString( "Portrait" ) ) self.mPaperOrientationComboBox.setCurrentIndex( 0 ) #read with/height from composition and find suitable entries to display self.displayCompositionWidthHeight() self.updateVariables() self.connect( self.mVariableEditor, SIGNAL( "scopeChanged()" ), self.variablesChanged) self.connect(self.mWorldFileMapComboBox, SIGNAL("currentIndexChanged(int)"), self.on_mWorldFileMapComboBox_currentIndexChanged) self.connect( view, SIGNAL( "actionFinished()" ), self.mView_actionFinished) # listen out for variable edits app = QgsApplication.instance() if ( app ): self.connect( app, SIGNAL( "settingsChanged()" ), self.updateVariables) self.connect( QgsProject.instance(), SIGNAL( "variablesChanged()" ), self.updateVariables) if ( self.mComposition ): self.mNumPagesSpinBox.setValue( self.mComposition.numPages() ) self.connect( self.mComposition, SIGNAL( "nPagesChanged()" ), self.setNumberPages) self.updatePageStyle() #read printout resolution from composition self.mResolutionSpinBox.setValue( self.mComposition.printResolution() ) topMargin = 0 rightMargin = 0 bottomMargin = 0 leftMargin = 0 topMargin, rightMargin, bottomMargin, leftMargin = self.mComposition.resizeToContentsMargins() self.mTopMarginSpinBox.setValue( topMargin ) self.mRightMarginSpinBox.setValue( rightMargin ) self.mBottomMarginSpinBox.setValue( bottomMargin ) self.mLeftMarginSpinBox.setValue( leftMargin ) #print as raster self.mPrintAsRasterCheckBox.setChecked( self.mComposition.printAsRaster() ) # world file generation self.mGenerateWorldFileCheckBox.setChecked( self.mComposition.generateWorldFile() ) # populate the map list self.mWorldFileMapComboBox.clear() availableMaps = self.mComposition.composerMapItems() # QList<const QgsComposerMap*>.const_iterator mapItemIt = availableMaps.constBegin() for mapItemIt in availableMaps: self.mWorldFileMapComboBox.addItem( QString( "Map %1" ).arg(( mapItemIt ).id() ), self.qVariantFromValue(mapItemIt, "Add" ) ) idx = self.mWorldFileMapComboBox.findData( self.qVariantFromValue(self.mComposition.worldFileMap(), "Find" ) ) if ( idx != -1 ): self.mWorldFileMapComboBox.setCurrentIndex( idx ) # Connect to addition / removal of maps self.connect( self.mComposition, SIGNAL( "composerMapAdded( QgsComposerMap* )" ), self.onComposerMapAdded) self.connect( self.mComposition, SIGNAL( "itemRemoved( QgsComposerItem* )" ), self.onItemRemoved) self.mSnapToleranceSpinBox.setValue( self.mComposition.snapTolerance() ) #snap grid self.mGridResolutionSpinBox.setValue( self.mComposition.snapGridResolution() ) self.mOffsetXSpinBox.setValue( self.mComposition.snapGridOffsetX() ) self.mOffsetYSpinBox.setValue( self.mComposition.snapGridOffsetY() ) atlas = self.mComposition.atlasComposition() if ( atlas ): # repopulate data defined buttons if atlas layer changes self.connect( atlas, SIGNAL( "coverageLayerChanged( QgsVectorLayer* )" ), self.populateDataDefinedButtons) self.connect( atlas, SIGNAL( "toggled( bool )" ), self.populateDataDefinedButtons) self.connect( self.mTopMarginSpinBox, SIGNAL( "valueChanged( double )" ), self.resizeMarginsChanged) self.connect( self.mRightMarginSpinBox, SIGNAL( "valueChanged( double )" ), self.resizeMarginsChanged) self.connect( self.mBottomMarginSpinBox, SIGNAL( "valueChanged( double )" ), self.resizeMarginsChanged) self.connect( self.mLeftMarginSpinBox, SIGNAL( "valueChanged( double )" ), self.resizeMarginsChanged) self.connect( self.mPaperSizeDDBtn, SIGNAL( "dataDefinedChanged( const QString& )" ), self.updateDataDefinedProperty) self.connect( self.mPaperSizeDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.updateDataDefinedProperty) self.connect( self.mPaperSizeDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.mPaperSizeComboBox, SLOT( "setDisabled( bool )" ) ) self.connect( self.mPaperWidthDDBtn, SIGNAL( "dataDefinedChanged( const QString& )" ), self.updateDataDefinedProperty) self.connect( self.mPaperWidthDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.updateDataDefinedProperty) self.connect( self.mPaperWidthDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.mPaperWidthDoubleSpinBox, SLOT( "setDisabled( bool )" ) ) self.connect( self.mPaperHeightDDBtn, SIGNAL( "dataDefinedChanged( const QString& )" ), self.updateDataDefinedProperty) self.connect( self.mPaperHeightDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.updateDataDefinedProperty) self.connect( self.mPaperHeightDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.mPaperHeightDoubleSpinBox, SLOT( "setDisabled( bool )" ) ) self.connect( self.mNumPagesDDBtn, SIGNAL( "dataDefinedChanged( const QString& )" ), self.updateDataDefinedProperty) self.connect( self.mNumPagesDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.updateDataDefinedProperty) self.connect( self.mNumPagesDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.mNumPagesSpinBox, SLOT( "setDisabled( bool )" ) ) self.connect( self.mPaperOrientationDDBtn, SIGNAL( "dataDefinedChanged( const QString& )" ), self.updateDataDefinedProperty) self.connect( self.mPaperOrientationDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.updateDataDefinedProperty) self.connect( self.mPaperOrientationDDBtn, SIGNAL( "dataDefinedActivated( bool )" ), self.mPaperOrientationComboBox, SLOT( "setDisabled( bool )" ) ) #initialize data defined buttons self.populateDataDefinedButtons() self.blockSignals( False ) self.addItemName = ""
def convert(self): """ Convert the project to a portable project. :param offline_editing: The offline editing instance :param export_folder: The folder to export to """ project = QgsProject.instance() original_project = project original_project_path = project.fileName() project_filename, _ = os.path.splitext( os.path.basename(original_project_path)) # Write a backup of the current project to a temporary file project_backup_folder = tempfile.mkdtemp() backup_project_path = os.path.join(project_backup_folder, project_filename + '.qgs') QgsProject.instance().write(backup_project_path) try: if not os.path.exists(self.export_folder): os.makedirs(self.export_folder) QApplication.setOverrideCursor(Qt.WaitCursor) self.__offline_layers = list() self.__layers = list(project.mapLayers().values()) original_layer_info = {} for layer in self.__layers: original_layer_info[layer.id()] = (layer.source(), layer.name()) # We store the pks of the original vector layers # and we check that the primary key fields names don't # have a comma in the name original_pk_fields_by_layer_name = {} for layer in self.__layers: if layer.type() == QgsMapLayer.VectorLayer: keys = [] for idx in layer.primaryKeyAttributes(): key = layer.fields()[idx].name() assert (',' not in key), 'Comma in field names not allowed' keys.append(key) original_pk_fields_by_layer_name[layer.name()] = ','.join( keys) self.total_progress_updated.emit(0, 1, self.trUtf8('Creating base map…')) # Create the base map before layers are removed if self.project_configuration.create_base_map: if 'processing' not in qgis.utils.plugins: QMessageBox.warning( None, self.tr('QFieldSync requires processing'), self. tr('Creating a basemap with QFieldSync requires the processing plugin to be enabled. Processing is not enabled on your system. Please go to Plugins > Manage and Install Plugins and enable processing.' )) return if self.project_configuration.base_map_type == ProjectProperties.BaseMapType.SINGLE_LAYER: self.createBaseMapLayer( None, self.project_configuration.base_map_layer, self.project_configuration.base_map_tile_size, self.project_configuration.base_map_mupp) else: self.createBaseMapLayer( self.project_configuration.base_map_theme, None, self.project_configuration.base_map_tile_size, self.project_configuration.base_map_mupp) # Loop through all layers and copy/remove/offline them pathResolver = QgsProject.instance().pathResolver() copied_files = list() for current_layer_index, layer in enumerate(self.__layers): self.total_progress_updated.emit( current_layer_index - len(self.__offline_layers), len(self.__layers), self.trUtf8('Copying layers…')) layer_source = LayerSource(layer) if not layer_source.is_supported: project.removeMapLayer(layer) continue if layer.dataProvider() is not None: md = QgsProviderRegistry.instance().providerMetadata( layer.dataProvider().name()) if md is not None: decoded = md.decodeUri(layer.source()) if "path" in decoded: path = pathResolver.writePath(decoded["path"]) if path.startswith("localized:"): # Layer stored in localized data path, skip continue if layer_source.action == SyncAction.OFFLINE: if self.project_configuration.offline_copy_only_aoi and not self.project_configuration.offline_copy_only_selected_features: layer.selectByRect(self.extent) elif self.project_configuration.offline_copy_only_aoi and self.project_configuration.offline_copy_only_selected_features: # This option is only possible via API QgsApplication.instance().messageLog().logMessage( self. tr('Both "Area of Interest" and "only selected features" options were enabled, tha latter takes precedence.' ), 'QFieldSync') self.__offline_layers.append(layer) # Store the primary key field name(s) as comma separated custom property if layer.type() == QgsMapLayer.VectorLayer: key_fields = ','.join([ layer.fields()[x].name() for x in layer.primaryKeyAttributes() ]) layer.setCustomProperty( 'QFieldSync/sourceDataPrimaryKeys', key_fields) elif layer_source.action == SyncAction.NO_ACTION: copied_files = layer_source.copy(self.export_folder, copied_files) elif layer_source.action == SyncAction.KEEP_EXISTENT: layer_source.copy(self.export_folder, copied_files, True) elif layer_source.action == SyncAction.REMOVE: project.removeMapLayer(layer) project_path = os.path.join(self.export_folder, project_filename + "_qfield.qgs") # save the original project path ProjectConfiguration( project).original_project_path = original_project_path # save the offline project twice so that the offline plugin can "know" that it's a relative path QgsProject.instance().write(project_path) # export the DCIM folder copy_images( os.path.join(os.path.dirname(original_project_path), "DCIM"), os.path.join(os.path.dirname(project_path), "DCIM")) try: # Run the offline plugin for gpkg gpkg_filename = "data.gpkg" if self.__offline_layers: offline_layer_ids = [l.id() for l in self.__offline_layers] only_selected = self.project_configuration.offline_copy_only_aoi or self.project_configuration.offline_copy_only_selected_features if Qgis.QGIS_VERSION_INT < 31601: if not self.offline_editing.convertToOfflineProject( self.export_folder, gpkg_filename, offline_layer_ids, only_selected, self.offline_editing.GPKG): raise Exception( self. tr("Error trying to convert layers to offline layers" )) else: if not self.offline_editing.convertToOfflineProject( self.export_folder, gpkg_filename, offline_layer_ids, only_selected, self.offline_editing.GPKG, None): raise Exception( self. tr("Error trying to convert layers to offline layers" )) except AttributeError: # Run the offline plugin for spatialite spatialite_filename = "data.sqlite" if self.__offline_layers: offline_layer_ids = [l.id() for l in self.__offline_layers] only_selected = self.project_configuration.offline_copy_only_aoi or self.project_configuration.offline_copy_only_selected_features if Qgis.QGIS_VERSION_INT < 31601: if not self.offline_editing.convertToOfflineProject( self.export_folder, spatialite_filename, offline_layer_ids, only_selected, self.offline_editing.SpatiaLite): raise Exception( self. tr("Error trying to convert layers to offline layers" )) else: if not self.offline_editing.convertToOfflineProject( self.export_folder, spatialite_filename, offline_layer_ids, only_selected, self.offline_editing.SpatiaLite, None): raise Exception( self. tr("Error trying to convert layers to offline layers" )) # Disable project options that could create problems on a portable # project with offline layers if self.__offline_layers: QgsProject.instance().setEvaluateDefaultValues(False) QgsProject.instance().setAutoTransaction(False) # check if value relations point to offline layers and adjust if necessary for layer in project.mapLayers().values(): if layer.type() == QgsMapLayer.VectorLayer: # Before QGIS 3.14 the custom properties of a layer are not # kept into the new layer during the conversion to offline project # So we try to identify the new created layer by its name and # we set the custom properties again. if not layer.customProperty( 'QFieldSync/cloudPrimaryKeys'): original_layer_name = layer.name().rsplit(' ', 1)[0] stored_fields = original_pk_fields_by_layer_name.get( original_layer_name, None) if stored_fields: layer.setCustomProperty( 'QFieldSync/sourceDataPrimaryKeys', stored_fields) if Qgis.QGIS_VERSION_INT < 31601: for field in layer.fields(): ews = field.editorWidgetSetup() if ews.type() == 'ValueRelation': widget_config = ews.config() online_layer_id = widget_config['Layer'] if project.mapLayer(online_layer_id): continue layer_id = None loose_layer_id = None for offline_layer in project.mapLayers( ).values(): if offline_layer.customProperty( 'remoteSource' ) == original_layer_info[ online_layer_id][0]: # First try strict matching: the offline layer should have a "remoteSource" property layer_id = offline_layer.id() break elif offline_layer.name().startswith( original_layer_info[ online_layer_id][1] + ' '): # If that did not work, go with loose matching # The offline layer should start with the online layer name + a translated version of " (offline)" loose_layer_id = offline_layer.id() widget_config[ 'Layer'] = layer_id or loose_layer_id offline_ews = QgsEditorWidgetSetup( ews.type(), widget_config) layer.setEditorWidgetSetup( layer.fields().indexOf(field.name()), offline_ews) # Now we have a project state which can be saved as offline project QgsProject.instance().write(project_path) finally: # We need to let the app handle events before loading the next project or QGIS will crash with rasters QCoreApplication.processEvents() QgsProject.instance().clear() QCoreApplication.processEvents() QgsProject.instance().read(backup_project_path) QgsProject.instance().setFileName(original_project_path) QApplication.restoreOverrideCursor() self.offline_editing.layerProgressUpdated.disconnect( self.on_offline_editing_next_layer) self.offline_editing.progressModeSet.disconnect( self.on_offline_editing_max_changed) self.offline_editing.progressUpdated.disconnect( self.offline_editing_task_progress) self.total_progress_updated.emit(100, 100, self.tr('Finished'))
def show_warning(self, _, message): # Most messages from the offline editing plugin are not important enough to show in the message bar. # In case we find important ones in the future, we need to filter them. QgsApplication.instance().messageLog().logMessage( message, 'QFieldSync')
def __init__(self, roamapp): super(MainWindow, self).__init__() self.setupUi(self) import roam self.projectwidget.project_base = roamapp.projectsroot QgsApplication.instance().setStyleSheet(roam.roam_style.appstyle()) self.menutoolbar.setStyleSheet(roam.roam_style.menubarstyle()) icon = roam.roam_style.iconsize() self.menutoolbar.setIconSize(QSize(icon, icon)) self.projectupdater = ProjectUpdater(projects_base=roamapp.projectsroot) self.projectupdater.foundProjects.connect(self.projectwidget.show_new_updateable) self.projectupdater.projectUpdateStatus.connect(self.projectwidget.update_project_status) self.projectupdater.projectInstalled.connect(self.projectwidget.project_installed) self.projectwidget.search_for_updates.connect(self.search_for_projects) self.projectwidget.projectUpdate.connect(self.projectupdater.update_project) self.projectwidget.projectInstall.connect(self.projectupdater.install_project) self.project = None self.tracking = GPSLogging(GPS) self.canvas_page.set_gps(GPS, self.tracking) self.canvas = self.canvas_page.canvas roam.defaults.canvas = self.canvas self.bar = roam.messagebaritems.MessageBar(self.centralwidget) self.actionMap.setVisible(False) self.actionLegend.setVisible(False) self.menuGroup = QActionGroup(self) self.menuGroup.setExclusive(True) self.menuGroup.addAction(self.actionMap) self.menuGroup.addAction(self.actionDataEntry) self.menuGroup.addAction(self.actionLegend) self.menuGroup.addAction(self.actionProject) self.menuGroup.addAction(self.actionSync) self.menuGroup.addAction(self.actionSettings) self.menuGroup.addAction(self.actionGPS) self.menuGroup.triggered.connect(self.updatePage) self.projectbuttons = [] self.pluginactions = [] self.actionQuit.triggered.connect(self.exit) self.actionLegend.triggered.connect(self.updatelegend) self.projectwidget.requestOpenProject.connect(self.loadProject) QgsProject.instance().readProject.connect(self._readProject) self.gpswidget.setgps(GPS) self.gpswidget.settracking(self.tracking) self.settings = {} self.actionSettings.toggled.connect(self.settingswidget.populateControls) self.actionSettings.toggled.connect(self.settingswidget.readSettings) self.settingswidget.settingsupdated.connect(self.settingsupdated) self.dataentrywidget = DataEntryWidget(self.canvas, self.bar) self.dataentrywidget.lastwidgetremoved.connect(self.dataentryfinished) self.widgetpage.layout().addWidget(self.dataentrywidget) self.dataentrywidget.rejected.connect(self.formrejected) RoamEvents.featuresaved.connect(self.featureSaved) RoamEvents.helprequest.connect(self.showhelp) RoamEvents.deletefeature.connect(self.delete_feature) def createSpacer(width=0, height=0): widget = QWidget() widget.setMinimumWidth(width) widget.setMinimumHeight(height) return widget gpsspacewidget = createSpacer(30) sidespacewidget = createSpacer(30) sidespacewidget2 = createSpacer(height=20) sidespacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sidespacewidget2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.projectlabel = QLabel("Project: {project}") self.userlabel = QLabel("User: {user}".format(user=getpass.getuser())) self.positionlabel = QLabel('') self.gpslabel = QLabel("GPS: Not active") self.statusbar.addWidget(self.projectlabel) self.statusbar.addWidget(self.userlabel) spacer = createSpacer() spacer2 = createSpacer() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.statusbar.addWidget(spacer) self.statusbar.addWidget(self.positionlabel) self.statusbar.addWidget(spacer2) self.statusbar.addWidget(self.gpslabel) self.scalewidget = QgsScaleComboBox() self.scalebutton = QToolButton() self.scalebutton.setAutoRaise(True) self.scalebutton.setMaximumHeight(self.statusbar.height()) self.scalebutton.pressed.connect(self.selectscale) self.scalebutton.setText("Scale") self.statusbar.addPermanentWidget(self.scalebutton) self.scalelist = BigList(parent=self.canvas, centeronparent=True, showsave=False) self.scalelist.hide() self.scalelist.setlabel("Map Scale") self.scalelist.setmodel(self.scalewidget.model()) self.scalelist.closewidget.connect(self.scalelist.close) self.scalelist.itemselected.connect(self.update_scale_from_item) self.scalelist.itemselected.connect(self.scalelist.close) self.menutoolbar.insertWidget(self.actionQuit, sidespacewidget2) self.spaceraction = self.menutoolbar.insertWidget(self.actionProject, sidespacewidget) self.panels = [] self.centralwidget.layout().addWidget(self.statusbar) self.actionGPSFeature.setProperty('dataentry', True) self.infodock = InfoDock(self.canvas) self.infodock.featureupdated.connect(self.highlightfeature) self.infodock.hide() self.hidedataentry() self.canvas.extentsChanged.connect(self.updatestatuslabel) self.canvas.scaleChanged.connect(self.updatestatuslabel) RoamEvents.openimage.connect(self.openimage) RoamEvents.openurl.connect(self.viewurl) RoamEvents.openfeatureform.connect(self.openForm) RoamEvents.openkeyboard.connect(self.openkeyboard) RoamEvents.editgeometry_complete.connect(self.on_geometryedit) RoamEvents.onShowMessage.connect(self.showUIMessage) RoamEvents.selectionchanged.connect(self.showInfoResults) RoamEvents.show_widget.connect(self.dataentrywidget.add_widget) RoamEvents.closeProject.connect(self.close_project) GPS.gpsposition.connect(self.update_gps_label) GPS.gpsdisconnected.connect(self.gps_disconnected) self.legendpage.showmap.connect(self.showmap) self.currentselection = {}
def enable_busy_cursor(self): """Set the hourglass enabled.""" QgsApplication.instance().setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor))
import os, json from qgis.core import Qgis, QgsMessageLog, QgsApplication from qgis.gui import QgsMessageBar from qgis.PyQt import uic from qgis.PyQt.QtCore import (Qt, QSize, pyqtSlot, QSettings, pyqtSignal) from qgis.PyQt.QtGui import QColor from qgis.PyQt.QtSql import QSqlQuery from qgis.PyQt.QtWidgets import (QDialog, QFileDialog, QMessageBox, QHeaderView, QRadioButton, QAbstractItemView) from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import CustomButtonSetup, CustomFeatureButton FORM_CLASS, _ = uic.loadUiType( os.path.join(os.path.dirname(__file__), 'buttonSetupWidget.ui')) app = QgsApplication.instance() class ButtonSetupWidget(QDialog, FORM_CLASS): def __init__(self, parent=None, buttonSetup=None): """ Class constructor. :param parent: (QtWidgets.*) any widget that 'contains' this tool. :param buttonSetup: (CustomButtonSetup) object that handles all buttons displayed and configured through this GUI. """ super(ButtonSetupWidget, self).__init__(parent) self.setupUi(self) self.messageBar = QgsMessageBar(self) self.setup = CustomButtonSetup() if buttonSetup:
def start_app(cleanup=True): """ Will start a QgsApplication and call all initialization code like registering the providers and other infrastructure. It will not load any plugins. You can always get the reference to a running app by calling `QgsApplication.instance()`. The initialization will only happen once, so it is safe to call this method repeatedly. Parameters ---------- cleanup: Do cleanup on exit. Defaults to true. Returns ------- QgsApplication A QgsApplication singleton """ global QGISAPP try: QGISAPP except NameError: myGuiFlag = True # All test will run qgis in gui mode try: sys.argv except: sys.argv = [''] # In python3 we need to convert to a bytes object (or should # QgsApplication accept a QString instead of const char* ?) try: argvb = list(map(os.fsencode, sys.argv)) except AttributeError: argvb = sys.argv # Note: QGIS_PREFIX_PATH is evaluated in QgsApplication - # no need to mess with it here. QGISAPP = QgsApplication(argvb, myGuiFlag) QGISAPP.initQgis() print(QGISAPP.showSettings()) def debug_log_message(message, tag, level): print('{}({}): {}'.format(tag, level, message)) QgsApplication.instance().messageLog().messageReceived.connect( debug_log_message) if cleanup: import atexit @atexit.register def exitQgis(): QGISAPP.exitQgis() return QGISAPP
def __init__(self, roamapp): super(MainWindow, self).__init__() self.setupUi(self) import roam self.projectwidget.project_base = roamapp.projectsroot QgsApplication.instance().setStyleSheet(roam.roam_style.appstyle()) self.menutoolbar.setStyleSheet(roam.roam_style.menubarstyle()) icon = roam.roam_style.iconsize() self.menutoolbar.setIconSize(QSize(icon, icon)) self.projectupdater = ProjectUpdater(projects_base=roamapp.projectsroot) self.projectupdater.foundProjects.connect(self.projectwidget.show_new_updateable) self.projectupdater.projectUpdateStatus.connect(self.projectwidget.update_project_status) self.projectupdater.projectInstalled.connect(self.projectwidget.project_installed) self.projectwidget.search_for_updates.connect(self.search_for_projects) self.projectwidget.projectUpdate.connect(self.projectupdater.update_project) self.projectwidget.projectInstall.connect(self.projectupdater.install_project) self.project = None self.tracking = GPSLogging(GPS) self.canvas_page.set_gps(GPS, self.tracking) self.canvas = self.canvas_page.canvas roam.defaults.canvas = self.canvas self.bar = roam.messagebaritems.MessageBar(self.centralwidget) self.actionMap.setVisible(False) self.actionLegend.setVisible(False) self.menuGroup = QActionGroup(self) self.menuGroup.setExclusive(True) self.menuGroup.addAction(self.actionMap) self.menuGroup.addAction(self.actionDataEntry) self.menuGroup.addAction(self.actionLegend) self.menuGroup.addAction(self.actionProject) self.menuGroup.addAction(self.actionSync) self.menuGroup.addAction(self.actionSettings) self.menuGroup.addAction(self.actionGPS) self.menuGroup.triggered.connect(self.updatePage) self.projectbuttons = [] self.pluginactions = [] self.actionQuit.triggered.connect(self.exit) self.actionLegend.triggered.connect(self.updatelegend) self.projectwidget.requestOpenProject.connect(self.loadProject) QgsProject.instance().readProject.connect(self._readProject) self.gpswidget.setgps(GPS) self.gpswidget.settracking(self.tracking) self.settings = {} self.actionSettings.toggled.connect(self.settingswidget.populateControls) self.actionSettings.toggled.connect(self.settingswidget.readSettings) self.settingswidget.settingsupdated.connect(self.settingsupdated) self.dataentrywidget = DataEntryWidget(self.canvas, self.bar) self.dataentrywidget.lastwidgetremoved.connect(self.dataentryfinished) self.widgetpage.layout().addWidget(self.dataentrywidget) self.dataentrywidget.rejected.connect(self.formrejected) RoamEvents.featuresaved.connect(self.featureSaved) RoamEvents.helprequest.connect(self.showhelp) RoamEvents.deletefeature.connect(self.delete_feature) def createSpacer(width=0, height=0): widget = QWidget() widget.setMinimumWidth(width) widget.setMinimumHeight(height) return widget gpsspacewidget = createSpacer(30) sidespacewidget = createSpacer(30) sidespacewidget2 = createSpacer(height=20) sidespacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sidespacewidget2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.projectlabel = QLabel("Project: {project}") self.userlabel = QLabel("User: {user}".format(user=getpass.getuser())) self.positionlabel = QLabel('') self.gpslabel = QLabel("GPS: Not active") icon = QIcon(":/icons/info") infobutton = QToolButton() infobutton.setAutoRaise(True) infobutton.setMaximumHeight(self.statusbar.height()) infobutton.setIcon(icon) # self.statusbar.addWidget(infobutton) self.snappingbutton = QToolButton() self.snappingbutton.setText("Snapping: On") self.snappingbutton.setAutoRaise(True) self.snappingbutton.pressed.connect(self.toggle_snapping) self.statusbar.addWidget(self.snappingbutton) # self.statusbar.addWidget(self.projectlabel) # self.statusbar.addWidget(self.userlabel) spacer = createSpacer() spacer2 = createSpacer() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) # self.statusbar.addWidget(spacer) # self.statusbar.addWidget(self.positionlabel) self.statusbar.addWidget(spacer2) self.statusbar.addWidget(self.gpslabel) self.scalewidget = QgsScaleComboBox() self.scalebutton = QToolButton() self.scalebutton.setAutoRaise(True) self.scalebutton.setMaximumHeight(self.statusbar.height()) self.scalebutton.pressed.connect(self.selectscale) self.scalebutton.setText("Scale") self.statusbar.addPermanentWidget(self.scalebutton) self.scalelist = BigList(parent=self.canvas, centeronparent=True, showsave=False) self.scalelist.hide() self.scalelist.setlabel("Map Scale") self.scalelist.setmodel(self.scalewidget.model()) self.scalelist.closewidget.connect(self.scalelist.close) self.scalelist.itemselected.connect(self.update_scale_from_item) self.scalelist.itemselected.connect(self.scalelist.close) self.menutoolbar.insertWidget(self.actionQuit, sidespacewidget2) self.spaceraction = self.menutoolbar.insertWidget(self.actionProject, sidespacewidget) self.panels = [] self.centralwidget.layout().addWidget(self.statusbar) self.actionGPSFeature.setProperty('dataentry', True) self.infodock = InfoDock(self.canvas) self.infodock.featureupdated.connect(self.highlightfeature) self.infodock.hide() self.hidedataentry() self.canvas.extentsChanged.connect(self.updatestatuslabel) self.canvas.scaleChanged.connect(self.updatestatuslabel) RoamEvents.openimage.connect(self.openimage) RoamEvents.openurl.connect(self.viewurl) RoamEvents.openfeatureform.connect(self.openForm) RoamEvents.openkeyboard.connect(self.openkeyboard) RoamEvents.editgeometry_complete.connect(self.on_geometryedit) RoamEvents.onShowMessage.connect(self.showUIMessage) RoamEvents.selectionchanged.connect(self.showInfoResults) RoamEvents.show_widget.connect(self.dataentrywidget.add_widget) RoamEvents.closeProject.connect(self.close_project) RoamEvents.snappingChanged.connect(self.snapping_changed) GPS.gpsposition.connect(self.update_gps_label) GPS.gpsdisconnected.connect(self.gps_disconnected) self.legendpage.showmap.connect(self.showmap) self.currentselection = {}
def qgis_excepthook(type, value, tb): # detect if running in the main thread in_main_thread = QThread.currentThread() == QgsApplication.instance().thread() # only use messagebar if running in main thread - otherwise it will crash! showException(type, value, tb, None, messagebar=in_main_thread)
def fetch(self): """ Fetch Occurrence records for selected taxon. """ QgsApplication.instance().setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor)) QgsMessageLog.logMessage('Fetching occurrences', 'SpeciesExplorer', 0) name = self.results_list.selectedItems()[0].text() end_of_records = False offset = 0 layer = QgsVectorLayer('Point', name, 'memory') layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) provider = layer.dataProvider() counter = 0 while not end_of_records: url = ('https://api.gbif.org/v1/occurrence/search?' 'scientificName=%s&offset=%i' % (name, offset)) offset += 100 result = gbif_GET(url, None) count = int(result['count']) end_of_records = result['endOfRecords'] records = result['results'] QgsMessageLog.logMessage( 'Fetching record %s of %s occurrences' % (offset, count), 'SpeciesExplorer', 0) # Will populate this in create_fields call if len(records) == 0: QgsMessageLog.logMessage('No records found', 'SpeciesExplorer', 0) QMessageBox.information(self, 'Species Explorer', 'No records found for %s' % name) return field_lookups = self.create_fields(layer, records[0]) QgsMessageLog.logMessage('Field lookup: %s' % field_lookups, 'SpeciesExplorer', 0) for record in records: QgsMessageLog.logMessage('Record: %s' % record, 'SpeciesExplorer', 0) if ('decimalLongitude' not in record or 'decimalLatitude' not in record): continue feature = QgsFeature() feature.setGeometry( QgsGeometry.fromPointXY( QgsPointXY(record['decimalLongitude'], record['decimalLatitude']))) attributes = [counter] for key in field_lookups: try: attributes.append(record[key]) except KeyError: # just append an empty item to make sure the list # size is correct attributes.append('') feature.setAttributes(attributes) provider.addFeatures([feature]) counter += 1 if offset > count: end_of_records = True QgsMessageLog.logMessage('End of records: %s' % end_of_records, 'SpeciesExplorer', 0) layer.commitChanges() QgsProject.instance().addMapLayer(layer) # recursively walk back the cursor to a pointer while QgsApplication.instance().overrideCursor() is not None and \ QgsApplication.instance().overrideCursor().shape() == \ QtCore.Qt.WaitCursor: QgsApplication.instance().restoreOverrideCursor()
def runAndWait(self, commandline): '''Subprocess pdal pipeline waiting it's end. Returns stdout/error log of execution. The execution is not blocking. ''' executionLog = '' QgsMessageLog.logMessage(" ".join(commandline), 'PDALTools', Qgis.Info) self.feedback.pushConsoleInfo(" ".join(commandline)) # !Note! subprocess call is similar as in Grass7Utils.executeGrass # For MS-Windows, we need to hide the console window. si = None if isWindows(): si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW si.wShowWindow = subprocess.SW_HIDE proc = subprocess.Popen(commandline, shell=True if isMac() else False, stdout=subprocess.PIPE, stdin=open(os.devnull), stderr=subprocess.STDOUT, universal_newlines=True, startupinfo=si) nbsr = NonBlockingStreamReader(proc.stdout) while proc.poll() is None: if self.feedback.isCanceled(): proc.kill() out = nbsr.readline(self.readlineTimeout) if out: QgsMessageLog.logMessage(out, 'PDALTools', Qgis.Info) self.feedback.pushConsoleInfo(out) executionLog += out # allow the dialog to be responsive allowing accept cancel process QgsApplication.instance().processEvents() # proc is terminated but could have more messages in stdout to read out = nbsr.readline(self.readlineTimeout) while out is not None: QgsMessageLog.logMessage(out, 'PDALTools', Qgis.Info) self.feedback.pushConsoleInfo(out) executionLog += out out = nbsr.readline(self.readlineTimeout) # check return code depending on platform if isWindows(): pass else: # it is a unix env if proc.returncode == -(signal.SIGKILL.value): raise QgsProcessingException( "Command {} has been cancelled with signal: {}".format( commandline, proc.returncode)) # check generic return code if proc.returncode != 0: raise QgsProcessingException( "Failed execution of command {} with return code: {}".format( commandline, proc.returncode)) # return only pdal log return executionLog
def enable_busy_cursor(self): """Set the hourglass enabled.""" QgsApplication.instance().setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor) )
def accept(self): description = str(self.nameTextBox.text()) if description.strip() == '': QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Invalid parameter name')) return if self.param is None: validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeName = ''.join(c for c in description if c in validChars) name = safeName.lower() i = 2 while self.alg.parameterDefinition(name): name = safeName.lower() + str(i) i += 1 else: name = self.param.name() if (self.paramType == parameters.PARAMETER_BOOLEAN or isinstance(self.param, QgsProcessingParameterBoolean)): self.param = QgsProcessingParameterBoolean(name, description, self.state.isChecked()) elif (self.paramType == parameters.PARAMETER_TABLE_FIELD or isinstance(self.param, QgsProcessingParameterField)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() datatype = self.datatypeCombo.currentData() default = self.defaultTextBox.text() if not default: default = None self.param = QgsProcessingParameterField(name, description, defaultValue=default, parentLayerParameterName=parent, type=datatype, allowMultiple=self.multipleCheck.isChecked()) elif (self.paramType == parameters.PARAMETER_BAND or isinstance(self.param, QgsProcessingParameterBand)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() self.param = QgsProcessingParameterBand(name, description, None, parent) elif (self.paramType == parameters.PARAMETER_MAP_LAYER or isinstance(self.param, QgsProcessingParameterMapLayer)): self.param = QgsProcessingParameterMapLayer( name, description) elif (self.paramType == parameters.PARAMETER_RASTER or isinstance(self.param, QgsProcessingParameterRasterLayer)): self.param = QgsProcessingParameterRasterLayer( name, description) elif (self.paramType == parameters.PARAMETER_TABLE or isinstance(self.param, QgsProcessingParameterVectorLayer)): self.param = QgsProcessingParameterVectorLayer( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_VECTOR or isinstance(self.param, QgsProcessingParameterFeatureSource)): self.param = QgsProcessingParameterFeatureSource( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_MULTIPLE or isinstance(self.param, QgsProcessingParameterMultipleLayers)): self.param = QgsProcessingParameterMultipleLayers( name, description, self.datatypeCombo.currentData()) elif (self.paramType == parameters.PARAMETER_NUMBER or isinstance(self.param, QgsProcessingParameterNumber)): try: self.param = QgsProcessingParameterNumber(name, description, QgsProcessingParameterNumber.Double, self.defaultTextBox.text()) vmin = self.minTextBox.text().strip() if not vmin == '': self.param.setMinimum(float(vmin)) vmax = self.maxTextBox.text().strip() if not vmax == '': self.param.setMaximum(float(vmax)) except: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return elif (self.paramType == parameters.PARAMETER_EXPRESSION or isinstance(self.param, QgsProcessingParameterExpression)): parent = self.parentCombo.currentData() self.param = QgsProcessingParameterExpression(name, description, str(self.defaultEdit.expression()), parent) elif (self.paramType == parameters.PARAMETER_STRING or isinstance(self.param, QgsProcessingParameterString)): self.param = QgsProcessingParameterString(name, description, str(self.defaultTextBox.text())) elif (self.paramType == parameters.PARAMETER_EXTENT or isinstance(self.param, QgsProcessingParameterExtent)): self.param = QgsProcessingParameterExtent(name, description) elif (self.paramType == parameters.PARAMETER_FILE or isinstance(self.param, QgsProcessingParameterFile)): isFolder = self.fileFolderCombo.currentIndex() == 1 self.param = QgsProcessingParameterFile(name, description, QgsProcessingParameterFile.Folder if isFolder else QgsProcessingParameterFile.File) elif (self.paramType == parameters.PARAMETER_POINT or isinstance(self.param, QgsProcessingParameterPoint)): self.param = QgsProcessingParameterPoint(name, description, str(self.defaultTextBox.text())) elif (self.paramType == parameters.PARAMETER_CRS or isinstance(self.param, QgsProcessingParameterCrs)): self.param = QgsProcessingParameterCrs(name, description, self.selector.crs().authid()) else: if self.paramType: typeId = self.paramType else: typeId = self.param.type() paramTypeDef = QgsApplication.instance().processingRegistry().parameterType(typeId) if not paramTypeDef: msg = self.tr('The parameter `{}` is not registered, are you missing a required plugin?'.format(typeId)) raise UndefinedParameterException(msg) self.param = paramTypeDef.create(name) self.param.setDescription(name) self.param.setMetadata(paramTypeDef.metadata()) if not self.requiredCheck.isChecked(): self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagOptional) settings = QgsSettings() settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.accept(self)
def setUpClass(cls): """Run before all tests""" QCoreApplication.setOrganizationName("QGIS_Test") QCoreApplication.setOrganizationDomain( "QGIS_TestPyQgsPackageLayers.com") QCoreApplication.setApplicationName("QGIS_TestPyQgsPackageLayers") QgsSettings().clear() Processing.initialize() QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms()) cls.registry = QgsApplication.instance().processingRegistry() cls.tmp_dir = QTemporaryDir() cls.temp_path = os.path.join(cls.tmp_dir.path(), 'package_layers.gpkg') cls.temp_export_path = os.path.join(cls.tmp_dir.path(), 'package_layers_export.gpkg') # Create test DB """ Test data: Region 1 Province 1 City 1 City 2 Province 2 City 3 Region 2 Province 3 Province 4 City 4 """ ds = ogr.GetDriverByName('GPKG').CreateDataSource(cls.temp_path) lyr = ds.CreateLayer('region', geom_type=ogr.wkbNone) lyr.CreateField(ogr.FieldDefn('name', ogr.OFTString)) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'region one' lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'region two' lyr.CreateFeature(f) lyr = ds.CreateLayer('province', geom_type=ogr.wkbNone) lyr.CreateField(ogr.FieldDefn('name', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('region', ogr.OFTInteger)) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'province one' f['region'] = 1 lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'province two' f['region'] = 1 lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'province three' f['region'] = 2 lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'province four' f['region'] = 2 lyr.CreateFeature(f) lyr = ds.CreateLayer('city', geom_type=ogr.wkbNone) lyr.CreateField(ogr.FieldDefn('name', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('province', ogr.OFTInteger)) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'city one' f['province'] = 1 lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'city two' f['province'] = 1 lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'city three' f['province'] = 2 lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f['name'] = 'city four' f['province'] = 4 lyr.CreateFeature(f) f = None ds = None region = QgsVectorLayer(cls.temp_path + '|layername=region', 'region') province = QgsVectorLayer(cls.temp_path + '|layername=province', 'province') city = QgsVectorLayer(cls.temp_path + '|layername=city', 'city') QgsProject.instance().addMapLayers([region, province, city]) relMgr = QgsProject.instance().relationManager() rel = QgsRelation() rel.setId('rel1') rel.setName('province -> region') rel.setReferencingLayer(province.id()) rel.setReferencedLayer(region.id()) rel.addFieldPair('region', 'fid') assert rel.isValid() relMgr.addRelation(rel) rel = QgsRelation() rel.setId('rel2') rel.setName('city -> province') rel.setReferencingLayer(city.id()) rel.setReferencedLayer(province.id()) rel.addFieldPair('province', 'fid') assert rel.isValid() relMgr.addRelation(rel)
def _init_qgis_app(): """Initialize a QGIS application and set signals to print debug messages.""" QgsApplication.initQgis() QgsApplication.instance().messageLog().messageReceived.connect( _debug_log_message)
def calculate(self): ''' Prepare environment to run the alg and run it. After run, merge produced data basing on plugin configuration. Before calculation a parametere validation will be executed ''' # perform validation if not self.gui.validate(): return else: # notify successful validation message = self.tr( "QTraffic: Parameters validation passed successfully") iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS) # set number of classes in the project config (that is the temporary one... but equal to the official one) fleetDistributionRoadTypes = self.gui.getRoadTypes() self.project.setValue('Processing.Parameters/maximum_type', len(fleetDistributionRoadTypes)) self.project.sync() # create the algorithm self.alg = Algorithm() roadLayer = self.gui.getRoadLayer() # prepare layer where to add result addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if addToInputLayer: self.outLayer = roadLayer self.outLayerId = self.outLayer.id() else: # if layer is present... remove it # out layer would not be the same of input road layer... in thi scase don't remove it if self.outLayer and self.outLayer.isValid(): # to be sure, remove only if roadLayer and outLayer are different if self.outLayer.publicSource() != roadLayer.publicSource(): self.outLayerRemoved = False QgsMapLayerRegistry.instance().layerRemoved.connect( self.checkOutLayerRemoved) QgsMapLayerRegistry.instance().removeMapLayer( self.outLayer.id()) # remove file when it has been removed from qgis while not self.outLayerRemoved: sleep(0.1) QgsMapLayerRegistry.instance().layerRemoved.disconnect( self.checkOutLayerRemoved) # reinit outLayer variables # If not, under windws remain a locking of the related file creating # an error during QgsVectorFileWriter.deleteShapeFile self.outLayer = None self.outLayerId = None if os.path.exists(newOutputLayer): if not QgsVectorFileWriter.deleteShapeFile( newOutputLayer): message = self.tr( "Error removing shape: {}".format( newOutputLayer)) iface.messageBar().pushMessage( message, QgsMessageBar.CRITICAL) return # copy input layer to the new one writeError = QgsVectorFileWriter.writeAsVectorFormat( roadLayer, newOutputLayer, 'utf-8', roadLayer.crs()) if writeError != QgsVectorFileWriter.NoError: message = self.tr( 'Error writing vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # load the layer newLayerName = os.path.splitext( os.path.basename(newOutputLayer))[0] self.outLayer = QgsVectorLayer(newOutputLayer, newLayerName, 'ogr') if not self.outLayer.isValid(): message = self.tr( 'Error loading vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return self.outLayerId = self.outLayer.id() # prepare environment try: self.alg.setProject(self.project) self.alg.setLayer(roadLayer) self.alg.initConfig() self.alg.prepareRun() except Exception as ex: traceback.print_exc() message = self.tr( 'Error preparing running contex for the algoritm: %s' % str(ex)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # run the self.alg self.thread = QtCore.QThread(self) self.thread.started.connect(self.alg.run) self.thread.finished.connect(self.threadCleanup) self.thread.terminated.connect(self.threadCleanup) self.alg.moveToThread(self.thread) self.alg.started.connect(self.manageStarted) self.alg.progress.connect(self.manageProgress) self.alg.message.connect(self.manageMessage) self.alg.error.connect(self.manageError) self.alg.finished.connect(self.manageFinished) # set wait cursor and start QgsApplication.instance().setOverrideCursor(QtCore.Qt.WaitCursor) self.thread.start()
def disable_busy_cursor(self): """Disable the hourglass cursor.""" QgsApplication.instance().restoreOverrideCursor()
def layers(self, filter_layer_list=[]): ignored_layers = self.get_ignored_layers() tables_info = self.get_tables_info() layers = list() db_factory = self.db_simple_factory.create_factory(self.tool) layer_uri = db_factory.get_layer_uri(self.uri) layer_uri.pg_estimated_metadata = self.pg_estimated_metadata for record in tables_info: # When in PostGIS mode, leaving schema blank should load tables from # all schemas, except the ignored ones if self.schema: if record['schemaname'] != self.schema: continue if ignored_layers and record['tablename'] in ignored_layers: continue if filter_layer_list and record[ 'tablename'] not in filter_layer_list: continue is_domain = record['kind_settings'] == 'ENUM' or record[ 'kind_settings'] == 'CATALOGUE' if 'kind_settings' in record else False is_attribute = bool(record['attribute_name'] ) if 'attribute_name' in record else False is_structure = record[ 'kind_settings'] == 'STRUCTURE' if 'kind_settings' in record else False is_nmrel = record[ 'kind_settings'] == 'ASSOCIATION' if 'kind_settings' in record else False alias = record['table_alias'] if 'table_alias' in record else None if not alias: if is_domain and is_attribute: short_name = record['ili_name'].split( '.')[-2] + '_' + record['ili_name'].split( '.')[-1] if 'ili_name' in record else '' else: short_name = record['ili_name'].split( '.')[-1] if 'ili_name' in record else '' alias = short_name display_expression = '' if 'ili_name' in record: meta_attrs = self.get_meta_attrs(record['ili_name']) for attr_record in meta_attrs: if attr_record['attr_name'] == 'dispExpression': display_expression = attr_record['attr_value'] coord_decimals = record[ 'coord_decimals'] if 'coord_decimals' in record else None coordinate_precision = None if coord_decimals: coordinate_precision = 1 / (10**coord_decimals) layer = Layer( layer_uri.provider, layer_uri.get_data_source_uri(record), record['tablename'], record['srid'], record['extent'] if 'extent' in record else None, record['geometry_column'], QgsWkbTypes.parseType(record['type']) or QgsWkbTypes.Unknown, alias, is_domain, is_structure, is_nmrel, display_expression, coordinate_precision) # Configure fields for current table fields_info = self.get_fields_info(record['tablename']) min_max_info = self.get_min_max_info(record['tablename']) value_map_info = self.get_value_map_info(record['tablename']) re_iliname = re.compile(r'.*\.(.*)$') for fielddef in fields_info: column_name = fielddef['column_name'] fully_qualified_name = fielddef[ 'fully_qualified_name'] if 'fully_qualified_name' in fielddef else None m = re_iliname.match( fully_qualified_name) if fully_qualified_name else None alias = None if 'column_alias' in fielddef: alias = fielddef['column_alias'] if m and not alias: alias = m.group(1) field = Field(column_name) field.alias = alias # Should we hide the field? hide_attribute = False if 'fully_qualified_name' in fielddef: fully_qualified_name = fielddef['fully_qualified_name'] if fully_qualified_name: meta_attrs_column = self.get_meta_attrs( fully_qualified_name) for attr_record in meta_attrs_column: if attr_record['attr_name'] == 'hidden': if attr_record['attr_value'] == 'True': hide_attribute = True break if column_name in IGNORED_FIELDNAMES: hide_attribute = True field.hidden = hide_attribute if column_name in READONLY_FIELDNAMES: field.read_only = True if column_name in min_max_info: field.widget = 'Range' field.widget_config['Min'] = min_max_info[column_name][0] field.widget_config['Max'] = min_max_info[column_name][1] if 'numeric_scale' in fielddef: field.widget_config['Step'] = pow( 10, -1 * fielddef['numeric_scale']) # field.widget_config['Suffix'] = fielddef['unit'] if 'unit' in fielddef else '' if 'unit' in fielddef and fielddef['unit'] is not None: field.alias = '{alias} [{unit}]'.format( alias=alias or column_name, unit=fielddef['unit']) if column_name in value_map_info: field.widget = 'ValueMap' field.widget_config['map'] = [{ val: val } for val in value_map_info[column_name]] if 'texttype' in fielddef and fielddef['texttype'] == 'MTEXT': field.widget = 'TextEdit' field.widget_config['IsMultiline'] = True data_type = self._db_connector.map_data_types( fielddef['data_type']) if 'time' in data_type or 'date' in data_type: field.widget = 'DateTime' field.widget_config['calendar_popup'] = True dateFormat = QLocale( QgsApplication.instance().locale()).dateFormat( QLocale.ShortFormat) timeFormat = QLocale( QgsApplication.instance().locale()).timeFormat( QLocale.ShortFormat) dateTimeFormat = QLocale( QgsApplication.instance().locale()).dateTimeFormat( QLocale.ShortFormat) if data_type == self._db_connector.QGIS_TIME_TYPE: field.widget_config['display_format'] = timeFormat elif data_type == self._db_connector.QGIS_DATE_TIME_TYPE: field.widget_config['display_format'] = dateTimeFormat elif data_type == self._db_connector.QGIS_DATE_TYPE: field.widget_config['display_format'] = dateFormat db_factory.customize_widget_editor(field, data_type) if 'default_value_expression' in fielddef: field.default_value_expression = fielddef[ 'default_value_expression'] if 'enum_domain' in fielddef and fielddef['enum_domain']: field.enum_domain = fielddef['enum_domain'] layer.fields.append(field) layers.append(layer) self.print_messages() return layers
def test_iface(self): iface = self.iface assert QgsApplication.instance() is not None
def get_qgis_app(cleanup=True): """ Start one QGIS application to test against. :returns: Handle to QGIS app, canvas, iface and parent. If there are any errors the tuple members will be returned as None. :rtype: (QgsApplication, CANVAS, IFACE, PARENT) If QGIS is already running the handle to that app will be returned. """ global QGIS_APP, PARENT, IFACE, CANVAS # pylint: disable=W0603 if iface: QGIS_APP = QgsApplication CANVAS = iface.mapCanvas() PARENT = iface.mainWindow() IFACE = iface return QGIS_APP, CANVAS, IFACE, PARENT global QGISAPP # pylint: disable=global-variable-undefined try: QGISAPP except NameError: myGuiFlag = True # All test will run qgis in gui mode # In python3 we need to convert to a bytes object (or should # QgsApplication accept a QString instead of const char* ?) try: argvb = list(map(os.fsencode, sys.argv)) except AttributeError: argvb = sys.argv # Note: QGIS_PREFIX_PATH is evaluated in QgsApplication - # no need to mess with it here. QGISAPP = QgsApplication(argvb, myGuiFlag) QGISAPP.initQgis() s = QGISAPP.showSettings() LOGGER.debug(s) def debug_log_message(message, tag, level): """ Prints a debug message to a log :param message: message to print :param tag: log tag :param level: log message level (severity) :return: """ print('{}({}): {}'.format(tag, level, message)) QgsApplication.instance().messageLog().messageReceived.connect( debug_log_message) if cleanup: @atexit.register def exitQgis(): # pylint: disable=unused-variable """ Gracefully closes the QgsApplication instance """ try: QGISAPP.exitQgis() # pylint: disable=used-before-assignment QGISAPP = None # pylint: disable=redefined-outer-name except NameError: pass if PARENT is None: # noinspection PyPep8Naming PARENT = QWidget() if CANVAS is None: # noinspection PyPep8Naming CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QSize(400, 400)) if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface # noinspection PyPep8Naming IFACE = QgisInterface(CANVAS) return QGISAPP, CANVAS, IFACE, PARENT
def accept(self): description = self.nameTextBox.text() if description.strip() == '': QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Invalid parameter name')) return if self.param is None: validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeName = ''.join(c for c in description if c in validChars) name = safeName.lower() i = 2 while self.alg.parameterDefinition(name): name = safeName.lower() + str(i) i += 1 else: name = self.param.name() if (self.paramType == parameters.PARAMETER_TABLE_FIELD or isinstance(self.param, QgsProcessingParameterField)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() datatype = self.datatypeCombo.currentData() default = self.defaultTextBox.text() if not default: default = None self.param = QgsProcessingParameterField(name, description, defaultValue=default, parentLayerParameterName=parent, type=datatype, allowMultiple=self.multipleCheck.isChecked()) elif (self.paramType == parameters.PARAMETER_BAND or isinstance(self.param, QgsProcessingParameterBand)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() self.param = QgsProcessingParameterBand(name, description, None, parent) elif (self.paramType == parameters.PARAMETER_MAP_LAYER or isinstance(self.param, QgsProcessingParameterMapLayer)): self.param = QgsProcessingParameterMapLayer( name, description, types=[self.datatypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_RASTER or isinstance(self.param, QgsProcessingParameterRasterLayer)): self.param = QgsProcessingParameterRasterLayer( name, description) elif (self.paramType == parameters.PARAMETER_TABLE or isinstance(self.param, QgsProcessingParameterVectorLayer)): self.param = QgsProcessingParameterVectorLayer( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_VECTOR or isinstance(self.param, QgsProcessingParameterFeatureSource)): self.param = QgsProcessingParameterFeatureSource( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_MULTIPLE or isinstance(self.param, QgsProcessingParameterMultipleLayers)): self.param = QgsProcessingParameterMultipleLayers( name, description, self.datatypeCombo.currentData()) elif (self.paramType == parameters.PARAMETER_DISTANCE or isinstance(self.param, QgsProcessingParameterDistance)): self.param = QgsProcessingParameterDistance(name, description, self.defaultTextBox.text()) try: vmin = self.minTextBox.text().strip() if not vmin == '': self.param.setMinimum(float(vmin)) vmax = self.maxTextBox.text().strip() if not vmax == '': self.param.setMaximum(float(vmax)) except: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() if parent: self.param.setParentParameterName(parent) elif (self.paramType == parameters.PARAMETER_SCALE or isinstance(self.param, QgsProcessingParameterScale)): self.param = QgsProcessingParameterScale(name, description, self.defaultTextBox.text()) elif (self.paramType == parameters.PARAMETER_NUMBER or isinstance(self.param, QgsProcessingParameterNumber)): type = self.type_combo.currentData() self.param = QgsProcessingParameterNumber(name, description, type, self.defaultTextBox.text()) try: vmin = self.minTextBox.text().strip() if not vmin == '': self.param.setMinimum(float(vmin)) vmax = self.maxTextBox.text().strip() if not vmax == '': self.param.setMaximum(float(vmax)) except: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return elif (self.paramType == parameters.PARAMETER_ENUM or isinstance(self.param, QgsProcessingParameterEnum)): self.param = QgsProcessingParameterEnum(name, description, self.widget.options(), self.widget.allowMultiple(), self.widget.defaultOptions()) elif (self.paramType == parameters.PARAMETER_MATRIX or isinstance(self.param, QgsProcessingParameterMatrix)): self.param = QgsProcessingParameterMatrix(name, description, hasFixedNumberRows=self.widget.fixedRows(), headers=self.widget.headers(), defaultValue=self.widget.value()) # Destination parameter elif (isinstance(self.param, QgsProcessingParameterFeatureSink)): self.param = QgsProcessingParameterFeatureSink( name=name, description=self.param.description(), type=self.param.dataType(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFileDestination)): self.param = QgsProcessingParameterFileDestination( name=name, description=self.param.description(), fileFilter=self.param.fileFilter(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFolderDestination)): self.param = QgsProcessingParameterFolderDestination( name=name, description=self.param.description(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterRasterDestination)): self.param = QgsProcessingParameterRasterDestination( name=name, description=self.param.description(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterVectorDestination)): self.param = QgsProcessingParameterVectorDestination( name=name, description=self.param.description(), type=self.param.dataType(), defaultValue=self.defaultWidget.value()) else: if self.paramType: typeId = self.paramType else: typeId = self.param.type() paramTypeDef = QgsApplication.instance().processingRegistry().parameterType(typeId) if not paramTypeDef: msg = self.tr('The parameter `{}` is not registered, are you missing a required plugin?'.format(typeId)) raise UndefinedParameterException(msg) self.param = paramTypeDef.create(name) self.param.setDescription(description) self.param.setMetadata(paramTypeDef.metadata()) if not self.requiredCheck.isChecked(): self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagOptional) else: self.param.setFlags(self.param.flags() & ~QgsProcessingParameterDefinition.FlagOptional) if self.advancedCheck.isChecked(): self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) else: self.param.setFlags(self.param.flags() & ~QgsProcessingParameterDefinition.FlagAdvanced) settings = QgsSettings() settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.accept(self)
def request(self, url, method="GET", body=None, headers=None, redirections=DEFAULT_MAX_REDIRECTS, connection_type=None, blocking=True): """ Make a network request by calling QgsNetworkAccessManager. redirections argument is ignored and is here only for httplib2 compatibility. """ self.msg_log(u'http_call request: {0}'.format(url)) self.blocking_mode = blocking req = QNetworkRequest() # Avoid double quoting form QUrl url = urllib.parse.unquote(url) req.setUrl(QUrl(url)) if headers is not None: # This fixes a wierd error with compressed content not being correctly # inflated. # If you set the header on the QNetworkRequest you are basically telling # QNetworkAccessManager "I know what I'm doing, please don't do any content # encoding processing". # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1 try: del headers['Accept-Encoding'] except KeyError: pass for k, v in list(headers.items()): self.msg_log("Setting header %s to %s" % (k, v)) req.setRawHeader(k, v) if self.authid: self.msg_log("Update request w/ authid: {0}".format(self.authid)) #QgsAuthManager.instance().updateNetworkRequest(req, self.authid) QgsApplication.instance().authManager().updateNetworkRequest(req, self.authid) if self.reply is not None and self.reply.isRunning(): self.reply.close() if method.lower() == 'delete': func = getattr(QgsNetworkAccessManager.instance(), 'deleteResource') else: func = getattr(QgsNetworkAccessManager.instance(), method.lower()) # Calling the server ... # Let's log the whole call for debugging purposes: self.msg_log("Sending %s request to %s" % (method.upper(), req.url().toString())) self.on_abort = False headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()} for k, v in list(headers.items()): self.msg_log("%s: %s" % (k, v)) if method.lower() in ['post', 'put']: #if isinstance(body, file): # body = body.read() self.reply = func(req, body) else: self.reply = func(req) if self.authid: self.msg_log("Update reply w/ authid: {0}".format(self.authid)) #QgsAuthManager.instance().updateNetworkReply(self.reply, self.authid) QgsApplication.instance().authManager().updateNetworkReply(self.reply, self.authid) # necessary to trap local timout manage by QgsNetworkAccessManager # calling QgsNetworkAccessManager::abortRequest QgsNetworkAccessManager.instance().requestTimedOut.connect(self.requestTimedOut) self.reply.sslErrors.connect(self.sslErrors) self.reply.finished.connect(self.replyFinished) self.reply.downloadProgress.connect(self.downloadProgress) # block if blocking mode otherwise return immediatly # it's up to the caller to manage listeners in case of no blocking mode if not self.blocking_mode: return (None, None) # Call and block self.el = QEventLoop() self.reply.finished.connect(self.el.quit) # Catch all exceptions (and clean up requests) try: self.el.exec_(QEventLoop.ExcludeUserInputEvents) except Exception as e: self.msg_log('EEEEEEEEEEEEEEEEEEEEEEEEEE {}'.format(self.http_call_result)) raise e if self.reply: self.reply.finished.disconnect(self.el.quit) # emit exception in case of error if not self.http_call_result.ok: self.msg_log('xxxx {}'.format(self.http_call_result)) self.msg_log('xxxx {}'.format(self.http_call_result.exception)) self.msg_log('xxxx {}'.format(self.http_call_result.status)) self.msg_log('xxxx {}'.format(self.http_call_result.status_code)) self.msg_log('xxxx {}'.format(self.exception_class)) self.msg_log('xxxx {}'.format(self.http_call_result.reason)) if self.http_call_result.exception and not self.exception_class: raise self.http_call_result.exception else: raise self.exception_class(self.http_call_result.reason) self.msg_log('OKOK {}'.format(self.http_call_result.ok)) return (self.http_call_result, self.http_call_result.content)
def unload(self): super().unload() QgsApplication.instance().processingRegistry().removeParameterType(self.parameterTypeFieldsMapping)
def initGui(self): # port old log, ONCE ONLY! settings = QgsSettings() if not settings.value("/Processing/hasPortedOldLog", False, bool): processing_history_provider = QgsGui.historyProviderRegistry( ).providerById('processing') if processing_history_provider: processing_history_provider.portOldLog() settings.setValue("/Processing/hasPortedOldLog", True) self.options_factory = ProcessingOptionsFactory() self.options_factory.setTitle(self.tr('Processing')) iface.registerOptionsWidgetFactory(self.options_factory) self.drop_handler = ProcessingDropHandler() iface.registerCustomDropHandler(self.drop_handler) self.item_provider = ProcessingDataItemProvider() QgsApplication.dataItemProviderRegistry().addProvider( self.item_provider) self.locator_filter = AlgorithmLocatorFilter() iface.registerLocatorFilter(self.locator_filter) # Invalidate the locator filter for in-place when active layer changes iface.currentLayerChanged.connect( lambda _: self.iface.invalidateLocatorResults()) self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter() iface.registerLocatorFilter(self.edit_features_locator_filter) self.toolbox = ProcessingToolbox() self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox) self.toolbox.hide() self.toolbox.visibilityChanged.connect(self.toolboxVisibilityChanged) self.toolbox.executeWithGui.connect(self.executeAlgorithm) self.resultsDock = ResultsDock() self.iface.addDockWidget(Qt.RightDockWidgetArea, self.resultsDock) self.resultsDock.hide() self.menu = QMenu(self.iface.mainWindow().menuBar()) self.menu.setObjectName('processing') self.menu.setTitle(self.tr('Pro&cessing')) self.toolboxAction = QAction(self.tr('&Toolbox'), self.iface.mainWindow()) self.toolboxAction.setCheckable(True) self.toolboxAction.setObjectName('toolboxAction') self.toolboxAction.setIcon( QgsApplication.getThemeIcon("/processingAlgorithm.svg")) self.iface.registerMainWindowAction( self.toolboxAction, QKeySequence('Ctrl+Alt+T').toString(QKeySequence.NativeText)) self.toolboxAction.toggled.connect(self.openToolbox) self.iface.attributesToolBar().insertAction( self.iface.actionOpenStatisticalSummary(), self.toolboxAction) self.menu.addAction(self.toolboxAction) self.modelerAction = QAction( QgsApplication.getThemeIcon("/processingModel.svg"), QCoreApplication.translate('ProcessingPlugin', '&Graphical Modeler…'), self.iface.mainWindow()) self.modelerAction.setObjectName('modelerAction') self.modelerAction.triggered.connect(self.openModeler) self.iface.registerMainWindowAction( self.modelerAction, QKeySequence('Ctrl+Alt+G').toString(QKeySequence.NativeText)) self.menu.addAction(self.modelerAction) self.historyAction = QAction( QgsApplication.getThemeIcon("/mIconHistory.svg"), QCoreApplication.translate('ProcessingPlugin', '&History…'), self.iface.mainWindow()) self.historyAction.setObjectName('historyAction') self.historyAction.triggered.connect(self.openHistory) self.iface.registerMainWindowAction( self.historyAction, QKeySequence('Ctrl+Alt+H').toString(QKeySequence.NativeText)) self.menu.addAction(self.historyAction) self.toolbox.processingToolbar.addAction(self.historyAction) self.resultsAction = QAction( QgsApplication.getThemeIcon("/processingResult.svg"), self.tr('&Results Viewer'), self.iface.mainWindow()) self.resultsAction.setObjectName('resultsViewer') self.resultsAction.setCheckable(True) self.iface.registerMainWindowAction( self.resultsAction, QKeySequence('Ctrl+Alt+R').toString(QKeySequence.NativeText)) self.menu.addAction(self.resultsAction) self.toolbox.processingToolbar.addAction(self.resultsAction) self.resultsDock.visibilityChanged.connect( self.resultsAction.setChecked) self.resultsAction.toggled.connect(self.resultsDock.setUserVisible) self.toolbox.processingToolbar.addSeparator() self.editInPlaceAction = QAction( QgsApplication.getThemeIcon("/mActionProcessSelected.svg"), self.tr('Edit Features In-Place'), self.iface.mainWindow()) self.editInPlaceAction.setObjectName('editInPlaceFeatures') self.editInPlaceAction.setCheckable(True) self.editInPlaceAction.toggled.connect(self.editSelected) self.menu.addAction(self.editInPlaceAction) self.toolbox.processingToolbar.addAction(self.editInPlaceAction) self.toolbox.processingToolbar.addSeparator() self.optionsAction = QAction( QgsApplication.getThemeIcon("/mActionOptions.svg"), self.tr('Options'), self.iface.mainWindow()) self.optionsAction.setObjectName('optionsAction') self.optionsAction.triggered.connect(self.openProcessingOptions) self.toolbox.processingToolbar.addAction(self.optionsAction) menuBar = self.iface.mainWindow().menuBar() menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(), self.menu) self.menu.addSeparator() initializeMenus() createMenus() createButtons() # In-place editing button state sync self.iface.currentLayerChanged.connect(self.sync_in_place_button_state) self.iface.mapCanvas().selectionChanged.connect( self.sync_in_place_button_state) self.iface.actionToggleEditing().triggered.connect( partial(self.sync_in_place_button_state, None)) self.sync_in_place_button_state() # Sync project models self.projectModelsMenu = None self.projectMenuAction = None self.projectMenuSeparator = None self.projectProvider = QgsApplication.instance().processingRegistry( ).providerById("project") self.projectProvider.algorithmsLoaded.connect( self.updateProjectModelMenu)
def executeAlgorithm(self, alg_id, parent, in_place=False, as_batch=False): """Executes a project model with GUI interaction if needed. :param alg_id: algorithm id :type alg_id: string :param parent: parent widget :type parent: QWidget :param in_place: in place flag, defaults to False :type in_place: bool, optional :param as_batch: execute as batch flag, defaults to False :type as_batch: bool, optional """ config = {} if in_place: config['IN_PLACE'] = True alg = QgsApplication.instance().processingRegistry( ).createAlgorithmById(alg_id, config) if alg is not None: ok, message = alg.canExecute() if not ok: dlg = MessageDialog() dlg.setTitle(self.tr('Error executing algorithm')) dlg.setMessage( self.tr('<h3>This algorithm cannot ' 'be run :-( </h3>\n{0}').format(message)) dlg.exec_() return if as_batch: dlg = BatchAlgorithmDialog(alg, iface.mainWindow()) dlg.setAttribute(Qt.WA_DeleteOnClose) dlg.show() dlg.exec_() else: in_place_input_parameter_name = 'INPUT' if hasattr(alg, 'inputParameterName'): in_place_input_parameter_name = alg.inputParameterName() if in_place and not [ d for d in alg.parameterDefinitions() if d.name() not in (in_place_input_parameter_name, 'OUTPUT') ]: parameters = {} feedback = MessageBarProgress(algname=alg.displayName()) ok, results = execute_in_place(alg, parameters, feedback=feedback) if ok: iface.messageBar().pushSuccess( '', self. tr('{algname} completed. %n feature(s) processed.', n=results['__count']).format( algname=alg.displayName())) feedback.close() # MessageBarProgress handles errors return if alg.countVisibleParameters() > 0: dlg = alg.createCustomParametersWidget(parent) if not dlg: dlg = AlgorithmDialog(alg, in_place, iface.mainWindow()) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except Exception: pass canvas.setMapTool(prevMapTool) else: feedback = MessageBarProgress(algname=alg.displayName()) context = dataobjects.createContext(feedback) parameters = {} ret, results = execute(alg, parameters, context, feedback) handleAlgorithmResults(alg, context, feedback) feedback.close()
def layers(self, filter_layer_list=[]): tables_info = self.get_tables_info() layers = list() for record in tables_info: # When in PostGIS mode, leaving schema blank should load tables from # all schemas, except the ignored ones if self.schema: if record['schemaname'] != self.schema: continue elif record['schemaname'] in IGNORED_SCHEMAS: continue if record['tablename'] in IGNORED_TABLES: continue if filter_layer_list and record[ 'tablename'] not in filter_layer_list: continue if self.tool_name == 'ili2pg': provider = 'postgres' if record['geometry_column']: data_source_uri = '{uri} key={primary_key} estimatedmetadata={estimated_metadata} srid={srid} type={type} table="{schema}"."{table}" ({geometry_column})'.format( uri=self.uri, primary_key=record['primary_key'], estimated_metadata=self.pg_estimated_metadata, srid=record['srid'], type=record['type'], schema=record['schemaname'], table=record['tablename'], geometry_column=record['geometry_column']) else: data_source_uri = '{uri} key={primary_key} table="{schema}"."{table}"'.format( uri=self.uri, primary_key=record['primary_key'], schema=record['schemaname'], table=record['tablename']) elif self.tool_name == 'ili2gpkg': provider = 'ogr' data_source_uri = '{uri}|layername={table}'.format( uri=self.uri, table=record['tablename']) alias = record['table_alias'] if 'table_alias' in record else '' is_domain = record['kind_settings'] == 'ENUM' or record[ 'kind_settings'] == 'CATALOGUE' if 'kind_settings' in record else False is_structure = record[ 'kind_settings'] == 'STRUCTURE' if 'kind_settings' in record else False is_nmrel = record[ 'kind_settings'] == 'ASSOCIATION' if 'kind_settings' in record else False display_expression = '' if 'ili_name' in record: meta_attrs = self.get_meta_attrs(record['ili_name']) for attr_record in meta_attrs: if attr_record['attr_name'] == 'dispExpression': display_expression = attr_record['attr_value'] layer = Layer( provider, data_source_uri, record['tablename'], record['extent'] if 'extent' in record else None, record['geometry_column'], QgsWkbTypes.parseType(record['type']) or QgsWkbTypes.Unknown, alias, is_domain, is_structure, is_nmrel, display_expression) # Configure fields for current table fields_info = self.get_fields_info(record['tablename']) constraints_info = self.get_constraints_info(record['tablename']) re_iliname = re.compile(r'^@iliname (.*)$') for fielddef in fields_info: column_name = fielddef['column_name'] comment = fielddef['comment'] m = re_iliname.match(comment) if comment else None alias = None if 'column_alias' in fielddef: alias = fielddef['column_alias'] if m and not alias: alias = m.group(1) field = Field(column_name) field.alias = alias # Should we hide the field? hide_attribute = False if 'fully_qualified_name' in fielddef: fully_qualified_name = fielddef['fully_qualified_name'] if fully_qualified_name: meta_attrs_column = self.get_meta_attrs( fully_qualified_name) for attr_record in meta_attrs_column: if attr_record['attr_name'] == 'hidden': if attr_record['attr_value'] == 'True': hide_attribute = True break if column_name in IGNORED_FIELDNAMES: hide_attribute = True field.hidden = hide_attribute if column_name in READONLY_FIELDNAMES: field.read_only = True if column_name in constraints_info: field.widget = 'Range' field.widget_config['Min'] = constraints_info[column_name][ 0] field.widget_config['Max'] = constraints_info[column_name][ 1] if 'numeric_scale' in fielddef: field.widget_config['Step'] = pow( 10, -1 * fielddef['numeric_scale']) # field.widget_config['Suffix'] = fielddef['unit'] if 'unit' in fielddef else '' if 'unit' in fielddef and fielddef['unit'] is not None: field.alias = '{alias} [{unit}]'.format( alias=alias or column_name, unit=fielddef['unit']) if 'texttype' in fielddef and fielddef['texttype'] == 'MTEXT': field.widget = 'TextEdit' field.widget_config['IsMultiline'] = True data_type = self._db_connector.map_data_types( fielddef['data_type']) if 'time' in data_type or 'date' in data_type: field.widget = 'DateTime' field.widget_config['calendar_popup'] = True dateFormat = QLocale( QgsApplication.instance().locale()).dateFormat( QLocale.ShortFormat) timeFormat = QLocale( QgsApplication.instance().locale()).timeFormat( QLocale.ShortFormat) dateTimeFormat = QLocale( QgsApplication.instance().locale()).dateTimeFormat( QLocale.ShortFormat) if data_type == self._db_connector.QGIS_TIME_TYPE: field.widget_config['display_format'] = timeFormat elif data_type == self._db_connector.QGIS_DATE_TIME_TYPE: field.widget_config['display_format'] = dateTimeFormat elif data_type == self._db_connector.QGIS_DATE_TYPE: field.widget_config['display_format'] = dateFormat layer.fields.append(field) layers.append(layer) return layers
def accept(self): description = self.nameTextBox.text() if description.strip() == '': QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Invalid parameter name')) return if self.param is None: validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeName = ''.join(c for c in description if c in validChars) name = safeName.lower() i = 2 while self.alg.parameterDefinition(name): name = safeName.lower() + str(i) i += 1 else: name = self.param.name() if (self.paramType == parameters.PARAMETER_BOOLEAN or isinstance(self.param, QgsProcessingParameterBoolean)): self.param = QgsProcessingParameterBoolean(name, description, self.state.isChecked()) elif (self.paramType == parameters.PARAMETER_TABLE_FIELD or isinstance(self.param, QgsProcessingParameterField)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() datatype = self.datatypeCombo.currentData() default = self.defaultTextBox.text() if not default: default = None self.param = QgsProcessingParameterField(name, description, defaultValue=default, parentLayerParameterName=parent, type=datatype, allowMultiple=self.multipleCheck.isChecked()) elif (self.paramType == parameters.PARAMETER_BAND or isinstance(self.param, QgsProcessingParameterBand)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() self.param = QgsProcessingParameterBand(name, description, None, parent) elif (self.paramType == parameters.PARAMETER_MAP_LAYER or isinstance(self.param, QgsProcessingParameterMapLayer)): self.param = QgsProcessingParameterMapLayer( name, description) elif (self.paramType == parameters.PARAMETER_RASTER or isinstance(self.param, QgsProcessingParameterRasterLayer)): self.param = QgsProcessingParameterRasterLayer( name, description) elif (self.paramType == parameters.PARAMETER_TABLE or isinstance(self.param, QgsProcessingParameterVectorLayer)): self.param = QgsProcessingParameterVectorLayer( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_VECTOR or isinstance(self.param, QgsProcessingParameterFeatureSource)): self.param = QgsProcessingParameterFeatureSource( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_MULTIPLE or isinstance(self.param, QgsProcessingParameterMultipleLayers)): self.param = QgsProcessingParameterMultipleLayers( name, description, self.datatypeCombo.currentData()) elif (self.paramType == parameters.PARAMETER_NUMBER or isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance))): try: self.param = QgsProcessingParameterNumber(name, description, QgsProcessingParameterNumber.Double, self.defaultTextBox.text()) vmin = self.minTextBox.text().strip() if not vmin == '': self.param.setMinimum(float(vmin)) vmax = self.maxTextBox.text().strip() if not vmax == '': self.param.setMaximum(float(vmax)) except: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return elif (self.paramType == parameters.PARAMETER_EXPRESSION or isinstance(self.param, QgsProcessingParameterExpression)): parent = self.parentCombo.currentData() self.param = QgsProcessingParameterExpression(name, description, str(self.defaultEdit.expression()), parent) elif (self.paramType == parameters.PARAMETER_STRING or isinstance(self.param, QgsProcessingParameterString)): self.param = QgsProcessingParameterString(name, description, str(self.defaultTextBox.text())) elif (self.paramType == parameters.PARAMETER_EXTENT or isinstance(self.param, QgsProcessingParameterExtent)): self.param = QgsProcessingParameterExtent(name, description) elif (self.paramType == parameters.PARAMETER_FILE or isinstance(self.param, QgsProcessingParameterFile)): isFolder = self.fileFolderCombo.currentIndex() == 1 self.param = QgsProcessingParameterFile(name, description, QgsProcessingParameterFile.Folder if isFolder else QgsProcessingParameterFile.File) elif (self.paramType == parameters.PARAMETER_POINT or isinstance(self.param, QgsProcessingParameterPoint)): self.param = QgsProcessingParameterPoint(name, description, str(self.defaultTextBox.text())) elif (self.paramType == parameters.PARAMETER_CRS or isinstance(self.param, QgsProcessingParameterCrs)): self.param = QgsProcessingParameterCrs(name, description, self.selector.crs().authid()) elif (self.paramType == parameters.PARAMETER_ENUM or isinstance(self.param, QgsProcessingParameterEnum)): self.param = QgsProcessingParameterEnum(name, description, self.widget.options(), self.widget.allowMultiple(), self.widget.defaultOptions()) elif (self.paramType == parameters.PARAMETER_MATRIX or isinstance(self.param, QgsProcessingParameterMatrix)): self.param = QgsProcessingParameterMatrix(name, description, hasFixedNumberRows=self.widget.fixedRows(), headers=self.widget.headers(), defaultValue=self.widget.value()) else: if self.paramType: typeId = self.paramType else: typeId = self.param.type() paramTypeDef = QgsApplication.instance().processingRegistry().parameterType(typeId) if not paramTypeDef: msg = self.tr('The parameter `{}` is not registered, are you missing a required plugin?'.format(typeId)) raise UndefinedParameterException(msg) self.param = paramTypeDef.create(name) self.param.setDescription(description) self.param.setMetadata(paramTypeDef.metadata()) if not self.requiredCheck.isChecked(): self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagOptional) settings = QgsSettings() settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.accept(self)
def unload(self): super().unload() QgsApplication.instance().processingRegistry().removeParameterType( self.parameterTypeFieldsMapping)
def input_dropped(id, pos): if id in [param.id() for param in QgsApplication.instance().processingRegistry().parameterTypes()]: self.addInputOfType(itemId, pos)
def input_dropped(id, pos): if id in [ param.id() for param in QgsApplication.instance(). processingRegistry().parameterTypes() ]: self.addInputOfType(itemId, pos)
def __init__(self, roamapp): super(MainWindow, self).__init__() self.setupUi(self) self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint) import roam self.projectwidget.project_base = roamapp.projectsroot QgsApplication.instance().setStyleSheet(roam.roam_style.appstyle()) self.menutoolbar.setStyleSheet(roam.roam_style.menubarstyle()) icon = roam.roam_style.iconsize() self.menutoolbar.setIconSize(QSize(icon, icon)) smallmode = roam.config.settings.get("smallmode", False) self.menutoolbar.setSmallMode(smallmode) self.projectupdater = ProjectUpdater( projects_base=roamapp.projectsroot) self.projectupdater.foundProjects.connect( self.projectwidget.show_new_updateable) self.projectupdater.projectUpdateStatus.connect( self.projectwidget.update_project_status) self.projectupdater.projectInstalled.connect( self.projectwidget.project_installed) self.projectwidget.search_for_updates.connect(self.search_for_projects) self.projectwidget.projectUpdate.connect( self.projectupdater.update_project) self.projectwidget.projectInstall.connect( self.projectupdater.install_project) self.project = None self.tracking = GPSLogging(GPS) self.canvas_page.set_gps(GPS, self.tracking) self.canvas = self.canvas_page.canvas # self.canvas_page.projecttoolbar.stateChanged.connect(self.menutoolbar.setSmallMode) # self.menutoolbar.stateChanged.connect(self.canvas_page.projecttoolbar.setSmallMode) roam.defaults.canvas = self.canvas self.bar = roam.messagebaritems.MessageBar(self.centralwidget) self.actionMap.setVisible(False) self.actionLegend.setVisible(False) self.menuGroup = QActionGroup(self) self.menuGroup.setExclusive(True) self.menuGroup.addAction(self.actionMap) self.menuGroup.addAction(self.actionDataEntry) self.menuGroup.addAction(self.actionLegend) self.menuGroup.addAction(self.actionProject) self.menuGroup.addAction(self.actionSync) self.menuGroup.addAction(self.actionSettings) self.menuGroup.addAction(self.actionGPS) self.menuGroup.triggered.connect(self.updatePage) self.projectbuttons = [] self.pluginactions = [] self.actionQuit.triggered.connect(self.exit) self.init_legend() self.projectwidget.requestOpenProject.connect(self.load_roam_project) QgsProject.instance().readProject.connect(self.project_opened) self.gpswidget.setgps(GPS) self.gpswidget.settracking(self.tracking) self.settings = {} self.actionSettings.toggled.connect( self.settingswidget.populateControls) self.actionSettings.toggled.connect(self.settingswidget.readSettings) self.settingswidget.settingsupdated.connect(self.settingsupdated) self.dataentrywidget = DataEntryWidget(self.canvas) self.dataentrywidget.lastwidgetremoved.connect(self.dataentryfinished) self.widgetpage.layout().addWidget(self.dataentrywidget) self.dataentrywidget.rejected.connect(self.formrejected) RoamEvents.featuresaved.connect(self.featureSaved) RoamEvents.helprequest.connect(self.showhelp) RoamEvents.deletefeature.connect(self.delete_feature) RoamEvents.layerLoaded.connect(self.update_layer_loaded_progress) def createSpacer(width=0, height=0): widget = QWidget() widget.setMinimumWidth(width) widget.setMinimumHeight(height) return widget sidespacewidget = createSpacer(30) sidespacewidget2 = createSpacer(height=20) sidespacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sidespacewidget2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.menutoolbar.insertWidget(self.actionQuit, sidespacewidget2) self.spaceraction = self.menutoolbar.insertWidget( self.actionProject, sidespacewidget) self.panels = [] self.actionGPSFeature.setProperty('dataentry', True) self.infodock = InfoDock(self.canvas) self.infodock.featureupdated.connect(self.highlightfeature) self.infodock.activeLayerChanged.connect(self.canvas.setCurrentLayer) self.infodock.hide() self.hidedataentry() RoamEvents.openimage.connect(self.openimage) RoamEvents.openurl.connect(self.viewurl) RoamEvents.openfeatureform.connect(self.openForm) RoamEvents.openkeyboard.connect(self.openkeyboard) RoamEvents.editgeometry_complete.connect(self.on_geometryedit) RoamEvents.onShowMessage.connect(self.show_ui_message) RoamEvents.selectionchanged.connect(self.show_info_results) RoamEvents.show_widget.connect(self.dataentrywidget.add_widget) RoamEvents.closeProject.connect(self.close_project) self.legendpage.showmap.connect(self.showmap) self.currentselection = {} iface = RoamInterface(RoamEvents, GPS, self, self.canvas_page, self) plugins.api = iface
def sync_auth_delete(sender, instance, **kwargs): """Sync the QGIS auth DB after delete""" am = QgsApplication.instance().authManager() am.removeAuthenticationConfig(instance.id)