def testLayerRemovalBeforeRun(self): """test behavior when layer is removed before task begins""" path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif') raster_layer = QgsRasterLayer(path, "test") self.assertTrue(raster_layer.isValid()) pipe = QgsRasterPipe() self.assertTrue(pipe.set(raster_layer.dataProvider().clone())) tmp = create_temp_filename('remove_layer.tif') writer = QgsRasterFileWriter(tmp) task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs()) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) # remove layer raster_layer = None QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() # in this case will still get a positive result - since the pipe is cloned before the task # begins the task is no longer dependent on the original layer self.assertTrue(self.success) self.assertFalse(self.fail) self.assertTrue(os.path.exists(tmp))
def write(self, m): if self.style == "_traceback": # Show errors in red stderrColor = QColor(self.sO.settings.value("pythonConsole/stderrFontColor", QColor(Qt.red))) self.sO.SendScintilla(QsciScintilla.SCI_STYLESETFORE, 0o01, stderrColor) self.sO.SendScintilla(QsciScintilla.SCI_STYLESETITALIC, 0o01, True) self.sO.SendScintilla(QsciScintilla.SCI_STYLESETBOLD, 0o01, True) pos = self.sO.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS) self.sO.SendScintilla(QsciScintilla.SCI_STARTSTYLING, pos, 31) self.sO.append(m) self.sO.SendScintilla(QsciScintilla.SCI_SETSTYLING, len(m), 0o01) else: self.sO.append(m) if self.out: self.out.write(m) self.move_cursor_to_end() if self.style != "_traceback": QCoreApplication.processEvents() if self.fire_keyboard_interrupt: self.fire_keyboard_interrupt = False raise KeyboardInterrupt
def testTaskFromFunctionWithSubTaskCompletedIsCalledOnce(self): # spellok """ test that when a parent task has subtasks it does emit taskCompleted only once""" self.finished = 0 self.completed = 0 def _on_finished(e): self.finished += 1 def _on_completed(): self.completed += 1 task = QgsTask.fromFunction('test task', run_no_result, on_finished=_on_finished) task.taskCompleted.connect(_on_completed) spy = QSignalSpy(task.taskCompleted) sub_task_1 = QgsTask.fromFunction('test subtask 1', run_no_result, on_finished=_on_finished) sub_task_2 = QgsTask.fromFunction('test subtask 2', run_no_result, on_finished=_on_finished) task.addSubTask(sub_task_1, [], QgsTask.ParentDependsOnSubTask) task.addSubTask(sub_task_2, [], QgsTask.ParentDependsOnSubTask) QgsApplication.taskManager().addTask(task) while task.status() not in [QgsTask.Complete, QgsTask.Terminated]: QCoreApplication.processEvents() while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents() self.assertEqual(self.completed, 1) self.assertEqual(self.finished, 3) self.assertEqual(len(spy), 1)
def pageProcessed(self, feedback): """Increment the page progressbar. Only atlas makes it run as there seems to be no obvious way to catch page export""" QCoreApplication.processEvents() if feedback: self.dlg.pageBar.setValue(feedback)
def set_progress(self, i, n): """Gets called when there is a progression""" self.__progress.show() self.__progress.setMinimum(0) self.__progress.setMaximum(n) self.__progress.setValue(i) QCoreApplication.processEvents()
def testFetchingResults(self): def got_hit(result): got_hit._results_.append(result.displayString) got_hit._results_ = [] context = QgsLocatorContext() # one filter l = QgsLocator() filter_a = test_filter('a') l.registerFilter(filter_a) l.foundResult.connect(got_hit) l.fetchResults('a', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'a0', 'a1', 'a2'}) # two filters filter_b = test_filter('b') l.registerFilter(filter_b) got_hit._results_ = [] l.fetchResults('a', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'a0', 'a1', 'a2', 'b0', 'b1', 'b2'})
def setInfo(self, msg, error=False, escape_html=True): if error: self.txtLog.append('<span style="color:red">{}</span><br />'.format(msg, quote=False)) elif escape_html: self.txtLog.append(html.escape(msg)) else: self.txtLog.append(msg) QCoreApplication.processEvents()
def set_text(self, t): """Gets called when a text is to be logged""" if isinstance(t, tuple): lvl, msg = t else: msg = t self.__label.setText(msg) QCoreApplication.processEvents()
def execute(func): try: QCoreApplication.processEvents() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) return func() finally: QApplication.restoreOverrideCursor() QCoreApplication.processEvents()
def run(self): nBands = self.tif.RasterCount for y in range(2, self.ySize, self.readrows): if (QCoreApplication != None): QCoreApplication.processEvents() if self.ySize-y < self.readrows : self.readrows = self.ySize-y-2 self.rasterLock.acquire() data = self.tif.ReadAsArray(0, y-2, self.xSize, self.readrows+4) self.rasterLock.release() self.inBuffer.put([data, y, self.numpyType]) self.inBuffer.put(False)
def grabHTTP(self, url, loadFunction, arguments=None): """Grab distant content via QGIS internal classes and QtNetwork.""" QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) request = QUrl(url) reply = self.manager.get(QNetworkRequest(request)) if arguments: reply.finished.connect(partial(loadFunction, reply, arguments)) else: reply.finished.connect(partial(loadFunction, reply)) while not reply.isFinished(): QCoreApplication.processEvents()
def testTaskFromFunctionFinishedWithVal(self): """ test that task from function can have callback finished function and is passed result values""" task = QgsTask.fromFunction('test task', run_single_val_result, on_finished=finished_single_value_result) QgsApplication.taskManager().addTask(task) while task.status() not in [QgsTask.Complete, QgsTask.Terminated]: pass while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents() # check that the finished function was called self.assertEqual(task.returned_values, (5)) self.assertFalse(task.exception) self.assertEqual(finished_single_value_result.value, 5)
def testTaskFromFunctionFinishedFail(self): """ test that task from function which fails calls finished with exception""" task = QgsTask.fromFunction('test task', run_fail, on_finished=finished_fail) QgsApplication.taskManager().addTask(task) while task.status() not in [QgsTask.Complete, QgsTask.Terminated]: pass while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents() # check that the finished function was called self.assertTrue(task.exception) self.assertTrue(finished_fail.finished_exception) self.assertEqual(task.exception, finished_fail.finished_exception)
def testTaskFromFunctionFinished(self): """ test that task from function can have callback finished function""" task = QgsTask.fromFunction('test task', run_no_result, on_finished=finished_no_val) QgsApplication.taskManager().addTask(task) while task.status() not in [QgsTask.Complete, QgsTask.Terminated]: pass while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents() # check that the finished function was called self.assertFalse(task.returned_values) self.assertFalse(task.exception) self.assertTrue(finished_no_val.called)
def testTaskFromFunctionCanceledWhileQueued(self): """ test that task from finished is called with exception when task is terminated while queued""" task = QgsTask.fromFunction('test task', run_no_result, on_finished=finished_fail) task.hold() QgsApplication.taskManager().addTask(task) task.cancel() while task.status() not in [QgsTask.Complete, QgsTask.Terminated]: pass while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents() # check that the finished function was called self.assertTrue(task.exception) self.assertTrue(finished_fail.finished_exception) self.assertEqual(task.exception, finished_fail.finished_exception)
def testTaskFromFunctionIsCancellable(self): """ test that task from function can check canceled status """ bad_task = QgsTask.fromFunction('test task4', cancellable) QgsApplication.taskManager().addTask(bad_task) while bad_task.status() != QgsTask.Running: pass bad_task.cancel() while bad_task.status() == QgsTask.Running: pass while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents() self.assertEqual(bad_task.status(), QgsTask.Terminated) self.assertTrue(bad_task.exception)
def testNoLayer(self): """test that failure (and not crash) occurs when no layer set""" options = QgsVectorFileWriter.SaveVectorOptions() tmp = create_temp_filename('fail.shp') task = QgsVectorFileWriterTask(None, tmp, options) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertFalse(self.success) self.assertTrue(self.fail)
def testSuccess(self): """test successfully writing a layer""" self.layer = self.createLayer() options = QgsVectorFileWriter.SaveVectorOptions() tmp = create_temp_filename('successlayer.shp') task = QgsVectorFileWriterTask(self.layer, tmp, options) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertTrue(self.success) self.assertFalse(self.fail)
def testTaskFromFunctionCanSetProgress(self): """ test that task from function can set progress """ task = QgsTask.fromFunction('test task5', progress_function) QgsApplication.taskManager().addTask(task) while task.status() != QgsTask.Running: pass # wait a fraction so that setProgress gets a chance to be called sleep(0.001) self.assertEqual(task.progress(), 50) self.assertFalse(task.exception) task.cancel() while task.status() == QgsTask.Running: pass while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents()
def testClearOnLayerAutoRefresh(self): """ test that cache is cleared when layer auto refresh is triggered """ cache = QgsMapRendererCache() layer1 = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") im = QImage(200, 200, QImage.Format_RGB32) cache.setCacheImage('l1', im, [layer1]) self.assertTrue(cache.hasCacheImage('l1')) layer1.setAutoRefreshInterval(100) layer1.setAutoRefreshEnabled(True) self.assertTrue(cache.hasCacheImage('l1')) # wait a second... sleep(1) QCoreApplication.processEvents() # cache should be cleared self.assertFalse(cache.hasCacheImage('l1'))
def on_searchButton_clicked(self): if self.currentProjectId is None: return self.sectionWidget.setEnabled(False) # init progress bar c = 0 for p_id in self.data.keys(): for s_id, section in self.data[p_id]['Sections'].items(): c += 1 self.progressBar.setMaximum(c) self.progressBar.setMinimum(0) self.progressBar.setValue(0) self.progressBar.setFormat('Recherche les collecteurs %v/%m') self.progressBar.show() self.cancelButton.show() self.importButton.hide() self.cancel = False i = 0 # find sections channel = self.data[self.currentProjectId]['Channel'] for p_id in self.data.keys(): if self.cancel: break for s_id, section in self.data[p_id]['Sections'].items(): QCoreApplication.processEvents() if self.cancel: break feature = findSection(channel, section['StartNode'], section['EndNode']) if not feature.isValid() and self.settings.value('remove_trailing_chars'): # try without trailing alpha char feature = findSection(channel, re.sub('\D*$', '', section['StartNode']), re.sub('\D*$', '', section['EndNode'])) if feature.isValid(): self.data[p_id]['Sections'][s_id]['QgepChannelId1'] = feature.attribute('obj_id') self.progressBar.setValue(i) i += 1 self.progressBar.hide() self.cancelButton.hide() self.importButton.show() self.sectionWidget.setEnabled(True) self.sectionWidget.set_project_id(self.currentProjectId)
def testAutoModel(self): """ Test automatic model, QgsLocatorAutomaticModel - should be no need for any manual connections """ l = QgsLocator() m = QgsLocatorAutomaticModel(l) filter_a = test_filter('a') l.registerFilter(filter_a) m.search('a') for i in range(100): sleep(0.002) QCoreApplication.processEvents() # 4 results - one is locator name self.assertEqual(m.rowCount(), 4) self.assertEqual(m.data(m.index(0, 0)), 'test') self.assertEqual(m.data(m.index(0, 0), QgsLocatorModel.ResultTypeRole), 0) self.assertEqual(m.data(m.index(0, 0), QgsLocatorModel.ResultFilterNameRole), 'test') self.assertEqual(m.data(m.index(1, 0)), 'a0') self.assertEqual(m.data(m.index(1, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(m.data(m.index(1, 0), QgsLocatorModel.ResultFilterNameRole), 'test') self.assertEqual(m.data(m.index(2, 0)), 'a1') self.assertEqual(m.data(m.index(2, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(m.data(m.index(2, 0), QgsLocatorModel.ResultFilterNameRole), 'test') self.assertEqual(m.data(m.index(3, 0)), 'a2') self.assertEqual(m.data(m.index(3, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(m.data(m.index(3, 0), QgsLocatorModel.ResultFilterNameRole), 'test') m.search('a') for i in range(100): sleep(0.002) QCoreApplication.processEvents() # 4 results - one is locator name self.assertEqual(m.rowCount(), 4) self.assertEqual(m.data(m.index(0, 0)), 'test') self.assertEqual(m.data(m.index(1, 0)), 'a0') self.assertEqual(m.data(m.index(2, 0)), 'a1') self.assertEqual(m.data(m.index(3, 0)), 'a2')
def execute(func, message = None, useThread = False): global _dialog cursor = QApplication.overrideCursor() waitCursor = (cursor is not None and cursor.shape() == Qt.WaitCursor) dialogCreated = False try: QCoreApplication.processEvents() if not waitCursor: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if message is not None and useThread: t = Thread(func) loop = QEventLoop() t.finished.connect(loop.exit, Qt.QueuedConnection) if _dialog is None: dialogCreated = True _dialog = QProgressDialog(message, "Mapstory", 0, 0, config.iface.mainWindow()) _dialog.setWindowTitle("Mapstory") _dialog.setWindowModality(Qt.WindowModal); _dialog.setMinimumDuration(1000) _dialog.setMaximum(100) _dialog.setValue(0) _dialog.setMaximum(0) _dialog.setCancelButton(None) else: oldText = _dialog.labelText() _dialog.setLabelText(message) QApplication.processEvents() t.start() loop.exec_(flags = QEventLoop.ExcludeUserInputEvents) if t.exception is not None: raise t.exception return t.returnValue else: return func() finally: if message is not None and useThread: if dialogCreated: _dialog.reset() _dialog = None else: _dialog.setLabelText(oldText) if not waitCursor: QApplication.restoreOverrideCursor() QCoreApplication.processEvents()
def testLayerRemovalBeforeRun(self): """test behavior when layer is removed before task begins""" self.layer = self.createLayer() options = QgsVectorFileWriter.SaveVectorOptions() tmp = create_temp_filename('fail.shp') task = QgsVectorFileWriterTask(self.layer, tmp, options) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) # remove layer self.layer = None QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertTrue(self.success) self.assertFalse(self.fail)
def testSuccessWithLayer(self): """test successfully writing to a layer-enabled format""" self.layer = self.createLayer() options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "KML" options.layerName = "test-dashes" tmp = create_temp_filename('successlayer.kml') task = QgsVectorFileWriterTask(self.layer, tmp, options) task.completed.connect(self.onComplete) task.errorOccurred.connect(self.onFail) QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertEqual(self.new_layer, "test_dashes") self.assertTrue(self.success) self.assertFalse(self.fail)
def testFieldValueConverter(self): """test no crash when fieldValueConverter is used""" self.layer = self.createLayer() options = QgsVectorFileWriter.SaveVectorOptions() converter = QgsVectorFileWriter.FieldValueConverter() options.fieldValueConverter = converter tmp = create_temp_filename('converter.shp') task = QgsVectorFileWriterTask(self.layer, tmp, options) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) del converter QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertTrue(self.success) self.assertFalse(self.fail)
def fetch(self): """Fetch the content.""" # Initialize some properties again self._content = None self._network_finished = False self._network_timeout = False request = QNetworkRequest(QUrl(self._url)) request.setAttribute( QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) if self._auth_cfg and qgis_version() >= 21200: LOGGER.info('Update request with auth_cfg %s' % self._auth_cfg) QgsAuthManager.instance().updateNetworkRequest( request, self._auth_cfg ) self._reply = self._network_manager.get(request) self._reply.finished.connect(self.fetch_finished) self._network_manager.requestTimedOut.connect(self.request_timeout) while not self._reply.isFinished(): # noinspection PyArgumentList QCoreApplication.processEvents() # Finished description = None if self._reply.error() != QNetworkReply.NoError: status = False description = self._reply.errorString() else: status = True self._content = self._reply.readAll() self._reply.deleteLater() return status, description
def test(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) df = QgsVirtualLayerDefinition() df.setQuery('select * from "françéà"') self.task = QgsVirtualLayerTask(df) ids = [f.id() for f in self.task.layer().getFeatures()] self.assertEqual(len(ids), 0) self.task.taskCompleted.connect(self.onSuccess) self.task.taskTerminated.connect(self.onFail) QgsApplication.taskManager().addTask(self.task) while not self._success and not self._fail: QCoreApplication.processEvents() self.assertTrue(self._success) self.assertFalse(self._fail) self.assertEqual(len(self.ids), 4) # Test exception self._success = False self._fail = False df.setQuery('select *') self.task = QgsVirtualLayerTask(df) self.task.taskCompleted.connect(self.onSuccess) self.task.taskTerminated.connect(self.onFail) QgsApplication.taskManager().addTask(self.task) while not self._success and not self._fail: QCoreApplication.processEvents() self.assertFalse(self._success) self.assertTrue(self._fail) self.assertEqual(self._exceptionText, 'Query preparation error on PRAGMA table_info(_tview): no tables specified', self._exceptionText)
def test(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) df = QgsVirtualLayerDefinition() df.setQuery('select * from "françéà"') self.task = QgsVirtualLayerTask(df) ids = [f.id() for f in self.task.layer().getFeatures()] self.assertEqual(len(ids), 0) self.task.taskCompleted.connect(self.onSuccess) self.task.taskTerminated.connect(self.onFail) QgsApplication.taskManager().addTask(self.task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertTrue(self.success) self.assertFalse(self.fail) self.assertEqual(len(self.ids), 4)
def testTaskFromFunctionFinishedWithMultipleValues(self): """ test that task from function can have callback finished function and is passed multiple result values""" result_value = None result_statement = None def finished_multiple_value_result(e, results): nonlocal result_value nonlocal result_statement assert e is None result_value = results[0] result_statement = results[1] task = QgsTask.fromFunction('test task', run_multiple_val_result, on_finished=finished_multiple_value_result) QgsApplication.taskManager().addTask(task) while task.status() not in [QgsTask.Complete, QgsTask.Terminated]: pass while QgsApplication.taskManager().countActiveTasks() > 0: QCoreApplication.processEvents() # check that the finished function was called self.assertEqual(task.returned_values, (5, 'whoo')) self.assertFalse(task.exception) self.assertEqual(result_value, 5) self.assertEqual(result_statement, 'whoo')
def is_source_service_valid(self): res = False msg = {'text': '', 'level': Qgis.Warning} url = self.txt_service_endpoint.text().strip() if url: with OverrideCursor(Qt.WaitCursor): self.qgis_utils.status_bar_message_emitted.emit( "Checking source service availability (this might take a while)...", 0) QCoreApplication.processEvents() if self.qgis_utils.is_connected(TEST_SERVER): nam = QNetworkAccessManager() request = QNetworkRequest(QUrl(url)) reply = nam.get(request) loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec_() allData = reply.readAll() response = QTextStream(allData, QIODevice.ReadOnly) status = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if status == 200: try: data = json.loads(response.readAll()) if 'id' in data and data[ 'id'] == SOURCE_SERVICE_EXPECTED_ID: res = True msg['text'] = QCoreApplication.translate( "SettingsDialog", "The tested service is valid to upload files!" ) msg['level'] = Qgis.Info else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "The tested upload service is not compatible: no valid 'id' found in response." ) except json.decoder.JSONDecodeError as e: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "Response from the tested service is not compatible: not valid JSON found." ) else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "There was a problem connecting to the server. The server might be down or the service cannot be reached at the given URL." ) else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "There was a problem connecting to Internet.") self.qgis_utils.clear_status_bar_emitted.emit() else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "Not valid service URL to test!") return (res, msg)
def setPercentage(self, value): if self.progressBar.maximum() == 0: self.progressBar.setMaximum(100) self.progressBar.setValue(value) QCoreApplication.processEvents()
def create_row_col_elev_mf_ii (self): time = datetime.now().strftime('[%m/%d/%y %H:%M:%S]') self.textEdit_mf_log.append(time+' -> ' + "Creating 'row', 'col, 'elev' ... processing") self.label_mf_status.setText("Creating 'row', 'col, 'elev' ... ") self.progressBar_mf_status.setValue(0) QCoreApplication.processEvents() import math APEXMOD_path_dict = self.dirs_and_paths() self.layer = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0] provider = self.layer.dataProvider() # from qgis.core import QgsField, QgsExpression, QgsFeature if provider.fields().indexFromName( "row" ) == -1: field = QgsField("row", QVariant.Int) provider.addAttributes([field]) self.layer.updateFields() # Create Column field if provider.fields().indexFromName( "col" ) == -1: field = QgsField("col", QVariant.Int) provider.addAttributes([field]) self.layer.updateFields() # Get the index numbers of the fields # elev_mean = provider.fields().indexFromName( "elev_mean" ) row = provider.fields().indexFromName("row") col = provider.fields().indexFromName("col") # Change name for field in self.layer.fields(): if field.name() == 'elev_mean': self.layer.startEditing() idx = provider.fields().indexFromName(field.name()) self.layer.renameAttribute(idx, "elev_mf") self.layer.commitChanges() # Get number of rows and of columns input1 = QgsProject.instance().mapLayersByName("mf_boundary (MODFLOW)")[0] ext = input1.extent() xmin = ext.xMinimum() xmax = ext.xMaximum() ymin = ext.yMinimum() ymax = ext.yMaximum() delc = float(self.doubleSpinBox_delc.value()) delr = float(self.doubleSpinBox_delr.value()) nx = math.ceil(abs(abs(xmax) - abs(xmin)) / delc) ny = math.ceil(abs(abs(ymax) - abs(ymin)) / delr) # Get row and column lists iy = [] # row ix = [] # col for i in range(1, ny + 1): for j in range(1, nx + 1): ix.append(j) iy.append(i) # Get features (Find out a way to change attribute values using another field) feats = self.layer.getFeatures() tot_feats = self.layer.featureCount() count = 0 self.layer.startEditing() # add row number for f, r, c in zip(feats, iy, ix): self.layer.changeAttributeValue(f.id(), row, r) self.layer.changeAttributeValue(f.id(), col, c) count += 1 provalue = round(count/tot_feats*100) self.progressBar_mf_status.setValue(provalue) QCoreApplication.processEvents() self.layer.commitChanges() QCoreApplication.processEvents() time = datetime.now().strftime('[%m/%d/%y %H:%M:%S]') self.textEdit_mf_log.append(time+' -> ' + "Creating 'row', 'col, 'elev' ... passed") self.label_mf_status.setText('Step Status: ') QCoreApplication.processEvents()
def create_MF_shps(self): self.progressBar_mf.setValue(0) self.create_MF_grid() self.progressBar_mf.setValue(30) QCoreApplication.processEvents() # it works as F5 !! Be careful to use this for long geoprocessing # Create grid_id self.create_grid_id_ii() self.progressBar_mf.setValue(40) QCoreApplication.processEvents() # Extract elevation self.getElevfromDem() self.progressBar_mf.setValue(50) QCoreApplication.processEvents() # Extract elevation self.create_row_col_elev_mf_ii() self.progressBar_mf.setValue(60) QCoreApplication.processEvents() # Get active cells self.create_mf_act_grid() self.progressBar_mf.setValue(70) QCoreApplication.processEvents() self.mf_act_grid_delete_NULL() QCoreApplication.processEvents() self.cvtElevToR() QCoreApplication.processEvents() time = datetime.now().strftime('[%m/%d/%y %H:%M:%S]') self.textEdit_mf_log.append(time+' -> ' + 'Done!') self.progressBar_mf.setValue(100) QCoreApplication.processEvents() msgBox = QMessageBox() msgBox.setWindowIcon(QtGui.QIcon(':/APEXMOD/pics/am_icon.png')) msgBox.setWindowTitle("Created!") msgBox.setText("MODFLOW grids and rasters were created!") msgBox.exec_()
def print_info(self, text, text_color=LogColor.COLOR_INFO): self.txtStdout.setTextColor(QColor(text_color)) self.txtStdout.append(text) QCoreApplication.processEvents()
def write_image( feedback, tex_layer, tex_pixel_size, destination_crs, destination_extent, filepath, imagetype, ): """ Save current QGIS canvas to image file. """ feedback.pushInfo("Rendering texture image (timeout in 30s)...") project = QgsProject.instance() # Get extent size in meters d = QgsDistanceArea() d.setSourceCrs( crs=destination_crs, context=QgsProject.instance().transformContext() ) p00, p10, p01 = ( QgsPointXY(destination_extent.xMinimum(), destination_extent.yMinimum()), QgsPointXY(destination_extent.xMaximum(), destination_extent.yMinimum()), QgsPointXY(destination_extent.xMinimum(), destination_extent.yMaximum()), ) wm = d.measureLine(p00, p10) # euclidean dist, extent width in m hm = d.measureLine(p00, p01) # euclidean dist, extent height in m # Image settings and texture layer choice settings = QgsMapSettings() # build settings settings.setDestinationCrs(destination_crs) # set output crs settings.setExtent(destination_extent) # in destination_crs if tex_layer: layers = (tex_layer,) # chosen texture layer else: canvas = iface.mapCanvas() layers = canvas.layers() # get visible layers wpix = int(wm / tex_pixel_size) hpix = int(hm / tex_pixel_size) settings.setOutputSize(QSize(wpix, hpix)) settings.setLayers(layers) feedback.pushInfo( f"Requested texture size: {wm:.2f}x{hm:.2f} m, {wpix}x{hpix} pixels." ) # Render and save image render = QgsMapRendererParallelJob(settings) render.start() t0 = time.time() while render.isActive(): dt = time.time() - t0 QCoreApplication.processEvents() if feedback.isCanceled(): render.cancelWithoutBlocking() return if dt >= 30.0: render.cancelWithoutBlocking() feedback.reportError("Render timed out, no texture saved.") return image = render.renderedImage() try: image.save(filepath, imagetype) except IOError: raise QgsProcessingException( f"Texture not writable to <{filepath}>, cannot proceed." ) feedback.pushInfo(f"Texture saved in {dt:.2f} seconds.")
def setDebugInfo(self, msg): if self.showDebug: self.setInfo('<span style="color:blue">%s</span>' % msg) QCoreApplication.processEvents()
def export_mf_recharge(self): QSWATMOD_path_dict = self.dirs_and_paths() stdate, eddate, stdate_warmup, eddate_warmup = self.define_sim_period() wd = QSWATMOD_path_dict['SMfolder'] startDate = stdate.strftime("%m-%d-%Y") # Open "swatmf_out_MF_recharge" file y = ("MODFLOW", "--Calculated", "daily", "Monthly", "Yearly" ) # Remove unnecssary lines if self.dlg.radioButton_mf_results_d.isChecked(): filename = "swatmf_out_MF_recharge" self.layer = QgsProject.instance().mapLayersByName("mf_rch_daily")[0] with open(os.path.join(wd, filename), "r") as f: data = [ x.strip() for x in f if x.strip() and not x.strip().startswith(y) ] # Remove blank lines date = [ x.strip().split() for x in data if x.strip().startswith("Day:") ] # Collect only lines with dates onlyDate = [x[1] for x in date] # Only date data1 = [x.split() for x in data] # make each line a list sdate = datetime.datetime.strptime( startDate, "%m-%d-%Y") # Change startDate format dateList = [ (sdate + datetime.timedelta(days=int(i) - 1)).strftime("%m-%d-%Y") for i in onlyDate ] elif self.dlg.radioButton_mf_results_m.isChecked(): filename = "swatmf_out_MF_recharge_monthly" self.layer = QgsProject.instance().mapLayersByName("mf_rch_monthly")[0] with open(os.path.join(wd, filename), "r") as f: data = [ x.strip() for x in f if x.strip() and not x.strip().startswith(y) ] # Remove blank lines date = [ x.strip().split() for x in data if x.strip().startswith("month:") ] # Collect only lines with dates onlyDate = [x[1] for x in date] # Only date data1 = [x.split() for x in data] # make each line a list dateList = pd.date_range(startDate, periods=len(onlyDate), freq='M').strftime("%b-%Y").tolist() elif self.dlg.radioButton_mf_results_y.isChecked(): filename = "swatmf_out_MF_recharge_yearly" self.layer = QgsProject.instance().mapLayersByName("mf_rch_yearly")[0] with open(os.path.join(wd, filename), "r") as f: data = [ x.strip() for x in f if x.strip() and not x.strip().startswith(y) ] # Remove blank lines date = [ x.strip().split() for x in data if x.strip().startswith("year:") ] # Collect only lines with dates onlyDate = [x[1] for x in date] # Only date data1 = [x.split() for x in data] # make each line a list dateList = pd.date_range(startDate, periods=len(onlyDate), freq='A').strftime("%Y").tolist() else: msgBox = QMessageBox() msgBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png')) msgBox.setWindowTitle("Oops!") msgBox.setText("Please, select one of the time options!") msgBox.exec_() selectedSdate = self.dlg.comboBox_mf_results_sdate.currentText() selectedEdate = self.dlg.comboBox_mf_results_edate.currentText() # Reverse step dateSidx = dateList.index(selectedSdate) dateEidx = dateList.index(selectedEdate) dateList_f = dateList[dateSidx:dateEidx + 1] input1 = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[ 0] # Put this here to know number of features per = 0 self.dlg.progressBar_mf_results.setValue(0) for selectedDate in dateList_f: # Reverse step dateIdx = dateList.index(selectedDate) #only onlyDate_lookup = onlyDate[dateIdx] if self.dlg.radioButton_mf_results_d.isChecked(): for num, line in enumerate(data1, 1): if line[0] == "Day:" in line and line[ 1] == onlyDate_lookup in line: ii = num # Starting line elif self.dlg.radioButton_mf_results_m.isChecked(): # Find year dt = datetime.datetime.strptime(selectedDate, "%b-%Y") year = dt.year for num, line in enumerate(data1, 1): if ((line[0] == "month:" in line) and (line[1] == onlyDate_lookup in line) and (line[3] == str(year) in line)): ii = num # Starting line elif self.dlg.radioButton_mf_results_y.isChecked(): for num, line in enumerate(data1, 1): if line[0] == "year:" in line and line[ 1] == onlyDate_lookup in line: ii = num # Starting line mf_rchs = [] count = 0 while count < input1.featureCount(): for jj in range(len(data1[ii])): mf_rchs.append(float(data1[ii][jj])) count += 1 ii += 1 provider = self.layer.dataProvider() if self.layer.dataProvider().fields().indexFromName( selectedDate) == -1: field = QgsField(selectedDate, QVariant.Double, 'double', 20, 5) provider.addAttributes([field]) self.layer.updateFields() mf_rchs_idx = provider.fields().indexFromName(selectedDate) tot_feats = self.layer.featureCount() count = 0 # Get features (Find out a way to change attribute values using another field) feats = self.layer.getFeatures() self.layer.startEditing() # add row number for f, mf_rch in zip(feats, mf_rchs): self.layer.changeAttributeValue(f.id(), mf_rchs_idx, mf_rch) count += 1 provalue = round(count / tot_feats * 100) self.dlg.progressBar_rch_head.setValue(provalue) QCoreApplication.processEvents() self.layer.commitChanges() QCoreApplication.processEvents() # Update progress bar per += 1 progress = round((per / len(dateList_f)) * 100) self.dlg.progressBar_mf_results.setValue(progress) QCoreApplication.processEvents() self.dlg.raise_() msgBox = QMessageBox() msgBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png')) msgBox.setWindowTitle("Exported!") msgBox.setText("mf_recharge results were exported successfully!") msgBox.exec_()
def print_info(self, text, text_color='#000000', clear=False): self.txtStdout.setTextColor(QColor(text_color)) self.txtStdout.append(text) QCoreApplication.processEvents()
def waitForFetch(self): self.fetched = False while not self.fetched: QCoreApplication.processEvents()
def setInfo(self, msg, error=False): if error: self.txtLog.append('<span style="color:red"><br>%s<br></span>' % msg) else: self.txtLog.append(msg) QCoreApplication.processEvents()
def setText(self, text): self.lblProgress.setText(text) self.setInfo(text, False) QCoreApplication.processEvents()
def test_service(self): self.setEnabled(False) QCoreApplication.processEvents() res, msg = self.is_source_service_valid() self.setEnabled(True) self.show_message(msg['text'], msg['level'])
def create_MF_grid(self): # Create fishnet based on user inputs time = datetime.now().strftime('[%m/%d/%y %H:%M:%S]') self.textEdit_mf_log.append(time+' -> ' + "Creating MODFLOW grids ... processing") self.label_mf_status.setText("Creating MODFLOW grids ... ") self.progressBar_mf_status.setValue(0) QCoreApplication.processEvents() APEXMOD_path_dict = self.dirs_and_paths() input1 = QgsProject.instance().mapLayersByName("mf_boundary (MODFLOW)")[0] ext = input1.extent() xmin = ext.xMinimum() xmax = ext.xMaximum() ymin = ext.yMinimum() ymax = ext.yMaximum() delc = float(self.doubleSpinBox_delc.value()) delr = float(self.doubleSpinBox_delr.value()) # Add_Subtract number of column, row n_row = self.spinBox_row.value() n_col = self.spinBox_col.value() if self.groupBox_mf_add.isChecked(): xmax = xmax + (delc * n_col) ymin = ymin - (delr * n_row) nx = round(abs(abs(xmax) - abs(xmin)) / delc) ny = round(abs(abs(ymax) - abs(ymin)) / delr) else: nx = round(abs(abs(xmax) - abs(xmin)) / delc) ny = round(abs(abs(ymax) - abs(ymin)) / delr) ngrid = abs(int(nx*ny)) MF_extent = "{a},{b},{c},{d}".format(a=xmin, b=xmax, c=ymin, d=ymax) # create dummy grid name_ext_ = "mf_grid_.gpkg" output_dir = APEXMOD_path_dict['org_shps'] output_file_ = os.path.normpath(os.path.join(output_dir, name_ext_)) crs = input1.crs() # running the acutal routine: params_ = { 'TYPE': 2, 'EXTENT': MF_extent, 'HSPACING': delc, 'VSPACING': delr, 'CRS': crs, 'OUTPUT': output_file_ } processing.run("native:creategrid", params_) time = datetime.now().strftime('[%m/%d/%y %H:%M:%S]') self.textEdit_mf_log.append(time+' -> ' + "Creating MODFLOW grids ... passed") self.label_mf_status.setText('Step Status: ') self.progressBar_mf_status.setValue(100) QCoreApplication.processEvents() time = datetime.now().strftime('[%m/%d/%y %H:%M:%S]') self.textEdit_mf_log.append(time+' -> ' + "Fixing starting index ... processing") self.label_mf_status.setText("Fixing starting index... ") self.progressBar_mf_status.setValue(0) QCoreApplication.processEvents() # rasterize name_ext_r = 'mf_grid_.tif' output_file_r = os.path.normpath(os.path.join(output_dir, name_ext_r)) params_r = { 'INPUT': output_file_, 'UNITS': 1, 'WIDTH': delc, 'HEIGHT': delr, 'EXTENT': MF_extent, 'NODATA': -9999, 'DATA_TYPE': 5, 'OUTPUT': output_file_r } processing.run("gdal:rasterize", params_r) # vecterize name_ext_v = 'mf_grid.gpkg' output_file_v = os.path.normpath(os.path.join(output_dir, name_ext_v)) # params_v = { 'INPUT_RASTER': output_file_r, 'RASTER_BAND': 1, 'FIELD': 'VALUE', 'OUTPUT': output_file_v } processing.run("native:pixelstopolygons", params_v) # Define the outputfile to be loaded into the canvas mf_grid_shapefile = os.path.join(output_dir, name_ext_v) layer = QgsVectorLayer(mf_grid_shapefile, '{0} ({1})'.format("mf_grid","MODFLOW"), 'ogr') # Put in the group root = QgsProject.instance().layerTreeRoot() mf_group = root.findGroup("MODFLOW") QgsProject.instance().addMapLayer(layer, False) mf_group.insertChildNode(0, QgsLayerTreeLayer(layer)) time = datetime.now().strftime('[%m/%d/%y %H:%M:%S]') self.textEdit_mf_log.append(time+' -> ' + "Fixing starting index ... passed") self.label_mf_status.setText('Step Status: ') self.progressBar_mf_status.setValue(100) QCoreApplication.processEvents()
def test_read_write_project(self): """ Test saving/restoring dialog state in project """ # print('read write project test') p = QgsProject.instance() dialog = DataPlotlyPanelWidget(None, override_iface=IFACE) dialog.set_plot_type('violin') # first, disable saving to project dialog.read_from_project = False dialog.save_to_project = False path = os.path.join(tempfile.gettempdir(), 'test_dataplotly_project.qgs') layer_path = os.path.join(os.path.dirname(__file__), 'test_layer.geojson') # create QgsVectorLayer from path and test validity vl = QgsVectorLayer(layer_path, 'test_layer', 'ogr') self.assertTrue(vl.isValid()) # print(dialog.layer_combo.currentLayer()) self.assertTrue(p.write(path)) res = PlotSettings() # def read(doc): # self.assertTrue(res.read_from_project(doc)) # self.assertEqual(res.plot_type, 'violin') # self.read_triggered = True p.clear() for _ in range(100): QCoreApplication.processEvents() self.assertTrue(p.read(path)) self.assertEqual(res.plot_type, 'scatter') # TODO - enable when dialog can restore properties and avoid this fragile test # # enable saving to project # dialog.save_to_project = True # dialog.read_from_project = True # self.assertTrue(p.write(path)) # for _ in range(100): # QCoreApplication.processEvents() # p.clear() # p.readProject.connect(read) # self.assertTrue(p.read(path)) # for _ in range(100): # QCoreApplication.processEvents() # self.assertTrue(self.read_triggered) # todo - test that dialog can restore properties, but requires the missing set_settings method dialog.x_combo.setExpression('"Ca"') dialog.layer_combo.setLayer(vl) dialog.x_combo.currentText() self.assertTrue(dialog.x_combo.expression(), '"Ca"')
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()) 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: layer.selectByRect(self.extent) self.__offline_layers.append(layer) 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] if not self.offline_editing.convertToOfflineProject(self.export_folder, gpkg_filename, offline_layer_ids, self.project_configuration.offline_copy_only_aoi, self.offline_editing.GPKG): 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] if not self.offline_editing.convertToOfflineProject(self.export_folder, spatialite_filename, offline_layer_ids, self.project_configuration.offline_copy_only_aoi): 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: 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 on_process_started(self, command): self.disable() self.txtStdout.setTextColor(QColor(LogColor.COLOR_INFO)) self.txtStdout.clear() self.txtStdout.setText(command) QCoreApplication.processEvents()
def on_process_started(self, command): self.txtStdout.setText(command) QCoreApplication.processEvents()
def writeMF(self): self.DB_push_mf_userVal() from APEXMOD.pyfolder.writeMF import extentlayer self.textEdit_mf_log.append(" ") self.textEdit_mf_log.append("- Exporting MODFLOW input files...") # ''' self.checkBox_mfPrepared.setChecked(0) self.progressBar_mf.setValue(0) # Bottom if (self.radioButton_aq_thic_single.isChecked() or self.radioButton_aq_thic_uniform.isChecked()): writeMF.createBotElev(self) self.progressBar_mf.setValue(10) QCoreApplication.processEvents() writeMF.cvtBotElevToR(self) self.progressBar_mf.setValue(20) QCoreApplication.processEvents() # HK if (self.radioButton_hk_raster.isChecked() and self.lineEdit_hk_raster.text()): writeMF.cvtHKtoR(self) self.progressBar_mf.setValue(30) QCoreApplication.processEvents() else: self.progressBar_mf.setValue(40) QCoreApplication.processEvents() # writeMF.cvtHKtoR(self) # self.progressBar_mf.setValue(40) # QCoreApplication.processEvents() # SS if (self.radioButton_ss_raster.isChecked() and self.lineEdit_ss_raster.text()): writeMF.cvtSStoR(self) self.progressBar_mf.setValue(60) QCoreApplication.processEvents() else: # writeMF.createSY(self) self.progressBar_mf.setValue(70) QCoreApplication.processEvents() # SY if (self.radioButton_sy_raster.isChecked() and self.lineEdit_sy_raster.text()): writeMF.cvtSYtoR(self) self.progressBar_mf.setValue(80) QCoreApplication.processEvents() else: self.progressBar_mf.setValue(85) QCoreApplication.processEvents() # IH if (self.radioButton_initialH_single.isChecked() or self.radioButton_initialH_uniform.isChecked()): writeMF.createInitialH(self) self.progressBar_mf.setValue(90) QCoreApplication.processEvents() writeMF.cvtInitialHtoR(self) self.progressBar_mf.setValue(95) QCoreApplication.processEvents() # EVT if self.groupBox_evt.isChecked(): if (self.radioButton_evt_raster.isChecked() and self.lineEdit_evt_raster.text()): writeMF.cvtEVTtoR(self) self.progressBar_mf.setValue(80) QCoreApplication.processEvents() else: self.progressBar_mf.setValue(85) QCoreApplication.processEvents() # ''' writeMF.writeMFmodel(self) self.progressBar_mf.setValue(100) self.checkBox_mfPrepared.setChecked(1)
def setPercentage(self, i): self.progress_updated.emit(i, 100) QCoreApplication.processEvents()
def setCommand(self, cmd): if self.showDebug: self.setInfo('<code>%s<code>' % cmd) QCoreApplication.processEvents()
class TestQgsNetworkContentFetcher(unittest.TestCase): @classmethod def setUpClass(cls): # Bring up a simple HTTP server os.chdir(unitTestDataPath() + '') handler = http.server.SimpleHTTPRequestHandler cls.httpd = socketserver.TCPServer(('localhost', 0), handler) cls.port = cls.httpd.server_address[1] cls.httpd_thread = threading.Thread(target=cls.httpd.serve_forever) cls.httpd_thread.setDaemon(True) cls.httpd_thread.start() def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.loaded = False self.app = QCoreApplication([]) def contentLoaded(self): self.loaded = True def testFetchEmptyUrl(self): fetcher = QgsNetworkContentFetcher() self.loaded = False fetcher.fetchContent(QUrl()) fetcher.finished.connect(self.contentLoaded) while not self.loaded: self.app.processEvents() r = fetcher.reply() assert r.error() != QNetworkReply.NoError def testFetchBadUrl(self): fetcher = QgsNetworkContentFetcher() self.loaded = False fetcher.fetchContent(QUrl('http://x')) fetcher.finished.connect(self.contentLoaded) while not self.loaded: self.app.processEvents() r = fetcher.reply() assert r.error() != QNetworkReply.NoError def testFetchUrlContent(self): fetcher = QgsNetworkContentFetcher() self.loaded = False fetcher.fetchContent( QUrl('http://localhost:' + str(TestQgsNetworkContentFetcher.port) + '/qgis_local_server/index.html')) fetcher.finished.connect(self.contentLoaded) while not self.loaded: self.app.processEvents() r = fetcher.reply() assert r.error() == QNetworkReply.NoError, r.error() html = fetcher.contentAsString() assert 'QGIS' in html def testDoubleFetch(self): fetcher = QgsNetworkContentFetcher() self.loaded = False fetcher.fetchContent(QUrl('http://www.qgis.org/')) # double fetch - this should happen before previous request finishes fetcher.fetchContent( QUrl('http://localhost:' + str(TestQgsNetworkContentFetcher.port) + '/qgis_local_server/index.html')) fetcher.finished.connect(self.contentLoaded) while not self.loaded: self.app.processEvents() r = fetcher.reply() assert r.error() == QNetworkReply.NoError, r.error() html = fetcher.contentAsString() assert 'QGIS' in html def testFetchEncodedContent(self): fetcher = QgsNetworkContentFetcher() self.loaded = False fetcher.fetchContent( QUrl('http://localhost:' + str(TestQgsNetworkContentFetcher.port) + '/encoded_html.html')) fetcher.finished.connect(self.contentLoaded) while not self.loaded: self.app.processEvents() r = fetcher.reply() assert r.error() == QNetworkReply.NoError, r.error() html = fetcher.contentAsString() assert chr(6040) in html
def updateMenus(): removeMenus() QCoreApplication.processEvents() createMenus()
def setConsoleInfo(self, msg): if self.showDebug: self.setCommand('<span style="color:darkgray">%s</span>' % msg) QCoreApplication.processEvents()
def testModel(self): m = QgsLocatorModel() l = QgsLocator() filter_a = test_filter('a') l.registerFilter(filter_a) l.foundResult.connect(m.addResult) context = QgsLocatorContext() l.fetchResults('a', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() # 4 results - one is locator name self.assertEqual(m.rowCount(), 4) self.assertEqual(m.data(m.index(0, 0)), 'test') self.assertEqual(m.data(m.index(0, 0), QgsLocatorModel.ResultTypeRole), 0) self.assertEqual( m.data(m.index(0, 0), QgsLocatorModel.ResultFilterNameRole), 'test') self.assertEqual(m.data(m.index(1, 0)), 'a0') self.assertEqual(m.data(m.index(1, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual( m.data(m.index(1, 0), QgsLocatorModel.ResultFilterNameRole), 'test') self.assertEqual(m.data(m.index(2, 0)), 'a1') self.assertEqual(m.data(m.index(2, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual( m.data(m.index(2, 0), QgsLocatorModel.ResultFilterNameRole), 'test') self.assertEqual(m.data(m.index(3, 0)), 'a2') self.assertEqual(m.data(m.index(3, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual( m.data(m.index(3, 0), QgsLocatorModel.ResultFilterNameRole), 'test') m.clear() self.assertEqual(m.rowCount(), 0) l.fetchResults('b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(m.rowCount(), 4) self.assertEqual(m.data(m.index(1, 0)), 'a0') self.assertEqual(m.data(m.index(2, 0)), 'a1') self.assertEqual(m.data(m.index(3, 0)), 'a2') m.deferredClear() # should not be immediately cleared! self.assertEqual(m.rowCount(), 4) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(m.rowCount(), 0)
def write_texture( feedback, tex_layer, tex_extent, tex_pixel_size, utm_crs, # destination_crs filepath, imagetype, ): """ Crop and save texture to image file. """ # Calc tex_extent size in meters (it is in utm) tex_extent_xm = tex_extent.xMaximum() - tex_extent.xMinimum() tex_extent_ym = tex_extent.yMaximum() - tex_extent.yMinimum() # Calc tex_extent size in pixels tex_extent_xpix = int(tex_extent_xm / tex_pixel_size) tex_extent_ypix = int(tex_extent_ym / tex_pixel_size) # Choose exporting layers if tex_layer: # use user tex layer layers = (tex_layer,) else: # no user tex layer, use map canvas canvas = iface.mapCanvas() layers = canvas.layers() # Image settings and texture layer choice settings = QgsMapSettings() # build settings settings.setDestinationCrs(utm_crs) # set output crs settings.setExtent(tex_extent) # in utm_crs settings.setOutputSize(QSize(tex_extent_xpix, tex_extent_ypix)) settings.setLayers(layers) feedback.pushInfo( f"Texture size: {tex_extent_xpix} x {tex_extent_ypix} pixels, {tex_extent_xm:.1f} x {tex_extent_ym:.1f} meters" ) # Render and save image render = QgsMapRendererParallelJob(settings) render.start() t0 = time.time() while render.isActive(): dt = time.time() - t0 QCoreApplication.processEvents() if feedback.isCanceled(): render.cancelWithoutBlocking() return if dt >= 30.0: render.cancelWithoutBlocking() feedback.reportError("Texture render timed out, no texture saved.") return image = render.renderedImage() try: image.save(filepath, imagetype) except IOError: raise QgsProcessingException( f"Texture not writable to <{filepath}>, cannot proceed." ) feedback.pushInfo(f"Saved (in {dt:.2f} s): <{filepath}>")
def testPrefixes(self): """ Test custom (active) prefixes """ def got_hit(result): got_hit._results_.append(result.displayString) got_hit._results_ = [] context = QgsLocatorContext() l = QgsLocator() # filter with prefix filter_a = test_filter('a', 'aaa') l.registerFilter(filter_a) self.assertEqual(filter_a.prefix(), 'aaa') self.assertEqual(filter_a.activePrefix(), 'aaa') self.assertEqual(filter_a.useWithoutPrefix(), True) l.foundResult.connect(got_hit) l.fetchResults('aaa a', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'a0', 'a1', 'a2'}) got_hit._results_ = [] l.fetchResults('bbb b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'a0', 'a1', 'a2'}) got_hit._results_ = [] filter_a.setUseWithoutPrefix(False) self.assertEqual(filter_a.useWithoutPrefix(), False) l.fetchResults('bbb b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(got_hit._results_, []) got_hit._results_ = [] # test with two filters filter_b = test_filter('b', 'bbb') l.registerFilter(filter_b) self.assertEqual(filter_b.prefix(), 'bbb') self.assertEqual(filter_b.activePrefix(), 'bbb') got_hit._results_ = [] l.fetchResults('bbb b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'b0', 'b1', 'b2'}) l.deregisterFilter(filter_b) # test with two filters with same prefix filter_b = test_filter('b', 'aaa') l.registerFilter(filter_b) self.assertEqual(filter_b.prefix(), 'aaa') self.assertEqual(filter_b.activePrefix(), 'aaa') got_hit._results_ = [] l.fetchResults('aaa b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'a0', 'a1', 'a2', 'b0', 'b1', 'b2'}) l.deregisterFilter(filter_b) # filter with invalid prefix (less than 3 char) filter_c = test_filter('c', 'bb') l.registerFilter(filter_c) self.assertEqual(filter_c.prefix(), 'bb') self.assertEqual(filter_c.activePrefix(), '') got_hit._results_ = [] l.fetchResults('b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'c0', 'c1', 'c2'}) l.deregisterFilter(filter_c) # filter with custom prefix QgsSettings().setValue("locator_filters/prefix_test_custom", 'xyz', QgsSettings.Gui) filter_c = test_filter('custom', 'abc') l.registerFilter(filter_c) self.assertEqual(filter_c.prefix(), 'abc') self.assertEqual(filter_c.activePrefix(), 'xyz') got_hit._results_ = [] l.fetchResults('b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(set(got_hit._results_), {'custom0', 'custom1', 'custom2'}) l.deregisterFilter(filter_c) del l
def testModel(self): m = QgsLocatorModel() p = QgsLocatorProxyModel(m) p.setSourceModel(m) l = QgsLocator() filter_a = test_filter('a') l.registerFilter(filter_a) l.foundResult.connect(m.addResult) context = QgsLocatorContext() l.fetchResults('a', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() # 4 results - one is locator name self.assertEqual(p.rowCount(), 4) self.assertEqual(p.data(p.index(0, 0)), 'test_a') self.assertEqual(p.data(p.index(0, 0), QgsLocatorModel.ResultTypeRole), 0) self.assertEqual(p.data(p.index(0, 0), QgsLocatorModel.ResultFilterNameRole), 'test_a') self.assertEqual(p.data(p.index(1, 0)), 'a0') self.assertEqual(p.data(p.index(1, 0), QgsLocatorModel.ResultTypeRole), QgsLocatorModel.NoGroup) self.assertEqual(p.data(p.index(1, 0), QgsLocatorModel.ResultFilterNameRole), 'test_a') self.assertEqual(p.data(p.index(2, 0)), 'a1') self.assertEqual(p.data(p.index(2, 0), QgsLocatorModel.ResultTypeRole), QgsLocatorModel.NoGroup) self.assertEqual(p.data(p.index(2, 0), QgsLocatorModel.ResultFilterNameRole), 'test_a') self.assertEqual(p.data(p.index(3, 0)), 'a2') self.assertEqual(p.data(p.index(3, 0), QgsLocatorModel.ResultTypeRole), QgsLocatorModel.NoGroup) self.assertEqual(p.data(p.index(3, 0), QgsLocatorModel.ResultFilterNameRole), 'test_a') m.clear() self.assertEqual(p.rowCount(), 0) l.fetchResults('b', context) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(p.rowCount(), 4) self.assertEqual(p.data(p.index(1, 0)), 'a0') self.assertEqual(p.data(p.index(2, 0)), 'a1') self.assertEqual(p.data(p.index(3, 0)), 'a2') m.deferredClear() # should not be immediately cleared! self.assertEqual(p.rowCount(), 4) for i in range(100): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(p.rowCount(), 0) m.clear() # test with groups self.assertEqual(p.rowCount(), 0) filter_b = test_filter('b', None, True) l.registerFilter(filter_b) l.fetchResults('c', context) for i in range(200): sleep(0.002) QCoreApplication.processEvents() self.assertEqual(p.rowCount(), 16) # 1 title a + 3 results + 1 title b + 2 groups + 9 results self.assertEqual(p.data(p.index(0, 0)), 'test_a') self.assertEqual(p.data(p.index(0, 0), QgsLocatorModel.ResultTypeRole), 0) self.assertEqual(p.data(p.index(1, 0)), 'a0') self.assertEqual(p.data(p.index(1, 0), QgsLocatorModel.ResultTypeRole), QgsLocatorModel.NoGroup) self.assertEqual(p.data(p.index(2, 0)), 'a1') self.assertEqual(p.data(p.index(2, 0), QgsLocatorModel.ResultTypeRole), QgsLocatorModel.NoGroup) self.assertEqual(p.data(p.index(3, 0)), 'a2') self.assertEqual(p.data(p.index(3, 0), QgsLocatorModel.ResultTypeRole), QgsLocatorModel.NoGroup) self.assertEqual(p.data(p.index(4, 0)), 'test_b') self.assertEqual(p.data(p.index(4, 0), QgsLocatorModel.ResultTypeRole), 0) self.assertEqual(p.data(p.index(4, 0), QgsLocatorModel.ResultFilterNameRole), 'test_b') self.assertEqual(p.data(p.index(5, 0)).strip(), 'first group') self.assertEqual(p.data(p.index(5, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(p.data(p.index(6, 0)), 'b0') self.assertEqual(p.data(p.index(6, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(p.data(p.index(7, 0)), 'b1') self.assertEqual(p.data(p.index(7, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(p.data(p.index(8, 0)), 'b2') self.assertEqual(p.data(p.index(8, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(p.data(p.index(9, 0)), 'b3') self.assertEqual(p.data(p.index(9, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(p.data(p.index(10, 0)), 'b4') self.assertEqual(p.data(p.index(10, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(p.data(p.index(11, 0)), 'b5') self.assertEqual(p.data(p.index(11, 0), QgsLocatorModel.ResultTypeRole), 1) self.assertEqual(p.data(p.index(12, 0)).strip(), 'second group') self.assertEqual(p.data(p.index(12, 0), QgsLocatorModel.ResultTypeRole), 2) self.assertEqual(p.data(p.index(13, 0)), 'b6') self.assertEqual(p.data(p.index(13, 0), QgsLocatorModel.ResultTypeRole), 2) self.assertEqual(p.data(p.index(14, 0)), 'b7') self.assertEqual(p.data(p.index(14, 0), QgsLocatorModel.ResultTypeRole), 2) self.assertEqual(p.data(p.index(15, 0)), 'b8') self.assertEqual(p.data(p.index(15, 0), QgsLocatorModel.ResultTypeRole), QgsLocatorModel.NoGroup)
def search_data(self, **kwargs): """ Get plot geometries associated with parcels, both collected and supplies, zoom to them, fill comparison table and activate map swipe tool. To fill the comparison table we build two search dicts, one for supplies (already given because the alphanumeric search is on supplies db source), and another one for collected. For the latter, we have 3 cases. We specify them below (inline). :param kwargs: key-value (field name-field value) to search in parcel tables, both collected and supplies Normally, keys are parcel_number, old_parcel_number or FMI, but if duplicates are found, an additional t_id disambiguates only for the collected source. In the supplies source we assume we will not find duplicates, if there are, we will choose the first record found an will not deal with letting the user choose one of the duplicates by hand (as we do for the collected source). """ self.chk_show_all_plots.setEnabled(False) self.chk_show_all_plots.setChecked(True) self.initialize_tools_and_layers() # Reset any filter on layers plots_supplies = list() plots_collected = list() self.clear_result_table() search_option = self.cbo_parcel_fields.currentData() search_field_supplies = get_supplies_search_options( self.utils._supplies_db.names)[search_option] search_field_collected = get_collected_search_options( self.utils._db.names)[search_option] search_value = list(kwargs.values())[0] # Build search criterion for both supplies and collected search_criterion_supplies = {search_field_supplies: search_value} # Get supplies parcel's t_id and get related plot(s) expression_supplies = QgsExpression("{}='{}'".format( search_field_supplies, search_value)) request = QgsFeatureRequest(expression_supplies) field_idx = self.utils._supplies_layers[ self.utils._supplies_db.names.GC_PARCEL_T].fields().indexFromName( self.utils._supplies_db.names.T_ID_F) request.setFlags(QgsFeatureRequest.NoGeometry) request.setSubsetOfAttributes([field_idx ]) # Note: this adds a new flag supplies_parcels = [ feature for feature in self.utils._supplies_layers[ self.utils._supplies_db.names.GC_PARCEL_T].getFeatures(request) ] if len(supplies_parcels) > 1: # We do not expect duplicates in the supplies source! pass # We'll choose the first one anyways elif len(supplies_parcels) == 0: self.logger.info( __name__, "No supplies parcel found! Search: {}={}".format( search_field_supplies, search_value)) supplies_plot_t_ids = [] if supplies_parcels: supplies_plot_t_ids = self.utils.ladm_data.get_plots_related_to_parcels_supplies( self.utils._supplies_db, [supplies_parcels[0][self.utils._supplies_db.names.T_ID_F]], self.utils._supplies_db.names.T_ID_F, self.utils._supplies_layers[ self.utils._supplies_db.names.GC_PLOT_T]) if supplies_plot_t_ids: self._current_supplies_substring = "\"{}\" IN ('{}')".format( self.utils._supplies_db.names.T_ID_F, "','".join([str(t_id) for t_id in supplies_plot_t_ids])) plots_supplies = self.utils.ladm_data.get_features_from_t_ids( self.utils._supplies_layers[ self.utils._supplies_db.names.GC_PLOT_T], self.utils._supplies_db.names.T_ID_F, supplies_plot_t_ids, True) # Now get COLLECTED parcel's t_id to build the search dict for collected collected_parcel_t_id = None if 'collected_parcel_t_id' in kwargs: # This is the case when this panel is called and we already know the parcel number is duplicated collected_parcel_t_id = kwargs['collected_parcel_t_id'] search_criterion_collected = { self.utils._db.names.T_ID_F: collected_parcel_t_id } # As there are duplicates, we need to use t_ids else: # This is the case when: # + Either this panel was called and we know the parcel number is not duplicated, or # + This panel was shown without knowing about duplicates (e.g., individual parcel search) and we still # need to discover whether we have duplicates for this search criterion search_criterion_collected = {search_field_collected: search_value} expression_collected = QgsExpression("{}='{}'".format( search_field_collected, search_value)) request = QgsFeatureRequest(expression_collected) request.setFlags(QgsFeatureRequest.NoGeometry) request.setSubsetOfAttributes( [self.utils._db.names.T_ID_F], self.utils._layers[self.utils._db.names.LC_PARCEL_T].fields( )) # Note this adds a new flag collected_parcels = self.utils._layers[ self.utils._db.names.LC_PARCEL_T].getFeatures(request) collected_parcels_t_ids = [ feature[self.utils._db.names.T_ID_F] for feature in collected_parcels ] if collected_parcels_t_ids: collected_parcel_t_id = collected_parcels_t_ids[0] if len(collected_parcels_t_ids ) > 1: # Duplicates in collected source after a search QApplication.restoreOverrideCursor( ) # Make sure cursor is not waiting (it is if on an identify) QCoreApplication.processEvents() dlg_select_parcel = SelectDuplicateParcelDialog( self.utils, collected_parcels_t_ids, self.parent) dlg_select_parcel.exec_() if dlg_select_parcel.parcel_t_id: # User selected one of the duplicated parcels collected_parcel_t_id = dlg_select_parcel.parcel_t_id search_criterion_collected = { self.utils._db.names.T_ID_F: collected_parcel_t_id } else: return # User just cancelled the dialog, there is nothing more to do self.fill_table(search_criterion_supplies, search_criterion_collected) # Now get related plot(s) for both collected and supplies, if collected_parcel_t_id is not None: plot_t_ids = self.utils.ladm_data.get_plots_related_to_parcels( self.utils._db, [collected_parcel_t_id], self.utils._db.names.T_ID_F, plot_layer=self.utils._layers[self.utils._db.names.LC_PLOT_T], uebaunit_table=self.utils._layers[ self.utils._db.names.COL_UE_BAUNIT_T]) if plot_t_ids: self._current_substring = "{} IN ('{}')".format( self.utils._db.names.T_ID_F, "','".join([str(t_id) for t_id in plot_t_ids])) plots_collected = self.utils.ladm_data.get_features_from_t_ids( self.utils._layers[self.utils._db.names.LC_PLOT_T], self.utils._db.names.T_ID_F, plot_t_ids, True) # Zoom to combined extent plot_features = plots_supplies + plots_collected # Feature list plots_extent = QgsRectangle() for plot in plot_features: plots_extent.combineExtentWith(plot.geometry().boundingBox()) if not plots_extent.isEmpty(): self.utils.iface.mapCanvas().zoomToFeatureExtent(plots_extent) if plots_supplies and plots_collected: # Otherwise the map swipe tool doesn't add any value :) # Activate Swipe Tool self.utils.app.gui.activate_layer(self.utils._supplies_layers[ self.utils._supplies_db.names.GC_PLOT_T]) self.parent.activate_map_swipe_tool() # Send a custom mouse move on the map to make the map swipe tool's limit appear on the canvas coord_x = plots_extent.xMaximum() - (plots_extent.xMaximum( ) - plots_extent.xMinimum()) / 9 # 90% coord_y = plots_extent.yMaximum() - (plots_extent.yMaximum( ) - plots_extent.yMinimum()) / 2 # 50% coord_transform = self.utils.iface.mapCanvas( ).getCoordinateTransform() map_point = coord_transform.transform(coord_x, coord_y) widget_point = map_point.toQPointF().toPoint() global_point = self.utils.canvas.mapToGlobal(widget_point) self.utils.canvas.mousePressEvent( QMouseEvent(QEvent.MouseButtonPress, global_point, Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)) self.utils.canvas.mouseMoveEvent( QMouseEvent(QEvent.MouseMove, widget_point + QPoint(1, 0), Qt.NoButton, Qt.LeftButton, Qt.NoModifier)) self.utils.canvas.mouseReleaseEvent( QMouseEvent(QEvent.MouseButtonRelease, widget_point + QPoint(1, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)) # Once the query is done, activate the checkbox to alternate all plots/only selected plot self.chk_show_all_plots.setEnabled(True)
def search(self): QgsMessageLog.logMessage('Changing button', 'Arlula') self.dlg.searchButton.setText("Loading...") self.dlg.searchButton.setEnabled(False) self.dlg.resultTable.setRowCount(0) self.dlg.status.setText("Searching the Arlula archive...") QCoreApplication.processEvents() QgsMessageLog.logMessage('Searching', 'Arlula') QgsMessageLog.logMessage(self.start_date.toString('yyyy-MM-dd'), 'Arlula') QgsMessageLog.logMessage(self.end_date.toString('yyyy-MM-dd'), 'Arlula') QgsMessageLog.logMessage(self.res, 'Arlula') with arlulaapi.ArlulaSession(self.key, self.secret, allow_async=False, user_agent=def_ua) as arlula_session: if self.coords: res = arlula_session.search( start=self.start_date.toString('yyyy-MM-dd'), end=self.end_date.toString('yyyy-MM-dd'), res=self.res, lat=self.lat, long=self.long) QgsMessageLog.logMessage(str(self.lat), 'Arlula') QgsMessageLog.logMessage(str(self.long), 'Arlula') elif self.box: res = arlula_session.search( start=self.start_date.toString('yyyy-MM-dd'), end=self.end_date.toString('yyyy-MM-dd'), res=self.res, south=self.south, north=self.north, east=self.east, west=self.west) QgsMessageLog.logMessage(str(self.north), 'Arlula') QgsMessageLog.logMessage(str(self.south), 'Arlula') QgsMessageLog.logMessage(str(self.east), 'Arlula') QgsMessageLog.logMessage(str(self.west), 'Arlula') QgsMessageLog.logMessage("Found {} results".format(len(res)), 'Arlula') for row in res: n = self.dlg.resultTable.rowCount() self.dlg.resultTable.insertRow(n) self.dlg.resultTable.setItem(n, 0, QTableWidgetItem(row.supplier)) self.dlg.resultTable.setItem(n, 1, QTableWidgetItem(row.date[:10])) self.dlg.resultTable.setItem(n, 2, QTableWidgetItem(str(row.resolution))) self.dlg.resultTable.setItem(n, 3, QTableWidgetItem(str(row.area))) self.dlg.resultTable.setItem( n, 4, QTableWidgetItem("$" + str(row.price.scene.base / 100))) self.dlg.resultTable.setItem( n, 5, QTableWidgetItem(str(row.cloud) + "%")) self.dlg.resultTable.setItem(n, 6, QTableWidgetItem(row.thumbnail)) self.dlg.resultTable.setItem( n, 7, QTableWidgetItem(json.dumps(row.bounding))) self.dlg.resultTable.setItem(n, 8, QTableWidgetItem("Add layer")) self.dlg.resultTable.setItem(n, 9, QTableWidgetItem("Place order")) self.dlg.searchButton.setText("Search") self.dlg.status.setText(DEFAULT_STATUS) self.dlg.searchButton.setEnabled(True)