class ProgressBarLogger(QDialog): """A simple dialog with a progress bar and a label""" def __init__(self, title = None): QDialog.__init__(self, None) if title is not None: self.setWindowTitle(title) self.__label = QLabel(self) self.__layout = QVBoxLayout() self.__layout.addWidget(self.__label) self.__progress = QProgressBar(self) self.__layout.addWidget(self.__progress) self.setLayout(self.__layout) self.resize(600, 70) self.setFixedSize(600, 70) self.__progress.hide() self.show() 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 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 on_restore_pressed(self): try: barra = QProgressBar(self) barra.show() barra.setMinimum(0) barra.setMaximum(9) for a in range(10): time.sleep(1) barra.setValue(a) path = self.percorso os.popen('dropdb -U postgres pyarchinit') os.popen( 'createdb -U postgres -p 5432 -h localhost -E UTF8 -T template_postgis_20 -e pyarchinit' ) os.popen( 'pg_restore --host localhost --port 5432 --username postgres --dbname pyarchinit --role postgres --no-password --verbose %s' % str(path)) QMessageBox.warning(self, 'Messaggio', 'Ripristino completato', QMessageBox.Ok) except Exception as e: QMessageBox.warning(self, 'Messaggio', 'Ripristino fallito!!' + str(e), QMessageBox.Ok)
class ProgressBarLogger(QDialog): """A simple dialog with a progress bar and a label""" def __init__(self, title=None): QDialog.__init__(self, None) if title is not None: self.setWindowTitle(title) self.__label = QLabel(self) self.__layout = QVBoxLayout() self.__layout.addWidget(self.__label) self.__progress = QProgressBar(self) self.__layout.addWidget(self.__progress) self.setLayout(self.__layout) self.resize(600, 70) self.setFixedSize(600, 70) self.__progress.hide() self.show() 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 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()
class StatusProgressBar(object): def __init__(self, maximum=100, message_title=""): self.maximum = maximum self.message_bar = iface.messageBar().createMessage(message_title, "") self.progress_bar = QProgressBar() self.progress_bar.setMaximum(maximum) self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.message_bar.layout().addWidget(self.progress_bar) if iface is not None: iface.messageBar().pushWidget(self.message_bar, Qgis.MessageLevel()) self.step_size = 1 self.progress = 0 def set_step_size(self, step_size): self.step_size = step_size def increase_progress(self, steps=1, message=None): self.progress += steps * self.step_size self.progress_bar.setValue(self.progress) if message: self.message_bar.setText(message) def __del__(self): if iface is not None: iface.messageBar().clearWidgets()
class MessageBarProgress(QgsProcessingFeedback): def __init__(self, algname=None): self.msg = [] self.progressMessageBar = \ iface.messageBar().createMessage(self.tr('Executing algorithm <i>{0}</i>'.format(algname if algname else ''))) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, iface.messageBar().INFO) def reportError(self, msg): self.msg.append(msg) def setProgress(self, i): self.progress.setValue(i) def close(self): if self.msg: dlg = MessageDialog() dlg.setTitle(QCoreApplication.translate('MessageBarProgress', 'Problem executing algorithm')) dlg.setMessage("<br>".join(self.msg)) dlg.exec_() iface.messageBar().clearWidgets() def tr(self, string, context=''): if context == '': context = 'MessageBarProgress' return QCoreApplication.translate(context, string)
class MessageBarProgress(QgsProcessingFeedback): def __init__(self, algname=None): QgsProcessingFeedback.__init__(self) self.msg = [] self.progressMessageBar = \ iface.messageBar().createMessage(self.tr('Executing algorithm <i>{0}</i>'.format(algname if algname else ''))) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, iface.messageBar().INFO) def reportError(self, msg): self.msg.append(msg) def setProgress(self, i): self.progress.setValue(i) def close(self): if self.msg: dlg = MessageDialog() dlg.setTitle( QCoreApplication.translate('MessageBarProgress', 'Problem executing algorithm')) dlg.setMessage("<br>".join(self.msg)) dlg.exec_() iface.messageBar().clearWidgets() def tr(self, string, context=''): if context == '': context = 'MessageBarProgress' return QCoreApplication.translate(context, string)
def on_downloaded(self): widget = self.iface.messageBar().createMessage( "Géofoncier", "Téléchargement du RFU.") progress_bar = QProgressBar() progress_bar.setMinimum(0) progress_bar.setMaximum(2) widget.layout().addWidget(progress_bar) self.iface.messageBar().pushWidget(widget) progress_bar.setValue(1) # https://pro.geofoncier.fr/index.php?¢re=-196406,5983255&context=metropole url = self.permalinkCmb.currentText() if not url: return self.abort_action(msg="Veuillez renseigner le permalien.") self.url = url try: self.download(self.url) except Exception as e: return self.abort_action(msg=str(e)) self.save_permalinks(self.url) progress_bar.setValue(2) self.iface.messageBar().clearWidgets() return
def progressWidget(self): """ Retrieves a progress widget bar. """ bar = QProgressBar() bar.setTextVisible(True) bar.setValue(0) return bar
def progressdialog(self, progress): pdialog = QProgressDialog() pdialog.setWindowTitle("Progress") pdialog.setLabelText("Voortgang van importeren:") pbar = QProgressBar(pdialog) pbar.setTextVisible(True) pbar.setValue(progress) pdialog.setBar(pbar) pdialog.setMinimumWidth(300) pdialog.show() return pdialog, pbar
def OnGenerate(self): """Reads the directory and other input values. Loops the TIF files and runs the conversion.""" input_dir = self.textInput.toPlainText() output_dir = self.textOutput.toPlainText() if input_dir == output_dir: iface.messageBar().pushMessage( self.tr("Error"), self.tr("The input and output directories must differ"), level=Qgis.Critical) return directory = os.fsencode(input_dir) # Sets the color values r_color = self.mColorButton.color().red() g_color = self.mColorButton.color().green() b_color = self.mColorButton.color().blue() # Sets the progress bar item to show progress in the loop progressMessageBar = iface.messageBar().createMessage("Converting...") progress = QProgressBar() progress.setMaximum(len(os.listdir(directory))) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) i = 0 # Loop the directory for file in os.listdir(directory): progress.setValue(i + 1) filename = os.fsdecode(file) if filename.endswith(".tif"): src_filename = os.path.join(input_dir, filename) dst_filename = os.path.join(output_dir, filename) try: self.addAlpha(src_filename, dst_filename, r_color, g_color, b_color) except: iface.messageBar().pushMessage( self.tr("Error"), self. tr("The conversion did not work. Please check input and out directories." ), level=Qgis.Critical) return # If succeeded the message appears iface.messageBar().clearWidgets() iface.messageBar().pushMessage( self.tr("Success"), self.tr("Output layers saved to {}").format(output_dir), level=Qgis.Success)
def initField(self): # get current layer layer = self.iface.mapCanvas().currentLayer( ) # nF = layer.selectedFeatureCount() #print nF #self.ui.txX.setText("Yes, you can!") layer.setLabelsEnabled(True) vpr = layer.dataProvider() # Get the field of current comobox cbField_origin = str( self.ui.cbField.currentText()) #print cbField_origin print(cbField_origin) # start to edit attributes of fields layer.startEditing() allFeatures = layer.getFeatures() count = layer.featureCount() infoString = str( "<font color='red'> Creating and initializing the label fields......Wait this completed please......</font>" ) progressMessageBar = self.iface.messageBar().createMessage(infoString) progress = QProgressBar() progress.setMaximum(count) progress.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) # loop for initialization n = -1 for feature in allFeatures: feature[share.field_list[0][0]] = feature[cbField_origin] feature[share.field_list[1][0]] = 999999999999999999.0 feature[share.field_list[2][0]] = 999999999999999999.0 feature[share.field_list[3][0]] = 0.0 feature[share.field_list[4][0]] = 1 feature[share.field_list[5][0]] = "Center" feature[share.field_list[6][0]] = "Half" n = n + 1 layer.updateFeature(feature) progress.setValue(n + 1) self.iface.messageBar().clearWidgets() # updateExtents and refresh mapCanvas #layer.updateExtents() layer.commitChanges() # make sure that fields are initialize correctly self.iface.mapCanvas().refresh()
def __init__(self, parent, msg = ''): ''' progressBar class instatiation method. It creates a QgsMessageBar with provided msg and a working QProgressBar :param parent: :param msg: string ''' self.iface = parent.iface widget = self.iface.messageBar().createMessage("GooGIS plugin:",msg) progressBar = QProgressBar() progressBar.setRange(0,0) #(1,steps) progressBar.setValue(0) progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) widget.layout().addWidget(progressBar) QApplication.processEvents() self.iface.messageBar().pushWidget(widget, Qgis.Info, 50) QApplication.processEvents()
def progressBar(self): progressMessageBar = self.iface.messageBar().createMessage( "Project setup...") progress = QProgressBar() progress.setMaximum(5) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) for i in range(5): time.sleep(1) progress.setValue(i + 1) self.iface.messageBar().clearWidgets() energy_plant_radiation_class.popupMessage(self, "Project setup:", "Completed with success", "success") print("Project Loaded")
class MessageBarProgressItem(QObject): """ Message bar item which shows a progress report bar """ def __init__(self, text, iface: QgisInterface, parent: QObject = None): """ Constructor for MessageBarProgressItem :param text: text to show :param parent: parent object """ super().__init__(parent) self.iface = iface self.progressMessageBar = \ self.iface.messageBar().createMessage(text) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.destroyed.connect(self.clear_progress) self.progressMessageBar.layout().addWidget(self.progress) self.iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) def close(self): # pylint disable=may-be-static """ Closes the message bar item """ if self.progressMessageBar is not None: self.iface.messageBar().popWidget(self.progressMessageBar) def clear_progress(self): """ Called on deletion of the progress bar, e.g. by user closing the bar """ self.progress = None self.progressMessageBar = None def set_progress(self, progress: int): """ Sets the progress to show in the item :param progress: integer for percent progress, 0 - 100 """ if self.progress is not None: self.progress.setValue(progress)
class Source: def __init__(self): placeholder = 100 def set_iface(self, iface): self.iface = iface def has_options_dialog(self): return False def download_data(self, url, path, msg): if not os.path.exists(path): try: progressMessageBar = self.iface.messageBar().createMessage( "Downloading " + msg) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(self.progress) self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) http = urllib3.PoolManager() response = http.request('GET', url, preload_content=False) content_length = response.headers['Content-Length'] total_size = int(content_length) downloaded = 0 CHUNK = 256 * 10240 self.progress.setMinimum(0) self.progress.setMaximum(total_size) with open(path, 'wb') as fp: while True: time.sleep(1) chunk = response.read(CHUNK) downloaded += len(chunk) self.progress.setValue(downloaded) if not chunk: break fp.write(chunk) response.release_conn() self.iface.messageBar().clearWidgets() except urllib3.exceptions.MaxRetryError: QMessageBox.information(self.iface.mainWindow(), "HTTP Error", "Unable to download file")
class ProgressWidget(QgsMessageBar): def __init__(self, min, max, message, parent=None, timeout=1.5): """ Constructs a progress widget """ super(self.__class__, self).__init__(parent) self.min = min self.max = max sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) if parent: self.setMinimumSize(parent.width(), 40) else: self.setMinimumSize(766, 40) self.setSizePolicy(sizePolicy) self.progressBar = QProgressBar() self.progressBar.setMinimum(min) self.progressBar.setMaximum(max) self.parent = parent self.msgBarItem = QgsMessageBarItem(self.tr("INFO: "), message, self.progressBar, level=Qgis.Info, duration=timeout, parent=self.parent) self.pushItem(self.msgBarItem) self.parent.repaint() def initBar(self): """ Initializes the progress bar """ self.progressBar.setValue(0) def step(self): """ Increments the progress bar """ value = self.progressBar.value() + 1 self.progressBar.setValue(value) if value == self.max: time.sleep(1) self.close()
class WaitDialog(IgnoreKeyPressesDialog): def __init__(self, parent, title, progress=False): super().__init__(parent, Qt.WindowTitleHint) vbox = QVBoxLayout() self.progress_bar = QProgressBar() max_val = PROGRESS_BAR_MAX if progress else 0 self.progress_bar.setRange(0, max_val) self.progress_bar.setTextVisible(False) vbox.addWidget(self.progress_bar) self.setModal(True) self.setWindowTitle(title) self.setLayout(vbox) self.setMaximumHeight(0) self.setFixedWidth(parent.width() * 0.25) self.show() def update_progress(self, progress: float) -> None: self.progress_bar.setValue(int(progress * PROGRESS_BAR_MAX)) self.progress_bar.repaint() # otherwise just updates in 1% steps
class progressBar: def __init__(self, parent, title=''): ''' progressBar class instatiation method. It creates a QgsMessageBar with provided msg and a working QProgressBar :param parent: :param msg: string ''' self.iface = parent.iface self.title = title def start(self, max=0, msg=''): self.widget = self.iface.messageBar().createMessage(self.title, msg) self.progressBar = QProgressBar() self.progressBar.setRange(0, max) self.progressBar.setValue(0) self.progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.widget.layout().addWidget(self.progressBar) QApplication.processEvents() self.iface.messageBar().pushWidget(self.widget, Qgis.Info, 50) QApplication.processEvents() def setProgress(self, value): try: self.progressBar.setValue(value) QApplication.processEvents() except: pass def setMsg(self, msg): self.widget.setText(msg) QApplication.processEvents() def stop(self, msg=''): ''' the progressbar is stopped with a succes message :param msg: string :return: ''' self.iface.messageBar().clearWidgets() message = self.iface.messageBar().createMessage(self.title, msg) self.iface.messageBar().pushWidget(message, Qgis.Info, 2)
class ProgessBarDialog(QDialog): def __init__(self, GTFS_folder, parent=None): QDialog.__init__(self, parent) self.resize(310, 140) self.setWindowTitle("Info") self.process_info = QLineEdit(self) self.process_info.resize(230, 20) self.process_info.move(40, 35) self.process_info.setAlignment(Qt.AlignVCenter) self.progBar = QProgressBar(self) self.progBar.resize(230,20) self.progBar.move(40, 70) self.progBar.setAlignment(Qt.AlignVCenter) self.newTask(GTFS_folder) def newTask(self,GTFS_folder): self.task = HeavyTask(GTFS_folder) self.task.progressChanged.connect(lambda: self.progBar.setValue(self.task.progress())) self.task.progressChanged.connect(lambda: self.info(self.task.progress())) QgsApplication.taskManager().addTask(self.task) def info(self,value): if value == 10: self.process_info.setText("Unzipping file") elif value == 60: self.process_info.setText("Saving layers into GeoPackage") elif value == 70: self.process_info.setText("Loading layers from GeoPackage") elif value == 80: self.process_info.setText("Deleting unzipped folder") elif value == 85: self.process_info.setText("Connecting shapes") elif value == 95: self.process_info.setText("Coloring of line layers") elif value == 100: time.sleep(2) self.close()
def import_mesh(self): qfd = QFileDialog() path = "" import_function = load_IO() fil = '' for model in import_function: fil += import_function[model]['extension']() + ';' fname = QFileDialog.getOpenFileName(qfd, 'Import Mesh file', path, fil) fname = fname[0] if fname == '': return filename, file_extension = os.path.splitext(fname) if file_extension == '': return progressMessageBar = self.iface.messageBar().createMessage("Load Mesh") progress = QProgressBar() progress.setMaximum(10) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) self.mesh = Mesh([], [], [], []) for model in import_function: ext = import_function[model]['extension']() if file_extension in ext: progress.setValue(0) self.mesh = import_function[model]['import'](self.mesh, fname) progress.setValue(3) self.mesh._calculate_face_nodes() progress.setValue(6) # self.mesh._remove_hanging_nodes() self.mesh.calc_parameters() progress.setValue(9) Mesh2Shapefile(self.mesh) self.iface.messageBar().clearWidgets()
def onSubmit(self): self.choosing.close() progressMessageBar = iface.messageBar().createMessage("") self.process_info = QLabel() progressMessageBar.layout().addWidget(self.process_info) progress = QProgressBar() progress.setMaximum(100) progress.setAlignment(Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) task = LoadTask(self.dockwidget.input_dir.filePath(), self.do_zones) task.progressChanged.connect( lambda: progress.setValue(task.progress())) task.progressChanged.connect(lambda: self.info(task.progress())) QgsApplication.taskManager().addTask(task)
class RFUDockWidget(QDockWidget, gui_dckwdgt_rfu_connector): closed = pyqtSignal() downloaded = pyqtSignal() uploaded = pyqtSignal() rfureset = pyqtSignal() def __init__(self, iface, canvas, project, conn=None, parent=None): super(RFUDockWidget, self).__init__(parent) self.setupUi(self) self.iface = iface self.canvas = canvas self.project = project self.conn = conn self.zone = None self.precision_class = [] self.ellips_acronym = [] self.dflt_ellips_acronym = None self.selected_ellips_acronym = None self.nature = [] self.typo_nature_som = [] self.typo_nature_lim = [] self.auth_creator = [] self.tol_same_pt = 0.0 self.config = Configuration() self.url_rfu = self.config.base_url_rfu self.url = None self.refdoss_cmt = None self.l_vertex = None self.l_edge = None self.layers = [self.l_vertex, self.l_edge] # Initialize dicts which contains changed datasets self.edges_added = {} self.edges_added_ft = {} self.vertices_added = {} self.vertices_added_ft = {} self.edges_removed = {} self.vertices_removed = {} self.edges_modified = {} self.vertices_modified = {} self.downloadPushButton.clicked.connect(self.on_downloaded) # self.permalinkLineEdit.returnPressed.connect(self.on_downloaded) self.projComboBox.currentIndexChanged.connect(self.set_destination_crs) # Loads permalinks into the permalink combox self.load_permalinks() # Create the WMS layer (from Geofoncier) self.wms_urlwithparams = 'contextualWMSLegend=0&crs=EPSG:4326&dpiMode=1&featureCount=10&format=image/png&layers=RFU&styles=default&url=' self.wms_urlwithparams += 'https://api.geofoncier.fr' # self.url_rfu self.wms_urlwithparams += '/referentielsoge/ogc/wxs/?' self.l_wms = QgsRasterLayer(self.wms_urlwithparams, 'Fond de plan RFU WMS', 'wms') # Define the contrast filter contrast_filter = QgsBrightnessContrastFilter() contrast_filter.setContrast(-100) # Assign filter to raster pipe self.l_wms.pipe().set(contrast_filter) # Add WMS layer to the registry self.project.addMapLayer(self.l_wms, True) # Apply changes to the WMS layer self.l_wms.triggerRepaint() def closeEvent(self, event): self.closed.emit() def on_downloaded(self): widget = self.iface.messageBar().createMessage( "Géofoncier", "Téléchargement du RFU.") progress_bar = QProgressBar() progress_bar.setMinimum(0) progress_bar.setMaximum(2) widget.layout().addWidget(progress_bar) self.iface.messageBar().pushWidget(widget) progress_bar.setValue(1) # https://pro.geofoncier.fr/index.php?¢re=-196406,5983255&context=metropole url = self.permalinkCmb.currentText() if not url: return self.abort_action(msg="Veuillez renseigner le permalien.") self.url = url try: self.download(self.url) except Exception as e: return self.abort_action(msg=str(e)) self.save_permalinks(self.url) progress_bar.setValue(2) self.iface.messageBar().clearWidgets() return def on_reset(self): # Ensure that the action is intentional resp = QMessageBox.question(self, reinit_msg[0], reinit_msg[1], QMessageBox.Yes, QMessageBox.No) if resp == QMessageBox.Yes: self.reset() self.rfureset.emit() return def on_uploaded(self): self.uploaded.emit() # Create message self.widget = self.iface.messageBar().createMessage( "Géofoncier", "Envoi des modifications.") self.progress_bar = QProgressBar() self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(3) self.widget.layout().addWidget(self.progress_bar) self.iface.messageBar().pushWidget(self.widget) self.progress_bar.setValue(1) # Specific dlg to manage the case of several doss with same ref self.refdoss_cmt = RefDossCmtEntry() self.refdoss_cmt.show() # Continue the process after capturing the dic of values self.refdoss_cmt.send_refdoss_cmt_vals.connect( self.on_uploaded_withref) # Continue the process after dlg validation def on_uploaded_withref(self, dic_vals): if dic_vals["ok"]: enr_ref_dossier = dic_vals["refdoss"] self.enr_cmt = dic_vals["cmt"] if not enr_ref_dossier: return self.abort_action( msg="Merci de renseigner une référence de dossier.") # Create correct comment if not self.enr_cmt: self.enr_cmt = cmt_dft % enr_ref_dossier else: self.enr_cmt += " - " + cmt_dft % enr_ref_dossier dossiers = self.conn.dossiersoge_dossiers(self.zone, enr_ref_dossier) dossiers_read = dossiers.read() # DEBUG: Export response as a text file # urlresp_to_file(dossiers_read) if dossiers.code != 200: return self.abort_action(msg=dossiers_read) data = json.loads(str(dossiers_read.decode('utf-8'))) nb_dossiers = data["count"] if nb_dossiers == 0: return self.abort_action( msg="Le dossier \'%s\' n'existe pas." % enr_ref_dossier) # Case of several same ref_dossier # In the case, the difference is made by enr_cab_createur if nb_dossiers >= 1: doss_infos = [] for doss in data["results"]: doss_info = [] doss_info.append(doss["enr_cab_createur"]) doss_info.append(doss["enr_ref_dossier"]) # doss_uri = doss.find(r"{http://www.w3.org/2005/Atom}link").attrib[r"href"].split(r"/")[-1][1:] # doss_info.append(doss_uri) # id = enr_api_dossier doss_info.append(doss["id"]) doss_info.append(doss["zone"]) doss_infos.append(doss_info) if len(doss_infos) > 1: self.doss_choice = MultiDossChoice(doss_infos) # Modal window self.doss_choice.setWindowModality(Qt.ApplicationModal) self.doss_choice.show() # Continue the process after capturing the dic of values self.doss_choice.send_refapidoss.connect( self.on_uploaded_proc) else: self.on_uploaded_proc(doss_info[2]) else: self.iface.messageBar().clearWidgets() # Launch the uploading after receiving the ref_api_doss def on_uploaded_proc(self, ref_api_doss): if ref_api_doss != "": self.progress_bar.setValue(2) # Stop editing mode for layer in self.layers: if layer.isEditable(): self.iface.setActiveLayer(layer) layer.commitChanges() # Check if dataset changes if (self.edges_added or self.vertices_added or self.edges_removed or self.vertices_removed or self.edges_modified or self.vertices_modified): pass else: return self.abort_action( msg="Aucune modification des données n'est détectée.") # Upload, reset and re-download datasets try: log = self.upload(enr_api_dossier=ref_api_doss, commentaire=self.enr_cmt) self.reset() self.permalinkCmb.setCurrentText(self.url) self.download(self.url) self.zoom_bbox() self.canvas.refresh() except Exception as e: self.reset() self.permalinkCmb.setCurrentText(self.url) self.download(self.url) self.zoom_bbox() self.canvas.refresh() return self.abort_action(msg="\n".join(e.args[0])) self.iface.messageBar().clearWidgets() return QMessageBox.information(self, r"Information", "\n".join(log)) # Case of dlg mutidoss_choice cancelled else: QMessageBox.information(self, multi_doss_canceled_msg[0], multi_doss_canceled_msg[1]) self.iface.messageBar().clearWidgets() def download(self, url): # Test if permalink is valid pattern = r"^(https?:\/\/(\w+[\w\-\.\:\/])+)\?((\&+)?(\w+)\=?([\w\-\.\:\,]+?)?)+(\&+)?$" if not re.match(pattern, self.url): raise Exception("Le permalien n'est pas valide.") # Extract params from url params = parse_qs(urlparse(self.url).query) # Check mandatory parameters try: context = str(params[r"context"][0]) center = params[r"centre"][0] except: raise Exception( "Les paramètres \'Context\' et \'Centre\' sont obligatoires.") auth_contexts = [ r"metropole", r"guadeloupe", r"stmartin", r"stbarthelemy", r"guyane", r"reunion", r"mayotte", r"martinique" ] # Check scale parameter try: scale = int(params[r"echelle"][0]) except: raise Exception("Le paramètre \'Echelle\' est obligatoire.") else: if scale > scale_limit: raise Exception(wrong_scale_txt.format(str(scale_limit))) # Check if context is valid if context not in auth_contexts: raise Exception( "La valeur \'%s\' est incorrecte.\n\n" "\'Context\' doit prentre une des %s valeurs suivantes: " "%s" % (context, len(auth_contexts), ", ".join(auth_contexts))) self.zone = context if self.zone in [ r"guadeloupe", r"stmartin", r"stbarthelemy", r"martinique" ]: self.zone = r"antilles" # Check if XY are valid if not re.match(r"^\-?\d+,\-?\d+$", center): raise Exception("Les coordonnées XY du centre sont incorrectes.") # Extract XY (¢re) xcenter = int(center.split(r",")[0]) ycenter = int(center.split(r",")[1]) # Compute the bbox xmin = xcenter - self.conn.extract_lim / 2 xmax = xcenter + self.conn.extract_lim / 2 ymin = ycenter - self.conn.extract_lim / 2 ymax = ycenter + self.conn.extract_lim / 2 # Transform coordinates in WGS84 bbox = tools.reproj(QgsRectangle(xmin, ymin, xmax, ymax), 3857, 4326, self.project) # Extract RFU (Send the request) resp = self.conn.extraction(bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum()) resp_read = resp.read() # DEBUG: Export response as a text file # urlresp_to_file(resp_read) if resp.code != 200: raise Exception(resp_read) tree = EltTree.fromstring(resp_read) # Check if error err = tree.find(r"./erreur") if err: raise Exception(err.text) # Create the layer: "Masque d'extraction" self.l_bbox = QgsVectorLayer(r"Polygon?crs=epsg:4326&index=yes", "Zone de travail", r"memory") p_bbox = self.l_bbox.dataProvider() simple_symbol = QgsFillSymbol.createSimple({ r"color": r"116,97,87,255", r"style": r"b_diagonal", r"outline_style": r"no" }) renderer_bbox = QgsInvertedPolygonRenderer( QgsSingleSymbolRenderer(simple_symbol)) self.l_bbox.setRenderer(renderer_bbox) self.ft_bbox = QgsFeature() self.limit_area = QgsRectangle(bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum()) self.ft_bbox.setGeometry(QgsGeometry.fromRect(self.limit_area)) p_bbox.addFeatures([self.ft_bbox]) self.l_bbox.updateFields() self.l_bbox.updateExtents() # Create layers.. self.layers = self.extract_layers(tree) self.l_vertex = self.layers[0] self.l_edge = self.layers[1] # Add layer to the registry self.project.addMapLayers([self.l_vertex, self.l_edge, self.l_bbox]) # Set extent # self.canvas.setExtent(QgsRectangle(bbox.xMinimum(), bbox.yMinimum(), # bbox.xMaximum(), bbox.yMaximum())) self.features_vertex_backed_up = \ dict((ft[r"fid"], ft) for ft in self.get_features(self.l_vertex)) self.features_edge_backed_up = \ dict((ft[r"fid"], ft) for ft in self.get_features(self.l_edge)) # Get Capabitilies resp = self.conn.get_capabilities(self.zone) resp_read = resp.read() # DEBUG # urlresp_to_file(resp_read) if resp.code != 200: raise Exception(resp_read) tree = EltTree.fromstring(resp_read) # Find tolerance to determine if 2 points are equals for entry in tree.findall(r"./tolerance"): self.tol_same_pt = float(entry.text) err = tree.find(r"./erreur") if err: raise Exception(err.text) for entry in tree.findall(r"./classe_rattachement/classe"): t = (entry.attrib[r"som_precision_rattachement"], entry.text) self.precision_class.append(t) for entry in tree.findall( r"./representation_plane_sommet_autorise/representation_plane_sommet" ): t = (entry.attrib[r"som_representation_plane"], entry.attrib[r"epsg_crs_id"], entry.text) self.ellips_acronym.append(t) # Added v2.1 << for entry in tree.findall(r"./typologie_nature_sommet/nature"): self.typo_nature_som.append(entry.text) for entry in tree.findall(r"./nature_sommet_conseille/nature"): self.nature.append(entry.text) for entry in tree.findall(r"./typologie_nature_limite/nature"): self.typo_nature_lim.append(entry.text) # >> for entry in tree.findall( r"./som_ge_createur_autorise/som_ge_createur"): t = (entry.attrib[r"num_ge"], entry.text) self.auth_creator.append(t) try: ft = next(ft for ft in self.l_vertex.getFeatures()) ft_attrib = tools.attrib_as_kv(ft.fields(), ft.attributes()) self.dflt_ellips_acronym = ft_attrib[r"som_representation_plane"] except: self.dflt_ellips_acronym = None for i, e in enumerate(self.ellips_acronym): self.projComboBox.addItem(e[2]) if not self.dflt_ellips_acronym and i == 0: self.project_crs = int(e[1]) if self.dflt_ellips_acronym == e[0]: # Check projection in combobox self.projComboBox.setCurrentIndex(i) # Then change the CRS in canvas epsg_str = "EPSG:" + str(int(e[1])) crs = QgsCoordinateReferenceSystem(epsg_str) self.project.setCrs(crs) self.project_crs = int(e[1]) # Calculate bbox in the project CRS (used for the scale limitation of the canvas) self.bbox_crsproject = tools.reproj( QgsRectangle(xmin, ymin, xmax, ymax), 3857, self.project_crs, self.project) # Zoom to bbox extents self.zoom_bbox() self.canvas.refresh() # Modified in v2.1 << # Add the list of possible values to the field som_nature map_predefined_vals_to_fld(self.l_vertex, "som_typologie_nature", self.typo_nature_som) # Add the list of possible values to the field som_precision_rattachement map_predefined_vals_to_fld(self.l_vertex, "som_precision_rattachement", self.precision_class, 0, 1) # Add the list of possible values to the field som_precision_rattachement map_predefined_vals_to_fld(self.l_vertex, "som_representation_plane", self.ellips_acronym, 0, 2) # Add the list of possible values to the field lim_typologie_nature map_predefined_vals_to_fld(self.l_edge, "lim_typologie_nature", self.typo_nature_lim) # Add the list of possible values to the field som_delimitation_publique false_true_lst = [('False', 'Faux'), ('True', 'Vrai')] map_predefined_vals_to_fld(self.l_vertex, "som_delimitation_publique", false_true_lst, 0, 1) # Add the list of possible values to the field lim_delimitation_publique map_predefined_vals_to_fld(self.l_edge, "lim_delimitation_publique", false_true_lst, 0, 1) # >> # Then, start editing mode.. for idx, layer in enumerate(self.layers): if not layer.isEditable(): layer.startEditing() if idx == 0: self.iface.setActiveLayer(layer) self.projComboBox.setDisabled(False) self.permalinkCmb.setDisabled(True) self.downloadPushButton.setDisabled(True) self.resetPushButton.setDisabled(False) self.uploadPushButton.setDisabled(False) self.downloadPushButton.clicked.disconnect(self.on_downloaded) # self.permalinkLineEdit.returnPressed.disconnect(self.on_downloaded) self.resetPushButton.clicked.connect(self.on_reset) self.uploadPushButton.clicked.connect(self.on_uploaded) # Activate the scale limitation for the canvas self.canvas.scaleChanged.connect(self.limit_cvs_scale) self.downloaded.emit() return True def reset(self): """Remove RFU layers.""" # Save (virtually) the changes in the layers # (to avoid alert messages when removing the layers) for layer in self.layers: if isinstance(layer, QgsVectorLayer): if layer.isEditable(): self.iface.setActiveLayer(layer) layer.commitChanges() # Remove RFU layers try: self.project.removeMapLayers( [self.l_vertex.id(), self.l_edge.id(), self.l_bbox.id()]) except: return # Remove eliminated lines layer if self.project.mapLayersByName(elimedge_lname): el_lyr = self.project.mapLayersByName(elimedge_lname)[0] self.iface.setActiveLayer(el_lyr) el_lyr.commitChanges() self.project.removeMapLayers([el_lyr.id()]) # Reset variable self.precision_class = [] self.ellips_acronym = [] self.dflt_ellips_acronym = None self.nature = [] self.typo_nature_lim = [] self.typo_nature_som = [] self.auth_creator = [] self.l_vertex = None self.l_edge = None self.layers = [self.l_vertex, self.l_edge] self.edges_added = {} self.vertices_added = {} self.edges_removed = {} self.vertices_removed = {} self.edges_modified = {} self.vertices_modified = {} self.tol_same_pt = 0.0 # Reset ComboBox which contains projections authorized self.projComboBox.clear() self.projComboBox.setDisabled(True) # Loads permalinks into the permalink combox self.load_permalinks() self.permalinkCmb.setDisabled(False) # self.permalinkLineEdit.returnPressed.connect(self.on_downloaded) self.downloadPushButton.setDisabled(False) self.downloadPushButton.clicked.connect(self.on_downloaded) self.resetPushButton.setDisabled(True) self.resetPushButton.clicked.disconnect(self.on_reset) self.uploadPushButton.setDisabled(True) self.uploadPushButton.clicked.disconnect(self.on_uploaded) return True def upload(self, enr_api_dossier=None, commentaire=None): """Upload data to Géofoncier REST API. On success returns the log messages (Array). """ # Set XML document root = EltTree.Element(r"rfu") first_vtx_kept = True first_edge_kept = True # Add to our XML document datasets which have been changed if self.vertices_added: for fid in self.vertices_added: # Check if vertex is out of the bbox to_export = check_vtx_outofbbox(self.vertices_added_ft[fid], self.ft_bbox) if to_export: tools.xml_subelt_creator(root, "sommet", data=self.vertices_added[fid], action=r"create") # If vertex is out of the bbox else: # Create a new layer to store the vertices non exported if first_vtx_kept: if layer_exists(vtx_outofbbox_lname, self.project): vtx_outofbbox_lyr = self.project.mapLayersByName( vtx_outofbbox_lname)[0] else: vtx_outofbbox_lyr = create_vtx_outofbbox_lyr() # Add the vertex to this layer if not vtx_outofbbox_lyr.isEditable(): vtx_outofbbox_lyr.startEditing() vtx_outofbbox_lyr.addFeature(self.vertices_added_ft[fid]) first_vtx_kept = False if self.edges_added: for fid in self.edges_added: # Check if edge is out of the bbox to_export = check_edge_outofbbox(self.edges_added_ft[fid], self.ft_bbox) if to_export: tools.xml_subelt_creator(root, "limite", data=self.edges_added[fid], action=r"create") # If edge is out of the bbox else: # Create a new layer to store the edges non exported if first_edge_kept: if layer_exists(edge_outofbbox_lname, self.project): edge_outofbbox_lyr = self.project.mapLayersByName( edge_outofbbox_lname)[0] else: edge_outofbbox_lyr = create_edge_outofbbox_lyr() # Add the edge to this layer if not edge_outofbbox_lyr.isEditable(): edge_outofbbox_lyr.startEditing() edge_outofbbox_lyr.addFeature(self.edges_added_ft[fid]) first_edge_kept = False if self.vertices_removed: for fid in self.vertices_removed: tools.xml_subelt_creator(root, "sommet", data=self.vertices_removed[fid], action=r"delete") if self.edges_removed: for fid in self.edges_removed: tools.xml_subelt_creator(root, "limite", data=self.edges_removed[fid], action=r"delete") if self.vertices_modified: for fid in self.vertices_modified: tools.xml_subelt_creator(root, "sommet", data=self.vertices_modified[fid], action=r"update") if self.edges_modified: for fid in self.edges_modified: tools.xml_subelt_creator(root, "limite", data=self.edges_modified[fid], action=r"update") # Create a new changeset Id changeset_id = self.create_changeset(enr_api_dossier=enr_api_dossier, commentaire=commentaire) # Add changeset value in our XML document root.attrib[r"changeset"] = changeset_id # Send data edit = self.conn.edit(self.zone, EltTree.tostring(root)) if edit.code != 200: edit_read = edit.read() # DEBUG # urlresp_to_file(edit_read) err_tree = EltTree.fromstring(edit_read) msgs_log = [] for log in err_tree.iter(r"log"): msgs_log.append("%s: %s" % (log.attrib["type"], log.text)) raise Exception(msgs_log) tree = EltTree.fromstring(edit.read()) err = tree.find(r"./erreur") if err: debug_msg('DEBUG', "erreur: %s", (str(err))) err_tree = EltTree.fromstring(err) msgs_log = [] for log in err_tree.iter(r"log"): msgs_log.append("%s: %s" % (log.attrib["type"], log.text)) raise Exception(msgs_log) # Returns log info msgs_log = [] for log in tree.iter(r"log"): msgs_log.append("%s: %s" % (log.attrib["type"], log.text)) # Close the changeset self.destroy_changeset(changeset_id) # Reset all self.edges_added = {} self.edges_added_ft = {} self.vertices_added = {} self.vertices_added_ft = {} self.edges_removed = {} self.vertices_removed = {} self.edges_modified = {} self.vertices_modified = {} # Alert message if elements out of bbox msg_outbbox = "" if not first_vtx_kept: msg_outbbox = msg_outbbox_vtx.format(vtx_outofbbox_lname) if not first_edge_kept: if msg_outbbox != "": msg_outbbox += "<br>" msg_outbbox += msg_outbbox_edge.format(edge_outofbbox_lname) if msg_outbbox != "": self.canvas.refresh() m_box = mbox_w_params(tl_atn, txt_msg_outbbox, msg_outbbox) m_box.exec_() return msgs_log def create_changeset(self, enr_api_dossier=None, commentaire=None): """Open a new changeset from Géofoncier API. On success, returns the new changeset id. """ opencs = self.conn.open_changeset(self.zone, enr_api_dossier=enr_api_dossier, commentaire=commentaire) if opencs.code != 200: raise Exception(opencs.read()) tree = EltTree.fromstring(opencs.read()) err = tree.find(r"./log") if err: raise Exception(err.text) # treeterator = list(tree.getiterator(tag=r"changeset")) # Python 3.9 -> getiterator deprecated treeterator = list(tree.iter(tag=r"changeset")) # We should get only one changeset if len(treeterator) != 1: raise Exception("Le nombre de \'changeset\' est incohérent.\n" "Merci de contacter l'administrateur Géofoncier.") return treeterator[0].attrib[r"id"] def destroy_changeset(self, id): """Close a changeset.""" closecs = self.conn.close_changeset(self.zone, id) if closecs.code != 200: raise Exception(closecs.read()) tree = EltTree.fromstring(closecs.read()) err = tree.find(r"./log") if err: raise Exception(err.text) return True def abort_action(self, msg=None): for layer in self.layers: if layer and not layer.isEditable(): layer.startEditing() # Clear message bar self.iface.messageBar().clearWidgets() if msg: return QMessageBox.warning(self, r"Attention", msg) return def extract_layers(self, tree): """Return a list of RFU layers.""" # Create vector layers.. l_vertex = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes", "Sommet RFU", r"memory") l_edge = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes", "Limite RFU", r"memory") p_vertex = l_vertex.dataProvider() p_edge = l_edge.dataProvider() # Define default style renderer.. renderer_vertex = QgsRuleBasedRenderer(QgsMarkerSymbol()) vertex_root_rule = renderer_vertex.rootRule() # Modified in v2.1 (som_nature replaced by som_typologie_nature) >> vertex_rules = ( (("Borne, borne à puce, pierre, piquet, clou ou broche"), ("$id >= 0 AND \"som_typologie_nature\" IN ('Borne'," "'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche')"), r"#EC0000", 2.2), (("Axe cours d'eau, axe fossé, haut de talus, pied de talus"), ("$id >= 0 AND \"som_typologie_nature\" IN ('Axe cours d\'\'eau'," "'Axe fossé', 'Haut de talus', 'Pied de talus')"), r"#EE8012", 2.2), (("Angle de bâtiment, axe de mur, angle de mur, " "angle de clôture, pylône et toute autre valeur"), ("$id >= 0 AND \"som_typologie_nature\" NOT IN ('Borne'," "'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche'," "'Axe cours d\'\'eau', 'Axe fossé', 'Haut de talus'," "'Pied de talus')"), r"#9784EC", 2.2), ("Temporaire", r"$id < 0", "cyan", 2.4), ("Point nouveau à traiter car proche d'un existant", r"point_rfu_proche is not null", "#bcff03", 3)) # >> for label, expression, color, size in vertex_rules: rule = vertex_root_rule.children()[0].clone() rule.setLabel(label) rule.setFilterExpression(expression) rule.symbol().setColor(QColor(color)) rule.symbol().setSize(size) vertex_root_rule.appendChild(rule) vertex_root_rule.removeChildAt(0) l_vertex.setRenderer(renderer_vertex) renderer_edge = QgsRuleBasedRenderer(QgsLineSymbol()) edge_root_rule = renderer_edge.rootRule() # Modified in v2.1 (lim_typologie_nature added) << edge_rules = (("Limite privée", "$id >= 0 AND \"lim_typologie_nature\" = '" + lim_typo_nat_vals[0] + "'", "#0A0AFF", 0.5), ("Limite naturelle", "$id >= 0 AND \"lim_typologie_nature\" = '" + lim_typo_nat_vals[1] + "'", "#aa876d", 0.5), ("Temporaire", "$id < 0", "cyan", 1)) # >> for label, expression, color, width in edge_rules: rule = edge_root_rule.children()[0].clone() rule.setLabel(label) rule.setFilterExpression(expression) rule.symbol().setColor(QColor(color)) rule.symbol().setWidth(width) edge_root_rule.appendChild(rule) edge_root_rule.removeChildAt(0) l_edge.setRenderer(renderer_edge) # Add fields.. p_vertex.addAttributes(vtx_atts) p_edge.addAttributes(edge_atts) # Add features from xml tree.. # ..to vertex layer.. fts_vertex = [] for e in tree.findall(r"sommet"): ft_vertex = QgsFeature() ft_vertex.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"])) _id_noeud = int(e.attrib[r"id_noeud"]) _version = int(e.attrib[r"version"]) som_ge_createur = str(e.find(r"./som_ge_createur").text) som_nature = str(e.find(r"./som_nature").text) som_prec_rattcht = int( e.find(r"./som_precision_rattachement").text) som_coord_est = float(e.find(r"./som_coord_est").text) som_coord_nord = float(e.find(r"./som_coord_nord").text) som_repres_plane = str(e.find(r"./som_representation_plane").text) som_tolerance = float(e.find(r"./som_tolerance").text) # Field used to store the attestation_qualite value # when modifying a vertex ("false" or "true") attestation_qualite = "false" som_delim_pub = str(e.find(r"./som_delimitation_publique").text) som_typo_nature = str(e.find(r"./som_typologie_nature").text) ft_vertex.setAttributes([ _id_noeud, _version, som_ge_createur, som_delim_pub, som_typo_nature, som_nature, som_prec_rattcht, som_coord_est, som_coord_nord, som_repres_plane, som_tolerance, attestation_qualite, NULL ]) fts_vertex.append(ft_vertex) # ..to edge layer.. fts_edge = [] for e in tree.findall(r"limite"): ft_edge = QgsFeature() ft_edge.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"])) _id_arc = int(e.attrib[r"id_arc"]) _version = int(e.attrib[r"version"]) lim_ge_createur = str(e.find(r"./lim_ge_createur").text) lim_typo_nature = str(e.find(r"./lim_typologie_nature").text) lim_delim_pub = str(e.find(r"./lim_delimitation_publique").text) ft_edge.setAttributes([ _id_arc, _version, lim_ge_createur, lim_delim_pub, lim_typo_nature ]) fts_edge.append(ft_edge) # Add features to layers.. p_vertex.addFeatures(fts_vertex) p_edge.addFeatures(fts_edge) # Update fields.. l_vertex.updateFields() l_edge.updateFields() # Update layer's extent.. l_vertex.updateExtents() l_edge.updateExtents() # Check if valid.. if not l_vertex.isValid() or not l_edge.isValid(): raise Exception( "Une erreur est survenue lors du chargement de la couche.") # Then return layers.. return [l_vertex, l_edge] def get_features(self, layer): features = [] for ft in layer.getFeatures(): attributes = tools.attrib_as_kv(ft.fields(), ft.attributes()) attributes[r"fid"] = ft.id() features.append(attributes) return features def remove_features(self, layer_id, fids): for fid in fids: if layer_id == self.l_edge.id( ) and fid in self.features_edge_backed_up: self.edges_removed[fid] = self.features_edge_backed_up[fid] if layer_id == self.l_vertex.id( ) and fid in self.features_vertex_backed_up: self.vertices_removed[fid] = self.features_vertex_backed_up[ fid] def add_features(self, layer_id, features): for ft in features: attrib = tools.attrib_as_kv(ft.fields(), ft.attributes(), qgsgeom=ft.geometry()) if layer_id == self.l_vertex.id(): self.vertices_added[ft.id()] = attrib self.vertices_added_ft[ft.id()] = ft if layer_id == self.l_edge.id(): self.edges_added[ft.id()] = attrib self.edges_added_ft[ft.id()] = ft def modify_feature(self, layer_id, feature, qgsgeom=None): if qgsgeom: f = tools.attrib_as_kv(feature.fields(), feature.attributes(), qgsgeom=qgsgeom) else: f = tools.attrib_as_kv(feature.fields(), feature.attributes()) if self.l_edge.id() == layer_id: if feature.id() not in self.features_edge_backed_up: return self.edges_modified[feature.id()] = f if self.l_vertex.id() == layer_id: if feature.id() not in self.features_vertex_backed_up: return self.vertices_modified[feature.id()] = f def set_destination_crs(self, j): epsg = 4326 # by default for i, e in enumerate(self.ellips_acronym): if i == j: self.selected_ellips_acronym = e[0] epsg = int(e[1]) continue epsg_str = "EPSG:" + str(epsg) crs = QgsCoordinateReferenceSystem(epsg_str) self.project.setCrs(crs) # Stop zoom when the scale limit is exceeded def limit_cvs_scale(self): if self.canvas.scale() > cvs_scale_limit: self.disconn_scale_limit() self.zoom_bbox() self.canvas.zoomScale(cvs_scale_limit) self.canvas.scaleChanged.connect(self.limit_cvs_scale) def zoom_bbox(self): self.canvas.setExtent( QgsRectangle(self.bbox_crsproject.xMinimum(), self.bbox_crsproject.yMinimum(), self.bbox_crsproject.xMaximum(), self.bbox_crsproject.yMaximum())) def disconn_scale_limit(self): self.canvas.scaleChanged.disconnect(self.limit_cvs_scale) def conn_scale_limit(self): self.canvas.scaleChanged.connect(self.limit_cvs_scale) # Loads permalinks from the json file into the combobox def load_permalinks(self): try: self.json_path = os.path.join(os.path.dirname(__file__), r"permalinks.json") except IOError as error: raise error with codecs.open(self.json_path, encoding='utf-8', mode='r') as json_file: json_permalinks = json.load(json_file) self.permalinks = json_permalinks[r"permalinks"] current_permalink_idx = json_permalinks[r"current_permalink_idx"] if len(self.permalinks) > 0: self.permalinkCmb.clear() for idx, permalink in enumerate(self.permalinks): self.permalinkCmb.addItem(permalink) self.permalinkCmb.setCurrentIndex(current_permalink_idx) # self.permalinkCmb.lineEdit().selectAll() # Save permalinks in the json file (limited to 5 permalinks) def save_permalinks(self, permalink): # Update the json file json_permalinks = {} if permalink not in self.permalinks: # Update the permalinks list if len(self.permalinks) == 5: del self.permalinks[0] self.permalinks.append(permalink) json_permalinks["current_permalink_idx"] = len(self.permalinks) - 1 else: json_permalinks[ "current_permalink_idx"] = self.permalinkCmb.currentIndex() json_permalinks["permalinks"] = self.permalinks with codecs.open(self.json_path, encoding='utf-8', mode='w') as json_file: json_file.write( json.dumps(json_permalinks, indent=4, separators=(',', ': '), ensure_ascii=False))
class OSMDownloaderDialog(QDialog, FORM_CLASS): def __init__(self, iface, startX, startY, endX, endY, parent=None): """Constructor.""" super(OSMDownloaderDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface self.setCoordinates(startX, startY, endX, endY) self.threadpool = QThreadPool() self.size = 0 def setCoordinates(self, startX, startY, endX, endY): if startX < endX: minLong = startX maxLong = endX else: minLong = endX maxLong = startX if startY < endY: minLat = startY maxLat = endY else: minLat = endY maxLat = startY self.wEdit.setText(str(minLong)) self.sEdit.setText(str(minLat)) self.eEdit.setText(str(maxLong)) self.nEdit.setText(str(maxLat)) @pyqtSlot() def on_saveButton_clicked(self): ret = QFileDialog.getSaveFileName(parent=None, caption='Define file name and location', filter='OSM Files(*.osm)') fileName = ret[0] split = fileName.split('.') if len(split)>0 and split[-1] == 'osm': pass else: fileName += '.osm' self.filenameEdit.setText(fileName) @pyqtSlot() def on_button_box_accepted(self): if self.filenameEdit.text() == '': QMessageBox.warning(self, self.tr("Warning!"), self.tr("Please, select a location to save the file.")) return # Initiating processing osmRequest = OSMRequest(self.filenameEdit.text()) osmRequest.setParameters(self.wEdit.text(), self.sEdit.text(), self.eEdit.text(), self.nEdit.text()) # Connecting end signal osmRequest.signals.processFinished.connect(self.processFinished) osmRequest.signals.sizeReported.connect(self.reportSize) osmRequest.signals.proxyOpened.connect(self.proxy) osmRequest.signals.errorOccurred.connect(self.errorOccurred) osmRequest.signals.userCanceled.connect(self.userCanceled) # Setting the progress bar self.progressMessageBar = self.iface.messageBar().createMessage('Downloading data...') self.progressBar = QProgressBar() self.progressBar.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progressBar) self.iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) self.progressBar.setRange(0, 0) self.progressMessageBar.destroyed.connect(osmRequest.signals.cancel) # Starting process self.threadpool.start(osmRequest) @pyqtSlot(str) def proxy(self, proxy): self.progressMessageBar.setText('Proxy set to: '+proxy) @pyqtSlot(str) def errorOccurred(self, message): QMessageBox.warning(self, 'Fatal!', message) self.close() @pyqtSlot() def userCanceled(self): QMessageBox.warning(self, 'Info!', 'Process canceled by user!') self.close() @pyqtSlot(float) def reportSize(self, size): self.size = size self.progressMessageBar.setText('Downloading: '+"{0:.2f}".format(size)+' megabytes from OSM servers...') @pyqtSlot(str) def processFinished(self, message): self.progressBar.setRange(0, 100) self.progressBar.setValue(100) self.progressMessageBar.setText('Downloaded '+"{0:.2f}".format(self.size)+' megabytes in total from OSM servers') QMessageBox.warning(self, 'Info!', message) if self.checkBox.isChecked(): self.iface.addVectorLayer(self.filenameEdit.text(), 'osm_data', 'ogr') self.close()
def run(self): """Run method that performs all the real work""" def blankPaint(geometry): blank = ee.Image(0).mask(0) geometryDraw = blank.paint(geometry, '0000AA', 1) return geometryDraw # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = simex_pluginDialog() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: uf = self.dlg.selectUF.currentText() path = self.dlg.path.toPlainText() row = self.dlg.row.toPlainText() cloud_cover = int(self.dlg.cloudcover.cleanText()) startdate = self.dlg.startdate.date().toString('yyyy-MM-dd') enddate = self.dlg.enddate.date().toString('yyyy-MM-dd') self.iface.messageBar().pushMessage('loading ...') geometry = path_row_am.filterMetadata('PATH', 'equals', int(path)).filterMetadata('ROW', 'equals', int(row)).geometry() countourGeometry = blankPaint(geometry) Map.centerObject(geometry, 100) progressMessageBar = iface.messageBar().createMessage("loading...") progress = QProgressBar() progress.setMaximum(10) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) for i in range(10): time.sleep(1) progress.setValue(i + 1) parametrosColecaoL8 = { 'collectionid': 'LANDSAT/LC08/C01/T1_SR', 'geometry': geometry.centroid(), 'dateStart': ee.Date(startdate), 'dateEnd': ee.Date(enddate), 'cloud_cover': cloud_cover, } colecaoL8 = getCollection(parametrosColecaoL8).select(bandNames("l8")['bandNames'],bandNames("l8")['newNames'])\ .map(getSMA).map(getNDFI) #nImages = colecaoL8.size().getInfo() #colList = colecaoL8.toList(nImages) #idG = 1 listYears = list(range(int(startdate[:4]),int(enddate[:4])+1)) for item in listYears: #imgYear = ee.Image(colecaoL8.filterDate(str(item) + '-01-01',str(item+1) + '-01-01').sort('cloud_cover').first()) colYear = colecaoL8.filterDate(str(item) + '-01-01',str(item+1) + '-01-01').sort('cloud_cover').limit(3) colList = colYear.toList(5) idG = 1 while idG < 3: img = ee.Image(colList.get(idG)) try: dictionaryInfos = ee.Dictionary({'satellite_name':img.get('satellite_name'), 'date':img.get('date'), 'cloud_cover':img.get('cloud_cover')}).getInfo() if listYears.index(item) == len(listYears)-2: status = True else: status = False Map.addLayer(img, {'bands': ['swir2'],'gain' : [0.2],'gamma':0.6},\ 'B7_' + str(dictionaryInfos['date']).replace('-','_')+'_'+dictionaryInfos['satellite_name'],status) Map.addLayer(img,{"bands": ['ndfi'], "palette": ['ffffff', 'fffcff', 'fff9ff', 'fff7ff', 'fff4ff', 'fff2ff', 'ffefff', 'ffecff', 'ffeaff', 'ffe7ff', 'ffe5ff', 'ffe2ff', 'ffe0ff', 'ffddff', 'ffdaff', 'ffd8ff', 'ffd5ff', 'ffd3ff', 'ffd0ff', 'ffceff', 'ffcbff', 'ffc8ff', 'ffc6ff', 'ffc3ff', 'ffc1ff', 'ffbeff', 'ffbcff', 'ffb9ff', 'ffb6ff', 'ffb4ff', 'ffb1ff', 'ffafff', 'ffacff', 'ffaaff', 'ffa7ff', 'ffa4ff', 'ffa2ff', 'ff9fff', 'ff9dff', 'ff9aff', 'ff97ff', 'ff95ff', 'ff92ff', 'ff90ff', 'ff8dff', 'ff8bff', 'ff88ff', 'ff85ff', 'ff83ff', 'ff80ff', 'ff7eff', 'ff7bff', 'ff79ff', 'ff76ff', 'ff73ff', 'ff71ff', 'ff6eff', 'ff6cff', 'ff69ff', 'ff67ff', 'ff64ff', 'ff61ff', 'ff5fff', 'ff5cff', 'ff5aff', 'ff57ff', 'ff55ff', 'ff52ff', 'ff4fff', 'ff4dff', 'ff4aff', 'ff48ff', 'ff45ff', 'ff42ff', 'ff40ff', 'ff3dff', 'ff3bff', 'ff38ff', 'ff36ff', 'ff33ff', 'ff30ff', 'ff2eff', 'ff2bff', 'ff29ff', 'ff26ff', 'ff24ff', 'ff21ff', 'ff1eff', 'ff1cff', 'ff19ff', 'ff17ff', 'ff14ff', 'ff12ff', 'ff0fff', 'ff0cff', 'ff0aff', 'ff07ff', 'ff05ff', 'ff02ff', 'ff00ff', 'ff00ff', 'ff0af4', 'ff15e9', 'ff1fdf', 'ff2ad4', 'ff35c9', 'ff3fbf', 'ff4ab4', 'ff55aa', 'ff5f9f', 'ff6a94', 'ff748a', 'ff7f7f', 'ff8a74', 'ff946a', 'ff9f5f', 'ffaa55', 'ffb44a', 'ffbf3f', 'ffc935', 'ffd42a', 'ffdf1f', 'ffe915', 'fff40a', 'ffff00', 'ffff00', 'fffb00', 'fff700', 'fff300', 'fff000', 'ffec00', 'ffe800', 'ffe400', 'ffe100', 'ffdd00', 'ffd900', 'ffd500', 'ffd200', 'ffce00', 'ffca00', 'ffc600', 'ffc300', 'ffbf00', 'ffbb00', 'ffb700', 'ffb400', 'ffb000', 'ffac00', 'ffa800', 'ffa500', 'ffa500', 'f7a400', 'f0a300', 'e8a200', 'e1a200', 'd9a100', 'd2a000', 'ca9f00', 'c39f00', 'bb9e00', 'b49d00', 'ac9c00', 'a59c00', '9d9b00', '969a00', '8e9900', '879900', '7f9800', '789700', '709700', '699600', '619500', '5a9400', '529400', '4b9300', '439200', '349100', '2d9000', '258f00', '1e8e00', '168e00', '0f8d00', '078c00', '008c00', '008c00', '008700', '008300', '007f00', '007a00', '007600', '007200', '006e00', '006900', '006500', '006100', '005c00', '005800', '005400', '005000', '004c00'],\ "min":0,"max":200},'NDFI_' + str(dictionaryInfos['date']).replace('-','_')+'_'+dictionaryInfos['satellite_name'],status) except Exception as e: # print('Exception\n',str(e)) pass idG = idG + 1 for i in range(10): time.sleep(1) progress.setValue(i + 1) iface.messageBar().clearWidgets() Map.addLayer(countourGeometry,{ 'palette': '#000000', 'opacity': 0.8 },str(path) + '_' + str(row)) for item in auxLayers[dicAuxState[uf]][0]: outline = blankPaint(auxLayers[dicAuxState[uf]][item][1][1]) Map.addLayer(outline,auxLayers[dicAuxState[uf]][item][1][3],\ auxLayers[dicAuxState[uf]][item][1][2], False)
def run(self): """Run method that performs all the real work""" layers = self.iface.mapCanvas().layers() layer_list = [] self.dlg.layerComboBox.clear() for layer in layers: layer_list.append(layer.name()) self.dlg.layerComboBox.addItems(layer_list) # TODO: Make the active layer the selected item in combo box aLayer = qgis.utils.iface.activeLayer() # TODO: Add signal to update toleranceSpinBox.suffix (Degrees) from layerComboBox.crs.mapUnits when layer is selected: #my_UnitType = { 0: 'Meters', 1: 'Feet', 2: 'Degrees', 7: 'NauticalMiles', 8: 'Kilometers', 9: 'Yards', 10: 'Miles', 3: 'UnknownUnit'} #suffix = my_UnitType[aLayer.crs().mapUnits()] # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: if self.checkNetworkXModule() < 0: return -4 import networkx as nx layerName = self.dlg.layerComboBox.currentText() try: aLayer = QgsProject.instance().mapLayersByName(layerName)[0] except: self.iface.messageBar().pushMessage("Error", "Failed to load layer!", level=Qgis.Critical) return -1 try: previousEditingMode = True if not aLayer.isEditable(): aLayer.startEditing() #self.iface.messageBar().pushMessage("Info", "Layer " + aLayer.name() + " needs to be in edit mode", level=Qgis.Info) #self.iface.messageBar().pushMessage("Error", "Layer " + aLayer.name() + " needs to be in edit mode", level=Qgis.Critical) #return -2 previousEditingMode = False attrIdx = self.getAttributeIndex(aLayer) if attrIdx < 0: return -3 progressMessageBar = self.iface.messageBar().createMessage("Creating network graph...") progress = QProgressBar() progress.setMaximum(aLayer.featureCount()) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) G = nx.Graph() aLayer.beginEditCommand("Clear group attribute, create graph") # construct undirected graph tolerance = self.dlg.toleranceSpinBox.value() if tolerance == 0: tolerance = 0.000001 count = 0 for feat in aLayer.getFeatures(): count += 1 progress.setValue(count) done = aLayer.changeAttributeValue(feat.id(), attrIdx, -1) geom = feat.geometry() QgsGeometry.convertToSingleType(geom) # QGIS 3.x seems to load single LineString as MultiLineString?? line = geom.asPolyline() for i in range(len(line)-1): G.add_edges_from([((int(line[i][0]/tolerance), int(line[i][1]/tolerance)), (int(line[i+1][0]/tolerance), int(line[i+1][1]/tolerance)), {'fid': feat.id()})]) # first scale by tolerance, then convert to int. Before doing this, there were problems (in NetworkX v1) with floats not equating, thus creating disconnects that weren't there. if count % 100 == 0: QApplication.processEvents() # keep the UI responsive, every 100 features #TODO: check to see if Esc pressed aLayer.endEditCommand() self.iface.messageBar().pushMessage("Finding connected subgraphs, please wait...", level=Qgis.Warning) # WARNING - to highlight the next stage, where we cannot show progress QApplication.processEvents() connected_components = list(nx.connected_component_subgraphs(G)) # this takes a long time. TODO: how to show progress? self.iface.messageBar().pushMessage("Updating group attribute...", level=Qgis.Info) QApplication.processEvents() # gather edges and components to which they belong fid_comp = {} for i, graph in enumerate(connected_components): for edge in graph.edges(data=True): fid_comp[edge[2].get('fid', None)] = i # write output to csv file #with open('C:/Tmp/Components.csv', 'wb') as f: # w = csv.DictWriter(f, fieldnames=['fid', 'group']) # w.writeheader() # for (fid, group) in fid_comp.items(): # w.writerow({'fid': fid, 'group': group}) aLayer.beginEditCommand("Update group attribute") for (fid, group) in fid_comp.items(): done = aLayer.changeAttributeValue(fid, attrIdx, group) aLayer.endEditCommand() groups = list(set(fid_comp.values())) if self.dlg.stylingCheckBox.isChecked(): aLayer.beginEditCommand("Update layer styling") categories = [] firstCat = True for cat in groups: symbol = QgsSymbol.defaultSymbol(aLayer.geometryType()) symbol.setColor(QColor(randint(0,255), randint(0,255), randint(0,255))) if firstCat: firstCat = False else: symbol.setWidth(symbol.width()*5) category = QgsRendererCategory(cat, symbol, "%d" % cat) categories.append(category) field = self.dlg.attributeNameEditBox.text() renderer = QgsCategorizedSymbolRenderer(field, categories) aLayer.setRenderer(renderer) # if self.iface.mapCanvas().isCachingEnabled(): # aLayer.setCacheImage(None) # else: # self.iface.mapCanvas().refresh() aLayer.triggerRepaint() aLayer.endEditCommand() self.iface.messageBar().clearWidgets() self.iface.messageBar().pushMessage("Found main network and %d disconnected islands in layer %s" % (len(groups)-1, aLayer.name()), level=Qgis.Success) aLayer.commitChanges() # if not previousEditingMode: except Exception as e: self.iface.messageBar().pushMessage("Error", "Exception caught: %s. Please report an issue to the author of the plugin." % repr(e), level=Qgis.Critical)
def AddFileRowToManager(self, name, filename, load_id=None, islocal=False, klv_folder=None): ''' Add file Video to new Row ''' # We limit the number of videos due to the buffer if self.VManager.rowCount() > 5: qgsu.showUserAndLogMessage( QCoreApplication.translate( "ManagerDock", "You must delete some video from the list before adding a new one" )) return self.islocal = islocal self.klv_folder = klv_folder self.isStreaming = False w = QWidget() layout = QVBoxLayout() pbar = QProgressBar() layout.addWidget(pbar) w.setLayout(layout) rowPosition = self.VManager.rowCount() pbar.setGeometry(0, 0, 300, 30) pbar.setValue(0) pbar.setMaximumHeight(30) if load_id is None: row_id = 0 if rowPosition != 0: row_id = int(self.VManager.item(rowPosition - 1, 0).text()) + 1 else: row_id = load_id self.VManager.insertRow(rowPosition) self.VManager.setItem(rowPosition, 0, QTableWidgetItem(str(row_id))) self.VManager.setItem(rowPosition, 1, QTableWidgetItem(name)) self.VManager.setItem( rowPosition, 2, QTableWidgetItem( QCoreApplication.translate("ManagerDock", "Loading"))) self.VManager.setItem(rowPosition, 3, QTableWidgetItem(filename)) self.VManager.setItem(rowPosition, 4, QTableWidgetItem("-")) self.VManager.setCellWidget(rowPosition, 5, w) self.VManager.setVisible(False) self.VManager.horizontalHeader().setStretchLastSection(True) self.VManager.setVisible(True) # resolve if it is a stream if "://" in filename: self.isStreaming = True if not self.isStreaming: # Disable row if not exist video file if not os.path.exists(filename): self.ToggleActiveRow(rowPosition, value="Missing source file") for j in range(self.VManager.columnCount()): try: self.VManager.item(rowPosition, j).setFlags(Qt.NoItemFlags | Qt.ItemIsEnabled) self.VManager.item(rowPosition, j).setBackground( QColor(211, 211, 211)) except Exception: self.VManager.cellWidget(rowPosition, j).setStyleSheet( "background-color:rgb(211,211,211);") pass return pbar.setValue(30) info = FFMpeg().probe(filename) if info is None: qgsu.showUserAndLogMessage( QCoreApplication.translate("ManagerDock", "Failed loading FFMPEG ! ")) return info.format.duration # init non-blocking metadata buffered reader self.meta_reader[str(rowPosition)] = BufferedMetaReader( filename, pass_time=self.pass_time) qgsu.showUserAndLogMessage( "", "buffered non-blocking metadata reader initialized.", onlyLog=True) pbar.setValue(60) try: # init point we can center the video on self.initialPt[str(rowPosition)] = getVideoLocationInfo( filename, islocal, klv_folder) if not self.initialPt[str(rowPosition)]: self.VManager.setItem( rowPosition, 4, QTableWidgetItem( QCoreApplication.translate( "ManagerDock", "Start location not available."))) self.ToggleActiveRow(rowPosition, value="Not MISB") pbar.setValue(99) return else: self.VManager.setItem( rowPosition, 4, QTableWidgetItem(self.initialPt[str(rowPosition)][2])) except Exception: qgsu.showUserAndLogMessage( QCoreApplication.translate( "ManagerDock", "This video don't have Metadata ! ")) pbar.setValue(99) self.ToggleActiveRow(rowPosition, value="Not MISB") return pbar.setValue(90) dtm_path = parser['GENERAL']['DTM_file'] if self.initialPt[str(rowPosition)] and dtm_path != '': try: initElevationModel(self.initialPt[str(rowPosition)][0], self.initialPt[str(rowPosition)][1], dtm_path) qgsu.showUserAndLogMessage("", "Elevation model initialized.", onlyLog=True) except Exception: None else: self.meta_reader[str(rowPosition)] = StreamMetaReader(filename) qgsu.showUserAndLogMessage("", "StreamMetaReader initialized.", onlyLog=True) self.initialPt[str(rowPosition)] = None pbar.setValue(100) if islocal: self.ToggleActiveRow(rowPosition, value="Ready Local") else: self.ToggleActiveRow(rowPosition, value="Ready") # Add video to settings list AddVideoToSettings(str(row_id), filename)
def CreateMISB(self): ''' Create MISB Video ''' ''' Only tested using DJI Data ''' # Create ProgressBar self.iface.messageBar().clearWidgets() progressMessageBar = self.iface.messageBar().createMessage("Creating video packets...") progress = QProgressBar() progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, QGis.Info) QApplication.setOverrideCursor(Qt.WaitCursor) QApplication.processEvents() HFOV = self.sp_hfov.value() #VFOV = self.sp_vfov.value() index = self.cmb_telemetry.currentIndex() out_record = self.cmb_telemetry.itemData(index) rowCount = self.GetRows(out_record) progress.setMaximum(rowCount) d = {} with open(out_record) as csvfile: reader = csv.DictReader(csvfile) for row in reader: date_start = datetime.strptime(row["CUSTOM.updateTime"], '%Y/%m/%d %H:%M:%S.%f') break with open(out_record) as csvfile: reader = csv.DictReader(csvfile) for row in reader: for k in row: stripK = k.strip() stripV = row[k].strip() d[stripK] = stripV # We create the klv file for every moment sizeTotal = 0 bufferData = b'' cnt = 0 for k, v in d.items(): try: if k == "CUSTOM.updateTime": # We prevent it from failing in the exact times that don't have milliseconds try: date_end = datetime.strptime(v, '%Y/%m/%d %H:%M:%S.%f') except: date_end = datetime.strptime(v, '%Y/%m/%d %H:%M:%S') _bytes = datetime_to_bytes(date_end) _len = int_to_bytes(len(_bytes)) _bytes = _key2 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Heading Angle if k == "OSD.yaw": OSD_yaw = float(v) _bytes = float_to_bytes(round(OSD_yaw, 4), _domain5, _range5) _len = int_to_bytes(len(_bytes)) _bytes = _key5 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Pitch Angle if k == "OSD.pitch": OSD_pitch = 0.0 _bytes = float_to_bytes(round(OSD_pitch, 4), _domain6, _range6) _len = int_to_bytes(len(_bytes)) _bytes = _key6 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Roll Angle if k == "OSD.roll": OSD_roll = 0.0 _bytes = float_to_bytes(round(OSD_roll, 4), _domain7, _range7) _len = int_to_bytes(len(_bytes)) _bytes = _key7 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Latitude if k == "OSD.latitude": OSD_latitude = float(v) _bytes = float_to_bytes(round(OSD_latitude, 4), _domain13, _range13) _len = int_to_bytes(len(_bytes)) _bytes = _key13 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Longitude if k == "OSD.longitude": OSD_longitude = float(v) _bytes = float_to_bytes(OSD_longitude, _domain14, _range14) _len = int_to_bytes(len(_bytes)) _bytes = _key14 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor True Altitude if k == "OSD.altitude [m]": OSD_altitude = float(v) _bytes = float_to_bytes(round(OSD_altitude, 4), _domain15, _range15) _len = int_to_bytes(len(_bytes)) _bytes = _key15 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Ellipsoid Height if k == "OSD.height [m]": OSD_height = float(v) _bytes = float_to_bytes(round(OSD_height, 4), _domain75, _range75) _len = int_to_bytes(len(_bytes)) _bytes = _key75 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Relative Azimuth Angle if k == "GIMBAL.yaw": #GIMBAL_yaw = float(v) GIMBAL_yaw = 0.0 _bytes = float_to_bytes(round(GIMBAL_yaw, 4), _domain18, _range18) _len = int_to_bytes(len(_bytes)) _bytes = _key18 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Relative Elevation Angle if k == "GIMBAL.pitch": GIMBAL_pitch = float(v) _bytes = float_to_bytes(round(GIMBAL_pitch, 4), _domain19, _range19) _len = int_to_bytes(len(_bytes)) _bytes = _key19 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Relative Roll Angle if k == "GIMBAL.roll": GIMBAL_roll = 0.0 _bytes = float_to_bytes(round(GIMBAL_roll, 4), _domain20, _range20) _len = int_to_bytes(len(_bytes)) _bytes = _key20 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes except Exception: print("Multiplexer error") continue try: # Diference time td = date_end - date_start end_path = self.klv_folder + "/%.1f.klv" % (round(td.total_seconds(), 1)) # CheckSum v = abs(hash(end_path)) % (10 ** 4) _bytes = int_to_bytes(v, 4) _len = int_to_bytes(len(_bytes)) _bytes = _key1 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Horizontal Field of View v = self.sp_hfov.value() _bytes = float_to_bytes(float(v), _domain16, _range16) _len = int_to_bytes(len(_bytes)) _bytes = _key16 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Vertical Field of View v = self.sp_vfov.value() _bytes = float_to_bytes(float(v), _domain17, _range17) _len = int_to_bytes(len(_bytes)) _bytes = _key17 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # TODO : Check these calculations # Slant Range anlge = 180 + (OSD_pitch + GIMBAL_pitch) slantRange = abs(OSD_altitude / (cos(radians(anlge)))) _bytes = float_to_bytes(round(slantRange, 4), _domain21, _range21) _len = int_to_bytes(len(_bytes)) _bytes = _key21 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Target Width # targetWidth = 0.0 targetWidth = 2.0 * slantRange * tan(radians(HFOV / 2.0)) _bytes = float_to_bytes(round(targetWidth, 4), _domain22, _range22) _len = int_to_bytes(len(_bytes)) _bytes = _key22 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Frame Center Latitude angle = 90 + (OSD_pitch + GIMBAL_pitch) tgHzDist = OSD_altitude * tan(radians(angle)) r_earth = 6371008.8 dy = tgHzDist * cos(radians(OSD_yaw)) framecenterlatitude = OSD_latitude + (dy / r_earth) * (180 / pi) _bytes = float_to_bytes(round(framecenterlatitude, 4), _domain23, _range23) _len = int_to_bytes(len(_bytes)) _bytes = _key23 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Frame Center Longitude dx = tgHzDist * sin(radians(OSD_yaw)) framecenterlongitude = OSD_longitude + (dx / r_earth) * (180 / pi) / cos(OSD_latitude * pi/180) _bytes = float_to_bytes(round(framecenterlongitude, 4), _domain24, _range24) _len = int_to_bytes(len(_bytes)) _bytes = _key24 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Frame Center Elevation frameCenterElevation = 0.0 _bytes = float_to_bytes(frameCenterElevation, _domain25, _range25) _len = int_to_bytes(len(_bytes)) _bytes = _key25 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # TODO : If we save the corners in the klv have a overflow # # CALCULATE CORNERS COORDINATES # sensor = (OSD_longitude, OSD_latitude, OSD_altitude) # frameCenter = (destPoint[0], destPoint[1], frameCenterElevation) # FOV = (VFOV, HFOV) # others = (OSD_yaw, GIMBAL_yaw, targetWidth, slantRange) # cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL = CornerEstimationWithoutOffsets(sensor=sensor, frameCenter=frameCenter, FOV=FOV, others=others) # # # Corner Latitude Point 1 (Full) # _bytes = float_to_bytes(round(cornerPointUL[0],4), _domain82, _range82) # _len = int_to_bytes(len(_bytes)) # _bytes = _key82 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 1 (Full) # _bytes = float_to_bytes(round(cornerPointUL[1],4), _domain83, _range83) # _len = int_to_bytes(len(_bytes)) # _bytes = _key83 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Latitude Point 2 (Full) # _bytes = float_to_bytes(round(cornerPointUR[0],4), _domain84, _range84) # _len = int_to_bytes(len(_bytes)) # _bytes = _key84 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 2 (Full) # _bytes = float_to_bytes(round(cornerPointUR[1],4), _domain85, _range85) # _len = int_to_bytes(len(_bytes)) # _bytes = _key85 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Latitude Point 3 (Full) # _bytes = float_to_bytes(round(cornerPointLR[0],4), _domain86, _range86) # _len = int_to_bytes(len(_bytes)) # _bytes = _key86 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 3 (Full) # _bytes = float_to_bytes(round(cornerPointLR[1],4), _domain87, _range87) # _len = int_to_bytes(len(_bytes)) # _bytes = _key87 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Latitude Point 4 (Full) # _bytes = float_to_bytes(round(cornerPointLL[0],4), _domain88, _range88) # _len = int_to_bytes(len(_bytes)) # _bytes = _key88 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 4 (Full) # _bytes = float_to_bytes(round(cornerPointLL[1],4), _domain89, _range89) # _len = int_to_bytes(len(_bytes)) # _bytes = _key89 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # Platform Pitch Angle (Full) _bytes = float_to_bytes(round(OSD_pitch, 4), _domain90, _range90) _len = int_to_bytes(len(_bytes)) _bytes = _key90 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Roll Angle (Full) _bytes = float_to_bytes(round(OSD_roll, 4), _domain91, _range91) _len = int_to_bytes(len(_bytes)) _bytes = _key91 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # set packet header writeData = cle writeData += int_to_bytes(sizeTotal) writeData += bufferData # Write packet f_write = open(end_path, "wb+") f_write.write(writeData) f_write.close() cnt += 1 progress.setValue(cnt) except Exception as e: print("Multiplexer error : " + str(e)) QApplication.restoreOverrideCursor() QApplication.processEvents() progress.setValue(rowCount) self.iface.messageBar().clearWidgets() # We add it to the manager _, name = os.path.split(self.video_file) self.parent.AddFileRowToManager(name, self.video_file, islocal=True, klv_folder=self.klv_folder) # Close dialog self.close() return
class Window(QDialog): def __init__(self): super().__init__() self.title = "PyQt5 ProgressBar" self.top = 200 self.left = 500 self.width = 300 self.height = 100 self.setWindowIcon(QtGui.QIcon("icon.png")) self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) vbox = QVBoxLayout() self.progressbar = QProgressBar() #self.progressbar.setOrientation(Qt.Vertical) self.progressbar.setMaximum(100) vbox.addWidget(self.progressbar) self.startProgressBar() self.setLayout(vbox) #self.show() def startProgressBar(self): self.thread = MyThread() self.thread.change_value.connect(self.setProgressBarAndMessages) self.thread.start() def setProgressBarAndMessages(self, val): self.progressbar.setValue(val) # --- Progress bar in the QGIS user messages (top) if val <= 10: message = "Starting..." self.progressMessageBar = iface.messageBar().createMessage(message) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) self.progress.setValue(val) elif val < 50: message = "First half" self.progressMessageBar = iface.messageBar().createMessage(message) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) self.progress.setValue(val) elif val < 100: message = "Second Half" self.progressMessageBar = iface.messageBar().createMessage(message) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) self.progress.setValue(val) elif val == 100: message = "Complete" self.progressMessageBar = iface.messageBar().createMessage(message) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) self.progress.setValue(val) iface.messageBar().clearWidgets()
#!/usr/bin/python
class ProgressDialog(QDialog): """ Progress dialog shows progress bar for algorithm. """ def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.workerThread = None self.state = False self.outputLoc = None self.resultStatus = None self.reRun = False self.savedProj = None # Build GUI Elements self.setWindowTitle("SEILAPLAN wird ausgeführt") self.resize(500, 100) self.container = QVBoxLayout() self.progressBar = QProgressBar(self) self.progressBar.setMinimumWidth(500) self.statusLabel = QLabel(self) self.hbox = QHBoxLayout() self.cancelButton = QDialogButtonBox() self.closeButton = QDialogButtonBox() self.resultLabel = ClickLabel(self) self.resultLabel.setMaximumWidth(500) self.resultLabel.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)) self.resultLabel.setWordWrap(True) self.rerunButton = QPushButton("Berechnungen wiederholen") self.rerunButton.setVisible(False) spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.cancelButton.setStandardButtons(QDialogButtonBox.Cancel) self.cancelButton.clicked.connect(self.onAbort) self.closeButton.setStandardButtons(QDialogButtonBox.Close) self.closeButton.clicked.connect(self.onClose) self.hbox.addWidget(self.rerunButton) self.hbox.addItem(spacer) self.hbox.addWidget(self.cancelButton) self.hbox.setAlignment(self.cancelButton, Qt.AlignHCenter) self.hbox.addWidget(self.closeButton) self.hbox.setAlignment(self.closeButton, Qt.AlignHCenter) self.closeButton.hide() self.container.addWidget(self.progressBar) self.container.addWidget(self.statusLabel) self.container.addWidget(self.resultLabel) self.container.addLayout(self.hbox) self.container.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(self.container) def setThread(self, workerThread): self.workerThread = workerThread self.connectProgressSignals() def connectProgressSignals(self): # Connet signals of thread self.workerThread.sig_jobEnded.connect(self.jobEnded) self.workerThread.sig_jobError.connect(self.onError) self.workerThread.sig_value.connect(self.valueFromThread) self.workerThread.sig_range.connect(self.rangeFromThread) self.workerThread.sig_text.connect(self.textFromThread) self.workerThread.sig_result.connect(self.resultFromThread) self.rerunButton.clicked.connect(self.onRerun) def run(self): # Show modal dialog window (QGIS is still responsive) self.show() # start event loop self.exec_() def jobEnded(self, success): self.setWindowTitle("SEILAPLAN") if success: self.statusLabel.setText("Berechnungen abgeschlossen.") self.progressBar.setValue(self.progressBar.maximum()) self.setFinalMessage() else: # If there was an abort by the user self.statusLabel.setText("Berechnungen abgebrochen.") self.progressBar.setValue(self.progressBar.minimum()) self.finallyDo() self.rerunButton.setVisible(True) def valueFromThread(self, value): self.progressBar.setValue(value) def rangeFromThread(self, range_vals): self.progressBar.setRange(range_vals[0], range_vals[1]) def maxFromThread(self, max): self.progressBar.setValue(self.progressBar.maximum()) def textFromThread(self, value): self.statusLabel.setText(value) def resultFromThread(self, result): [self.outputLoc, self.resultStatus] = result def setFinalMessage(self): self.resultLabel.clicked.connect(self.onResultClicked) self.resultLabel.blockSignals(True) linkToFolder = ('<html><head/><body><p></p><p><a href=' '"file:////{0}"><span style="text-decoration: ' 'underline; color:#0000ff;">{0}</span></a></p>' '</body></html>'.format(self.outputLoc)) # Optimization successful if self.resultStatus == 1: self.resultLabel.setText(textOK + linkToFolder) self.resultLabel.blockSignals(False) # Cable takes off of support elif self.resultStatus == 2: self.resultLabel.setText(textSeil + linkToFolder) self.resultLabel.blockSignals(False) # Optimization partially successful elif self.resultStatus == 3: self.resultLabel.setText(textHalf + linkToFolder) self.resultLabel.blockSignals(False) # Optimization not successful elif self.resultStatus == 4: self.resultLabel.setText(textBad) self.setLayout(self.container) def onResultClicked(self): # Open a folder window if sys.platform == 'darwin': # MAC subprocess.call(["open", "-R", self.outputLoc]) elif sys.platform.startswith('linux'): # LINUX subprocess.Popen(["xdg-open", self.outputLoc]) elif 'win32' in sys.platform: # WINDOWS from subprocess import CalledProcessError try: subprocess.check_call(['explorer', self.outputLoc]) except CalledProcessError: pass def onAbort(self): self.setWindowTitle("SEILAPLAN") self.statusLabel.setText("Laufender Prozess wird abgebrochen...") self.workerThread.cancel() # Terminates process cleanly def onError(self, exception_string): self.setWindowTitle("SEILAPLAN: Berechnung fehlgeschlagen") self.statusLabel.setText("Ein Fehler ist aufgetreten:") self.resultLabel.setText(exception_string) self.progressBar.setValue(self.progressBar.minimum()) self.finallyDo() def onRerun(self): self.reRun = True self.onClose() def finallyDo(self): self.cancelButton.hide() self.closeButton.show() def onClose(self): self.close()
class ProgressPage(QWizardPage): def __init__(self, title = "Performing analysis", sub_title = " "): QWizardPage.__init__(self) self._task = None self._done = False self.setTitle(title); self.setSubTitle(sub_title); self.createWidgets() def createWidgets(self): vlayout = QVBoxLayout() vlayout.addStretch(1); self._statusLabel = QLabel("") vlayout.addWidget(self._statusLabel) self._progressBar = QProgressBar() self._progressBar.setMaximum(1000) vlayout.addWidget(self._progressBar) self._etaLabel = QLabel("") vlayout.addWidget(self._etaLabel) vlayout.addStretch(1); self.setLayout(vlayout); # QWizardPage overrides def initializePage(self): self._done = False self._statusLabel.setText("") self._progressBar.setValue(0) self._etaLabel.setText("") self.startDeferred() # QWizardPage override def isComplete(self): return self._done def start(self): props = self.wizard().properties() task = self.wizard().createTask(props) if not task: self._done = True self.finish() return self._task = task #task.terminated.connect(self.onTaskTerminated) #task.finished.connect(self.onTaskFinished) #task.statusChanged.connect(self.onTaskStatusChanged) #task.progressChanged.connect(self.onTaskProgressChanged) #if THREADED: # task.start() # Run as separate thread dlgt = AnalysisDelegateFilter(self) try: task.run(dlgt) except AnalysisException as e: QMessageBox.critical(self, "PST Error", str(e)) self.wizard().restart() return dlgt.outputStats() self.finish() def startDeferred(self): QTimer.singleShot(0, self.start) def finish(self): self._task = None self._done = True self.completeChanged.emit() self.wizard().next() # AnalysisDelegate interface def setProgress(self, progress): self._progressBar.setValue(1000 * progress) QApplication.processEvents() # UI update # AnalysisDelegate interface def setStatus(self, text): self._statusLabel.setText(text + "...") QApplication.processEvents() # UI update # AnalysisDelegate interface def getCancel(self): return False # slot, unused def onTaskTerminated(self): print("ProgressPage.onTaskTerminated") # TODO: Show error popup self.finish() # slot, unused def onTaskFinished(self): print("ProgressPage.onTaskFinished") self.finish() # slot, unused def onTaskStatusChanged(self, text): self.setStatus(text) # slot, unused def onTaskProgressChanged(self, progress): self.setProgress(progress)
class Create_model: def __init__(self, dlg, current_layer): """This constructor need Qt Dialog class as dlg and need current layer to execute the algorithm in current_layer parameter""" self.layers = current_layer self.bar = QProgressBar() self.dlg = dlg #self.list = [] self.border = [] self.X = [] self.Y = [] self.Z = [] self.faces = [] self.points = [] #self.list_of_all=[] self.NoData = -3.4028234663852886e+38 '''def iterator(self): """Main algorithm to iterate through all the pixels and also to create boundaries""" self.layer = self.dlg.cmbSelectLayer.currentLayer() #get the extent of layer provider = self.layer.dataProvider() extent = provider.extent() xmin = extent.xMinimum() ymax = extent.yMaximum() rows = self.layer.height() cols = self.layer.width() xsize = self.layer.rasterUnitsPerPixelX() ysize = self.layer.rasterUnitsPerPixelY() xinit = xmin + xsize / 2 yinit = ymax - ysize / 2 block = provider.block(1, extent, cols, rows) #iterate the raster to get the values of pixels k=1 for i in range(rows): for j in range(cols): x = xinit + j * xsize y = yinit k += 1 if block.value(i, j) == self.NoData: self.list_of_all.append([i,j,x,y,block.value(i,j)]) elif block.value(i,j)>=self.dlg.dsbDatum.value(): self.list.append([x, y, block.value(i, j)]) self.list_of_all.append([i,j,x,y,block.value(i,j)]) else: self.list_of_all.append([i,j,x,y,self.NoData]) xinit = xmin + xsize / 2 yinit -= ysize #get minimal value to stretching method print(len(self.list_of_all)) height=[] for searching in self.list: height.append(searching[2]) self.minimal=min(height) #iterate the raster to get the boundaries colrow=[] rowcol=[] for pixelo in self.list_of_all: rowcol.append(pixelo) if pixelo[1]==j: colrow.append(rowcol) rowcol=[] for pixel in self.list_of_all: if pixel[4] != self.NoData: if pixel[0]==0 or pixel[1]==0 or pixel[0]==i or pixel[1]==j: pixel[4] = float(self.dlg.dsbDatum.value()) self.border.append([pixel[2],pixel[3],pixel[4]]) #self.list = self.border + self.list else: wii=pixel[0] kol=pixel[1] pixel[4]=float(self.dlg.dsbDatum.value()) condition1 = colrow[wii-1][kol][4] condition2 = colrow[wii][kol-1][4] condition3 = colrow[wii+1][kol][4] condition4 = colrow[wii][kol+1][4] if condition1> self.NoData or condition2> self.NoData or condition3> self.NoData or condition4 > self.NoData: if condition1 == self.NoData or condition2== self.NoData or condition3== self.NoData or condition4 == self.NoData: self.border.append([pixel[2],pixel[3],pixel[4]]) #self.list=self.border+self.list self.list += self.border print(len(self.border)) #print(self.list) print(len(self.list)) return self.list, self.minimal''' def iterator(self): #path = iface.activeLayer().source() path = self.dlg.cmbSelectLayer.currentLayer().source() data_source = gdal.Open(path) #extract one band, because we don't need 3d matrix band = data_source.GetRasterBand(1) #read matrix as numpy array raster = band.ReadAsArray().astype(np.float) #threshold = 222 #poziom odniesienia - wyzsze od 222 threshold = self.dlg.dsbDatum.value() #change no data to nan value raster[raster == band.GetNoDataValue()] = np.nan raster2 = raster[np.logical_not( np.isnan(raster) )] #w raster2 nie mam nanow i sa to tylko wartosci wysokosci (y_index, x_index) = np.nonzero(raster >= threshold) #get the minimal value to stretching method self.minimal = np.nanmin(raster) #To demonstate this compare a.shape to band.XSize and band.YSize (upper_left_x, x_size, x_rotation, upper_left_y, y_rotation, y_size) = data_source.GetGeoTransform() x_coords = x_index * x_size + upper_left_x + ( x_size / 2) #add half the cell size y_coords = y_index * y_size + upper_left_y + (y_size / 2 ) #to centre the point raster3 = raster2[raster2 >= threshold] z_coords = np.asarray(raster3).reshape(-1) entire_matrix = np.stack((x_coords, y_coords, z_coords), axis=-1) #add outer bounder = np.pad(raster, pad_width=1, mode='constant', constant_values=np.nan) bounder_inner = (np.roll(bounder, 1, axis=0) * np.roll(bounder, -1, axis=0) * np.roll(bounder, 1, axis=1) * np.roll(bounder, -1, axis=1) * np.roll(np.roll(bounder, 1, axis=0), 1, axis=1) * np.roll(np.roll(bounder, 1, axis=0), -1, axis=1) * np.roll(np.roll(bounder, -1, axis=0), 1, axis=1) * np.roll(np.roll(bounder, -1, axis=0), -1, axis=1)) is_inner = (np.isnan(bounder_inner) == False) b = bounder b[is_inner] = np.nan b[~np.isnan(b)] = threshold boundary_real = b[1:-1, 1:-1] boundary_real_2 = boundary_real[np.logical_not( np.isnan(boundary_real))] #create boundary coordinates (y_index_boundary, x_index_boundary) = np.nonzero(boundary_real == threshold) #print(len(boundary_real_2)) x_coords_boundary = x_index_boundary * x_size + upper_left_x + ( x_size / 2) #add half the cell size y_coords_boundary = y_index_boundary * y_size + upper_left_y + ( y_size / 2) #to centre the point z_coords_boundary = np.asarray(boundary_real_2).reshape(-1) boundary_the_end = np.stack( (x_coords_boundary, y_coords_boundary, z_coords_boundary), axis=-1) boundary_the_end = np.repeat(boundary_the_end, 10, axis=0) self.entire_mat_with_heights = np.concatenate( (entire_matrix, boundary_the_end)) #entire_mat_with_heights[entire_mat_with_heights[:, [0,1,2]].argsort()] self.entire_mat_with_heights = self.entire_mat_with_heights[np.argsort( self.entire_mat_with_heights[:, 2])] return self.entire_mat_with_heights, self.minimal def delaunay(self): """This is Delaunay algorithm from Scipy lib This is needed to create vertices and faces which will be going to executed in creating STL model""" self.x = self.entire_mat_with_heights[:, 0] self.y = self.entire_mat_with_heights[:, 1] self.z = self.entire_mat_with_heights[:, 2] #print(self.x.shape) self.tri = Delaunay(np.array([self.x, self.y]).T) for vert in self.tri.simplices: self.faces.append([vert[0], vert[1], vert[2]]) for i in range(self.x.shape[0]): self.points.append([self.x[i], self.y[i], self.z[i]]) return self.faces, self.points, self.x, self.y, self.z, self.tri def saver(self): """ Create STL model """ # Define the vertices vertices = np.array(self.points) # Define the triangles facess = np.array(self.faces) # Create the mesh self.figure = mesh.Mesh( np.zeros(facess.shape[0], dtype=mesh.Mesh.dtype)) all_percentage = len(facess) value = self.bar.value() for i, f in enumerate(facess): if value < all_percentage: value = value + 1 self.bar.setValue(value) else: self.timer.stop() for j in range(3): self.figure.vectors[i][j] = vertices[f[j], :] filename = self.dlg.lineEdit.text() self.figure.save(filename) return self.figure def create_graph(self): """ Visualize model by Matplotlib lib""" fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection='3d') ax.plot_trisurf(self.x, self.y, self.z, triangles=self.tri.simplices, cmap=plt.cm.Spectral) ax.set_title('3D_Graph') ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') plt.show() def stretching(self): """ This method stretching the entire model to the given Datum level""" for cords in self.entire_mat_with_heights: if cords[2] > self.minimal: height_stretched = cords[2] - float(self.dlg.dsbDatum.value()) height_stretched = height_stretched * self.dlg.sbStretch.value( ) height_stretched += float(self.dlg.dsbDatum.value()) cords[2] = height_stretched return self.entire_mat_with_heights def loading(self): """ Loading progress bar """ self.dialog = QProgressDialog() self.dialog.setWindowTitle("Loading") self.dialog.setLabelText("That's your progress") self.bar = QProgressBar() self.bar.setTextVisible(True) self.dialog.setBar(self.bar) self.dialog.setMinimumWidth(300) self.dialog.show() self.timer = QTimer() self.timer.timeout.connect(self.saver) self.timer.start(1000) def shape(self, direction): """ This algorithm convert ShapeFile to the .tif file. To created that process I used a lot of GDAL processing algorithms and this gave me possibility to convert the shape to .tif file, drape them to the correct elevation and merge this new raster to the current main tif """ self.plugin_dir = direction buffer_distance = self.dlg.dsbBuffer.value() output_data_type = self.dlg.sbOutputData.value() output_raster_size_unit = 0 no_data_value = 0 layer2 = self.dlg.cmbSelectShape.currentLayer() shape_dir = os.path.join(self.plugin_dir, 'TRASH') layer_ext_cor = self.dlg.cmbSelectLayer.currentLayer() provider = layer_ext_cor.dataProvider() extent = provider.extent() xmin = extent.xMinimum() ymax = extent.yMaximum() xmax = extent.xMaximum() ymin = extent.yMinimum() cord_sys = layer_ext_cor.crs().authid() coords = "%f,%f,%f,%f " % (xmin, xmax, ymin, ymax) + '[' + str(cord_sys) + ']' rows = layer_ext_cor.height() cols = layer_ext_cor.width() set_shp_height = self.dlg.sbHeight.value() processing.run( "native:buffer", { 'INPUT': layer2, 'DISTANCE': buffer_distance, 'SEGMENTS': 5, 'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 2, 'DISSOLVE': False, 'OUTPUT': os.path.join(shape_dir, 'shape_bufor.shp') }) #### tu poprawic ten dissolve \/ zredukowac ten na dole processing.run( "native:dissolve", { 'INPUT': os.path.join(shape_dir, 'shape_bufor.shp'), 'FIELD': [], 'OUTPUT': os.path.join(shape_dir, 'shape_dissolve.shp') }) processing.run( "qgis:generatepointspixelcentroidsinsidepolygons", { 'INPUT_RASTER': self.dlg.cmbSelectLayer.currentLayer().dataProvider(). dataSourceUri(), 'INPUT_VECTOR': os.path.join(shape_dir, 'shape_dissolve.shp'), 'OUTPUT': os.path.join(shape_dir, 'shape_points.shp') }) processing.run( "native:setzfromraster", { 'INPUT': os.path.join(shape_dir, 'shape_points.shp'), 'RASTER': self.dlg.cmbSelectLayer.currentLayer().dataProvider(). dataSourceUri(), 'BAND': 1, 'NODATA': 0, 'SCALE': 1, 'OUTPUT': os.path.join(shape_dir, 'shape_drape.shp') }) layer3 = iface.addVectorLayer( os.path.join(shape_dir, 'shape_drape.shp'), "Shape_Drape", "ogr") if not layer3: print("Layer failed to load!") field_name = "height" field_namess = [field.name() for field in layer3.fields()] i = 0 for l in range(100): i += 1 if field_name in field_namess: print('Exist') field_name = field_name + str(i) continue else: print('Doesn\'t Exist') break processing.run( "qgis:fieldcalculator", { 'INPUT': os.path.join(shape_dir, 'shape_drape.shp'), 'FIELD_NAME': field_name, 'FIELD_TYPE': 0, 'FIELD_LENGTH': 10, 'FIELD_PRECISION': 3, 'NEW_FIELD': True, 'FORMULA': 'z($geometry)+' + str(set_shp_height), 'OUTPUT': os.path.join(shape_dir, 'shape_drape_c.shp') }) processing.run( "gdal:rasterize", { 'INPUT': os.path.join(shape_dir, 'shape_drape_c.shp'), 'FIELD': field_name, 'BURN': 0, 'UNITS': output_raster_size_unit, 'WIDTH': cols, 'HEIGHT': rows, 'EXTENT': coords, 'NODATA': no_data_value, 'OPTIONS': '', 'DATA_TYPE': output_data_type, 'INIT': None, 'INVERT': False, 'OUTPUT': os.path.join(shape_dir, 'shape_to_raster.tif') }) iface.addRasterLayer(os.path.join(shape_dir, 'shape_to_raster.tif'), "Shape_to_Raster") QgsProject.instance().removeMapLayers([layer3.id()]) processing.run( "gdal:merge", { 'INPUT': [ self.dlg.cmbSelectLayer.currentLayer().dataProvider(). dataSourceUri(), os.path.join(shape_dir, 'shape_to_raster.tif') ], 'PCT': False, 'SEPARATE': False, 'NODATA_INPUT': None, 'NODATA_OUTPUT': None, 'OPTIONS': '', 'DATA_TYPE': 5, 'OUTPUT': os.path.join(shape_dir, 'merged.tif') }) iface.addRasterLayer(os.path.join(shape_dir, 'merged.tif'), "Raster_With_Shape") shape_to_raster = QgsProject.instance().mapLayersByName( 'Shape_to_Raster') QgsProject.instance().removeMapLayers([shape_to_raster[0].id()])
def generate_report(self, db, report_type): # Check if mapfish and Jasper are installed, otherwise show where to # download them from and return if not self.report_dependency.check_if_dependency_is_valid(): self.report_dependency.download_dependency(URL_REPORTS_LIBRARIES) return java_home_set = self.java_dependency.set_java_home() if not java_home_set: self.java_dependency.get_java_on_demand() self.logger.info_msg( __name__, QCoreApplication.translate( "ReportGenerator", "Java is a prerequisite. Since it was not found, it is being configured..." )) return plot_layer = self.app.core.get_layer(db, db.names.LC_PLOT_T, load=True) if not plot_layer: return selected_plots = plot_layer.selectedFeatures() if not selected_plots: self.logger.warning_msg( __name__, QCoreApplication.translate( "ReportGenerator", "To generate reports, first select at least a plot!")) return # Where to store the reports? previous_folder = QSettings().value( "Asistente-LADM-COL/reports/save_into_dir", ".") save_into_folder = QFileDialog.getExistingDirectory( None, QCoreApplication.translate( "ReportGenerator", "Select a folder to save the reports to be generated"), previous_folder) if not save_into_folder: self.logger.warning_msg( __name__, QCoreApplication.translate( "ReportGenerator", "You need to select a folder where to save the reports before continuing." )) return QSettings().setValue("Asistente-LADM-COL/reports/save_into_dir", save_into_folder) config_path = os.path.join(DEPENDENCY_REPORTS_DIR_NAME, report_type) json_spec_file = os.path.join(config_path, 'spec_json_file.json') script_name = '' if os.name == 'posix': script_name = 'print' elif os.name == 'nt': script_name = 'print.bat' script_path = os.path.join(DEPENDENCY_REPORTS_DIR_NAME, 'bin', script_name) if not os.path.isfile(script_path): self.logger.warning( __name__, "Script file for reports wasn't found! {}".format(script_path)) return self.enable_action_requested.emit(report_type, False) # Update config file yaml_config_path = self.update_yaml_config(db, config_path) self.logger.debug( __name__, "Config file for reports: {}".format(yaml_config_path)) total = len(selected_plots) step = 0 count = 0 tmp_dir = self.get_tmp_dir() # Progress bar setup progress = QProgressBar() if total == 1: progress.setRange(0, 0) else: progress.setRange(0, 100) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.app.gui.create_progress_message_bar( QCoreApplication.translate("ReportGenerator", "Generating {} report{}...").format( total, '' if total == 1 else 's'), progress) polygons_with_holes = [] multi_polygons = [] for selected_plot in selected_plots: plot_id = selected_plot[db.names.T_ID_F] geometry = selected_plot.geometry() abstract_geometry = geometry.get() if abstract_geometry.ringCount() > 1: polygons_with_holes.append(str(plot_id)) self.logger.warning( __name__, QCoreApplication.translate( "ReportGenerator", "Skipping Annex 17 for plot with {}={} because it has holes. The reporter module does not support such polygons." ).format(db.names.T_ID_F, plot_id)) continue if abstract_geometry.numGeometries() > 1: multi_polygons.append(str(plot_id)) self.logger.warning( __name__, QCoreApplication.translate( "ReportGenerator", "Skipping Annex 17 for plot with {}={} because it is a multi-polygon. The reporter module does not support such polygons." ).format(db.names.T_ID_F, plot_id)) continue # Generate data file json_file = self.update_json_data(db, json_spec_file, plot_id, tmp_dir, report_type) self.logger.debug(__name__, "JSON file for reports: {}".format(json_file)) # Run sh/bat passing config and data files proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) parcel_number = self.ladm_data.get_parcels_related_to_plots( db, [plot_id], db.names.LC_PARCEL_T_PARCEL_NUMBER_F) or [''] file_name = '{}_{}_{}.pdf'.format(report_type, plot_id, parcel_number[0]) current_report_path = os.path.join(save_into_folder, file_name) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): # Grant execution permissions os.chmod( script_path, stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR | stat.S_IRUSR | stat.S_IRGRP) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): proc = None self.logger.warning( __name__, "Couldn't execute script to generate report...") else: loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.logger.debug(__name__, "{}:{}".format(plot_id, proc.exitCode())) if proc.exitCode() == 0: count += 1 step += 1 progress.setValue(step * 100 / total) os.remove(yaml_config_path) self.enable_action_requested.emit(report_type, True) self.logger.clear_message_bar() if total == count: if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report <a href='file:///{}'>{}</a> was successfully generated!" ).format(normalize_local_url(save_into_folder), file_name) else: msg = QCoreApplication.translate( "ReportGenerator", "All reports were successfully generated in folder <a href='file:///{path}'>{path}</a>!" ).format(path=normalize_local_url(save_into_folder)) self.logger.success_msg(__name__, msg) else: details_msg = '' if polygons_with_holes: details_msg += QCoreApplication.translate( "ReportGenerator", " The following polygons were skipped because they have holes and are not supported: {}." ).format(", ".join(polygons_with_holes)) if multi_polygons: details_msg += QCoreApplication.translate( "ReportGenerator", " The following polygons were skipped because they are multi-polygons and are not supported: {}." ).format(", ".join(multi_polygons)) if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report for plot {} couldn't be generated!{} See QGIS log (tab '{}') for details." ).format(plot_id, details_msg, self.LOG_TAB) else: if count == 0: msg = QCoreApplication.translate( "ReportGenerator", "No report could be generated!{} See QGIS log (tab '{}') for details." ).format(details_msg, self.LOG_TAB) else: msg = QCoreApplication.translate( "ReportGenerator", "At least one report couldn't be generated!{details_msg} See QGIS log (tab '{log_tab}') for details. Go to <a href='file:///{path}'>{path}</a> to see the reports that were generated." ).format(details_msg=details_msg, path=normalize_local_url(save_into_folder), log_tab=self.LOG_TAB) self.logger.warning_msg(__name__, msg)
def AddFileRowToManager(self, name, filename, load_id=None, islocal=False, klv_folder=None): ''' Add file Video to new Row ''' # We limit the number of videos due to the buffer self.loading = True if self.VManager.rowCount() > 5: qgsu.showUserAndLogMessage(QCoreApplication.translate( "ManagerDock", "You must delete some video from the list before adding a new one" ), level=QGis.Warning) self.loading = False return self.islocal = islocal self.klv_folder = klv_folder w = QWidget() layout = QVBoxLayout() pbar = QProgressBar() layout.addWidget(pbar) w.setLayout(layout) rowPosition = self.VManager.rowCount() self.videoPlayable.append(False) pbar.setGeometry(0, 0, 300, 30) pbar.setValue(0) pbar.setMaximumHeight(30) if load_id is None: row_id = 0 if rowPosition != 0: row_id = int(self.VManager.item(rowPosition - 1, 0).text()) + 1 else: row_id = load_id self.VManager.insertRow(rowPosition) self.VManager.setItem(rowPosition, 0, QTableWidgetItem(str(row_id))) self.VManager.setItem(rowPosition, 1, QTableWidgetItem(name)) self.VManager.setItem( rowPosition, 2, QTableWidgetItem( QCoreApplication.translate("ManagerDock", "Loading"))) self.VManager.setItem(rowPosition, 3, QTableWidgetItem(filename)) self.VManager.setItem(rowPosition, 4, QTableWidgetItem("-")) self.VManager.setCellWidget(rowPosition, 5, w) self.VManager.setVisible(False) self.VManager.horizontalHeader().setStretchLastSection(True) self.VManager.setVisible(True) # resolve if it is a stream if "://" in filename: self.videoIsStreaming.append(True) else: self.videoIsStreaming.append(False) if not self.videoIsStreaming[-1]: # Disable row if not exist video file if not os.path.exists(filename): self.ToggleActiveRow(rowPosition, value="Missing source file") for j in range(self.VManager.columnCount()): try: self.VManager.item(rowPosition, j).setFlags(Qt.NoItemFlags | Qt.ItemIsEnabled) self.VManager.item(rowPosition, j).setBackground( QColor(211, 211, 211)) except Exception: self.VManager.cellWidget(rowPosition, j).setStyleSheet( "background-color:rgb(211,211,211);") pass self.loading = False return pbar.setValue(30) info = FFMpeg().probe(filename) if info is None: qgsu.showUserAndLogMessage( QCoreApplication.translate("ManagerDock", "Failed loading FFMPEG ! ")) klvIdx = getKlvStreamIndex(filename, islocal) # init non-blocking metadata buffered reader self.meta_reader.append( BufferedMetaReader(filename, klv_index=klvIdx, pass_time=self.pass_time, interval=self.buf_interval)) pbar.setValue(60) try: # init point we can center the video on self.initialPt.append( getVideoLocationInfo(filename, islocal, klv_folder)) if not self.initialPt[rowPosition]: self.VManager.setItem( rowPosition, 4, QTableWidgetItem( QCoreApplication.translate( "ManagerDock", "Start location not available."))) self.ToggleActiveRow(rowPosition, value="Video not applicable") pbar.setValue(100) else: self.VManager.setItem( rowPosition, 4, QTableWidgetItem(self.initialPt[rowPosition][2])) pbar.setValue(90) self.videoPlayable[rowPosition] = True except Exception: qgsu.showUserAndLogMessage( QCoreApplication.translate( "ManagerDock", "This video doesn't have Metadata ! ")) pbar.setValue(100) self.ToggleActiveRow(rowPosition, value="Video not applicable") else: self.meta_reader.append(StreamMetaReader(filename)) qgsu.showUserAndLogMessage("", "StreamMetaReader initialized.", onlyLog=True) self.initialPt.append(None) self.videoPlayable[rowPosition] = True url = "" if self.videoIsStreaming[-1]: # show video from splitter (port +1) oldPort = filename.split(":")[2] newPort = str(int(oldPort) + 10) proto = filename.split(":")[0] url = QUrl(proto + "://127.0.0.1:" + newPort) else: url = QUrl.fromLocalFile(filename) self.playlist.addMedia(QMediaContent(url)) if self.videoPlayable[rowPosition]: pbar.setValue(100) if islocal: self.ToggleActiveRow(rowPosition, value="Ready Local") else: self.ToggleActiveRow(rowPosition, value="Ready") # Add video to settings list AddVideoToSettings(str(row_id), filename) self.loading = False
def processRequest(self): #iface.messageBar().pushMessage("BC TRO API", "Processing Request", level=0) progressMessageBar = iface.messageBar().createMessage("Processing Request...") progress = QProgressBar() progress.setMaximum(100) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) #API Code here apilayer = 'bctroapi' maplayerName = "BC TRO" layers_names = [] lopen = False for layer in QgsProject.instance().mapLayers().values(): if layer.name() == maplayerName: lopen = True layers_names.append(layer.name()) progress.setValue(10) #Params from dialog troformat = str(self.dlg.Formatcombobox.currentText()) area = self.dlg.AreaTextBox.text() radius = "{}".format(self.dlg.RadiusSlider.value()) x = self.dlg.Xtextbox.text() y = self.dlg.Ytextbox.text() epsg = str(self.dlg.Projectioncombobox.currentText()) #self.iface.mapCanvas().mapSettings().destinationCrs().authid() api_token = self.dlg.APIKeyTextBox.text() progress.setValue(20) time.sleep(0.5) #Set EPSG value as expected by TRO API if "27700" in epsg: epsg = "27700" elif "4326" in epsg: epsg = "4326" elif "3857" in epsg: epsg = "3857" else: return; progress.setValue(25) #Construct request parameters payload = {'api_token':api_token,'epsg': epsg, 'x': x, 'y': y, 'radius': radius} print ("API Payload: {}".format(payload)) #Set Endpoint from troformat if troformat == "TRO-D": url = 'https://dev.trafficorders.uk/tro/v1/trod' else: url = 'https://dev.trafficorders.uk/tro/v1/{}'.format(troformat.lower()) progress.setValue(30) # Send Request print ("Sending Request...") try: response = requests.get(url,params=payload) print ("Normal Request Success") except: print ("Normal Request Failed") """try: response = requests.get(url,params=payload, verify ='IONOS_trafficorders.uk.pem') print ("PEM File Request Success") except: print ("PEM File Request Failed")""" try: response = requests.get(url,params=payload, verify = False) print ("Verify Request Success") except: print ("Verify Request Failed") QMessageBox.critical(self.iface.mainWindow(), "BC TRO API error", "The request processed unsuccesfully!\n\n" "Error Code:\n" "Unable to send GET request") iface.messageBar().clearWidgets() return progress.setValue(50) print(response.url) print("Status: {}".format(response.status_code)) #Check request status for error if response.status_code != 200: QMessageBox.critical(self.iface.mainWindow(), "BC TRO API error", "The request processed unsuccesfully!\n\n" "Error Code:\n" "{}".format(response.status_code)) iface.messageBar().clearWidgets() return progress.setValue(60) #Convert JSON to Geojson r_json = self.geojsontojson(response.json(),troformat) progress.setValue(70) #Save Converted Geojson to file path_to_tro_layer = os.path.join(self.temp_dir,"bcnativedata.geojson") print ("Write Geojson...") with open(path_to_tro_layer, "w") as outfile: outfile.write(r_json) progress.setValue(80) ExitMessage = '' #Map geojson file #print("{}".format(self.currentformat)) #print(troformat) if not lopen: #Open file print ("Open Geojson...") if not self.addTROlayers(path_to_tro_layer,epsg,maplayerName,troformat): ExitMessage = 'Layer Failed' else: self.currentformat = troformat ExitMessage = 'Layer added to map' elif self.currentformat != troformat: print ("Rebuild table format...") #Remove Layer vlayers = QgsProject.instance().mapLayersByName(maplayerName) for vlayer in vlayers: QgsProject.instance().removeMapLayer(vlayer.id()) #Add - Rebuilding Table structure if not self.addTROlayers(path_to_tro_layer,epsg,maplayerName,troformat): ExitMessage = 'Layer Failed' else: self.currentformat = troformat ExitMessage = 'Layer added to map - Format change' else: print ("Reload Geojson...") #Refresh Layer vlayers = QgsProject.instance().mapLayersByName(maplayerName) for vlayer in vlayers: vlayer.dataProvider().reloadData() vlayer.triggerRepaint() ExitMessage = 'Layer refreshed' progress.setValue(100) #Show Exit message iface.messageBar().clearWidgets() iface.messageBar().pushMessage("BC TRO API", ExitMessage, level=3)