def __init__(self, iface): locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( os.path.dirname(__file__), 'i18n', 'qgeric_{}.qm'.format(locale)) self.translator = None if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.iface = iface self.sb = self.iface.mainWindow().statusBar() self.tool = None self.results = [] self.actions = [] self.menu = '&Qgeric' self.toolbar = self.iface.addToolBar('Qgeric') self.toolbar.setObjectName('Qgeric') self.loadingWindow = QProgressDialog(self.tr('Selecting...'),self.tr('Pass'),0,100) self.loadingWindow.setAutoClose(False) self.loadingWindow.close() self.themeColor = QColor(60,151,255, 128)
def onFeaturesCommitted(self, layerid, features): """ Update the related entities with the FK key from the primary spatial unit PK. """ if layerid in self._pendingFKEntities: pendingLayerEntity = self._pendingFKEntities[layerid] # Get map layer using layerid refLayer = QgsProject.instance().mapLayer(layerid) if refLayer is not None: fidx = refLayer.fields().indexFromName( pendingLayerEntity.featureAttributeName()) # Show progress dialog for updating the features. progressLabel = QApplication.translate( "StdmMapToolCreateFeature", "Updating related entities...") progressDlg = QProgressDialog(progressLabel, "", 0, len(features), self.iface.mainWindow()) progressDlg.setWindowModality(Qt.WindowModal) for i, feat in enumerate(features): progressDlg.setValue(i) uniqueAttrValue = feat.attributes()[fidx] pendingLayerEntity.setPrimaryKey(uniqueAttrValue, int(feat.id())) progressDlg.setValue(len(features)) progressDlg.deleteLater() del progressDlg
def __init__(self, iface): QWidget.__init__(self) self.setWindowTitle(self.tr('Search results')) self.resize(480,320) self.setMinimumSize(320,240) self.center() # Results export button self.btn_saveTab = QAction(QIcon(':/plugins/qgeric/resources/icon_save.png'), self.tr('Save this tab\'s results'), self) self.btn_saveTab.triggered.connect(lambda : self.saveAttributes(True)) self.btn_saveAllTabs = QAction(QIcon(':/plugins/qgeric/resources/icon_saveAll.png'), self.tr('Save all results'), self) self.btn_saveAllTabs.triggered.connect(lambda : self.saveAttributes(False)) self.btn_export = QAction(QIcon(':/plugins/qgeric/resources/icon_export.png'), self.tr('Export the selection as a memory layer'), self) self.btn_export.triggered.connect(self.exportLayer) self.btn_zoom = QAction(QIcon(':/plugins/qgeric/resources/icon_Zoom.png'), self.tr('Zoom to selected attributes'), self) self.btn_zoom.triggered.connect(self.zoomToFeature) self.btn_selectGeom = QAction(QIcon(':/plugins/qgeric/resources/icon_HlG.png'), self.tr('Highlight feature\'s geometry'), self) self.btn_selectGeom.triggered.connect(self.selectGeomChanged) self.btn_rename = QAction(QIcon(':/plugins/qgeric/resources/icon_Settings.png'), self.tr('Settings'), self) self.btn_rename.triggered.connect(self.renameWindow) self.tabWidget = QTabWidget() # Tab container self.tabWidget.setTabsClosable(True) self.tabWidget.currentChanged.connect(self.highlight_features) self.tabWidget.tabCloseRequested.connect(self.closeTab) self.loadingWindow = QProgressDialog() self.loadingWindow.setWindowTitle(self.tr('Loading...')) self.loadingWindow.setRange(0,100) self.loadingWindow.setAutoClose(False) self.loadingWindow.setCancelButton(None) self.canvas = iface.mapCanvas() self.canvas.extentsChanged.connect(self.highlight_features) self.highlight = [] self.highlight_rows = [] toolbar = QToolBar() toolbar.addAction(self.btn_saveTab) toolbar.addAction(self.btn_saveAllTabs) toolbar.addAction(self.btn_export) toolbar.addSeparator() toolbar.addAction(self.btn_zoom) toolbar.addSeparator() toolbar.addAction(self.btn_selectGeom) toolbar.addAction(self.btn_rename) vbox = QVBoxLayout() vbox.setContentsMargins(0,0,0,0) vbox.addWidget(toolbar) vbox.addWidget(self.tabWidget) self.setLayout(vbox) self.mb = iface.messageBar() self.selectGeom = False # False for point, True for geometry
def __init__(self, parent): """ Initializes the progress dialog of the template updater with the option of updating the label of the dialog. :return: :rtype: """ QProgressDialog.__init__(self, parent) self.title = None self.prog = None
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 detectTripleStoreConfiguration(self): progress = QProgressDialog("Detecting configuration for triple store "+self.tripleStoreEdit.text()+"...", "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.show() self.qtask=DetectTripleStoreTask("Detecting configuration for triple store "+self.tripleStoreEdit.text()+"...",self.triplestoreconf,self.tripleStoreEdit.text(),self.tripleStoreNameEdit.text(),False,True,self.prefixes,self.prefixstore,self.tripleStoreChooser,self.comboBox,progress) QgsApplication.taskManager().addTask(self.qtask)
def testTripleStoreConnection(self,calledfromotherfunction=False,showMessageBox=True,query="SELECT ?a ?b ?c WHERE { ?a ?b ?c .} LIMIT 1"): progress = QProgressDialog("Checking connection to triple store "+self.tripleStoreEdit.text()+"...", "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.show() self.qtask=DetectTripleStoreTask("Checking connection to triple store "+self.tripleStoreEdit.text()+"...",self.triplestoreconf,self.tripleStoreEdit.text(),self.tripleStoreNameEdit.text(),True,False,self.prefixes,self.prefixstore,self.tripleStoreChooser,self.comboBox,progress) QgsApplication.taskManager().addTask(self.qtask)
def create_unicorn_layer(self): endpointIndex = self.dlg.comboBox.currentIndex() # SPARQL query #print(self.loadedfromfile) # query query = self.dlg.inp_sparql2.toPlainText() if self.loadedfromfile: curindex = self.dlg.proxyModel.mapToSource( self.dlg.geoClassList.selectionModel().currentIndex()) if curindex != None and self.dlg.geoClassListModel.itemFromIndex( curindex) != None: concept = self.dlg.geoClassListModel.itemFromIndex( curindex).data(1) else: concept = "http://www.opengis.net/ont/geosparql#Feature" geojson = self.getGeoJSONFromGeoConcept(self.currentgraph, concept) vlayer = QgsVectorLayer( json.dumps(geojson, sort_keys=True, indent=4), "unicorn_" + self.dlg.inp_label.text(), "ogr") print(vlayer.isValid()) QgsProject.instance().addMapLayer(vlayer) canvas = iface.mapCanvas() canvas.setExtent(vlayer.extent()) iface.messageBar().pushMessage("Add layer", "OK", level=Qgis.Success) #iface.messageBar().pushMessage("Error", "An error occured", level=Qgis.Critical) #self.dlg.close() return else: endpoint_url = self.triplestoreconf[endpointIndex]["endpoint"] missingmandvars = [] for mandvar in self.triplestoreconf[endpointIndex][ "mandatoryvariables"]: if mandvar not in query: missingmandvars.append("?" + mandvar) if missingmandvars != [] and not self.dlg.allownongeo.isChecked(): msgBox = QMessageBox() msgBox.setWindowTitle("Mandatory variables missing!") msgBox.setText( "The SPARQL query is missing the following mandatory variables: " + str(missingmandvars)) msgBox.exec() progress = QProgressDialog( "Querying layer from " + endpoint_url + "...", "Abort", 0, 0, self.dlg) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.show() self.qtask = QueryLayerTask( "Querying QGIS Layer from " + endpoint_url, endpoint_url, "".join(self.prefixes[endpointIndex]) + query, self.triplestoreconf[endpointIndex], self.dlg.allownongeo.isChecked(), self.dlg.inp_label.text(), progress) QgsApplication.taskManager().addTask(self.qtask)
def show_progress_dialog(self, text): """Show infinite progress dialog with given text. :param text: Text as the label of the progress dialog :type text: str """ if self.progress_dialog is None: self.progress_dialog = QProgressDialog(self) self.progress_dialog.setWindowModality(Qt.WindowModal) self.progress_dialog.setAutoClose(False) title = self.tr("Resource Sharing") self.progress_dialog.setWindowTitle(title) # Just use an infinite progress bar here self.progress_dialog.setMaximum(0) self.progress_dialog.setMinimum(0) self.progress_dialog.setValue(0) self.progress_dialog.setLabelText(text) self.progress_dialog.show()
def loadURI(self): if self.graphURIEdit.text()!="": progress = QProgressDialog("Loading Graph from "+self.graphURIEdit.text(), "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask=LoadGraphTask("Loading Graph: "+self.graphURIEdit.text(), self.graphURIEdit.text(),self,self.dlg,self.maindlg,self.triplestoreconf[0]["geoconceptquery"],self.triplestoreconf,progress) QgsApplication.taskManager().addTask(self.qtask)
def run_task(self): """ Sets up the QgsTask and the progression dialog. The heavy work of the plugin will be outsourced to a QgsTask to not stagger the QGIS Application. Technically the main application runs on the main thread, QgsTask lets you run heavy stuff on a seperate thread to not clutter the main thread. """ # Qt5 progressionDialog on the main progDialog = QProgressDialog('Running Task in the background...', 'Cancel', 0, 100) # Create task # With 'self' this class will be sent to the QgsTask so that # its methods and attributes can be accessed. task = HeavyLifting('PRW Database Bevraging', self) # Connect events from the ProgressDialog to the task progDialog.canceled.connect(task.cancel) task.begun.connect(lambda: progDialog.setLabelText( 'Begonnen met PRW peilbuisgegevens ophalen...')) task.progressChanged.connect( lambda: progDialog.setValue(task.progress())) # Show ProgressDialog progDialog.show() # Add task to taskManager (start task) QgsApplication.taskManager().addTask(task)
def loadFile(self): dialog = QFileDialog(self.dlg) dialog.setFileMode(QFileDialog.AnyFile) self.justloadingfromfile=True if dialog.exec_(): fileNames = dialog.selectedFiles() filepath=fileNames[0].split(".") progress = QProgressDialog("Loading Graph: "+fileNames[0], "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask=LoadGraphTask("Loading Graph: "+fileNames[0], fileNames[0],self,self.dlg,self.maindlg,self.triplestoreconf[0]["geoconceptquery"],self.triplestoreconf,progress) QgsApplication.taskManager().addTask(self.qtask)
def getAttributeStatistics(self,concept="wd:Q3914",endpoint_url="https://query.wikidata.org/sparql",labellang="en",inarea="wd:Q183"): if self.conceptSearchEdit.text()=="": return concept="<"+self.conceptSearchEdit.text()+">" progress = QProgressDialog("Executing enrichment search query....", "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask=WhatToEnrichQueryTask("Get Property Enrichment Candidates ("+self.conceptSearchEdit.text()+")", endpoint_url, self.triplestoreconf[self.tripleStoreEdit.currentIndex()+1]["whattoenrichquery"].replace("%%concept%%",concept).replace("%%area%%","?area"), self.conceptSearchEdit.text(), self.prefixes[self.tripleStoreEdit.currentIndex()], self.searchResult,progress) QgsApplication.taskManager().addTask(self.qtask)
def run_task(self, args): """Sets up a QgsTask to do the heavy lifting in a background process of QGIS. Sets up the ProevenVerzamelingTask, which inherits from QgsTask, to handle the processor heavy queries and calculations in a background process, QGIS will stay stay responsive in the meantime. The ProevenVerzamelingTask is added to the QGIS taskmanager to handle it. Parameters ---------- args : arguments dict Dictionary of arguments that will be passed to a QgsTask class. """ progressDialog = QProgressDialog('Initializing Task: BIS Bevraging...', 'Cancel', 0, 100) progressDialog.show() task = ProevenVerzamelingTask('Proeven Verzameling Bevraging', self, **args) task.progressChanged.connect( lambda: progressDialog.setValue(task.progress())) progressDialog.canceled.connect(task.cancel) task.begun.connect(lambda: progressDialog.setLabelText( 'Task Running: BIS Bevraging...')) QgsApplication.taskManager().addTask(task)
def enrichLayerProcess(self): layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = self.dlg.chooseLayerEnrich.currentIndex() self.enrichLayer = layers[selectedLayerIndex].layer().clone() attlist = {} itemlist = [] propertylist = [] excludelist = [] resultmap = {} self.dlg.enrichTableResult.clear() self.dlg.enrichTableResult.setRowCount(0) self.dlg.enrichTableResult.setColumnCount( self.dlg.enrichTable.rowCount()) fieldnames = [] for row in range(self.dlg.enrichTable.rowCount()): fieldnames.append(self.dlg.enrichTable.item(row, 0).text()) self.dlg.enrichTableResult.setHorizontalHeaderLabels(fieldnames) self.enrichLayer.startEditing() for row in range(self.dlg.enrichTable.rowCount()): idfield = self.dlg.enrichTable.cellWidget(row, 5).currentText() idprop = self.dlg.enrichTable.item(row, 6).text() if idprop == None or idprop == "": msgBox = QMessageBox() msgBox.setText( "ID Property has not been specified for column " + str(self.dlg.enrichTable.item(row, 0).text())) msgBox.exec() return item = self.dlg.enrichTable.item(row, 0).text() propertyy = self.dlg.enrichTable.item(row, 1) triplestoreurl = "" if self.dlg.enrichTable.item(row, 2) != None: triplestoreurl = self.dlg.enrichTable.item(row, 2).text() print(self.dlg.enrichTable.item(row, 2).text()) strategy = self.dlg.enrichTable.cellWidget(row, 3).currentText() content = "" if self.dlg.enrichTable.cellWidget(row, 4) != None: content = self.dlg.enrichTable.cellWidget(row, 4).currentText() if item != idfield: propertylist.append(self.dlg.enrichTable.item(row, 1)) if strategy == "Exclude": excludelist.append(row) if strategy != "No Enrichment" and propertyy != None: progress = QProgressDialog( "Enriching column " + self.dlg.enrichTable.item(row, 0).text(), "Abort", 0, 0, self.dlg) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask = EnrichmentQueryTask( "Enriching column: " + self.dlg.enrichTable.item(row, 0).text(), triplestoreurl, self.enrichLayer, strategy, self.dlg.enrichTable.item(row, 8).text(), row, len(self.enrichLayer.fields()), self.dlg.enrichTable.item(row, 0).text(), self.dlg.enrichTable, self.dlg.enrichTableResult, idfield, idprop, self.dlg.enrichTable.item(row, 1), content, progress) QgsApplication.taskManager().addTask(self.qtask) else: rowww = 0 for f in self.enrichLayer.getFeatures(): if rowww >= self.dlg.enrichTableResult.rowCount(): self.dlg.enrichTableResult.insertRow(rowww) #if item in f: newitem = QTableWidgetItem(str(f[item])) self.dlg.enrichTableResult.setItem(rowww, row, newitem) #if ";" in str(newitem): # newitem.setBackground(QColor.red) print(str(newitem)) rowww += 1 self.enrichLayer.commitChanges() row += 1 iface.vectorLayerTools().stopEditing(self.enrichLayer) self.enrichLayer.dataProvider().deleteAttributes(excludelist) self.enrichLayer.updateFields() self.dlg.enrichTable.hide() self.dlg.enrichTableResult.show() self.dlg.startEnrichment.setText("Enrichment Configuration") self.dlg.startEnrichment.clicked.disconnect() self.dlg.startEnrichment.clicked.connect(self.dlg.showConfigTable) self.dlg.addEnrichedLayerRowButton.setEnabled(False) return self.enrichLayer
def featToDb(self, targettable, columnmatch, append, parentdialog, geomColumn=None, geomCode=-1, translator_manager=None): """ Performs the data import from the source layer to the STDM database. :param targettable: Destination table name :param columnmatch: Dictionary containing source columns as keys and target columns as the values. :param append: True to append, false to overwrite by deleting previous records :param parentdialog: A reference to the calling dialog. :param translator_manager: Instance of 'stdm.data.importexport.ValueTranslatorManager' containing value translators defined for the destination table columns. :type translator_manager: ValueTranslatorManager """ # Check current profile if self._current_profile is None: msg = QApplication.translate( 'OGRReader', 'The current profile could not be determined.\nPlease set it ' 'in the Options dialog or Configuration Wizard.') raise ConfigurationException(msg) if translator_manager is None: translator_manager = ValueTranslatorManager() # Delete existing rows in the target table if user has chosen to overwrite if not append: delete_table_data(targettable) # Container for mapping column names to their corresponding values lyr = self.getLayer() lyr.ResetReading() feat_defn = lyr.GetLayerDefn() numFeat = lyr.GetFeatureCount() # Configure progress dialog init_val = 0 progress = QProgressDialog("", "&Cancel", init_val, numFeat, parentdialog) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = "Importing {0} of {1} to STDM..." # Set entity for use in translators destination_entity = self._data_source_entity(targettable) for feat in lyr: column_value_mapping = {} column_count = 0 progress.setValue(init_val) progressMsg = lblMsgTemp.format((init_val + 1), numFeat) progress.setLabelText(progressMsg) if progress.wasCanceled(): break # Reset source document manager for new records if destination_entity.supports_documents: if not self._source_doc_manager is None: self._source_doc_manager.reset() for f in range(feat_defn.GetFieldCount()): field_defn = feat_defn.GetFieldDefn(f) field_name = field_defn.GetNameRef() # Append value only if it has been defined by the user if field_name in columnmatch: dest_column = columnmatch[field_name] field_value = feat.GetField(f) # Create mapped class only once if self._mapped_cls is None: mapped_cls, mapped_doc_cls = self._get_mapped_class( targettable) if mapped_cls is None: msg = QApplication.translate( "OGRReader", "Something happened that caused the " "database table not to be mapped to the " "corresponding model class. Please contact" " your system administrator.") raise RuntimeError(msg) self._mapped_cls = mapped_cls self._mapped_doc_cls = mapped_doc_cls # Create source document manager if the entity supports them if destination_entity.supports_documents: self._source_doc_manager = SourceDocumentManager( destination_entity.supporting_doc, self._mapped_doc_cls) if geomColumn is not None: # Use geometry column SRID in the target table self._geomType, self._targetGeomColSRID = \ geometryType(targettable, geomColumn) ''' Check if there is a value translator defined for the specified destination column. ''' value_translator = translator_manager.translator( dest_column) if value_translator is not None: # Set destination table entity value_translator.entity = destination_entity source_col_names = value_translator.source_column_names( ) field_value_mappings = self._map_column_values( feat, feat_defn, source_col_names) # Set source document manager if required if value_translator.requires_source_document_manager: value_translator.source_document_manager = self._source_doc_manager field_value = value_translator.referencing_column_value( field_value_mappings) if not isinstance(field_value, IgnoreType): # Check column type and rename if multiple select for # SQLAlchemy compatibility col_obj = destination_entity.column(dest_column) if col_obj.TYPE_INFO == 'MULTIPLE_SELECT': lk_name = col_obj.value_list.name dest_column = '{0}_collection'.format(lk_name) column_value_mapping[dest_column] = field_value # Set supporting documents if destination_entity.supports_documents: column_value_mapping['documents'] = \ self._source_doc_manager.model_objects() column_count += 1 # Only insert geometry if it has been defined by the user if geomColumn is not None: geom = feat.GetGeometryRef() if geom is not None: # Check if the geometry types match layerGeomType = geom.GetGeometryName() # Convert polygon to multipolygon if the destination table is multi-polygon. geom_wkb, geom_type = self.auto_fix_geom_type( geom, layerGeomType, self._geomType) column_value_mapping[geomColumn] = "SRID={0!s};{1}".format( self._targetGeomColSRID, geom_wkb) if geom_type.lower() != self._geomType.lower(): raise TypeError( "The geometries of the source and destination columns do not match.\n" \ "Source Geometry Type: {0}, Destination Geometry Type: {1}".format( geom_type, self._geomType)) try: # Insert the record self._insertRow(targettable, column_value_mapping) except: progress.close() raise init_val += 1 progress.setValue(numFeat)
def get_pixel_count_by_pixel_values(layer, band, pixel_values=None, nodata=-1): app = QCoreApplication.instance() nodata = nodata if nodata != -1 else None if pixel_values is None: pixel_values = get_pixel_values(layer, band) # put nodata at the beginning, with the idea to include it for stopping # the counting when reaching the total pixels, delete it at the end if nodata is not None: if nodata in pixel_values: pixel_values.remove(nodata) pixel_values.insert(0, nodata) try: import xarray as xr import dask.array as da dataset = xr.open_rasterio(get_file_path_of_layer(layer), chunks={ 'band': 1, 'x': 2000, 'y': 2000 }) parallel = True except: dataset = gdal_array.LoadFile(get_file_path_of_layer(layer)) parallel = False if len(dataset.shape) == 3: if parallel: dataset = dataset.sel(band=band) else: dataset = dataset[band - 1] max_pixels = dataset.shape[-1] * dataset.shape[-2] progress = QProgressDialog( 'AcATaMa is counting the number of pixels for each thematic value.\n' 'Depending on the size of the image, it would take a few minutes.', None, 0, 100, iface.mainWindow()) progress.setWindowTitle("AcATaMa - Counting pixels by values... " + ("[parallel]" if parallel else "[not parallel!]")) progress.setWindowModality(Qt.WindowModal) progress.setValue(0) progress.show() app.processEvents() global total_count total_count = 0 def count_value(pixel_value): global total_count if total_count >= max_pixels: return 0 if parallel: count = da.count_nonzero(dataset == pixel_value).compute() else: count = np.count_nonzero(dataset == pixel_value) total_count += count progress.setValue(int(total_count * 100 / max_pixels)) return count pixel_counts = [count_value(pixel_value) for pixel_value in pixel_values] if nodata is not None: pixel_values.pop(0) pixel_counts.pop(0) progress.accept() return dict(zip(pixel_values, pixel_counts))
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 executeSearch(self): """ Base class override. Search for matching items for the specified entity and column. """ model_root_node = None prog_dialog = QProgressDialog(self) prog_dialog.setFixedWidth(380) prog_dialog.setWindowTitle( QApplication.translate("STRViewEntityWidget", "Searching for STR...")) prog_dialog.show() prog_dialog.setRange(0, 10) search_term = self._searchTerm() prog_dialog.setValue(2) # Try to get the corresponding search term value from the completer model if not self._completer_model is None: reg_exp = QRegExp("^%s$" % (search_term), Qt.CaseInsensitive, QRegExp.RegExp2) self._proxy_completer_model.setFilterRegExp(reg_exp) if self._proxy_completer_model.rowCount() > 0: # Get corresponding actual value from the first matching item value_model_idx = self._proxy_completer_model.index(0, 1) source_model_idx = self._proxy_completer_model.mapToSource( value_model_idx) prog_dialog.setValue(4) search_term = self._completer_model.data( source_model_idx, Qt.DisplayRole) modelInstance = self.config.STRModel() modelQueryObj = modelInstance.queryObject() queryObjProperty = getattr(self.config.STRModel, self.currentFieldName()) entity_name = modelQueryObj._primary_entity._label_name entity = self.curr_profile.entity_by_name(entity_name) prog_dialog.setValue(6) # Get property type so that the filter can # be applied according to the appropriate type propType = queryObjProperty.property.columns[0].type results = [] try: if not isinstance(propType, String): col_name = self.currentFieldName() col = entity.columns[self.currentFieldName()] if col.TYPE_INFO == 'LOOKUP': lookup_entity = lookup_parent_entity( self.curr_profile, col_name) lkp_model = entity_model(lookup_entity) lkp_obj = lkp_model() value_obj = getattr(lkp_model, 'value') result = lkp_obj.queryObject().filter( func.lower(value_obj) == func.lower( search_term)).first() if result is None: result = lkp_obj.queryObject().filter( func.lower(value_obj).like(search_term + '%')).first() if not result is None: results = modelQueryObj.filter( queryObjProperty == result.id).all() else: results = [] else: results = modelQueryObj.filter( func.lower(queryObjProperty) == func.lower( search_term)).all() if self.validity.isEnabled(): valid_str_ids = self.str_validity_period_filter(results) else: valid_str_ids = None prog_dialog.setValue(7) except exc.StatementError: return model_root_node, [], search_term # if self.formatter is not None: # self.formatter.setData(results) # model_root_node = self.formatter.root(valid_str_ids) prog_dialog.setValue(10) prog_dialog.hide() return results, search_term
class GeoServerWidget(ServerWidgetBase, BASE, WIDGET): def __init__(self, parent, server_type): super().__init__(parent, server_type) self.setupUi(self) self.geoserverAuth = QgsAuthConfigSelect() self.geoserverAuth.selectedConfigIdChanged.connect(self.setDirty) self.addAuthWidget() self.populateStorageCombo() self.comboStorageType.currentIndexChanged.connect(self.datastoreChanged) self.btnRefreshDatabases.clicked.connect(partial(self.updateDbServersCombo, True)) self.btnAddDatastore.clicked.connect(self.addPostgisDatastore) self.txtGeoserverName.textChanged.connect(self.setDirty) self.txtGeoserverUrl.textChanged.connect(self.setDirty) self.chkUseOriginalDataSource.stateChanged.connect(self.setDirty) self.chkUseVectorTiles.stateChanged.connect(self.setDirty) self.comboGeoserverDatabase.currentIndexChanged.connect(self.setDirty) # Declare progress dialog self._pgdialog = None def createServerInstance(self): """ Reads the settings form fields and returns a new server instance with these settings. """ db = None storage = self.comboStorageType.currentIndex() if storage in (GeoserverStorage.POSTGIS_BRIDGE, GeoserverStorage.POSTGIS_GEOSERVER): db = self.comboGeoserverDatabase.currentText() try: name = self.txtGeoserverName.text().strip() url = self.txtGeoserverUrl.text().strip() if not name: raise RuntimeError(f'missing {self.serverType.getLabel()} name') if not url: raise RuntimeError(f'missing {self.serverType.getLabel()} URL') return self.serverType( name=name, authid=self.geoserverAuth.configId() or None, url=url, storage=storage, postgisdb=db, useOriginalDataSource=self.chkUseOriginalDataSource.isChecked(), useVectorTiles=self.chkUseVectorTiles.isChecked() ) except Exception as e: self.parent.logError(f"Failed to create {self.serverType.getLabel()} instance: {e}") return None def newFromName(self, name: str): """ Sets the name field and keeps all others empty. """ self.txtGeoserverName.setText(name) self.txtGeoserverUrl.clear() self.geoserverAuth.setConfigId(None) # Set datastore and database comboboxes self.comboStorageType.blockSignals(True) self.comboStorageType.setCurrentIndex(GeoserverStorage.FILE_BASED) self.datastoreChanged(GeoserverStorage.FILE_BASED) self.chkUseOriginalDataSource.setChecked(False) self.chkUseVectorTiles.setChecked(False) self.comboStorageType.blockSignals(False) def loadFromInstance(self, server): """ Populates the form fields with the values from the given server instance. """ self.txtGeoserverName.setText(server.serverName) self.txtGeoserverUrl.setText(server.baseUrl) self.geoserverAuth.setConfigId(server.authId) # Set datastore and database comboboxes self.comboStorageType.blockSignals(True) self.comboStorageType.setCurrentIndex(server.storage) self.datastoreChanged(server.storage, server.postgisdb) self.chkUseOriginalDataSource.setChecked(server.useOriginalDataSource) self.chkUseVectorTiles.setChecked(server.useVectorTiles) self.comboStorageType.blockSignals(False) # After the data has loaded, the form is "clean" self.setClean() def addAuthWidget(self): layout = QHBoxLayout() layout.setContentsMargins(0, 3, 0, 0) layout.addWidget(self.geoserverAuth) self.geoserverAuthWidget.setLayout(layout) self.geoserverAuthWidget.setFixedHeight(self.txtGeoserverUrl.height()) def populateStorageCombo(self): self.comboStorageType.clear() self.comboStorageType.addItems(GeoserverStorage.values()) def datastoreChanged(self, storage, init_value=None): """ Called each time the database combobox selection changed. """ if storage is None: storage = GeoserverStorage[self.comboStorageType.currentIndex()] if storage == GeoserverStorage.POSTGIS_BRIDGE: self.updateDbServersCombo(False, init_value) self.comboGeoserverDatabase.setVisible(True) self.labelGeoserverDatastore.setText('Database') self.labelGeoserverDatastore.setVisible(True) self.datastoreControls.setVisible(False) elif storage == GeoserverStorage.POSTGIS_GEOSERVER: self.comboGeoserverDatabase.setVisible(True) self.labelGeoserverDatastore.setText('Datastore') self.labelGeoserverDatastore.setVisible(True) self.datastoreControls.setVisible(True) self.updateDbServersCombo(True, init_value) elif storage == GeoserverStorage.FILE_BASED: self.comboGeoserverDatabase.setVisible(False) self.labelGeoserverDatastore.setVisible(False) self.datastoreControls.setVisible(False) self.setDirty() def addGeoserverPgDatastores(self, current, result): if self._pgdialog and self._pgdialog.isVisible(): self._pgdialog.hide() if result: # Worker result might be a list of lists, so we should flatten it datastores = list(chain.from_iterable(result)) self.comboGeoserverDatabase.addItems(datastores) if current: self.comboGeoserverDatabase.setCurrentText(current) else: self.parent.showWarningBar("Warning", "No PostGIS datastores on server or could not retrieve them") def showProgressDialog(self, text, length, handler): self._pgdialog = QProgressDialog(text, "Cancel", 0, length, self) self._pgdialog.setWindowTitle(getAppName()) self._pgdialog.setWindowModality(QtCore.Qt.WindowModal) self._pgdialog.canceled.connect(handler, type=QtCore.Qt.DirectConnection) self._pgdialog.forceShow() def updateDbServersCombo(self, managed_by_geoserver: bool, init_value=None): """ (Re)populate the combobox with database-driven datastores. :param managed_by_geoserver: If True, GeoServer manages the DB connection. If False, Bridge manages it. :param init_value: When the combobox shows for the first time and no databases have been loaded, this value can be set immediately as the only available and selected item. Doing so prevents a full refresh of GeoServer datastores. """ if managed_by_geoserver and init_value: if self.comboGeoserverDatabase.count() == 0: # Only add the given init_value item to the empty combo (user should manually refresh) self.comboGeoserverDatabase.addItem(init_value) self.comboGeoserverDatabase.setCurrentText(init_value) return # If combo has values, try and find the init_value and set it to that (user should manually refresh) index = self.comboGeoserverDatabase.findText(init_value) if index >= 0: self.comboGeoserverDatabase.setCurrentIndex(index) return current_db = self.comboGeoserverDatabase.currentText() or init_value self.comboGeoserverDatabase.clear() if managed_by_geoserver: # Database is managed by GeoServer: instantiate server and retrieve datastores # TODO: only PostGIS datastores are supported for now server = self.createServerInstance() if not server: self.parent.showErrorBar("Error", "Bad values in server definition") return try: # Retrieve workspaces (single REST request) workspaces = gui.execute(server.getWorkspaces) if not workspaces: return # Retrieve datastores for each workspace: # This is a potentially long-running operation and uses a separate QThread worker = gui.ItemProcessor(workspaces, server.getPostgisDatastores) self.showProgressDialog("Fetching PostGIS datastores...", len(workspaces), worker.stop) worker.progress.connect(self._pgdialog.setValue) worker.finished.connect(partial(self.addGeoserverPgDatastores, current_db)) worker.run() except Exception as e: msg = f'Failed to retrieve datastores for {self.serverName}' if isinstance(e, HTTPError) and e.response.status_code == 401: msg = f'{msg}: please check credentials' else: msg = f'{msg}: {e}' self.parent.showErrorBar(msg) else: # Database is managed by Bridge: iterate over all user-defined database connections db_servers = self.parent.serverManager.getDbServerNames() self.comboGeoserverDatabase.addItems(db_servers) if current_db in db_servers: self.comboGeoserverDatabase.setCurrentText(current_db) def addPostgisDatastore(self): server = self.createServerInstance() if server is None: self.parent.showErrorBar("Error", "Wrong values in server definition") return dlg = GeoserverDatastoreDialog(self) dlg.exec_() name = dlg.name if name is None: return def _entry(k, v): return {"@key": k, "$": v} ds = { "dataStore": { "name": dlg.name, "type": "PostGIS", "enabled": True, "connectionParameters": { "entry": [ _entry("schema", dlg.schema), _entry("port", dlg.port), _entry("database", dlg.database), _entry("passwd", dlg.password), _entry("user", dlg.username), _entry("host", dlg.host), _entry("dbtype", "postgis") ] } } } try: gui.execute(partial(server.addPostgisDatastore, ds)) except Exception as e: self.parent.showErrorBar("Error", "Could not create new PostGIS dataset", propagate=e) else: self.updateDbServersCombo(True)
def accept(self): """Do osm download and display it in QGIS.""" error_dialog_title = self.tr('InaSAFE OpenStreetMap Downloader Error') # Lock the bounding_box_group self.bounding_box_group.setDisabled(True) # Get the extent y_minimum = self.y_minimum.value() y_maximum = self.y_maximum.value() x_minimum = self.x_minimum.value() x_maximum = self.x_maximum.value() extent = [x_minimum, y_minimum, x_maximum, y_maximum] # Validate extent valid_flag = validate_geo_array(extent) if not valid_flag: message = self.tr( 'The bounding box is not valid. Please make sure it is ' 'valid or check your projection!') # noinspection PyCallByClass,PyTypeChecker,PyArgumentList display_warning_message_box(self, error_dialog_title, message) # Unlock the bounding_box_group self.bounding_box_group.setEnabled(True) return # Validate features feature_types = self.get_checked_features() if len(feature_types) < 1: message = self.tr('No feature selected. ' 'Please make sure you have checked one feature.') # noinspection PyCallByClass,PyTypeChecker,PyArgumentList display_warning_message_box(self, error_dialog_title, message) # Unlock the bounding_box_group self.bounding_box_group.setEnabled(True) return if self.radio_custom.isChecked(): server_url = self.line_edit_custom.text() if not server_url: # It's the place holder. server_url = STAGING_SERVER else: server_url = PRODUCTION_SERVER try: self.save_state() self.require_directory() # creating progress dialog for download self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(False) self.progress_dialog.setWindowTitle(self.windowTitle()) for feature_type in feature_types: output_directory = self.output_directory.text() if output_directory == '': output_directory = temp_dir(sub_dir='work') output_prefix = self.filename_prefix.text() overwrite = self.overwrite_flag.isChecked() output_base_file_path = self.get_output_base_path( output_directory, output_prefix, feature_type, overwrite) # noinspection PyTypeChecker download(feature_type, output_base_file_path, extent, self.progress_dialog, server_url) try: self.load_shapefile(feature_type, output_base_file_path) except FileMissingError as exception: display_warning_message_box(self, error_dialog_title, str(exception)) self.done(QDialog.Accepted) self.rectangle_map_tool.reset() except CanceledImportDialogError: # don't show anything because this exception raised # when user canceling the import process directly pass except Exception as exception: # pylint: disable=broad-except # noinspection PyCallByClass,PyTypeChecker,PyArgumentList display_warning_message_box(self, error_dialog_title, str(exception)) self.progress_dialog.cancel() self.progress_dialog.deleteLater() finally: # Unlock the bounding_box_group self.bounding_box_group.setEnabled(True)
def open_style(input_file): # pylint: disable=too-many-locals,too-many-branches,too-many-statements """ Opens a .style file """ if not Extractor.is_mdb_tools_binary_available(): bar = iface.messageBar() widget = bar.createMessage('SLYR', "MDB Tools utility not found") settings_button = QPushButton("Configure…", pressed=partial(open_settings, widget)) widget.layout().addWidget(settings_button) bar.pushWidget(widget, Qgis.Critical) return True style = QgsStyle() style.createMemoryDatabase() symbol_names = set() def make_name_unique(name): """ Ensures that the symbol name is unique (in a case insensitive way) """ counter = 0 candidate = name while candidate.lower() in symbol_names: # make name unique if counter == 0: candidate += '_1' else: candidate = candidate[:candidate.rfind('_') + 1] + str(counter) counter += 1 symbol_names.add(candidate.lower()) return candidate feedback = QgsFeedback() progress_dialog = QProgressDialog("Loading style database…", "Abort", 0, 100, None) progress_dialog.setWindowTitle("Loading Style") def progress_changed(progress): """ Handles feedback to progress dialog bridge """ progress_dialog.setValue(progress) iters = 0 while QCoreApplication.hasPendingEvents() and iters < 100: QCoreApplication.processEvents() iters += 1 feedback.progressChanged.connect(progress_changed) def cancel(): """ Slot to cancel the import """ feedback.cancel() progress_dialog.canceled.connect(cancel) unreadable = [] warnings = set() errors = set() types_to_extract = [Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS, Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS, Extractor.TEXT_SYMBOLS, Extractor.LABELS, Extractor.MAPLEX_LABELS, Extractor.AREA_PATCHES, Extractor.LINE_PATCHES] type_percent = 100 / len(types_to_extract) for type_index, symbol_type in enumerate(types_to_extract): try: raw_symbols = Extractor.extract_styles(input_file, symbol_type) except MissingBinaryException: show_warning('MDB Tools utility not found', 'Convert style', 'The MDB tools "mdb-export" utility is required to convert .style databases. Please setup a path to the MDB tools utility in the SLYR options panel.', level=Qgis.Critical) progress_dialog.deleteLater() return True if feedback.isCanceled(): break for index, raw_symbol in enumerate(raw_symbols): feedback.setProgress(index / len(raw_symbols) * type_percent + type_percent * type_index) if feedback.isCanceled(): break name = raw_symbol[Extractor.NAME] tags = raw_symbol[Extractor.TAGS].split(';') if symbol_type in ( Extractor.AREA_PATCHES, Extractor.LINE_PATCHES, Extractor.TEXT_SYMBOLS, Extractor.MAPLEX_LABELS, Extractor.LABELS): if symbol_type == Extractor.AREA_PATCHES: type_string = 'area patches' elif symbol_type == Extractor.LINE_PATCHES: type_string = 'line patches' elif symbol_type == Extractor.TEXT_SYMBOLS: type_string = 'text symbols' elif symbol_type == Extractor.MAPLEX_LABELS: type_string = 'maplex labels' elif symbol_type == Extractor.LABELS: type_string = 'labels' else: type_string = '' unreadable.append('<b>{}</b>: {} conversion requires a licensed version of the SLYR plugin'.format( html.escape(name), type_string)) continue unique_name = make_name_unique(name) handle = BytesIO(raw_symbol[Extractor.BLOB]) stream = Stream(handle) stream.allow_shortcuts = False try: symbol = stream.read_object() except UnreadableSymbolException as e: e = 'Unreadable object: {}'.format(e) unreadable.append('<b>{}</b>: {}'.format(html.escape(name), html.escape(str(e)))) continue except NotImplementedException as e: unreadable.append('<b>{}</b>: {}'.format(html.escape(name), html.escape(str(e)))) continue except UnsupportedVersionException as e: e = 'Unsupported version: {}'.format(e) unreadable.append('<b>{}</b>: {}'.format(html.escape(name), html.escape(str(e)))) continue except UnknownClsidException as e: unreadable.append('<b>{}</b>: {}'.format(html.escape(name), html.escape(str(e)))) continue except UnreadablePictureException as e: unreadable.append('<b>{}</b>: {}'.format(html.escape(name), html.escape(str(e)))) continue context = Context() context.symbol_name = unique_name def unsupported_object_callback(msg, level=Context.WARNING): if level == Context.WARNING: warnings.add('<b>{}</b>: {}'.format(html.escape(unique_name), html.escape(msg))) elif level == Context.CRITICAL: errors.add('<b>{}</b>: {}'.format(html.escape(unique_name), html.escape(msg))) context.unsupported_object_callback = unsupported_object_callback # context.style_folder, _ = os.path.split(output_file) try: qgis_symbol = SymbolConverter.Symbol_to_QgsSymbol(symbol, context) except NotImplementedException as e: unreadable.append('<b>{}</b>: {}'.format(html.escape(name), html.escape(str(e)))) continue except UnreadablePictureException as e: unreadable.append('<b>{}</b>: {}'.format(html.escape(name), html.escape(str(e)))) continue if isinstance(qgis_symbol, QgsSymbol): # self.check_for_missing_fonts(qgis_symbol, feedback) style.addSymbol(unique_name, qgis_symbol, True) elif isinstance(qgis_symbol, QgsColorRamp): style.addColorRamp(unique_name, qgis_symbol, True) if tags: if isinstance(qgis_symbol, QgsSymbol): assert style.tagSymbol(QgsStyle.SymbolEntity, unique_name, tags) elif isinstance(qgis_symbol, QgsColorRamp): assert style.tagSymbol(QgsStyle.ColorrampEntity, unique_name, tags) progress_dialog.deleteLater() if feedback.isCanceled(): return True if errors or unreadable or warnings: message = '' if unreadable: message = '<p>The following symbols could not be converted:</p>' message += '<ul>' for w in unreadable: message += '<li>{}</li>'.format(w.replace('\n', '<br>')) message += '</ul>' if errors: message += '<p>The following errors were generated while converting symbols:</p>' message += '<ul>' for w in errors: message += '<li>{}</li>'.format(w.replace('\n', '<br>')) message += '</ul>' if warnings: message += '<p>The following warnings were generated while converting symbols:</p>' message += '<ul>' for w in warnings: message += '<li>{}</li>'.format(w.replace('\n', '<br>')) message += '</ul>' show_warning('style could not be completely converted', 'Convert style', message, level=Qgis.Critical if (unreadable or errors) else Qgis.Warning) if Qgis.QGIS_VERSION_INT >= 30800: dlg = QgsStyleManagerDialog(style, readOnly=True) dlg.setFavoritesGroupVisible(False) dlg.setSmartGroupsVisible(False) fi = QFileInfo(input_file) dlg.setBaseStyleName(fi.baseName()) else: dlg = QgsStyleManagerDialog(style) dlg.exec_() return True
def execute(func, message = None, useThread = False): global _dialog cursor = QApplication.overrideCursor() waitCursor = (cursor is not None and cursor.shape() == Qt.WaitCursor) dialogCreated = False try: QCoreApplication.processEvents() if not waitCursor: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if message is not None and useThread: t = Thread(func) loop = QEventLoop() t.finished.connect(loop.exit, Qt.QueuedConnection) if _dialog is None: dialogCreated = True _dialog = QProgressDialog(message, "Mapstory", 0, 0, config.iface.mainWindow()) _dialog.setWindowTitle("Mapstory") _dialog.setWindowModality(Qt.WindowModal); _dialog.setMinimumDuration(1000) _dialog.setMaximum(100) _dialog.setValue(0) _dialog.setMaximum(0) _dialog.setCancelButton(None) else: oldText = _dialog.labelText() _dialog.setLabelText(message) QApplication.processEvents() t.start() loop.exec_(flags = QEventLoop.ExcludeUserInputEvents) if t.exception is not None: raise t.exception return t.returnValue else: return func() finally: if message is not None and useThread: if dialogCreated: _dialog.reset() _dialog = None else: _dialog.setLabelText(oldText) if not waitCursor: QApplication.restoreOverrideCursor() QCoreApplication.processEvents()
def 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 translate(self, params): if params is None: return params['callback'] = self.translate_callback dlg = QProgressDialog(self) dlg.setWindowTitle(plugin_name()) dlg.setLabelText('Operation in progress') dlg.setMinimum(0) dlg.setMaximum(100) dlg.setWindowModality(Qt.WindowModal) self.progress_dlg = dlg self.setCursor(Qt.WaitCursor) try: log("gdal.VectorTranslate({})".format(str(params))) gdal.PushErrorHandler(gdal_error_handler) with qgis_proxy_settings(): res = gdal.VectorTranslate(**params) gdal.PopErrorHandler() log(str(res)) finally: self.unsetCursor() self.progress_dlg.reset() self.progress_dlg = None
def db2Feat(self, parent, table, results, columns, geom=""): # Execute the export process # Create driver drv = ogr.GetDriverByName(self.getDriverName()) if drv is None: raise Exception("{0} driver not available.".format( self.getDriverName())) # Create data source self._ds = drv.CreateDataSource(self._targetFile) if self._ds is None: raise Exception("Creation of output file failed.") dest_crs = None # Create layer if geom != "": pgGeomType, srid = geometryType(table, geom) geomType = wkbTypes[pgGeomType] try: dest_crs = ogr.osr.SpatialReference() except AttributeError: dest_crs = osr.SpatialReference() dest_crs.ImportFromEPSG(srid) else: geomType = ogr.wkbNone layer_name = self.getLayerName() lyr = self._ds.CreateLayer(layer_name, dest_crs, geomType) if lyr is None: raise Exception("Layer creation failed") # Create fields for c in columns: field_defn = self.createField(table, c) if lyr.CreateField(field_defn) != 0: raise Exception("Creating %s field failed" % (c)) # Add Geometry column to list for referencing in the result set if geom != "": columns.append(geom) featGeom = None # Configure progress dialog initVal = 0 numFeat = results.rowcount progress = QProgressDialog("", "&Cancel", initVal, numFeat, parent) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = QApplication.translate('OGRWriter', 'Writing {0} of {1} to file...') entity = current_profile().entity_by_name(table) # Iterate the result set for r in results: # Progress dialog progress.setValue(initVal) progressMsg = lblMsgTemp.format(str(initVal + 1), str(numFeat)) progress.setLabelText(progressMsg) if progress.wasCanceled(): break # Create OGR Feature feat = ogr.Feature(lyr.GetLayerDefn()) for i in range(len(columns)): colName = columns[i] # Check if its the geometry column in the iteration if colName == geom: if r[i] is not None: featGeom = ogr.CreateGeometryFromWkt(r[i]) else: featGeom = ogr.CreateGeometryFromWkt("") feat.SetGeometry(featGeom) else: field_value = r[i] feat.SetField(i, str(field_value)) if lyr.CreateFeature(feat) != 0: progress.close() progress.deleteLater() del progress raise Exception("Failed to create feature in %s" % (self._targetFile)) if featGeom is not None: featGeom.Destroy() feat.Destroy() initVal += 1 progress.setValue(numFeat) progress.deleteLater() del progress
class UpdateThemesOfGroup: def __init__(self, iface, plugin_dir, yleiskaavaSettings, yleiskaavaDatabase, yleiskaavaUtils): self.iface = iface self.yleiskaavaSettings = yleiskaavaSettings self.yleiskaavaDatabase = yleiskaavaDatabase self.yleiskaavaUtils = yleiskaavaUtils self.plugin_dir = plugin_dir self.dialogUpdateThemeOfGroup = uic.loadUi( os.path.join(self.plugin_dir, 'ui', 'yleiskaava_dialog_update_themes_of_group.ui')) self.themes = None self.themeNames = None self.currentTheme = None self.hasUserSelectedPolygonFeaturesForUpdate = False self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate = False self.hasUserSelectedLineFeaturesForUpdate = False self.hasUserSelectedPointFeaturesForUpdate = False self.hasUserCanceledCopy = False self.progressDialog = None self.shouldHide = False def setup(self): self.setupDialogUpdateThemeOfGroup() def setupDialogUpdateThemeOfGroup(self): self.dialogUpdateThemeOfGroup.comboBoxThemeNames.currentIndexChanged.connect( self.handleComboBoxThemeNameChanged) self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.stateChanged.connect( self.checkBoxUpdatePolygonFeaturesStateChanged) self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.stateChanged.connect( self.checkBoxUpdateSupplementaryPolygonFeaturesStateChanged) self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.stateChanged.connect( self.checkBoxUpdateLineFeaturesStateChanged) self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.stateChanged.connect( self.checkBoxUpdatePointFeaturesStateChanged) # Varoita käyttäjää, jos jo valmiiksi valittuja kohteita self.dialogUpdateThemeOfGroup.pushButtonSelectPolygonFeatures.clicked.connect( self.selectPolygonFeatures) self.dialogUpdateThemeOfGroup.pushButtonSelectSupplementaryPolygonFeatures.clicked.connect( self.selectSupplementaryPolygonFeatures) self.dialogUpdateThemeOfGroup.pushButtonSelectLineFeatures.clicked.connect( self.selectLineFeatures) self.dialogUpdateThemeOfGroup.pushButtonSelectPointFeatures.clicked.connect( self.selectPointFeatures) self.dialogUpdateThemeOfGroup.pushButtonUpdate.clicked.connect( self.handleUpdateTheme) self.dialogUpdateThemeOfGroup.pushButtonUpdateAndClose.clicked.connect( self.handleUpdateThemeAndClose) self.dialogUpdateThemeOfGroup.pushButtonCancel.clicked.connect( self.dialogUpdateThemeOfGroup.hide) def selectPolygonFeatures(self): layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_ALUE)[0] if layer.selectedFeatureCount() > 0: self.iface.messageBar().pushMessage( 'Aluevaraukset karttatasolla on jo valmiiksi valittuja kohteita', Qgis.Info, duration=20) self.iface.showAttributeTable(layer) self.hasUserSelectedPolygonFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.setChecked( True) def selectSupplementaryPolygonFeatures(self): layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_ALUE_TAYDENTAVA)[0] if layer.selectedFeatureCount() > 0: self.iface.messageBar().pushMessage( 'Täydentävät aluekohteet karttatasolla on jo valmiiksi valittuja kohteita', Qgis.Info, duration=20) self.iface.showAttributeTable(layer) self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.setChecked( True) def selectLineFeatures(self): layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_VIIVA)[0] if layer.selectedFeatureCount() > 0: self.iface.messageBar().pushMessage( 'Viivamaiset kaavakohteet karttatasolla on jo valmiiksi valittuja kohteita', Qgis.Info, duration=20) self.iface.showAttributeTable(layer) self.hasUserSelectedLineFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.setChecked( True) def selectPointFeatures(self): layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_PISTE)[0] if layer.selectedFeatureCount() > 0: self.iface.messageBar().pushMessage( 'Pistemäiset kaavakohteet karttatasolla on jo valmiiksi valittuja kohteita', Qgis.Info, duration=20) self.iface.showAttributeTable(layer) self.hasUserSelectedPointFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.setChecked( True) def checkBoxUpdatePolygonFeaturesStateChanged(self): pass # if self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.isChecked(): # self.dialogUpdateThemeOfGroup.pushButtonSelectPolygonFeatures.setEnabled(True) # else: # self.dialogUpdateThemeOfGroup.pushButtonSelectPolygonFeatures.setEnabled(False) def checkBoxUpdateSupplementaryPolygonFeaturesStateChanged(self): pass # if self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.isChecked(): # self.dialogUpdateThemeOfGroup.pushButtonSelectSupplementaryPolygonFeatures.setEnabled(True) # else: # self.dialogUpdateThemeOfGroup.pushButtonSelectSupplementaryPolygonFeatures.setEnabled(False) def checkBoxUpdateLineFeaturesStateChanged(self): pass # if self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.isChecked(): # self.dialogUpdateThemeOfGroup.pushButtonSelectLineFeatures.setEnabled(True) # else: # self.dialogUpdateThemeOfGroup.pushButtonSelectLineFeatures.setEnabled(False) def checkBoxUpdatePointFeaturesStateChanged(self): pass # if self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.isChecked(): # self.dialogUpdateThemeOfGroup.pushButtonSelectPointFeatures.setEnabled(True) # else: # self.dialogUpdateThemeOfGroup.pushButtonSelectPointFeatures.setEnabled(False) def openDialogUpdateThemeForGroup(self): self.reset() if self.yleiskaavaSettings.shouldKeepDialogsOnTop(): self.dialogUpdateThemeOfGroup.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint) else: self.dialogUpdateThemeOfGroup.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) self.dialogUpdateThemeOfGroup.show() def handleUpdateTheme(self): self.shouldHide = False self.updateTheme() def handleUpdateThemeAndClose(self): self.shouldHide = True self.updateTheme() def updateTheme(self): # Päivitä teema ja siihen liitetyt kaavakohteet ja huomio asetukset, sekä mahd. useat teemat kohteella # Tarkista, onko teeman lomaketiedoissa eroa ja jos ei, niin ilmoita käyttäjälle. # Lisää teema sellaisille kaavakohteille, joilla sitä ei vielä ole, mutta käyttäjä on ko. kaavakohteen valinnut / valitsee # Anna käyttäjän valita kaavakohteet, joille teema päivitetään. # Varmista, että käyttäjä ei voi vahingossa päivittää jo aiemmin valitsemiaan kaavaobjekteja. # Varmista jotenkin, että käyttäjän valitsemat kohteet päivitetään vaikka niillä olisi eri teema kuin muutettava teema / rajoita valintamahdollisuus kohteisiin, joilla muutettavan teeman relaatio # Ilmoita käyttäjälle, että valitse kohteet, tms., jos ei ole valinnut. # Varmista, että self.currentTheme != None jo vaikka käyttäjä ei ole valinnut dialogista kohteita / lisää ensimmäiseksi vaihtoehdoksi comboboxiin "Valitse teema" # Huomioi, "Poista kaavakohteilta vanhat teemat"-asetuksen pois päältä olo, kun käyttäjä vain päivittää kohteilla jo olevaa teemaa -> ei siis tehdä duplikaattirelaatiota # näytä käyttöliittymässä yleiskaavan id, nimi, nro if self.currentTheme != None: themeID = self.currentTheme["id"] themeName = self.dialogUpdateThemeOfGroup.lineEditThemeName.text() themeDescription = self.dialogUpdateThemeOfGroup.plainTextEditThemeDescription.toPlainText( ) if not self.equalsThemeAndFormTexts(themeName, themeDescription): # self.yleiskaavaDatabase.reconnectToDB() success = self.yleiskaavaDatabase.updateTheme( themeID, themeName, themeDescription) if success: self.currentTheme["alpha_sort_key"] = themeName self.currentTheme["nimi"] = QVariant(themeName) self.currentTheme["kuvaus"] = QVariant(themeDescription) # self.currentTheme["id_yleiskaava"] = QVariant(themeDescription) self.iface.messageBar().pushMessage('Teema päivitetty', Qgis.Info, duration=30) elif not self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.isChecked( ) and not self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.isChecked( ) and not self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.isChecked( ) and not self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.isChecked( ): self.iface.messageBar().pushMessage( 'Teemaan ei ole tehty muutoksia eikä päivitettäviä kaavakohteita ole valittu. Ei tehdä päivityksiä', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.isChecked( ): if not self.hasUserSelectedPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä aluevarauksia; aluevarauksia ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään aluevarausten teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("alue") if self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.isChecked( ): if not self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä täydentäviä aluekohteita; täydentäviä aluekohteita ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään täydentävien aluekohteiden teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("alue_taydentava") if self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.isChecked( ): if not self.hasUserSelectedLineFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä viivamaisia kohteita; viivamaisia ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään viivamaisten kohteiden teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("viiva") if self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.isChecked( ): if not self.hasUserSelectedPointFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä pistemäisiä kohteita; pistemäisiä kohteita ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään pistemäisten kohteiden teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("piste") if self.shouldHide: self.dialogUpdateThemeOfGroup.hide() # else: # self.iface.messageBar().pushMessage("Kaavakohteita ei päivitetty", Qgis.Critical) elif self.dialogUpdateThemeOfGroup.checkBoxRemoveOldThemesFromSpatialFeatures.isChecked( ): # ainoastaan poistetaan vanha(t) teema(t) valituilta kohteilta if self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.isChecked( ): if not self.hasUserSelectedPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä aluevarauksia; aluevarauksia ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures("alue") if success: self.iface.messageBar().pushMessage( 'Aluvarausten teemat poistettu', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.isChecked( ): if not self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä täydentäviä aluekohteita; täydentäviä aluekohteita ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures( "alue_taydentava") if success: self.iface.messageBar().pushMessage( 'Täydentävien aluekohteiden teemat poistettu', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.isChecked( ): if not self.hasUserSelectedLineFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä viivamaisia kohteita; viivamaisia ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures("viiva") if success: self.iface.messageBar().pushMessage( 'Viivamaisten kohteiden teemat poistettu', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.isChecked( ): if not self.hasUserSelectedPointFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä pistemäisiä kohteita; pistemäisiä kohteita ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures("piste") if success: self.iface.messageBar().pushMessage( 'Pistemäisten kohteiden teemat poistettu', Qgis.Info, duration=30) if self.shouldHide: self.dialogUpdateThemeOfGroup.hide() self.finishUpdate() else: self.iface.messageBar().pushMessage('Valitse teema', Qgis.Info, duration=30) def equalsThemeAndFormTexts(self, formThemeName, formThemeDescription): themeName = self.currentTheme["nimi"] themeDescription = "" if self.currentTheme["kuvaus"] is not None: themeDescription = self.currentTheme["kuvaus"] if formThemeName == themeName and formThemeDescription == themeDescription: return True return False def finishUpdate(self): self.yleiskaavaUtils.refreshTargetLayersInProject() def reset(self): self.setupThemesInDialog() self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.setChecked( False) self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.setChecked( False) self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.setChecked( False) self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.setChecked( False) self.hasUserSelectedPolygonFeaturesForUpdate = False self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate = False self.hasUserSelectedLineFeaturesForUpdate = False self.hasUserSelectedPointFeaturesForUpdate = False self.updateUserSelectionsBasedOnLayers() def updateUserSelectionsBasedOnLayers(self): layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_ALUE)[0] if layer.selectedFeatureCount() > 0: self.hasUserSelectedPolygonFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.setChecked( True) layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_ALUE_TAYDENTAVA)[0] if layer.selectedFeatureCount() > 0: self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.setChecked( True) layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_VIIVA)[0] if layer.selectedFeatureCount() > 0: self.hasUserSelectedLineFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.setChecked( True) layer = QgsProject.instance().mapLayersByName( YleiskaavaDatabase.KAAVAOBJEKTI_PISTE)[0] if layer.selectedFeatureCount() > 0: self.hasUserSelectedPointFeaturesForUpdate = True self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.setChecked( True) def updateSpatialFeatures(self, featureType): if self.currentTheme != None: themeID = self.currentTheme["id"] themeName = self.currentTheme["nimi"] shouldRemoveOldThemeRelations = self.dialogUpdateThemeOfGroup.checkBoxRemoveOldThemesFromSpatialFeatures.isChecked( ) # self.yleiskaavaDatabase.reconnectToDB() self.updateThemesOfGroupTask = UpdateThemesOfGroupTask( self.yleiskaavaDatabase, featureType, themeID, themeName, shouldRemoveOldThemeRelations) targetLayer = self.yleiskaavaDatabase.getTargetLayer(featureType) themeLayer = self.yleiskaavaDatabase.getProjectLayer( "yk_kuvaustekniikka.teema") themeRelationLayer = self.yleiskaavaDatabase.getProjectLayer( "yk_kuvaustekniikka.kaavaobjekti_teema_yhteys") self.updateThemesOfGroupTask.setDependentLayers( [targetLayer, themeLayer, themeRelationLayer]) self.progressDialog.canceled.connect( self.handleUpdateThemesOfGroupTaskStopRequestedByUser) self.updateThemesOfGroupTask.progressChanged.connect( self.handleUpdateThemesOfGroupTaskProgressChanged) self.updateThemesOfGroupTask.taskCompleted.connect( self.handleUpdateThemesOfGroupTaskCompleted) self.updateThemesOfGroupTask.taskTerminated.connect( self.handleUpdateThemesOfGroupTaskTerminated) self.progressDialog.setValue(0) self.progressDialog.show() QgsApplication.taskManager().addTask(self.updateThemesOfGroupTask) def handleUpdateThemesOfGroupTaskStopRequestedByUser(self): self.hasUserCanceledCopy = True self.updateThemesOfGroupTask.cancel() def handleUpdateThemesOfGroupTaskProgressChanged(self, progress): self.progressDialog.setValue(int(progress)) def handleUpdateThemesOfGroupTaskCompleted(self): self.progressDialog.hide() self.finishUpdate() if not self.hasUserCanceledCopy: self.iface.messageBar().pushMessage( 'Valittujen kaavakohteiden teemat päivitetty', Qgis.Info, duration=30) else: self.iface.messageBar().pushMessage( 'Valittujen kaavakohteiden teemoja ei päivitetty kokonaisuudessaan tietokantaan', Qgis.Info, duration=30) self.hasUserCanceledCopy = False def handleUpdateThemesOfGroupTaskTerminated(self): if not self.hasUserCanceledCopy: self.iface.messageBar().pushMessage( "Teemojen päivityksessä tapahtui virhe", Qgis.Critical, duration=0) else: self.hasUserCanceledCopy = False self.progressDialog.hide() self.finishUpdate() def removeThemesFromSpatialFeatures(self, featureType): # self.yleiskaavaDatabase.reconnectToDB() spatialFeatures = self.yleiskaavaDatabase.getSelectedFeatures( featureType, ["id"]) # spatialFeatures = self.yleiskaavaDatabase.getSpatialFeaturesWithRegulationForType(regulationID, featureType) for feature in spatialFeatures: success = self.yleiskaavaDatabase.removeSpatialFeatureThemes( feature["id"], featureType) if not success: self.iface.messageBar().pushMessage( "Kaavakohteelta, jonka tyyppi on " + self.yleiskaavaDatabase. getUserFriendlySpatialFeatureTypeName(featureType) + " ja id on " + str(feature["id"]) + " ei voitu poistaa teemoja", Qgis.Critical, duration=0) return False return True def setupThemesInDialog(self): # self.yleiskaavaDatabase.reconnectToDB() self.themes = sorted(self.yleiskaavaDatabase.getThemes(), key=itemgetter('alpha_sort_key')) self.themeNames = [] for index, theme in enumerate(self.themes): # QgsMessageLog.logMessage("setupThemesInDialog - index: " + str(index) + ", theme['kuvaus']: " + str(theme['kuvaus']) + ", theme['nimi']: " + str(theme['nimi']), 'Yleiskaava-työkalu', Qgis.Info) nimi = "" kuvaus = "" if theme["nimi"] is not None or theme["kuvaus"] is not None: if theme["kuvaus"] is not None: kuvaus = ( theme["kuvaus"][:25] + '..') if len(theme["kuvaus"]) > 25 else theme["kuvaus"] self.themeNames.append(str(theme["nimi"]) + ' - ' + kuvaus) self.dialogUpdateThemeOfGroup.comboBoxThemeNames.clear() self.dialogUpdateThemeOfGroup.comboBoxThemeNames.addItems( self.themeNames) self.dialogUpdateThemeOfGroup.comboBoxThemeNames.insertItem( 0, "Valitse teema") self.dialogUpdateThemeOfGroup.comboBoxThemeNames.setCurrentIndex(0) self.currentTheme = None def handleComboBoxThemeNameChanged(self, currentIndex): self.currentTheme = self.themes[currentIndex - 1] if currentIndex > 0: self.dialogUpdateThemeOfGroup.lineEditThemeName.setText( self.currentTheme["nimi"]) if self.currentTheme["kuvaus"] is not None: self.dialogUpdateThemeOfGroup.plainTextEditThemeDescription.setPlainText( self.currentTheme["kuvaus"]) else: self.dialogUpdateThemeOfGroup.plainTextEditThemeDescription.setPlainText( "") if self.currentTheme["yleiskaava_nimi"] is not None: self.dialogUpdateThemeOfGroup.lineEditPlanName.setText( self.currentTheme["yleiskaava_nimi"]) else: self.dialogUpdateThemeOfGroup.lineEditPlanName.setText("") else: self.currentTheme = None self.dialogUpdateThemeOfGroup.lineEditThemeName.setText("") self.dialogUpdateThemeOfGroup.plainTextEditThemeDescription.setPlainText( "") self.dialogUpdateThemeOfGroup.lineEditPlanName.setText("")
def translate(self, params): if params is None: return params["callback"] = self.translate_callback dlg = QProgressDialog(self) dlg.setWindowTitle(plugin_name()) dlg.setLabelText("Operation in progress") dlg.setMinimum(0) dlg.setMaximum(100) dlg.setWindowModality(Qt.WindowModal) self.progress_dlg = dlg self.setCursor(Qt.WaitCursor) try: log("gdal.VectorTranslate({})".format(str(params))) gdal.PushErrorHandler(gdal_error_handler) with qgis_proxy_settings(): res = gdal.VectorTranslate(**params) gdal.PopErrorHandler() log(str(res)) finally: self.unsetCursor() self.progress_dlg.reset() self.progress_dlg = None
def updateTheme(self): # Päivitä teema ja siihen liitetyt kaavakohteet ja huomio asetukset, sekä mahd. useat teemat kohteella # Tarkista, onko teeman lomaketiedoissa eroa ja jos ei, niin ilmoita käyttäjälle. # Lisää teema sellaisille kaavakohteille, joilla sitä ei vielä ole, mutta käyttäjä on ko. kaavakohteen valinnut / valitsee # Anna käyttäjän valita kaavakohteet, joille teema päivitetään. # Varmista, että käyttäjä ei voi vahingossa päivittää jo aiemmin valitsemiaan kaavaobjekteja. # Varmista jotenkin, että käyttäjän valitsemat kohteet päivitetään vaikka niillä olisi eri teema kuin muutettava teema / rajoita valintamahdollisuus kohteisiin, joilla muutettavan teeman relaatio # Ilmoita käyttäjälle, että valitse kohteet, tms., jos ei ole valinnut. # Varmista, että self.currentTheme != None jo vaikka käyttäjä ei ole valinnut dialogista kohteita / lisää ensimmäiseksi vaihtoehdoksi comboboxiin "Valitse teema" # Huomioi, "Poista kaavakohteilta vanhat teemat"-asetuksen pois päältä olo, kun käyttäjä vain päivittää kohteilla jo olevaa teemaa -> ei siis tehdä duplikaattirelaatiota # näytä käyttöliittymässä yleiskaavan id, nimi, nro if self.currentTheme != None: themeID = self.currentTheme["id"] themeName = self.dialogUpdateThemeOfGroup.lineEditThemeName.text() themeDescription = self.dialogUpdateThemeOfGroup.plainTextEditThemeDescription.toPlainText( ) if not self.equalsThemeAndFormTexts(themeName, themeDescription): # self.yleiskaavaDatabase.reconnectToDB() success = self.yleiskaavaDatabase.updateTheme( themeID, themeName, themeDescription) if success: self.currentTheme["alpha_sort_key"] = themeName self.currentTheme["nimi"] = QVariant(themeName) self.currentTheme["kuvaus"] = QVariant(themeDescription) # self.currentTheme["id_yleiskaava"] = QVariant(themeDescription) self.iface.messageBar().pushMessage('Teema päivitetty', Qgis.Info, duration=30) elif not self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.isChecked( ) and not self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.isChecked( ) and not self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.isChecked( ) and not self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.isChecked( ): self.iface.messageBar().pushMessage( 'Teemaan ei ole tehty muutoksia eikä päivitettäviä kaavakohteita ole valittu. Ei tehdä päivityksiä', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.isChecked( ): if not self.hasUserSelectedPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä aluevarauksia; aluevarauksia ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään aluevarausten teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("alue") if self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.isChecked( ): if not self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä täydentäviä aluekohteita; täydentäviä aluekohteita ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään täydentävien aluekohteiden teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("alue_taydentava") if self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.isChecked( ): if not self.hasUserSelectedLineFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä viivamaisia kohteita; viivamaisia ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään viivamaisten kohteiden teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("viiva") if self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.isChecked( ): if not self.hasUserSelectedPointFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä pistemäisiä kohteita; pistemäisiä kohteita ei päivitetty', Qgis.Warning, duration=0) else: self.progressDialog = QProgressDialog( "Päivitetään pistemäisten kohteiden teemoja...", "Keskeytä", 0, 100) self.progressDialog.setWindowFlags( Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.updateSpatialFeatures("piste") if self.shouldHide: self.dialogUpdateThemeOfGroup.hide() # else: # self.iface.messageBar().pushMessage("Kaavakohteita ei päivitetty", Qgis.Critical) elif self.dialogUpdateThemeOfGroup.checkBoxRemoveOldThemesFromSpatialFeatures.isChecked( ): # ainoastaan poistetaan vanha(t) teema(t) valituilta kohteilta if self.dialogUpdateThemeOfGroup.checkBoxUpdatePolygonFeatures.isChecked( ): if not self.hasUserSelectedPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä aluevarauksia; aluevarauksia ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures("alue") if success: self.iface.messageBar().pushMessage( 'Aluvarausten teemat poistettu', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdateSupplementaryPolygonFeatures.isChecked( ): if not self.hasUserSelectedSuplementaryPolygonFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä täydentäviä aluekohteita; täydentäviä aluekohteita ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures( "alue_taydentava") if success: self.iface.messageBar().pushMessage( 'Täydentävien aluekohteiden teemat poistettu', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdateLineFeatures.isChecked( ): if not self.hasUserSelectedLineFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä viivamaisia kohteita; viivamaisia ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures("viiva") if success: self.iface.messageBar().pushMessage( 'Viivamaisten kohteiden teemat poistettu', Qgis.Info, duration=30) if self.dialogUpdateThemeOfGroup.checkBoxUpdatePointFeatures.isChecked( ): if not self.hasUserSelectedPointFeaturesForUpdate: self.iface.messageBar().pushMessage( 'Et ole valinnut päivitettäviä pistemäisiä kohteita; pistemäisiä kohteita ei päivitetty', Qgis.Warning, duration=0) else: success = self.removeThemesFromSpatialFeatures("piste") if success: self.iface.messageBar().pushMessage( 'Pistemäisten kohteiden teemat poistettu', Qgis.Info, duration=30) if self.shouldHide: self.dialogUpdateThemeOfGroup.hide() self.finishUpdate() else: self.iface.messageBar().pushMessage('Valitse teema', Qgis.Info, duration=30)
def _load_source_documents(self, source_docs): """ Load source documents into document listing widget. """ # Configure progress dialog progress_msg = QApplication.translate( "ViewSTR", "Loading supporting documents...") progress_dialog = QProgressDialog(self) if len(source_docs) > 0: progress_dialog.setWindowTitle(progress_msg) progress_dialog.setRange(0, len(source_docs)) progress_dialog.setWindowModality(Qt.WindowModal) progress_dialog.setFixedWidth(380) progress_dialog.show() progress_dialog.setValue(0) self._notif_search_config.clear() self.tbSupportingDocs.clear() self._source_doc_manager.reset() if len(source_docs) < 1: empty_msg = QApplication.translate( 'ViewSTR', 'No supporting document is uploaded ' 'for this social tenure relationship.') self._notif_search_config.clear() self._notif_search_config.insertWarningNotification(empty_msg) for i, (doc_type_id, doc_obj) in enumerate(source_docs.items()): # add tabs, and container and widget for each tab tab_title = self._source_doc_manager.doc_type_mapping[doc_type_id] tab_widget = QWidget() tab_widget.setObjectName(tab_title) cont_layout = QVBoxLayout(tab_widget) cont_layout.setObjectName('widget_layout_' + tab_title) scrollArea = QScrollArea(tab_widget) scrollArea.setFrameShape(QFrame.NoFrame) scrollArea_contents = QWidget() scrollArea_contents.setObjectName('tab_scroll_area_' + tab_title) tab_layout = QVBoxLayout(scrollArea_contents) tab_layout.setObjectName('layout_' + tab_title) scrollArea.setWidgetResizable(True) scrollArea.setWidget(scrollArea_contents) cont_layout.addWidget(scrollArea) self._source_doc_manager.registerContainer(tab_layout, doc_type_id) for doc in doc_obj: try: # add doc widgets self._source_doc_manager.insertDocFromModel( doc, doc_type_id) except DummyException as ex: LOGGER.debug(str(ex)) self.tbSupportingDocs.addTab(tab_widget, tab_title) progress_dialog.setValue(i + 1)
class OsmDownloaderDialog(QDialog, FORM_CLASS): """Downloader for OSM data.""" def __init__(self, parent=None, iface=None): """Constructor for import dialog. :param parent: Optional widget to use as parent. :type parent: QWidget :param iface: An instance of QgisInterface. :type iface: QgisInterface """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) icon = resources_path('img', 'icons', 'show-osm-download.svg') self.setWindowIcon(QtGui.QIcon(icon)) title = self.tr('InaSAFE OpenStreetMap Downloader') self.setWindowTitle(title) self.iface = iface self.progress_dialog = None # Set up things for context help self.help_button = self.button_box.button( QtWidgets.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Output directory self.directory_button.clicked.connect(self.directory_button_clicked) self.output_directory.setPlaceholderText( self.tr('[Create a temporary layer]')) # Disable boundaries group box until boundary checkbox is ticked self.boundary_group.setEnabled(False) # set up the validator for the file name prefix expression = QRegExp('^[A-Za-z0-9-_]*$') validator = QtGui.QRegExpValidator(expression, self.filename_prefix) self.filename_prefix.setValidator(validator) # Advanced panel self.line_edit_custom.setPlaceholderText(STAGING_SERVER) developer_mode = setting('developer_mode', expected_type=bool) self.group_box_advanced.setVisible(developer_mode) self.restore_state() # Setup the rectangle map tool self.canvas = iface.mapCanvas() self.rectangle_map_tool = \ RectangleMapTool(self.canvas) self.rectangle_map_tool.rectangle_created.connect( self.update_extent_from_rectangle) self.capture_button.clicked.connect(self.drag_rectangle_on_map_canvas) # Setup pan tool self.pan_tool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.pan_tool) # Setup helper for admin_level json_file_path = resources_path('osm', 'admin_level_per_country.json') if os.path.isfile(json_file_path): with open(json_file_path, encoding='utf-8') as f: self.countries = json.load(f) self.bbox_countries = None self.populate_countries() # connect self.country_comboBox.currentIndexChanged.connect( self.update_helper_political_level) self.admin_level_comboBox.currentIndexChanged.connect( self.update_helper_political_level) self.update_extent_from_map_canvas() def update_helper_political_level(self): """To update the helper about the country and the admin_level.""" current_country = self.country_comboBox.currentText() index = self.admin_level_comboBox.currentIndex() current_level = self.admin_level_comboBox.itemData(index) content = None try: content = \ self.countries[current_country]['levels'][str(current_level)] if content == 'N/A' or content == 'fixme' or content == '': raise KeyError except KeyError: content = self.tr('undefined') finally: text = self.tr('which represents %s in') % content self.boundary_helper.setText(text) def populate_countries(self): """Populate the combobox about countries and levels.""" for i in range(1, 12): self.admin_level_comboBox.addItem(self.tr('Level %s') % i, i) # Set current index to admin_level 8, the most common one self.admin_level_comboBox.setCurrentIndex(7) list_countries = sorted( [self.tr(country) for country in list(self.countries.keys())]) for country in list_countries: self.country_comboBox.addItem(country) self.bbox_countries = {} for country in list_countries: multipolygons = self.countries[country]['bbox'] self.bbox_countries[country] = [] for coords in multipolygons: bbox = QgsRectangle(coords[0], coords[3], coords[2], coords[1]) self.bbox_countries[country].append(bbox) self.update_helper_political_level() def help_toggled(self, flag): """Show or hide the help tab in the stacked widget. .. versionadded: 3.2 :param flag: Flag indicating whether help should be shown or hidden. :type flag: bool """ if flag: self.help_button.setText(self.tr('Hide Help')) self.show_help() else: self.help_button.setText(self.tr('Show Help')) self.hide_help() def hide_help(self): """Hide the usage info from the user. .. versionadded:: 3.2 """ self.main_stacked_widget.setCurrentIndex(1) def show_help(self): """Show usage info to the user.""" # Read the header and footer html snippets self.main_stacked_widget.setCurrentIndex(0) header = html_header() footer = html_footer() string = header message = osm_downloader_help() string += message.to_html() string += footer self.help_web_view.setHtml(string) def restore_state(self): """Read last state of GUI from configuration file.""" last_path = setting('directory', '', expected_type=str) self.output_directory.setText(last_path) def save_state(self): """Store current state of GUI to configuration file.""" set_setting('directory', self.output_directory.text()) def update_extent(self, extent): """Update extent value in GUI based from an extent. :param extent: A list in the form [xmin, ymin, xmax, ymax] where all coordinates provided are in Geographic / EPSG:4326. :type extent: list """ self.x_minimum.setValue(extent[0]) self.y_minimum.setValue(extent[1]) self.x_maximum.setValue(extent[2]) self.y_maximum.setValue(extent[3]) # Updating the country if possible. rectangle = QgsRectangle(extent[0], extent[1], extent[2], extent[3]) center = rectangle.center() for country in self.bbox_countries: for polygon in self.bbox_countries[country]: if polygon.contains(center): index = self.country_comboBox.findText(country) self.country_comboBox.setCurrentIndex(index) break else: # Continue if the inner loop wasn't broken. continue # Inner loop was broken, break the outer. break else: self.country_comboBox.setCurrentIndex(0) def update_extent_from_map_canvas(self): """Update extent value in GUI based from value in map. .. note:: Delegates to update_extent() """ self.bounding_box_group.setTitle( self.tr('Bounding box from the map canvas')) # Get the extent as [xmin, ymin, xmax, ymax] extent = viewport_geo_array(self.iface.mapCanvas()) self.update_extent(extent) def update_extent_from_rectangle(self): """Update extent value in GUI based from the QgsMapTool rectangle. .. note:: Delegates to update_extent() """ self.show() self.canvas.unsetMapTool(self.rectangle_map_tool) self.canvas.setMapTool(self.pan_tool) rectangle = self.rectangle_map_tool.rectangle() if rectangle: self.bounding_box_group.setTitle( self.tr('Bounding box from rectangle')) extent = rectangle_geo_array(rectangle, self.iface.mapCanvas()) self.update_extent(extent) def directory_button_clicked(self): """Show a dialog to choose directory.""" # noinspection PyCallByClass,PyTypeChecker self.output_directory.setText( QFileDialog.getExistingDirectory( self, self.tr('Select download directory'))) def drag_rectangle_on_map_canvas(self): """Hide the dialog and allow the user to draw a rectangle.""" self.hide() self.rectangle_map_tool.reset() self.canvas.unsetMapTool(self.pan_tool) self.canvas.setMapTool(self.rectangle_map_tool) def get_checked_features(self): """Create a tab with all checked features. :return A list with all features which are checked in the UI. :rtype list """ feature_types = [] if self.roads_flag.isChecked(): feature_types.append('roads') if self.buildings_flag.isChecked(): feature_types.append('buildings') if self.building_points_flag.isChecked(): feature_types.append('building-points') if self.flood_prone_flag.isChecked(): feature_types.append('flood-prone') if self.evacuation_centers_flag.isChecked(): feature_types.append('evacuation-centers') if self.boundary_flag.isChecked(): level = self.admin_level_comboBox.currentIndex() + 1 feature_types.append('boundary-%s' % level) return feature_types def accept(self): """Do osm download and display it in QGIS.""" error_dialog_title = self.tr('InaSAFE OpenStreetMap Downloader Error') # Lock the bounding_box_group self.bounding_box_group.setDisabled(True) # Get the extent y_minimum = self.y_minimum.value() y_maximum = self.y_maximum.value() x_minimum = self.x_minimum.value() x_maximum = self.x_maximum.value() extent = [x_minimum, y_minimum, x_maximum, y_maximum] # Validate extent valid_flag = validate_geo_array(extent) if not valid_flag: message = self.tr( 'The bounding box is not valid. Please make sure it is ' 'valid or check your projection!') # noinspection PyCallByClass,PyTypeChecker,PyArgumentList display_warning_message_box(self, error_dialog_title, message) # Unlock the bounding_box_group self.bounding_box_group.setEnabled(True) return # Validate features feature_types = self.get_checked_features() if len(feature_types) < 1: message = self.tr('No feature selected. ' 'Please make sure you have checked one feature.') # noinspection PyCallByClass,PyTypeChecker,PyArgumentList display_warning_message_box(self, error_dialog_title, message) # Unlock the bounding_box_group self.bounding_box_group.setEnabled(True) return if self.radio_custom.isChecked(): server_url = self.line_edit_custom.text() if not server_url: # It's the place holder. server_url = STAGING_SERVER else: server_url = PRODUCTION_SERVER try: self.save_state() self.require_directory() # creating progress dialog for download self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(False) self.progress_dialog.setWindowTitle(self.windowTitle()) for feature_type in feature_types: output_directory = self.output_directory.text() if output_directory == '': output_directory = temp_dir(sub_dir='work') output_prefix = self.filename_prefix.text() overwrite = self.overwrite_flag.isChecked() output_base_file_path = self.get_output_base_path( output_directory, output_prefix, feature_type, overwrite) # noinspection PyTypeChecker download(feature_type, output_base_file_path, extent, self.progress_dialog, server_url) try: self.load_shapefile(feature_type, output_base_file_path) except FileMissingError as exception: display_warning_message_box(self, error_dialog_title, str(exception)) self.done(QDialog.Accepted) self.rectangle_map_tool.reset() except CanceledImportDialogError: # don't show anything because this exception raised # when user canceling the import process directly pass except Exception as exception: # pylint: disable=broad-except # noinspection PyCallByClass,PyTypeChecker,PyArgumentList display_warning_message_box(self, error_dialog_title, str(exception)) self.progress_dialog.cancel() self.progress_dialog.deleteLater() finally: # Unlock the bounding_box_group self.bounding_box_group.setEnabled(True) def get_output_base_path(self, output_directory, output_prefix, feature_type, overwrite): """Get a full base name path to save the shapefile. :param output_directory: The directory where to put results. :type output_directory: str :param output_prefix: The prefix to add for the shapefile. :type output_prefix: str :param feature_type: What kind of features should be downloaded. Currently 'buildings', 'building-points' or 'roads' are supported. :type feature_type: str :param overwrite: Boolean to know if we can overwrite existing files. :type overwrite: bool :return: The base path. :rtype: str """ path = os.path.join(output_directory, '%s%s' % (output_prefix, feature_type)) if overwrite: # If a shapefile exists, we must remove it (only the .shp) shp = '%s.shp' % path if os.path.isfile(shp): os.remove(shp) else: separator = '-' suffix = self.get_unique_file_path_suffix('%s.shp' % path, separator) if suffix: path = os.path.join( output_directory, '%s%s%s%s' % (output_prefix, feature_type, separator, suffix)) return path @staticmethod def get_unique_file_path_suffix(file_path, separator='-', i=0): """Return the minimum number to suffix the file to not overwrite one. Example : /tmp/a.txt exists. - With file_path='/tmp/b.txt' will return 0. - With file_path='/tmp/a.txt' will return 1 (/tmp/a-1.txt) :param file_path: The file to check. :type file_path: str :param separator: The separator to add before the prefix. :type separator: str :param i: The minimum prefix to check. :type i: int :return: The minimum prefix you should add to not overwrite a file. :rtype: int """ basename = os.path.splitext(file_path) if i != 0: file_path_test = os.path.join( '%s%s%s%s' % (basename[0], separator, i, basename[1])) else: file_path_test = file_path if os.path.isfile(file_path_test): return OsmDownloaderDialog.get_unique_file_path_suffix( file_path, separator, i + 1) else: return i def require_directory(self): """Ensure directory path entered in dialog exist. When the path does not exist, this function will ask the user if he want to create it or not. :raises: CanceledImportDialogError - when user choose 'No' in the question dialog for creating directory. """ path = self.output_directory.text() if path == '': # If let empty, we create an temporary directory return if os.path.exists(path): return title = self.tr('Directory %s not exist') % path question = self.tr( 'Directory %s not exist. Do you want to create it?') % path # noinspection PyCallByClass,PyTypeChecker answer = QMessageBox.question(self, title, question, QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: if len(path) != 0: os.makedirs(path) else: # noinspection PyCallByClass,PyTypeChecker,PyArgumentList display_warning_message_box( self, self.tr('InaSAFE error'), self.tr('Output directory can not be empty.')) raise CanceledImportDialogError() else: raise CanceledImportDialogError() def load_shapefile(self, feature_type, base_path): """Load downloaded shape file to QGIS Main Window. :param feature_type: What kind of features should be downloaded. Currently 'buildings', 'building-points' or 'roads' are supported. :type feature_type: str :param base_path: The base path of the shape file (without extension). :type base_path: str :raises: FileMissingError - when buildings.shp not exist """ path = '%s.shp' % base_path if not os.path.exists(path): message = self.tr( '%s does not exist. The server does not have any data for ' 'this extent.' % path) raise FileMissingError(message) layer = self.iface.addVectorLayer(path, feature_type, 'ogr') # Check if it's a building layer about the 2.5D if feature_type == 'buildings': layer_scope = QgsExpressionContextUtils.layerScope(layer) if not layer_scope.variable('qgis_25d_height'): QgsExpressionContextUtils.setLayerVariable( layer, 'qgis_25d_height', 0.0002) if not layer_scope.variable('qgis_25d_angle'): QgsExpressionContextUtils.setLayerVariable( layer, 'qgis_25d_angle', 70) def reject(self): """Redefinition of the method to remove the rectangle selection tool. It will call the super method. """ self.canvas.unsetMapTool(self.rectangle_map_tool) self.rectangle_map_tool.reset() super(OsmDownloaderDialog, self).reject()
def showProgressDialog(self, text, length, handler): self._pgdialog = QProgressDialog(text, "Cancel", 0, length, self) self._pgdialog.setWindowTitle(getAppName()) self._pgdialog.setWindowModality(QtCore.Qt.WindowModal) self._pgdialog.canceled.connect(handler, type=QtCore.Qt.DirectConnection) self._pgdialog.forceShow()