Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
 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)
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
    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)
Ejemplo n.º 11
0
    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
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
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))
Ejemplo n.º 18
0
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()])
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
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)
Ejemplo n.º 21
0
    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)
Ejemplo n.º 22
0
    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
Ejemplo n.º 23
0
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()
Ejemplo n.º 24
0
 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
Ejemplo n.º 26
0
Archivo: writer.py Proyecto: gltn/stdm
    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)
Ejemplo n.º 30
0
    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)
Ejemplo n.º 31
0
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()
Ejemplo n.º 32
0
 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()