class RasterCheckerDialogWidget(QDialog): def __init__(self, parent=None, checks=[], command=None): """Constructor Args: parent: Qt parent Widget iface: QGiS interface command: Command instance with a run_it method which will be called on acceptance of the dialog """ super().__init__(parent) self.checks = checks self.setupUi(checks) self.command = command # rasterchecker only works on spatialte db (and not also postgres db) self.databases = {} self.all_databases = get_databases() for k, v in self.all_databases.items(): if "spatialite" in k: if v["db_name"]: self.databases[k] = v self.database_combo.addItems(self.databases.keys()) # Connect signals self.buttonBox.accepted.connect(self.on_accept) self.buttonBox.rejected.connect(self.on_reject) def on_accept(self): """Accept and run the Command.run_it method.""" db_key = self.database_combo.currentText() settings = self.databases[db_key] db_set = settings["db_settings"] if not os.path.isfile(db_set["db_path"]): msg = "sqlite %s not found" % str(db_set["db_path"]) raise Exception(msg) # TODO: check_all_rasters always runs. Enable check per model entry checks = [] if self.check_all_rasters.isChecked(): checks.append("check all rasters") # TODO: write improve first # improve_when_necessary may only be checked when # 'check_all_rasters' is checked # if self.improve_when_necessary.isChecked(): # checks.append('improve when necessary') self.command.run_it(checks, db_set, settings["db_type"]) self.accept() def on_reject(self): """Cancel""" self.reject() logger.debug("Reject") def closeEvent(self, event): """ Close widget, called by Qt on close :param event: QEvent, close event """ self.buttonBox.accepted.disconnect(self.on_accept) self.buttonBox.rejected.disconnect(self.on_reject) event.accept() def setupUi(self, checks): self.resize(815, 266) self.verticalLayout = QVBoxLayout(self) self.groupBox_2 = QGroupBox(self) self.groupBox_2.setObjectName("groupBox_2") self.database_combo = QComboBox(self.groupBox_2) self.database_combo.setGeometry(QRect(10, 30, 481, 34)) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.database_combo.sizePolicy().hasHeightForWidth()) self.database_combo.setSizePolicy(sizePolicy) self.database_combo.setObjectName("database_combo") self.verticalLayout.addWidget(self.groupBox_2) self.groupBox = QGroupBox(self) self.verticalLayoutBox = QVBoxLayout(self.groupBox) self.check_all_rasters = QCheckBox(self.groupBox) self.check_all_rasters.setChecked(True) self.check_all_rasters.setDisabled(True) self.verticalLayoutBox.addWidget(self.check_all_rasters) # TODO: write improve function first # self.improve_when_necessary = QCheckBox(self.groupBox) # self.improve_when_necessary.setChecked(False) # self.improve_when_necessary.setDisabled(True) # self.verticalLayoutBox.addWidget(self.improve_when_necessary) self.verticalLayout.addWidget(self.groupBox) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName("buttonBox") self.verticalLayout.addWidget(self.buttonBox) self.retranslateUi() self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) QMetaObject.connectSlotsByName(self) def retranslateUi(self): self.setWindowTitle("Raster Checker") self.groupBox_2.setTitle("Model schematisation database") self.groupBox.setTitle("Options") self.check_all_rasters.setText( "1. Check all rasters of all v2_global_settings rows")
def download_finished(self, exception, result=None): """ This is called when download_asset is finished. Exception is not None if download_asset raises an exception. result is the return value of download_asset. """ # VERY SLOW TO DO HERE # def __pszXML(nbands): # specband = '\n'.join([f"""<SpectralBand dstBand="{n+1}">\n</SpectralBand>""" for n in range(nbands)]) # return f"""<VRTDataset subClass="VRTPansharpenedDataset"> # <PansharpeningOptions> # {specband} # </PansharpeningOptions> # </VRTDataset>""" def __add_images(images, description, outdir, msgbar, check, vrt=True, shown=True): if check.isChecked() and vrt: pan = images.pop('pan', None) # take out pan if len(images) > 1: # stack images in a VRT file if there are more than one image left vrtfile = os.path.join(outdir, description + '.vrt') # to sort in r/g/b/nir order here sort(images.keys, key=lambda k: rgbn[k]) _RGBN = {'red': 1, 'green': 2, 'blue': 3, 'nir': 4} images_keys_ordered = sorted(images.keys(), key=lambda k: _RGBN.get(k, 5)) filenames = [images[k] for k in images_keys_ordered ] # filenames list in RGBN order ds = gdal.BuildVRT( vrtfile, filenames, options=gdal.BuildVRTOptions(separate=True, resolution='highest')) for i, bn in enumerate(images_keys_ordered): b = ds.GetRasterBand(i + 1) b.SetDescription(bn) ds.FlushCache() ds = None if pan is None: # nothing to do anymore, add VRT file __add_images({'vrt': vrtfile}, description, outdir, msgbar, check, vrt=False) else: # VERY SLOW TO DO HERE (perhaps as ProcessingProvider?) # nbands = len(images) # if nbands > 2: # may be a setting here for pansharpening choice # pan_ds = gdal.Open(pan) # pansharpened_ds = gdal.CreatePansharpenedVRT(__pszXML(nbands), pan_ds.GetRasterBand(1), # [ds.GetRasterBand(i + 1) for i in range(nbands)]) # pansharpened_filename = os.path.join(outdir, description + '_pansharpened.vrt') # driver = gdal.GetDriverByName('VRT') # driver.CreateCopy(pansharpened_filename, pansharpened_ds, 0) # # add ALL # __add_images({'pansharpened': pansharpened_filename, # 'pan': pan, 'vrt': vrtfile}, description, outdir, msgbar, check, vrt=False, shown=False) # else: # # just add pan and vrt files __add_images({ 'pan': pan, 'vrt': vrtfile }, description, outdir, msgbar, check, vrt=False) else: # do not stack since there are not enough images assert pan is not None # 'pan' should be not 'None' here images.update({'pan': pan}) # restore pan __add_images(images, description, outdir, msgbar, check, vrt=False) else: for k in images.keys(): fn = images[k] name = os.path.basename(fn).split('.')[0] layer = QgsRasterLayer(fn, name) if layer.isValid(): QgsProject.instance().addMapLayer(layer) if not shown: QgsProject.instance().layerTreeRoot().findLayer( layer.id()).setItemVisibilityChecked(shown) msgbar.dismiss() # unlock another downloading self.downloading = False self.dockwidget.options.setEnabled(True) self.dockwidget.results.setEnabled(True) self.dockwidget.downloadButton.setText('Download') self.dockwidget.downloadButton.setStyleSheet( 'background-color: None') # restore default background color self.dockwidget.assetsList.setEnabled(True) if exception is None: if result is None: self.log( 'Finished with no exception and no result (probably manually canceled by the user)', level=Qgis.Warning) else: assets = result['filenames'].keys() images = { asset: result['filenames'][asset] for asset in assets if not asset.lower().endswith(('_xml', 'thumbnail')) } if images: # ask to add image(s) to canvas widget = self.iface.messageBar().createMessage( f"Download {result['description']} finished") button = QPushButton(widget) button.setText('Add image(s)') widget.layout().addWidget(button) check = QCheckBox(widget) check.setText('Stack in VRT file') widget.layout().addWidget(check) if len(images) < 2: check.setDisabled(True) button.clicked.connect( lambda: __add_images(images, result['description'], result['outdir'], widget, check)) self.iface.messageBar().pushWidget(widget, Qgis.Info) else: self.info(f"Download {result['description']} finished") else: self.log("Exception: {}".format(exception), level=Qgis.Critical) raise exception