예제 #1
0
def crs_text_element(crs, feature, parent):
    """Retrieve coordinate reference system text string from definitions.

    Example usage: crs_text_element('EPSG:3857').
    """
    _ = feature, parent  # NOQA
    crs_definition = QgsCoordinateReferenceSystem(crs)
    crs_description = crs_definition.description()
    text = crs_text['string_format'].format(crs=crs_description)
    return text
예제 #2
0
def crs_text_element(crs, feature, parent):
    """Retrieve coordinate reference system text string from definitions.

    Example usage: crs_text_element('EPSG:3857').
    """
    _ = feature, parent  # NOQA
    crs_definition = QgsCoordinateReferenceSystem(crs)
    crs_description = crs_definition.description()
    text = crs_text['string_format'].format(crs=crs_description)
    return text
예제 #3
0
파일: settings.py 프로젝트: co-city/qgyf
 def setDatabase(self, index):
     self.activeDatabase.setCurrentIndex(index)
     if self.activeDatabase.currentText():
         self.proj.writeEntry("QGYF", "activeDataBase",
                              self.activeDatabase.currentText())
         crs_id = self.getCRS(
             self.proj.readEntry("QGYF", "activeDataBase")[0])
         self.proj.writeEntry("QGYF", "CRS", crs_id)
         crs = QgsCoordinateReferenceSystem(int(float(crs_id)))
         self.crs.setText(crs.description())
     else:
         self.proj.writeEntry("QGYF", "activeDataBase", 'qgyf.sqlite')
예제 #4
0
 def on_srsButton_clicked(self):
     projSelector = QgsGenericProjectionSelector()
     message = self.tr('Select the Spatial Reference System!')
     projSelector.setMessage(theMessage=message)
     if not projSelector.exec_():
         QMessageBox.warning(self, self.tr("Warning!"), message)
         return
     else:
         self.epsg = int(projSelector.selectedAuthId().split(':')[-1])
     srs = QgsCoordinateReferenceSystem(
         self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
     self.srLineEdit.setText(srs.description())
예제 #5
0
 def on_srsButton_clicked(self):
     '''
     Opens the dialog to select CRS
     '''
     projSelector = QgsGenericProjectionSelector()
     message = self.tr('Select the Spatial Reference System!')
     projSelector.setMessage(theMessage=message)
     if not projSelector.exec_():
         QMessageBox.warning(self, self.tr("Warning!"), message)
         return
     else:
         self.epsg = int(projSelector.selectedAuthId().split(':')[-1])
     srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
     self.srLineEdit.setText(srs.description())
예제 #6
0
 def on_srsButton_clicked(self):
     projSelector = QgsGenericProjectionSelector()
     message = 'Select the Spatial Reference System!'
     projSelector.setMessage(theMessage=message)
     projSelector.exec_()
     try:
         self.epsg = int(projSelector.selectedAuthId().split(':')[-1])
         srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
         if srs:
             self.srsEdit.setText(srs.description())
         else:
             self.epsg = 4326
     except:
         QMessageBox.warning(self, self.tr("Warning!"), self.tr(message))
예제 #7
0
    def __init__(self, iface):
        """Constructor."""
        super(ProcessingTools, self).__init__()
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.iface = iface

        self.tabWidget.removeTab(1)

        self.epsg = 4326
        srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
        self.srLineEdit.setText(srs.description())
예제 #8
0
    def __init__(self, iface):
        """Constructor."""
        super(ProcessingTools, self).__init__()
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.iface = iface

        self.tabWidget.removeTab(1)

        self.epsg = 4326
        srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
        self.srLineEdit.setText(srs.description())
예제 #9
0
    def init(self, config):  # called from tool
        try:
            self.debug = config.get('debug', False)
            if self.debug: self.info.log("init")
            #status
            self.layer = self.iface.activeLayer()
            self.prj = QgsProject.instance()
            self.cboCoordSystems.clear()
            # tooldata
            self.coords = config.get('coordinatereferences', self.coords)
            self.pointScale = config.get('point_scale', self.pointScale)
            self.buffer_scale = config.get("buffer_scale", self.buffer_scale)
            self.minimum_scale = config.get("minimum_scale",
                                            self.minimum_scale)

            if not self.coords:
                self.cboCoordSystems.setHidden(True)
                self.projectWid.setHidden(False)
                self.projectWid.setCrs(self.prj.crs())
                cbos = self.projectWid.findChildren(QComboBox)
                for cbo in cbos:
                    cbo.setMaximumHeight(self.iface.iconSize().height())
            else:
                self.projectWid.setHidden(True)
                self.cboCoordSystems.setHidden(False)
                crs = self.prj.crs()
                self.cboCoordSystems.addItem(
                    "Project CRS: " + crs.authid() + " - " + crs.description(),
                    crs)
                for crsID in self.coords:
                    try:
                        crs = QgsCoordinateReferenceSystem(crsID)
                        self.cboCoordSystems.addItem(
                            crs.authid() + " - " + crs.description(), crs)
                    except Exception as e:
                        self.info.err(e)
            #ui stuff
            btns = self.findChildren(QToolButton)
            for btn in btns:
                btn.setIconSize(self.iface.iconSize())
            #start
            self.fillCombo(self.layer)
            self.fillTable(True)
        except Exception as e:
            self.info.err(e)
예제 #10
0
 def sdbinfo(self, filename):
     """Populate dialog with current values"""
     self.sdbname.setText(filename)
     try:
         sdb = SDB(filename)
         crs = QgsCoordinateReferenceSystem()
         crs.createFromUserInput(sdb.meta("crs"))
         self.sdb_info_basic.setPlainText(
             sdb.info(report='basic') +
             '\nCRS parsed by QGIS:\n{}'.format(crs.description()))
         self.sdb_info_data.setPlainText(sdb.info(report='data'))
         self.sdb_info_tags.setPlainText(sdb.info(report='tags'))
         self.dbok = True
     except:
         self.sdb_info_basic.clear()
         self.sdb_info_data.clear()
         self.sdb_info_tags.clear()
         self.sdbname.clear()
         self.dbok = False
예제 #11
0
def define_crs_if_not_exist():
    __logger.debug('Check if CQFS CRS is defined...')

    config = __config['global']
    name = config['crs_name']
    proj4 = config['crs_proj4']

    crs = QgsCoordinateReferenceSystem()
    crs.createFromProj4(proj4)
    description = str(crs.description())

    if description == '':
        success = crs.saveAsUserCRS(name)
        if success:
            __logger.debug('CRS defined successfully.')
        else:
            __logger.warning('Fail to save CRS "{}".'.format(name))
    else:
        __logger.debug('CRS "{}" already exists.'.format(description))
예제 #12
0
    def added(self):  # widget was added to parent
        try:
            self.crs_transform = self.prj.crs()
            self.crs_layer = self.iface.activeLayer().crs()
            # set crs widget
            if self.coordinatereferences is None:
                # qgis transform
                self.cboCoordSys.setHidden(True)
                self.cboCoordSystems = self.mQgsProjectionSelectionWidget
                self.cboCoordSystems.setMinimumWidth(460)
                self.cboCoordSystems.setOptionVisible(QgsProjectionSelectionWidget.ProjectCrs, True)
                self.cboCoordSystems.setCrs(self.prj.crs())
                self.setCrs(self.cboCoordSystems.crs())
                self.cboCoordSystems.crsChanged.connect(self.setCrs)
            else:
                # custom transform
                self.mQgsProjectionSelectionWidget.setHidden(True)
                self.cboCoordSystems = self.cboCoordSys
                self.cboCoordSystems.setMinimumWidth(400)

                self.cboCoordSystems.currentIndexChanged.connect(
                    lambda: self.setCrs(self.cboCoordSystems.currentData()))
                self.cboCoordSystems.addItem(
                    "Projekt CRS: " + self.crs_transform.authid() + " - " + self.crs_transform.description(),
                    self.crs_transform)
                for crsID in self.coordinatereferences:
                    try:
                        crs = QgsCoordinateReferenceSystem(crsID)
                        self.cboCoordSystems.addItem(crs.authid() + " - " + crs.description(), crs)
                    except Exception as e:
                        self.info.err(e)
                self.cboCoordSystems.setCurrentIndex(0)
            # here we know which type is cboCoordSystems!
            self.setIconSizes()
        except Exception as e:
            self.info.err(e)
예제 #13
0
파일: settings.py 프로젝트: co-city/qgyf
 def __init__(self,
              dockwidget,
              model,
              plugin_dir,
              layerSelectorDialog,
              parent=None,
              parentWidget=None):
     super(SettingsDialog, self).__init__(parent)
     self.setupUi(self)
     self.proj = QgsProject.instance()
     modelGyf = model
     self.switch = SwitchGYFs(dockwidget, plugin_dir)
     self.populate()
     self.populateGYF()
     self.dataPath.setText(self.proj.readEntry("QGYF", "dataPath")[0])
     if self.proj.readEntry("QGYF", "CRS")[0]:
         crs = QgsCoordinateReferenceSystem(
             int(self.proj.readEntry("QGYF", "CRS")[0]))
         self.crs.setText(crs.description())
     self.selectPathButton.clicked.connect(self.openFileDialog)
     self.clearDatabaseButton.clicked.connect(
         lambda: self.clearDataBase(dockwidget))
     self.activeDatabase.currentIndexChanged.connect(self.setDatabase)
     self.parent = parentWidget
     self.selectCRSButton.clicked.connect(self.setCRS)
     updateDockwidget = lambda: self.updateDockwidget(
         dockwidget, layerSelectorDialog)
     self.db = Db()
     self.quality = QualityTable()
     if self.db.checkClass():
         self.currentGyf.setEnabled(True)
         self.currentGyf.currentIndexChanged.connect(self.setGYF)
         if dockwidget.isVisible():
             self.currentGyf.currentIndexChanged.connect(updateDockwidget)
     else:
         self.currentGyf.setEnabled(False)
예제 #14
0
 def getSpatialRefInfo(self, srid):
     crs = QgsCoordinateReferenceSystem(srid)
     return crs.description()
예제 #15
0
class LoadByClass(QtGui.QDialog, load_by_class_base.Ui_LoadByClass):
    def __init__(self, parent=None):
        """Constructor."""
        super(LoadByClass, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.filename = ""
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        self.selectedClasses = []

        #Sql factory generator
        self.isSpatialite = True

        self.setupUi(self)
        self.tabWidget.setCurrentIndex(0)
        self.factory = SqlGeneratorFactory()
        self.gen = self.factory.createSqlGenerator(self.isSpatialite)
        self.utils = Utils()

        self.bar = QgsMessageBar()
        self.setLayout(QtGui.QGridLayout(self))
        self.layout().setContentsMargins(0,0,0,0)
        self.layout().setAlignment(QtCore.Qt.AlignTop)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        self.bar.setSizePolicy(sizePolicy)
        self.layout().addWidget(self.bar, 0,0,1,1)

        #Objects Connections
        QtCore.QObject.connect(self.pushButtonOpenFile, QtCore.SIGNAL(("clicked()")), self.loadDatabase)
        QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel)
        QtCore.QObject.connect(self.selectAllCheck, QtCore.SIGNAL(("stateChanged(int)")), self.selectAll)
        QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected)
        QtCore.QObject.connect(self.tabWidget,QtCore.SIGNAL(("currentChanged(int)")), self.restoreInitialState)

        self.db = None
        #populating the postgis combobox
        self.populatePostGISConnectionsCombo()

    def __del__(self):
        self.closeDatabase()

    def closeDatabase(self):
        if self.db:
            self.db.close()
            self.db = None

    def restoreInitialState(self):
        self.filename = ""
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        self.selectedClasses = []
        self.spatialiteFileEdit.setText(self.filename)
        self.postGISCrsEdit.setText('')
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setText('')
        self.spatialiteCrsEdit.setReadOnly(True)

        tam = self.classesListWidget.__len__()
        for i in range(tam+1,1,-1):
            item = self.classesListWidget.takeItem(i-2)

        self.selectAllCheck.setCheckState(0)
        #Setting the database type
        if self.tabWidget.currentIndex() == 0:
            self.isSpatialite = True
        else:
            self.isSpatialite = False
        #getting the sql generator according to the database type
        self.gen = self.factory.createSqlGenerator(self.isSpatialite)
        self.comboBoxPostgis.setCurrentIndex(0)

    def updateBDField(self):
        if self.dbLoaded == True:
            self.spatialiteFileEdit.setText(self.filename)
        else:
            self.filename = ""
            self.spatialiteFileEdit.setText(self.filename)

    def getDatabaseVersion(self):
        self.dbVersion = self.utils.getDatabaseVersion(self.db)
        self.qmlPath = self.utils.getQmlDir(self.db)

    def listClassesFromDatabase(self):
        self.classesListWidget.clear()
        self.getDatabaseVersion()
        sql = self.gen.getTablesFromDatabase()
        query = QSqlQuery(sql, self.db)
        while query.next():
            if self.isSpatialite:
                tableName = query.value(0)
                layerName = tableName
            else:
                tableSchema = query.value(0)
                tableName = query.value(1)
                layerName = tableSchema+'.'+tableName
            if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" \
                or tableName.split("_")[-1] == "a":

                item = QtGui.QListWidgetItem(layerName)
                self.classesListWidget.addItem(item)
        self.classesListWidget.sortItems()
        self.setCRS()

    def setCRS(self):
        try:
            self.epsg = self.utils.findEPSG(self.db)
            if self.epsg == -1:
                self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING)
            else:
                self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
                if self.isSpatialite:
                    self.spatialiteCrsEdit.setText(self.crs.description())
                    self.spatialiteCrsEdit.setReadOnly(True)
                else:
                    self.postGISCrsEdit.setText(self.crs.description())
                    self.postGISCrsEdit.setReadOnly(True)
        except:
            pass

    @pyqtSlot(int)
    def on_comboBoxPostgis_currentIndexChanged(self):
        if self.comboBoxPostgis.currentIndex() > 0:
            self.loadDatabase()

    def loadDatabase(self):
        self.closeDatabase()
        if self.isSpatialite:
            (self.filename, self.db) = self.utils.getSpatialiteDatabase()
            if self.filename:
                self.spatialiteFileEdit.setText(self.filename)
        else:
            self.db = self.utils.getPostGISDatabase(self.comboBoxPostgis.currentText())
        try:
            if not self.db.open():
                QgsMessageLog.logMessage(self.db.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
            else:
                self.dbLoaded = True
                self.listClassesFromDatabase()
        except:
            pass

    def populatePostGISConnectionsCombo(self):
        self.comboBoxPostgis.clear()
        self.comboBoxPostgis.addItem(self.tr("Select Database"))
        self.comboBoxPostgis.addItems(self.utils.getPostGISConnections())

    def cancel(self):
        self.restoreInitialState()
        self.close()

    def selectAll(self):
        if self.selectAllCheck.isChecked():
            tam = self.classesListWidget.__len__()
            for i in range(tam+1):
                item = self.classesListWidget.item(i-1)
                self.classesListWidget.setItemSelected(item,2)

        else:
            tam = self.classesListWidget.__len__()
            for i in range(tam+1):
                item = self.classesListWidget.item(i-1)
                self.classesListWidget.setItemSelected(item,0)

    def getSelectedItems(self):
        lista = self.classesListWidget.selectedItems()
        self.selectedClasses = []
        tam = len(lista)
        for i in range(tam):
            self.selectedClasses.append(lista[i].text())
        self.selectedClasses.sort()

    def okSelected(self):
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            if self.isSpatialite:
                self.loadSpatialiteLayers()
            else:
                self.loadPostGISLayers()
            QApplication.restoreOverrideCursor()
        except:
            QApplication.restoreOverrideCursor()

    def loadPostGISLayers(self):
        self.getSelectedItems()
        (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText())
        uri = QgsDataSourceURI()
        uri.setConnection(str(host),str(port), str(database), str(user), str(password))
        if len(self.selectedClasses)>0:
            try:
                geom_column = 'geom'
                for layer in self.selectedClasses:
                    split = layer.split('.')
                    schema = split[0]
                    layerName = split[1]
                    sql = self.gen.loadLayerFromDatabase(layer)
                    uri.setDataSource(schema, layerName, geom_column, sql,'id')
                    uri.disableSelectAtId(True)
                    self.loadEDGVLayer(uri, layerName, 'postgres')
                self.restoreInitialState()
                self.close()
            except:
                self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the selected classes!"), level=QgsMessageBar.CRITICAL)
        else:
            self.bar.pushMessage(self.tr("Warning!"), self.tr("Please, select at least one class!"), level=QgsMessageBar.WARNING)

    def loadSpatialiteLayers(self):
        self.getSelectedItems()
        uri = QgsDataSourceURI()
        uri.setDatabase(self.filename)
        schema = ''
        geom_column = 'GEOMETRY'
        if len(self.selectedClasses)>0:
            try:
                for layer_name in self.selectedClasses:
                    uri.setDataSource(schema, layer_name, geom_column)
                    self.loadEDGVLayer(uri, layer_name, 'spatialite')
                self.restoreInitialState()
                self.close()
            except:
                self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the layer(s)!"), level=QgsMessageBar.CRITICAL)
        else:
            self.bar.pushMessage(self.tr("Warning!"), self.tr("Please select at least one layer!"), level=QgsMessageBar.WARNING)

    def loadEDGVLayer(self, uri, layer_name, provider):
        vlayer = QgsVectorLayer(uri.uri(), layer_name, provider)
        vlayer.setCrs(self.crs)
        QgsMapLayerRegistry.instance().addMapLayer(vlayer) #added due to api changes
        if self.isSpatialite and (self.dbVersion == '3.0' or self.dbVersion == '2.1.3'):
            lyr = '_'.join(layer_name.replace('\r', '').split('_')[1::])
        else:
            lyr = layer_name.replace('\r','')
        vlayerQml = os.path.join(self.qmlPath, lyr+'.qml')
        vlayer.loadNamedStyle(vlayerQml, False)
        QgsMapLayerRegistry.instance().addMapLayer(vlayer)
        if not vlayer.isValid():
            QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
예제 #16
0
class StripTrialPointsDialog(QtGui.QDialog, FORM_CLASS):
    """Extract statistics from a list of rasters at set locations."""
    toolKey = 'StripTrialPointsDialog'

    def __init__(self, iface, parent=None):

        super(StripTrialPointsDialog, self).__init__(parent)

        # Set up the user interface from Designer.
        self.setupUi(self)

        self.iface = iface
        self.DISP_TEMP_LAYERS = read_setting(PLUGIN_NAME + '/DISP_TEMP_LAYERS',
                                             bool)
        self.DEBUG = config.get_debug_mode()

        # Catch and redirect python errors directed at the log messages python error tab.
        QgsMessageLog.instance().messageReceived.connect(errorCatcher)

        if not os.path.exists(TEMPDIR):
            os.mkdir(TEMPDIR)

        # Setup for validation messagebar on gui-----------------------------
        self.messageBar = QgsMessageBar(
            self)  # leave this message bar for bailouts
        self.validationLayout = QtGui.QFormLayout(self)  # new layout to gui

        if isinstance(self.layout(), (QtGui.QFormLayout, QtGui.QGridLayout)):
            # create a validation layout so multiple messages can be added and cleaned up.
            self.layout().insertRow(0, self.validationLayout)
            self.layout().insertRow(0, self.messageBar)
        else:
            self.layout().insertWidget(
                0,
                self.messageBar)  # for use with Vertical/horizontal layout box

        self.outQgsCRS = None

        self.exclude_map_layers()
        # self.updateUseSelected()
        self.autoSetCoordinateSystem()

        # GUI Runtime Customisation -----------------------------------------------
        self.setWindowIcon(
            QtGui.QIcon(':/plugins/pat/icons/icon_stripTrialPoints.svg'))
        self.chkUseSelected.setChecked(False)
        self.chkUseSelected.hide()
        self.chkSaveLinesFile.setChecked(False)

    def cleanMessageBars(self, AllBars=True):
        """Clean Messages from the validation layout.
        Args:
            AllBars (bool): Remove All bars including those which haven't timed-out. Defaults to True
        """
        layout = self.validationLayout
        for i in reversed(range(layout.count())):
            # when it timed out the row becomes empty....
            if layout.itemAt(i).isEmpty():
                # .removeItem doesn't always work. so takeAt(pop) it instead
                item = layout.takeAt(i)
            elif AllBars:  # ie remove all
                item = layout.takeAt(i)
                # also have to remove any widgets associated with it.
                if item.widget() is not None:
                    item.widget().deleteLater()

    def send_to_messagebar(self,
                           message,
                           title='',
                           level=QgsMessageBar.INFO,
                           duration=5,
                           exc_info=None,
                           core_QGIS=False,
                           addToLog=False,
                           showLogPanel=False):
        """ Add a message to the forms message bar.

        Args:
            message (str): Message to display
            title (str): Title of message. Will appear in bold. Defaults to ''
            level (QgsMessageBarLevel): The level of message to log. Defaults to QgsMessageBar.INFO
            duration (int): Number of seconds to display message for. 0 is no timeout. Defaults to 5
            core_QGIS (bool): Add to QGIS interface rather than the dialog
            addToLog (bool): Also add message to Log. Defaults to False
            showLogPanel (bool): Display the log panel
            exc_info () : Information to be used as a traceback if required

        """

        if core_QGIS:
            newMessageBar = self.iface.messageBar()
        else:
            newMessageBar = QgsMessageBar(self)

        widget = newMessageBar.createMessage(title, message)

        if showLogPanel:
            button = QPushButton(widget)
            button.setText('View')
            button.setContentsMargins(0, 0, 0, 0)
            button.setFixedWidth(35)
            button.pressed.connect(openLogPanel)
            widget.layout().addWidget(button)

        newMessageBar.pushWidget(widget, level, duration=duration)

        if not core_QGIS:
            rowCount = self.validationLayout.count()
            self.validationLayout.insertRow(rowCount + 1, newMessageBar)

        if addToLog:
            if level == 1:  # 'WARNING':
                LOGGER.warning(message)
            elif level == 2:  # 'CRITICAL':
                # Add a traceback to log only for bailouts only
                if exc_info is not None:
                    exc_type, exc_value, exc_traceback = sys.exc_info()
                    mess = str(traceback.format_exc())
                    message = message + '\n' + mess

                LOGGER.critical(message)
            else:  # INFO = 0
                LOGGER.info(message)

    def exclude_map_layers(self):
        """ Run through all loaded layers to find ones which should be excluded. In this case exclude services."""

        exVlayer_list = []

        for layer in self.iface.legendInterface().layers():
            if layer.type() == QgsMapLayer.VectorLayer:
                if layer.providerType() != 'ogr':
                    exVlayer_list.append(layer)

        if len(exVlayer_list) > 0:
            self.mcboLineLayer.setExceptedLayerList(exVlayer_list)

    def updateUseSelected(self):
        """Update use selected checkbox if active layer has a feature selection"""

        self.chkUseSelected.setChecked(False)

        if self.mcboLineLayer.count() == 0:
            return

        line_lyr = self.mcboLineLayer.currentLayer()
        self.mFieldComboBox.setLayer(line_lyr)
        if len(line_lyr.selectedFeatures()) > 0:
            self.chkUseSelected.setText(
                'Use the {} selected feature(s) ?'.format(
                    len(line_lyr.selectedFeatures())))
            self.chkUseSelected.setEnabled(True)
        else:
            self.chkUseSelected.setText('No features selected')
            self.chkUseSelected.setEnabled(False)

    def autoSetCoordinateSystem(self):
        if self.mcboLineLayer.count() == 0:
            return

        self.cleanMessageBars()
        line_lyr = self.mcboLineLayer.currentLayer()

        line_utm_crs = crs.getProjectedCRSForXY(
            line_lyr.extent().xMinimum(),
            line_lyr.extent().yMinimum(),
            int(line_lyr.crs().authid().replace('EPSG:', '')))
        self.outQgsCRS = None

        if line_utm_crs is not None:
            line_crs = QgsCoordinateReferenceSystem('EPSG:{}'.format(
                line_utm_crs.epsg_number))
            self.outQgsCRS = line_crs

        if self.outQgsCRS is not None:
            self.lblOutCRS.setText('{}  -  {}'.format(
                self.outQgsCRS.description(), self.outQgsCRS.authid()))
            self.lblOutCRSTitle.setStyleSheet('color:black')
            self.lblOutCRS.setStyleSheet('color:black')
        else:
            self.lblOutCRSTitle.setStyleSheet('color:red')
            self.lblOutCRS.setStyleSheet('color:red')
            self.lblOutCRS.setText('Unspecified')
            self.send_to_messagebar(
                'Auto detect coordinate system Failed. Check coordinate system of input raster layer',
                level=QgsMessageBar.CRITICAL,
                duration=5)
        return

    def on_mcboLineLayer_layerChanged(self):
        # self.updateUseSelected()
        self.autoSetCoordinateSystem()

    @QtCore.pyqtSlot(int)
    def on_chkUseSelected_stateChanged(self, state):
        if self.chkUseSelected.isChecked():
            self.chkUsePoly.setChecked(True)

    @QtCore.pyqtSlot(name='on_cmdOutCRS_clicked')
    def on_cmdOutCRS_clicked(self):
        dlg = QgsGenericProjectionSelector(self)
        dlg.setMessage(self.tr('Select coordinate system'))
        if dlg.exec_():
            if dlg.selectedAuthId() != '':
                self.outQgsCRS = QgsCoordinateReferenceSystem(
                    dlg.selectedAuthId())

                if self.outQgsCRS.geographicFlag():
                    self.outQgsCRS = None
                    self.send_to_messagebar(unicode(
                        self.
                        tr("Geographic coordinate systems are not allowed. Resetting to default.."
                           )),
                                            level=QgsMessageBar.WARNING,
                                            duration=5)
            else:
                self.outQgsCRS = None

            if self.outQgsCRS is None:
                self.autoSetCoordinateSystem()

            self.lblOutCRSTitle.setStyleSheet('color:black')
            self.lblOutCRS.setStyleSheet('color:black')
            self.lblOutCRS.setText(
                self.tr('{}  -  {}'.format(self.outQgsCRS.description(),
                                           self.outQgsCRS.authid())))

    @QtCore.pyqtSlot(name='on_cmdSavePointsFile_clicked')
    def on_cmdSavePointsFile_clicked(self):
        self.messageBar.clearWidgets()

        lastFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey +
                                  "/LastOutFolder")
        if lastFolder is None or not os.path.exists(lastFolder):
            lastFolder = read_setting(PLUGIN_NAME + "/BASE_OUT_FOLDER")

        filename = self.mcboLineLayer.currentText() + '_strip-trial-points'

        s = save_as_dialog(self,
                           self.tr("Save As"),
                           self.tr("ESRI Shapefile") + " (*.shp);;",
                           default_name=os.path.join(lastFolder, filename))

        if s == '' or s is None:
            return

        s = os.path.normpath(s)
        write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder",
                      os.path.dirname(s))

        self.lneSavePointsFile.setText(s)
        self.lblSavePointsFile.setStyleSheet('color:black')
        self.lneSavePointsFile.setStyleSheet('color:black')

    @QtCore.pyqtSlot(int)
    def on_chkSaveLinesFile_stateChanged(self, state):
        self.lneSaveLinesFile.setEnabled(state)
        if state:
            lastFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey +
                                      "/LastOutFolder")
            if lastFolder is None or not os.path.exists(lastFolder):
                lastFolder = read_setting(PLUGIN_NAME + "/BASE_OUT_FOLDER")

            if self.lneSavePointsFile.text() == '':
                filename = os.path.join(
                    lastFolder,
                    self.mcboLineLayer.currentText() +
                    '_strip-trial-lines.shp')
            else:
                path, file = os.path.split(self.lneSavePointsFile.text())
                file, ext = os.path.splitext(file)
                filename = os.path.join(
                    path,
                    file.replace('-points', '') + '-lines' + ext)

            self.lneSaveLinesFile.setText(filename)
            self.chkSaveLinesFile.setStyleSheet('color:black')
            self.lneSaveLinesFile.setStyleSheet('color:black')
        else:
            self.lneSaveLinesFile.setText('')

    @QtCore.pyqtSlot(name='on_cmdSaveLinesFile_clicked')
    def on_cmdSaveLinesFile_clicked(self):
        self.messageBar.clearWidgets()

        lastFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey +
                                  "/LastOutFolder")
        if lastFolder is None or not os.path.exists(lastFolder):
            lastFolder = read_setting(PLUGIN_NAME + "/BASE_OUT_FOLDER")

        if self.lneSaveLinesFile.text() != '':
            filename = self.lneSaveLinesFile.text()
        elif self.lneSavePointsFile.text() == '':
            filename = os.path.join(
                lastFolder,
                self.mcboLineLayer.currentText() + '_strip-trial-lines')
        else:
            path, file = os.path.split(self.lneSavePointsFile.text())
            file, ext = os.path.splitext(file)
            filename = os.path.join(
                path,
                file.replace('-points', '') + '-lines' + ext)

        s = save_as_dialog(self,
                           self.tr("Save As"),
                           self.tr("ESRI Shapefile") + " (*.shp);;",
                           default_name=os.path.join(lastFolder, filename))

        if s == '' or s is None:
            return

        s = os.path.normpath(s)
        write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder",
                      os.path.dirname(s))

        self.chkSaveLinesFile.setChecked(True)
        self.lneSaveLinesFile.setText(s)
        self.chkSaveLinesFile.setStyleSheet('color:black')
        self.lneSaveLinesFile.setStyleSheet('color:black')

    def validate(self):
        """Check to see that all required gui elements have been entered and are valid."""
        self.messageBar.clearWidgets()
        self.cleanMessageBars(AllBars=True)
        try:
            errorList = []
            if self.mcboLineLayer.currentLayer() is None:
                self.lblLineLayer.setStyleSheet('color:red')
                errorList.append(self.tr("Input line layer required."))
            else:
                self.lblLineLayer.setStyleSheet('color:black')

            if self.dsbDistBtwnPoints.value() <= 0:
                self.lblDistBtwnPoints.setStyleSheet('color:red')
                errorList.append(
                    self.tr("Distance between points must be greater than 0."))
            else:
                self.lblDistBtwnPoints.setStyleSheet('color:black')

            if self.dsbLineOffsetDist.value() <= 0:
                self.lblLineOffsetDist.setStyleSheet('color:red')
                errorList.append(
                    self.tr("Line offset distance must be greater than 0"))
            else:
                self.lblLineOffsetDist.setStyleSheet('color:black')

            if self.outQgsCRS is None:
                self.lblOutCRSTitle.setStyleSheet('color:red')
                self.lblOutCRS.setStyleSheet('color:red')
                errorList.append(
                    self.tr("Select output projected coordinate system"))
            else:
                if self.outQgsCRS.geographicFlag():
                    self.lblOutCRSTitle.setStyleSheet('color:red')
                    self.lblOutCRS.setStyleSheet('color:red')
                    errorList.append(
                        self.
                        tr("Output projected coordinate system (not geographic) required"
                           ))
                else:
                    self.lblOutCRSTitle.setStyleSheet('color:black')
                    self.lblOutCRS.setStyleSheet('color:black')

            if self.lneSavePointsFile.text() == '':
                self.lblSavePointsFile.setStyleSheet('color:red')
                errorList.append(self.tr("Save points shapefile"))
            elif not os.path.exists(
                    os.path.dirname(self.lneSavePointsFile.text())):
                self.lneSavePointsFile.setStyleSheet('color:red')
                self.lblSavePointsFile.setStyleSheet('color:red')
                errorList.append(
                    self.tr("Output shapefile folder cannot be found"))
            else:
                self.lblSavePointsFile.setStyleSheet('color:black')
                self.lneSavePointsFile.setStyleSheet('color:black')

            if self.chkSaveLinesFile.isChecked():
                if self.lneSaveLinesFile.text() == '':
                    self.chkSaveLinesFile.setStyleSheet('color:red')
                    errorList.append(self.tr("Save lines shapefile"))
                elif not os.path.exists(
                        os.path.dirname(self.lneSaveLinesFile.text())):
                    self.lneSaveLinesFile.setStyleSheet('color:red')
                    errorList.append(
                        self.tr("Output shapefile folder cannot be found"))
                else:
                    self.chkSaveLinesFile.setStyleSheet('color:black')
                    self.lneSaveLinesFile.setStyleSheet('color:black')
            else:
                self.chkSaveLinesFile.setStyleSheet('color:black')
                self.lneSaveLinesFile.setStyleSheet('color:black')

            if len(errorList) > 0:
                raise ValueError(errorList)

        except ValueError as e:
            self.cleanMessageBars(True)
            if len(errorList) > 0:
                for i, ea in enumerate(errorList):
                    self.send_to_messagebar(unicode(ea),
                                            level=QgsMessageBar.WARNING,
                                            duration=(i + 1) * 5)
                return False

        return True

    def accept(self, *args, **kwargs):
        try:

            if not self.validate():
                return False

            # disable form via a frame, this will still allow interaction with the message bar
            self.fraMain.setDisabled(True)

            # clean gui and Qgis messagebars
            self.cleanMessageBars(True)

            # Change cursor to Wait cursor
            QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
            self.iface.mainWindow().statusBar().showMessage(
                'Processing {}'.format(self.windowTitle()))
            LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(),
                                                     st='*' * 50))

            self.send_to_messagebar(
                "Please wait.. QGIS will be locked... See log panel for progress.",
                level=QgsMessageBar.WARNING,
                duration=0,
                addToLog=False,
                core_QGIS=False,
                showLogPanel=True)

            # Add settings to log
            settingsStr = 'Parameters:---------------------------------------'
            settingsStr += '\n    {:20}\t{}'.format(
                'Line layer:',
                self.mcboLineLayer.currentLayer().name())
            settingsStr += '\n    {:20}\t{}'.format(
                'Distance between points (m):', self.dsbDistBtwnPoints.value())
            settingsStr += '\n    {:20}\t{}'.format(
                'Line offset distance (m):', self.dsbLineOffsetDist.value())

            if self.chkUseSelected.isChecked():
                settingsStr += '\n    {:20}\t{} with {} selected features'.format(
                    'Layer:',
                    self.mcboLineLayer.currentLayer().name(),
                    len(self.mcboLineLayer.currentLayer().selectedFeatures()))

            settingsStr += '\n    {:30}\t{}'.format(
                'Output coordinate system:', self.lblOutCRS.text())
            settingsStr += '\n    {:30}\t{}'.format(
                'Output points :', self.lneSavePointsFile.text())

            if self.chkSaveLinesFile.isChecked():
                settingsStr += '\n    {:30}\t{}\n'.format(
                    'Output points :', self.chkSaveLinesFile.text())

            LOGGER.info(settingsStr)

            lyr_line = self.mcboLineLayer.currentLayer()

            if self.chkUseSelected.isChecked():
                line_shapefile = os.path.join(TEMPDIR,
                                              lyr_line.name() + '_lines.shp')

                if os.path.exists(line_shapefile):
                    removeFileFromQGIS(line_shapefile)

                QgsVectorFileWriter.writeAsVectorFormat(lyr_line,
                                                        line_shapefile,
                                                        "utf-8",
                                                        self.outQgsCRS,
                                                        "ESRI Shapefile",
                                                        onlySelected=True)

                if self.DISP_TEMP_LAYERS:
                    addVectorFileToQGIS(
                        line_shapefile,
                        layer_name=os.path.splitext(
                            os.path.basename(line_shapefile))[0],
                        group_layer_name='DEBUG',
                        atTop=True)
            else:
                line_shapefile = lyr_line.source()

            lines_desc = describe.VectorDescribe(line_shapefile)
            gdf_lines = lines_desc.open_geo_dataframe()
            epsgOut = int(self.outQgsCRS.authid().replace('EPSG:', ''))

            out_lines = None
            if self.chkSaveLinesFile.isChecked():
                out_lines = self.lneSaveLinesFile.text()

            _ = create_points_along_line(
                gdf_lines,
                lines_desc.crs,
                self.dsbDistBtwnPoints.value(),
                self.dsbLineOffsetDist.value(),
                epsgOut,
                out_points_shapefile=self.lneSavePointsFile.text(),
                out_lines_shapefile=out_lines)

            out_lyr_points = addVectorFileToQGIS(
                self.lneSavePointsFile.text(),
                atTop=True,
                layer_name=os.path.splitext(
                    os.path.basename(self.lneSavePointsFile.text()))[0])
            vector_apply_unique_value_renderer(out_lyr_points, 'Strip_Name')

            if self.chkSaveLinesFile.isChecked():
                out_lyr_lines = addVectorFileToQGIS(
                    self.lneSaveLinesFile.text(),
                    atTop=True,
                    layer_name=os.path.splitext(
                        os.path.basename(self.lneSaveLinesFile.text()))[0])

                vector_apply_unique_value_renderer(out_lyr_lines, 'Strip_Name')

            self.cleanMessageBars(True)
            self.fraMain.setDisabled(False)

            self.iface.mainWindow().statusBar().clearMessage()
            self.iface.messageBar().popWidget()
            QtGui.qApp.restoreOverrideCursor()
            return super(StripTrialPointsDialog, self).accept(*args, **kwargs)

        except Exception as err:

            QtGui.qApp.restoreOverrideCursor()
            self.iface.mainWindow().statusBar().clearMessage()
            self.cleanMessageBars(True)
            self.fraMain.setDisabled(False)

            self.send_to_messagebar(str(err),
                                    level=QgsMessageBar.CRITICAL,
                                    duration=0,
                                    addToLog=True,
                                    core_QGIS=False,
                                    showLogPanel=True,
                                    exc_info=sys.exc_info())

            return False  # leave dialog open
예제 #17
0
class vectorLayerPropertyDlg(QDialog):
    '''
    classdocs
    '''
    def __init__(self, parent, layer):
        '''
        Constructor
        '''
        QDialog.__init__(self, parent)
        self.ui = Ui_VectorLayerProPertyDialog()
        self.ui.setupUi(self)

        self.ui.txtLayerName.setText(layer.name())
        self.ui.txtLayerSource.setText(layer.source())
        self.ui.txtCrs.setText(layer.crs().authid() + " - " +
                               layer.crs().description())
        self.ui.btnCrsSelect.clicked.connect(self.selectCrs)
        self.mCrs = layer.crs()
        self.vLayer = layer
        self.ui.mOptionsListWidget.currentRowChanged.connect(
            self.changeStackWidget)
        ''' init RenderV2 Widget'''
        self.mRendererDialog = QgsRendererV2PropertiesDialog(
            self.vLayer, QgsStyleV2.defaultStyle(), True)
        self.ui.stackedWidget.insertWidget(1, self.mRendererDialog)
        self.ui.buttonBox.accepted.connect(self.OK)

        frame_Label = QFrame()
        verticalLayout_Label = QVBoxLayout(frame_Label)
        self.mLabelWidget = QgsFieldExpressionWidget()
        self.mLabelWidget.setLayer(layer)
        verticalLayout_Label.addWidget(self.mLabelWidget)

        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        verticalLayout_Label.addItem(spacerItem)
        frame_Label.setLayout(verticalLayout_Label)
        self.ui.stackedWidget.insertWidget(2, frame_Label)
#         self.ui.buttonBox.accepted.connect(self.OK)

    def selectCrs(self):
        projectionDlg = QgsGenericProjectionSelector(self)
        projectionDlg.setSelectedAuthId(self.mCrs.authid())
        if projectionDlg.exec_():
            self.mCrs = QgsCoordinateReferenceSystem(
                projectionDlg.selectedCrsId(),
                QgsCoordinateReferenceSystem.InternalCrsId)
            self.ui.txtCrs.setText(self.mCrs.authid() + " - " +
                                   self.mCrs.description())

    def changeStackWidget(self, index):
        self.ui.stackedWidget.setCurrentIndex(index)

    def OK(self):
        self.vLayer.setCrs(self.mCrs)
        self.mRendererDialog.apply()
        self.vLayer.triggerRepaint()
        if self.ui.stackedWidget.currentIndex(
        ) == 2 and self.mLabelWidget.currentText() != "":
            self.vLayer.setCustomProperty("labeling", "pal")
            self.vLayer.setCustomProperty("labeling/enabled", "true")
            self.vLayer.setCustomProperty("labeling/fontFamily", "Arial")
            self.vLayer.setCustomProperty("labeling/fontSize", "8")
            self.vLayer.setCustomProperty("labeling/fieldName",
                                          self.mLabelWidget.currentText())

            # palLayerSetting = QgsPalLayerSettings()
            # palLayerSetting.readFromLayer(self.vLayer)
            # palLayerSetting.enabled = True
            # palLayerSetting.fieldName = self.mLabelWidget.currentText()
            # palLayerSetting.isExpression = True
            if self.vLayer.geometryType() == QGis.Line:
                self.vLayer.setCustomProperty("labeling/placement", "2")
                self.vLayer.setCustomProperty(
                    "labeling/placementFlags",
                    str(QgsPalLayerSettings.AboveLine))
                # palLayerSetting.placement = QgsPalLayerSettings.Line
                # palLayerSetting.placementFlags = QgsPalLayerSettings.AboveLine
            elif self.vLayer.geometryType() == QGis.Point:
                self.vLayer.setCustomProperty("labeling/placement", "0")
                self.vLayer.setCustomProperty(
                    "labeling/placementFlags",
                    str(QgsPalLayerSettings.AroundPoint))
                # self.vLayer.setCustomProperty("labeling/placementFlags", "0")
                # palLayerSetting.placement = QgsPalLayerSettings.Points
                # palLayerSetting.placementFlags = QgsPalLayerSettings.AroundPoint
            else:
                self.vLayer.setCustomProperty("labeling/placement", "3")
                self.vLayer.setCustomProperty(
                    "labeling/placementFlags",
                    str(QgsPalLayerSettings.AboveLine))
                # palLayerSetting.placement = QgsPalLayerSettings.PolygonBoundary
                # palLayerSetting.placementFlags = QgsPalLayerSettings.AboveLine
            # palLayerSetting.setDataDefinedProperty(QgsPalLayerSettings.Size, True, True, '8', "")
            # palLayerSetting.writeToLayer(self.vLayer)
        elif self.ui.stackedWidget.currentIndex(
        ) == 2 and self.mLabelWidget.currentText() == "":
            self.vLayer.setCustomProperty("labeling", "")
        QgsProject.instance().dirty(True)
        QDialog.accept(self)
예제 #18
0
class LoadByCategory(QtGui.QDialog, FORM_CLASS):
    def __init__(self, codeList, parent=None):
        """Constructor."""
        super(LoadByCategory, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)

        self.categories = []
        self.selectedClasses = []

        self.point = []
        self.line = []
        self.polygon = []
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []

        self.parentTreeNode = None

        self.checkBoxPoint.setCheckState(0)
        self.checkBoxLine.setCheckState(0)
        self.checkBoxPolygon.setCheckState(0)
        self.checkBoxAll.setCheckState(0)

        self.bar = QgsMessageBar()
        self.setLayout(QtGui.QGridLayout(self))
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().setAlignment(QtCore.Qt.AlignTop)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum,
                                       QtGui.QSizePolicy.Fixed)
        self.bar.setSizePolicy(sizePolicy)
        self.layout().addWidget(self.bar, 0, 0, 1, 1)

        #Objects Connections
        self.widget.connectionChanged.connect(self.listCategoriesFromDatabase)
        self.widget.problemOccurred.connect(self.pushMessage)

        self.pushButtonCancel.clicked.connect(self.cancel)
        self.pushButtonOk.clicked.connect(self.okSelected)
        self.pushButtonSelectAll.clicked.connect(self.selectAll)
        self.pushButtonDeselectAll.clicked.connect(self.deselectAll)
        self.pushButtonSelectOne.clicked.connect(self.selectOne)
        self.pushButtonDeselectOne.clicked.connect(self.deselectOne)
        self.checkBoxAll.stateChanged.connect(self.setAllGroup)

        self.widget.tabWidget.currentChanged.connect(self.restoreInitialState)

        self.codeList = codeList
        self.layerFactory = LayerFactory()

    def restoreInitialState(self):
        self.categories = []
        self.selectedClasses = []
        self.listWidgetCategoryFrom.clear()
        self.listWidgetCategoryTo.clear()

        self.point = []
        self.line = []
        self.polygon = []
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []
        self.parentTreeNode = None

        self.checkBoxPoint.setCheckState(0)
        self.checkBoxLine.setCheckState(0)
        self.checkBoxPolygon.setCheckState(0)
        self.checkBoxAll.setCheckState(0)

    def listCategoriesFromDatabase(self):
        self.listWidgetCategoryFrom.clear()
        self.listWidgetCategoryTo.clear()

        self.dbVersion = self.widget.getDBVersion()
        self.qmlPath = self.widget.getQmlPath()
        classes = self.widget.abstractDb.listGeomClassesFromDatabase()
        for table in classes:
            schema, layerName = self.widget.abstractDb.getTableSchema(table)
            category = layerName.split('_')[0]
            categoryName = schema + '.' + category
            if layerName.split("_")[-1] == "p":
                self.point.append(table)
            if layerName.split("_")[-1] == "l":
                self.line.append(table)
            if layerName.split("_")[-1] == "a":
                self.polygon.append(table)

            self.insertIntoListView(categoryName)
        self.listWidgetCategoryFrom.sortItems()
        self.setCRS()

    def insertIntoListView(self, item_name):
        found = self.listWidgetCategoryFrom.findItems(item_name,
                                                      Qt.MatchExactly)
        if len(found) == 0:
            item = QtGui.QListWidgetItem(item_name)
            self.listWidgetCategoryFrom.addItem(item)

    def selectAll(self):
        tam = self.listWidgetCategoryFrom.__len__()
        for i in range(tam + 1, 1, -1):
            item = self.listWidgetCategoryFrom.takeItem(i - 2)
            self.listWidgetCategoryTo.addItem(item)
        self.listWidgetCategoryTo.sortItems()

    def deselectAll(self):
        tam = self.listWidgetCategoryTo.__len__()
        for i in range(tam + 1, 1, -1):
            item = self.listWidgetCategoryTo.takeItem(i - 2)
            self.listWidgetCategoryFrom.addItem(item)
        self.listWidgetCategoryFrom.sortItems()

    def selectOne(self):
        listedItems = self.listWidgetCategoryFrom.selectedItems()
        for i in listedItems:
            item = self.listWidgetCategoryFrom.takeItem(
                self.listWidgetCategoryFrom.row(i))
            self.listWidgetCategoryTo.addItem(item)
        self.listWidgetCategoryTo.sortItems()

    def deselectOne(self):
        listedItems = self.listWidgetCategoryTo.selectedItems()
        for i in listedItems:
            item = self.listWidgetCategoryTo.takeItem(
                self.listWidgetCategoryTo.row(i))
            self.listWidgetCategoryFrom.addItem(item)
        self.listWidgetCategoryFrom.sortItems()

    def setAllGroup(self):
        if self.checkBoxAll.isChecked():
            self.checkBoxPoint.setCheckState(2)
            self.checkBoxLine.setCheckState(2)
            self.checkBoxPolygon.setCheckState(2)
        else:
            self.checkBoxPoint.setCheckState(0)
            self.checkBoxLine.setCheckState(0)
            self.checkBoxPolygon.setCheckState(0)

    def pushMessage(self, msg):
        self.bar.pushMessage('', msg, level=QgsMessageBar.WARNING)

    def setCRS(self):
        try:
            self.epsg = self.utils.findEPSG(self.db)
            if self.epsg == -1:
                self.bar.pushMessage(
                    "",
                    self.tr("Coordinate Reference System not set or invalid!"),
                    level=QgsMessageBar.WARNING)
            else:
                self.crs = QgsCoordinateReferenceSystem(
                    self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
                if self.isSpatialite:
                    self.spatialiteCrsEdit.setText(self.crs.description())
                    self.spatialiteCrsEdit.setReadOnly(True)
                else:
                    self.postGISCrsEdit.setText(self.crs.description())
                    self.postGISCrsEdit.setReadOnly(True)
        except:
            pass

    def cancel(self):
        self.restoreInitialState()
        self.close()

    def getSelectedItems(self):
        lista = self.classesListWidget.selectedItems()
        self.selectedClasses = []
        tam = len(lista)
        for i in range(tam):
            self.selectedClasses.append(lista[i].text())
        self.selectedClasses.sort()

    def okSelected(self):
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

            if self.checkBoxOnlyWithElements.isChecked():
                self.setLayersWithElements()
                ponto = self.pointWithElement
                linha = self.lineWithElement
                area = self.polygonWithElement
            else:
                ponto = self.point
                linha = self.line
                area = self.polygon

            if len(self.listWidgetCategoryTo) > 0:
                categoriasSelecionadas = []
                for i in range(self.listWidgetCategoryTo.__len__()):
                    categoriasSelecionadas.append(
                        self.listWidgetCategoryTo.item(i).text())

                if self.checkBoxPoint.isChecked():
                    self.loadLayers('p', categoriasSelecionadas, ponto)
                if self.checkBoxLine.isChecked():
                    self.loadLayers('l', categoriasSelecionadas, linha)
                if self.checkBoxPolygon.isChecked():
                    self.loadLayers('a', categoriasSelecionadas, area)
                if self.checkBoxPoint.isChecked(
                ) == False and self.checkBoxLine.isChecked(
                ) == False and self.checkBoxPolygon.isChecked() == False:
                    self.bar.pushMessage(
                        self.tr("WARNING!"),
                        self.tr("Please, select at least one type of layer!"),
                        level=QgsMessageBar.WARNING)
                else:
                    self.restoreInitialState()
                    self.close()
            else:
                if self.widget.db and not self.widget.crs:
                    self.bar.pushMessage(
                        self.tr("CRITICAL!"),
                        self.
                        tr("Could not determine the coordinate reference system!"
                           ),
                        level=QgsMessageBar.CRITICAL)
                if not self.widget.db and not self.widget.crs:
                    self.bar.pushMessage(
                        self.tr("CRITICAL!"),
                        self.tr("Database not loaded properly!"),
                        level=QgsMessageBar.CRITICAL)
                    self.bar.pushMessage(
                        self.tr("CRITICAL!"),
                        self.
                        tr("Could not determine the coordinate reference system!"
                           ),
                        level=QgsMessageBar.CRITICAL)
                if len(self.listWidgetCategoryTo) == 0:
                    self.bar.pushMessage(
                        self.tr("WARNING!"),
                        self.tr("Please, select at least one category!"),
                        level=QgsMessageBar.WARNING)
                categoriasSelecionadas = []
                self.pointWithElement = []
                self.lineWithElement = []
                self.polygonWithElement = []

            QApplication.restoreOverrideCursor()
        except:
            QApplication.restoreOverrideCursor()

    def setLayersWithElements(self):
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []

        pontoAux = self.widget.abstractDb.countElements(self.point)
        linhaAux = self.widget.abstractDb.countElements(self.line)
        areaAux = self.widget.abstractDb.countElements(self.polygon)

        for i in pontoAux:
            if i[1] > 0:
                self.pointWithElement.append(i[0])

        for i in linhaAux:
            if i[1] > 0:
                self.lineWithElement.append(i[0])

        for i in areaAux:
            if i[1] > 0:
                self.polygonWithElement.append(i[0])

    def loadLayers(self, type, categories, table_names):
        dbName = self.widget.abstractDb.getDatabaseName()
        groupList = qgis.utils.iface.legendInterface().groups()
        groupRelationshipList = qgis.utils.iface.legendInterface(
        ).groupLayerRelationship()
        if dbName not in groupList:
            self.parentTreeNode = qgis.utils.iface.legendInterface().addGroup(
                dbName, -1)
        else:
            self.parentTreeNode = groupList.index(dbName)

        if type == 'p':
            if len(groupList[self.parentTreeNode::]) == 0:
                idGrupo = qgis.utils.iface.legendInterface().addGroup(
                    self.tr('Point'), True, self.parentTreeNode)
            elif self.tr('Point') not in groupRelationshipList[
                    self.parentTreeNode][1]:
                idGrupo = qgis.utils.iface.legendInterface().addGroup(
                    self.tr('Point'), True, self.parentTreeNode)
            else:
                idGrupo = groupList[self.parentTreeNode::].index(
                    self.tr('Point'))
            for category in categories:
                self.prepareLayer(category, table_names, idGrupo)
        if type == 'l':
            if len(groupList[self.parentTreeNode::]) == 0:
                idGrupo = qgis.utils.iface.legendInterface().addGroup(
                    self.tr('Line'), True, self.parentTreeNode)
            elif self.tr('Line') not in groupRelationshipList[
                    self.parentTreeNode][1]:
                idGrupo = qgis.utils.iface.legendInterface().addGroup(
                    self.tr('Line'), True, self.parentTreeNode)
            else:
                idGrupo = groupList[self.parentTreeNode::].index(
                    self.tr('Line'))
            for category in categories:
                self.prepareLayer(category, table_names, idGrupo)
        if type == 'a':
            if len(groupList[self.parentTreeNode::]) == 0:
                idGrupo = qgis.utils.iface.legendInterface().addGroup(
                    self.tr('Area'), True, self.parentTreeNode)
            elif self.tr('Area') not in groupRelationshipList[
                    self.parentTreeNode][1]:
                idGrupo = qgis.utils.iface.legendInterface().addGroup(
                    self.tr('Area'), True, self.parentTreeNode)
            else:
                idGrupo = groupList[self.parentTreeNode::].index(
                    self.tr('Area'))
            for category in categories:
                self.prepareLayer(category, table_names, idGrupo)

    def prepareLayer(self, category, table_names, idGrupo):
        idSubgrupo = qgis.utils.iface.legendInterface().addGroup(
            category, True, idGrupo)
        table_names.sort(reverse=True)
        for table_name in table_names:
            schema, layerName = self.widget.abstractDb.getTableSchema(
                table_name)
            if (category.split('.')[1]
                    == layerName.split('_')[0]) and (category.split('.')[0]
                                                     == schema):
                edgvLayer = self.layerFactory.makeLayer(
                    self.widget.abstractDb, self.codeList, table_name)
                edgvLayer.load(self.widget.crs, idSubgrupo)
예제 #19
0
class QGISRedLayerManagementDialog(QDialog, FORM_CLASS):
    # Common variables
    iface = None
    NetworkName = ""
    ProjectDirectory = ""

    def __init__(self, parent=None):
        """Constructor."""
        super(QGISRedLayerManagementDialog, self).__init__(parent)
        self.setupUi(self)
        self.btAccept.clicked.connect(self.accept)
        self.btSelectCRS.clicked.connect(self.selectCRS)

        self.btPipes.clicked.connect(lambda: self.createElement("Pipes"))
        self.btJunctions.clicked.connect(
            lambda: self.createElement("Junctions"))
        self.btTanks.clicked.connect(lambda: self.createElement("Tanks"))
        self.btReservoirs.clicked.connect(
            lambda: self.createElement("Reservoirs"))
        self.btValves.clicked.connect(lambda: self.createElement("Valves"))
        self.btPumps.clicked.connect(lambda: self.createElement("Pumps"))
        self.btDemands.clicked.connect(
            lambda: self.createElement("Demands", True))
        self.btSources.clicked.connect(
            lambda: self.createElement("Sources", True))
        self.btIsolatedValves.clicked.connect(
            lambda: self.createElement("IsolationValves", True))
        self.btHydrants.clicked.connect(
            lambda: self.createElement("Hydrants", True))
        self.btPurgeValves.clicked.connect(
            lambda: self.createElement("WashoutValves", True))
        self.btAirReleases.clicked.connect(
            lambda: self.createElement("AirReleaseValves", True))
        self.btConnections.clicked.connect(
            lambda: self.createElement("ServiceConnections", True))
        self.btMeters.clicked.connect(
            lambda: self.createElement("Meters", True))

    def config(self, ifac, direct, netw, parent):
        self.iface = ifac
        self.parent = parent

        utils = QGISRedUtils(direct, netw, ifac)
        self.crs = utils.getProjectCrs()
        self.originalCrs = self.crs
        self.tbCRS.setText(self.crs.description())

        self.NetworkName = netw
        self.ProjectDirectory = direct

        self.setProperties()

    def setProperties(self):
        dirList = os.listdir(self.ProjectDirectory)
        # Visibilities
        self.btPipes.setVisible(not self.NetworkName + "_Pipes.shp" in dirList)
        self.btJunctions.setVisible(not self.NetworkName +
                                    "_Junctions.shp" in dirList)
        self.btTanks.setVisible(not self.NetworkName + "_Tanks.shp" in dirList)
        self.btReservoirs.setVisible(not self.NetworkName +
                                     "_Reservoirs.shp" in dirList)
        self.btValves.setVisible(not self.NetworkName +
                                 "_Valves.shp" in dirList)
        self.btPumps.setVisible(not self.NetworkName + "_Pumps.shp" in dirList)
        self.btDemands.setVisible(not self.NetworkName +
                                  "_Demands.shp" in dirList)
        self.btSources.setVisible(not self.NetworkName +
                                  "_Sources.shp" in dirList)
        self.btIsolatedValves.setVisible(not self.NetworkName +
                                         "_IsolationValves.shp" in dirList)
        self.btHydrants.setVisible(not self.NetworkName +
                                   "_Hydrants.shp" in dirList)
        self.btPurgeValves.setVisible(not self.NetworkName +
                                      "_WashoutValves.shp" in dirList)
        self.btAirReleases.setVisible(not self.NetworkName +
                                      "_AirReleaseValves.shp" in dirList)
        self.btConnections.setVisible(not self.NetworkName +
                                      "_ServiceConnections.shp" in dirList)
        self.btMeters.setVisible(not self.NetworkName +
                                 "_Meters.shp" in dirList)

        # Enables
        self.cbDemands.setEnabled(self.NetworkName + "_Demands.shp" in dirList)
        self.cbSources.setEnabled(self.NetworkName + "_Sources.shp" in dirList)
        self.cbIsolatedValves.setEnabled(self.NetworkName +
                                         "_IsolationValves.shp" in dirList)
        self.cbHydrants.setEnabled(self.NetworkName +
                                   "_Hydrants.shp" in dirList)
        self.cbPurgeValves.setEnabled(self.NetworkName +
                                      "_WashoutValves.shp" in dirList)
        self.cbAirReleases.setEnabled(self.NetworkName +
                                      "_AirReleaseValves.shp" in dirList)
        self.cbConnections.setEnabled(self.NetworkName +
                                      "_ServiceConnections.shp" in dirList)
        self.cbMeters.setEnabled(self.NetworkName + "_Meters.shp" in dirList)

        # Los básicos: Enables and checked
        utils = QGISRedUtils(self.ProjectDirectory, self.NetworkName,
                             self.iface)
        hasLayer = utils.isLayerOpened("Pipes")
        self.cbPipes.setChecked(hasLayer)
        self.cbPipes.setEnabled(self.NetworkName + "_Pipes.shp" in dirList
                                and not hasLayer)
        hasLayer = utils.isLayerOpened("Junctions")
        self.cbJunctions.setChecked(hasLayer)
        self.cbJunctions.setEnabled(
            self.NetworkName + "_Junctions.shp" in dirList and not hasLayer)
        hasLayer = utils.isLayerOpened("Tanks")
        self.cbTanks.setChecked(hasLayer)
        self.cbTanks.setEnabled(self.NetworkName + "_Tanks.shp" in dirList
                                and not hasLayer)
        hasLayer = utils.isLayerOpened("Reservoirs")
        self.cbReservoirs.setChecked(hasLayer)
        self.cbReservoirs.setEnabled(
            self.NetworkName + "_Reservoirs.shp" in dirList and not hasLayer)
        hasLayer = utils.isLayerOpened("Valves")
        self.cbValves.setChecked(hasLayer)
        self.cbValves.setEnabled(self.NetworkName + "_Valves.shp" in dirList
                                 and not hasLayer)
        hasLayer = utils.isLayerOpened("Pumps")
        self.cbPumps.setChecked(hasLayer)
        self.cbPumps.setEnabled(self.NetworkName + "_Pumps.shp" in dirList
                                and not hasLayer)

        # Checked
        self.cbDemands.setChecked(utils.isLayerOpened("Demands"))
        self.cbSources.setChecked(utils.isLayerOpened("Sources"))
        self.cbIsolatedValves.setChecked(
            utils.isLayerOpened("IsolationValves"))
        self.cbHydrants.setChecked(utils.isLayerOpened("Hydrants"))
        self.cbPurgeValves.setChecked(utils.isLayerOpened("WashoutValves"))
        self.cbAirReleases.setChecked(utils.isLayerOpened("AirReleaseValves"))
        self.cbConnections.setChecked(
            utils.isLayerOpened("ServiceConnections"))
        self.cbMeters.setChecked(utils.isLayerOpened("Meters"))

    def selectCRS(self):
        projSelector = QgsGenericProjectionSelector()
        if projSelector.exec_():
            crsId = projSelector.crs().srsid()
            if not crsId == 0:
                self.crs = QgsCoordinateReferenceSystem()
                self.crs.createFromId(
                    crsId, QgsCoordinateReferenceSystem.InternalCrsId)
                self.tbCRS.setText(self.crs.description())

    def getLayerPath(self, layer):
        return QGISRedUtils().getLayerPath(layer)

    def generatePath(self, folder, fileName):
        return QGISRedUtils().generatePath(folder, fileName)

    def getLayers(self):
        return QGISRedUtils().getLayers()

    def isInLegend(self, layerName):
        openedLayers = self.getLayers()
        for layer in openedLayers:
            layerPath = self.generatePath(
                self.ProjectDirectory,
                self.NetworkName + "_" + layerName + ".shp")
            if self.getLayerPath(layer) == layerPath:
                return True
        return False

    def createElementsList(self):
        if self.cbPipes.isChecked():
            self.layers.append("Pipes")
        if self.cbJunctions.isChecked():
            self.layers.append("Junctions")
        if self.cbTanks.isChecked():
            self.layers.append("Tanks")
        if self.cbReservoirs.isChecked():
            self.layers.append("Reservoirs")
        if self.cbValves.isChecked():
            self.layers.append("Valves")
        if self.cbPumps.isChecked():
            self.layers.append("Pumps")

    def createComplementaryList(self):
        if self.cbDemands.isChecked():
            self.layers.append("Demands")
        if self.cbSources.isChecked():
            self.layers.append("Sources")

        if self.cbIsolatedValves.isChecked():
            self.layers.append("Isolation Valves")
        if self.cbHydrants.isChecked():
            self.layers.append("Hydrants")
        if self.cbPurgeValves.isChecked():
            self.layers.append("Washout Valves")
        if self.cbAirReleases.isChecked():
            self.layers.append("AirRelease Valves")
        if self.cbConnections.isChecked():
            self.layers.append("Service Connections")
        if self.cbMeters.isChecked():
            self.layers.append("Meters")

    def createElement(self, layerName, complementary=False):
        layer = "" if complementary else layerName
        complLayer = layerName if complementary else ""
        # Process
        QApplication.setOverrideCursor(Qt.WaitCursor)
        resMessage = GISRed.CreateLayer(self.ProjectDirectory,
                                        self.NetworkName, layer, complLayer)
        QApplication.restoreOverrideCursor()

        if resMessage == "True":
            self.parent.openElementLayer(layerName)
        elif resMessage == "False":
            self.iface.messageBar().pushMessage(
                "Warning",
                "Some issues occurred in the process",
                level=1,
                duration=5)
        else:
            self.iface.messageBar().pushMessage("Error",
                                                resMessage,
                                                level=2,
                                                duration=5)
        self.close()

    def accept(self):
        self.layers = []
        self.createElementsList()
        self.createComplementaryList()
        epsg = None
        if not self.crs.srsid() == self.originalCrs.srsid():
            epsg = self.crs.authid().replace("EPSG:", "")
        self.parent.openRemoveSpecificLayers(self.layers, epsg)
        self.close()
class SurvexImport:
    """QGIS Plugin Implementation."""

    # The following are some dictionaries for flags in the .3d file

    station_attr = {
        0x01: 'SURFACE',
        0x02: 'UNDERGROUND',
        0x04: 'ENTRANCE',
        0x08: 'EXPORTED',
        0x10: 'FIXED',
        0x20: 'ANON'
    }

    leg_attr = {0x01: 'SURFACE', 0x02: 'DUPLICATE', 0x04: 'SPLAY'}

    style_type = {
        0x00: 'NORMAL',
        0x01: 'DIVING',
        0x02: 'CARTESIAN',
        0x03: 'CYLPOLAR',
        0x04: 'NOSURVEY',
        0xff: 'NOSTYLE'
    }

    # lists of keys of above, sorted to restore ordering

    station_flags = sorted(station_attr.keys())
    leg_flags = sorted(leg_attr.keys())

    # field names if there is error data

    error_fields = ('ERROR_VERT', 'ERROR_HORIZ', 'ERROR', 'LENGTH')

    # main data structures

    leg_list = []  # accumulates legs + metadata
    station_list = []  # ditto stations
    xsect_list = []  # ditto for cross sections for walls

    station_xyz = {}  # map station names to xyz coordinates

    crs = None  # used to set layer CRS in memory provider
    crs_source = None  # records the origin of the CRS
    title = ''  # used to set layer title in memory provider

    path_3d = ''  # to remember the path to the survex .3d file
    path_gpkg = ''  # ditto for path to save GeoPackage (.gpkg)

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'SurvexImport_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Import .3d file')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('SurvexImport', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToVectorMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/survex_import/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'.3d import'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginVectorMenu(self.tr(u'&Import .3d file'),
                                              action)
            self.iface.removeToolBarIcon(action)

    def crs_from_file(self):
        """Enforce consistent CRS selector state"""
        if self.dlg.CRSFromFile.isChecked():
            self.dlg.CRSFromProject.setChecked(False)

    def crs_from_project(self):
        """Enforce consistent CRS selector state"""
        if self.dlg.CRSFromProject.isChecked():
            self.dlg.CRSFromFile.setChecked(False)

    def select_3d_file(self):
        """Select 3d file"""
        file_3d, _filter_3d = QFileDialog.getOpenFileName(
            self.dlg, "Select .3d file ", self.path_3d, '*.3d')
        self.dlg.selectedFile.setText(file_3d)
        self.path_3d = QFileInfo(file_3d).path()  # memorise path selection

    def select_gpkg(self):
        """Select GeoPackage (.gpkg)"""
        file_gpkg, _filter_gpkg = QFileDialog.getSaveFileName(
            self.dlg, "Enter or select existing .gpkg file ", self.path_gpkg,
            '*.gpkg')
        self.dlg.selectedGPKG.setText(file_gpkg)
        self.path_gpkg = QFileInfo(file_gpkg).path()  # memorise path selection

    def set_crs(self, s):
        """Figure out the CRS for layer creation, from the selected options and/or string"""
        if self.dlg.CRSFromProject.isChecked():
            self.crs_source = 'from project'
            self.crs = QgsProject.instance().crs()
        elif self.dlg.CRSFromFile.isChecked() and s:
            self.crs_source = 'from .3d file'
            self.crs = QgsCoordinateReferenceSystem()
            match = search('epsg:([0-9]*)', s)  # check for epsg in proj string
            if match:  # if found, use the EPSG number explicitly
                self.crs.createFromString('EPSG:{}'.format(int(
                    match.group(1))))
            else:  # fall back to proj4
                self.crs.createFromProj4(s)
        else:  # fall back to raising a CRS selection dialog
            self.crs_source = 'from dialog'
            dialog = QgsProjectionSelectionDialog()
            dialog.setMessage('define the CRS for the imported layers')
            dialog.exec()  # run the dialog ..
            self.crs = dialog.crs()  # .. and recover the user input
        if self.crs.isValid():
            msg = 'CRS {} : {}'.format(self.crs_source, self.crs.authid())
            QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info)
            QgsMessageLog.logMessage(self.crs.description(),
                                     tag='Import .3d',
                                     level=Qgis.Info)
        else:  # hopefully never happens
            msg = "CRS invalid!"
            QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info)
            self.crs = None

    def all_checked(self):
        """ ensures the import all check box is consistent"""
        check = self.dlg.Legs.isChecked()
        check = check and self.dlg.Stations.isChecked()
        check = check and self.dlg.Polygons.isChecked()
        check = check and self.dlg.Walls.isChecked()
        check = check and self.dlg.XSections.isChecked()
        check = check and self.dlg.Traverses.isChecked()
        check = check and self.dlg.LegsSurface.isChecked()
        check = check and self.dlg.LegsSplay.isChecked()
        check = check and self.dlg.LegsDuplicate.isChecked()
        check = check and self.dlg.StationsSurface.isChecked()
        self.dlg.ImportAll.setChecked(check)

    def toggle_import_all(self):
        """toggle import all possible data"""
        checked = self.dlg.ImportAll.isChecked()
        self.dlg.Legs.setChecked(checked)
        self.dlg.Stations.setChecked(checked)
        self.dlg.Polygons.setChecked(checked)
        self.dlg.Walls.setChecked(checked)
        self.dlg.XSections.setChecked(checked)
        self.dlg.Traverses.setChecked(checked)
        self.dlg.LegsSurface.setChecked(checked)
        self.dlg.LegsSplay.setChecked(checked)
        self.dlg.LegsDuplicate.setChecked(checked)
        self.dlg.StationsSurface.setChecked(checked)

    def add_layer(self, subtitle, geom):
        """Add a memory layer with title(subtitle) and geom"""
        name = '%s(%s)' % (self.title, subtitle) if self.title else subtitle
        layer = QgsVectorLayer(geom, name, 'memory')
        if self.crs:  # this should have been set by now
            layer.setCrs(self.crs)
        if not layer.isValid():
            raise Exception("Invalid layer with %s" % geom)
        msg = "Memory layer '%s' called '%s' added" % (geom, name)
        QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info)
        return layer

# The next three routines are to do with reading .3d binary file format

    def read_xyz(self, fp):
        """Read xyz as integers, according to .3d spec"""
        return unpack('<iii', fp.read(12))

    def read_len(self, fp):
        """Read a number as a length according to .3d spec"""
        byte = ord(fp.read(1))
        if byte != 0xff:
            return byte
        else:
            return unpack('<I', fp.read(4))[0]

    def read_label(self, fp, current_label):
        """Read a string as a label, or part thereof, according to .3d spec"""
        byte = ord(fp.read(1))
        if byte != 0x00:
            ndel = byte >> 4
            nadd = byte & 0x0f
        else:
            ndel = self.read_len(fp)
            nadd = self.read_len(fp)
        oldlen = len(current_label)
        return current_label[:oldlen - ndel] + fp.read(nadd).decode('ascii')

    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started

        if self.first_start == True:
            self.first_start = False
            self.dlg = SurvexImportDialog()
            self.dlg.selectedFile.clear()
            self.dlg.fileSelector.clicked.connect(self.select_3d_file)
            self.dlg.selectedGPKG.clear()
            self.dlg.GPKGSelector.clicked.connect(self.select_gpkg)
            self.dlg.CRSFromProject.setChecked(False)
            self.dlg.CRSFromFile.clicked.connect(self.crs_from_file)
            self.dlg.CRSFromFile.setChecked(False)
            self.dlg.CRSFromProject.clicked.connect(self.crs_from_project)
            self.dlg.ImportAll.clicked.connect(self.toggle_import_all)
            self.dlg.Legs.clicked.connect(self.all_checked)
            self.dlg.Stations.clicked.connect(self.all_checked)
            self.dlg.Polygons.clicked.connect(self.all_checked)
            self.dlg.Walls.clicked.connect(self.all_checked)
            self.dlg.XSections.clicked.connect(self.all_checked)
            self.dlg.Traverses.clicked.connect(self.all_checked)
            self.dlg.LegsSurface.clicked.connect(self.all_checked)
            self.dlg.LegsSplay.clicked.connect(self.all_checked)
            self.dlg.LegsDuplicate.clicked.connect(self.all_checked)
            self.dlg.StationsSurface.clicked.connect(self.all_checked)

        self.dlg.show()  # show the dialog

        result = self.dlg.exec_()  # Run the dialog event loop

        if result:  # The user pressed OK, and this is what happened next!

            survex_3d = self.dlg.selectedFile.text()
            gpkg_file = self.dlg.selectedGPKG.text()

            include_legs = self.dlg.Legs.isChecked()
            include_stations = self.dlg.Stations.isChecked()
            include_polygons = self.dlg.Polygons.isChecked()
            include_walls = self.dlg.Walls.isChecked()
            include_xsections = self.dlg.XSections.isChecked()
            include_traverses = self.dlg.Traverses.isChecked()

            exclude_surface_legs = not self.dlg.LegsSurface.isChecked()
            exclude_splay_legs = not self.dlg.LegsSplay.isChecked()
            exclude_duplicate_legs = not self.dlg.LegsDuplicate.isChecked()

            exclude_surface_stations = not self.dlg.StationsSurface.isChecked()

            use_clino_wgt = self.dlg.UseClinoWeights.isChecked()
            include_up_down = self.dlg.IncludeUpDown.isChecked()

            discard_features = not self.dlg.KeepFeatures.isChecked()

            if not os.path.exists(survex_3d):
                raise Exception("File '%s' doesn't exist" % survex_3d)

            if discard_features:
                self.leg_list = []
                self.station_list = []
                self.station_xyz = {}
                self.xsect_list = []

            # Read .3d file as binary, parse, and save data structures

            with open(survex_3d, 'rb') as fp:

                line = fp.readline().rstrip()  # File ID check

                if not line.startswith(b'Survex 3D Image File'):
                    raise IOError('Not a survex .3d file: ' + survex_3d)

                line = fp.readline().rstrip()  # File format version

                if not line.startswith(b'v'):
                    raise IOError('Unrecognised survex .3d version in ' +
                                  survex_3d)

                version = int(line[1:])
                if version < 8:
                    raise IOError('Survex .3d version >= 8 required in ' +
                                  survex_3d)

                line = fp.readline().rstrip(
                )  # Metadata (title and coordinate system)
                fields = line.split(b'\x00')

                previous_title = '' if discard_features else self.title

                if previous_title:
                    self.title = previous_title + ' + ' + fields[0].decode(
                        'ascii')
                else:
                    self.title = fields[0].decode('ascii')

                self.set_crs(
                    fields[1].decode('ascii') if len(fields) > 1 else None)

                line = fp.readline().rstrip(
                )  # Timestamp, unused in present application

                if not line.startswith(b'@'):
                    raise IOError('Unrecognised timestamp in ' + survex_3d)

                # timestamp = int(line[1:])

                flag = ord(fp.read(1))  # file-wide flag

                if flag & 0x80:  # abort if extended elevation
                    raise IOError("Can't deal with extended elevation in " +
                                  survex_3d)

                # All file-wide header data read in, now read byte-wise
                # according to .3d spec.  Note that all elements must
                # be processed, in order, otherwise we get out of sync.

                # We first define some baseline dates

                date0 = QDate(1900, 1, 1)
                date1 = QDate(1900, 1, 1)
                date2 = QDate(1900, 1, 1)

                label, style = '', 0xff  # initialise label and style

                legs = []  # will be used to capture leg data between MOVEs
                xsect = []  # will be used to capture XSECT data
                nlehv = None  # .. remains None if there isn't any error data...

                while True:  # start of byte-gobbling while loop

                    char = fp.read(1)

                    if not char:  # End of file (reached prematurely?)
                        raise IOError('Premature end of file in ' + survex_3d)

                    byte = ord(char)

                    if byte <= 0x05:  # STYLE
                        if byte == 0x00 and style == 0x00:  # this signals end of data
                            if legs:  # there may be a pending list of legs to save
                                self.leg_list.append((legs, nlehv))
                            break  # escape from byte-gobbling while loop
                        else:
                            style = byte

                    elif byte <= 0x0e:  # Reserved
                        continue

                    elif byte == 0x0f:  # MOVE
                        xyz = self.read_xyz(fp)
                        if legs:
                            self.leg_list.append((legs, nlehv))
                            legs = []

                    elif byte == 0x10:  # DATE (none)
                        date1 = date2 = date0

                    elif byte == 0x11:  # DATE (single date)
                        days = unpack('<H', fp.read(2))[0]
                        date1 = date2 = date0.addDays(days)

                    elif byte == 0x12:  # DATE (date range, short format)
                        days, extra = unpack('<HB', fp.read(3))
                        date1 = date0.addDays(days)
                        date2 = date0.addDays(days + extra + 1)

                    elif byte == 0x13:  # DATE (date range, long format)
                        days1, days2 = unpack('<HH', fp.read(4))
                        date1 = date0.addDays(days1)
                        date2 = date0.addDays(days2)

                    elif byte <= 0x1e:  # Reserved
                        continue

                    elif byte == 0x1f:  # Error info
                        nlehv = unpack('<iiiii', fp.read(20))

                    elif byte <= 0x2f:  # Reserved
                        continue

                    elif byte <= 0x33:  # XSECT
                        label = self.read_label(fp, label)
                        if byte & 0x02:
                            lrud = unpack('<iiii', fp.read(16))
                        else:
                            lrud = unpack('<hhhh', fp.read(8))
                        xsect.append((label, lrud))
                        if byte & 0x01:  # XSECT_END
                            self.xsect_list.append(xsect)
                            xsect = []

                    elif byte <= 0x3f:  # Reserved
                        continue

                    elif byte <= 0x7f:  # LINE
                        flag = byte & 0x3f
                        if not (flag & 0x20):
                            label = self.read_label(fp, label)
                        xyz_prev = xyz
                        xyz = self.read_xyz(fp)
                        while (True):  # code pattern to implement logic
                            if exclude_surface_legs and flag & 0x01: break
                            if exclude_duplicate_legs and flag & 0x02: break
                            if exclude_splay_legs and flag & 0x04: break
                            legs.append(((xyz_prev, xyz), label, style, date1,
                                         date2, flag))
                            break

                    elif byte <= 0xff:  # LABEL (or NODE)
                        flag = byte & 0x7f
                        label = self.read_label(fp, label)
                        xyz = self.read_xyz(fp)
                        while (True):  # code pattern to implement logic
                            if exclude_surface_stations and flag & 0x01 and not flag & 0x02:
                                break
                            self.station_list.append((xyz, label, flag))
                            break
                        self.station_xyz[label] = xyz

                # End of byte-gobbling while loop

            # file closes automatically, with open(survex_3d, 'rb') as fp:

            layers = []  # used to keep a list of the created layers

            if include_stations and self.station_list:  # station layer

                station_layer = self.add_layer('stations', 'PointZ')

                attrs = [
                    QgsField(self.station_attr[k], QVariant.Int)
                    for k in self.station_flags
                ]
                attrs.insert(0, QgsField('ELEVATION', QVariant.Double))
                attrs.insert(0, QgsField('NAME', QVariant.String))
                station_layer.dataProvider().addAttributes(attrs)
                station_layer.updateFields()

                features = []

                for (xyz, label, flag) in self.station_list:
                    xyz = [0.01 * v for v in xyz]
                    attrs = [1 if flag & k else 0 for k in self.station_flags]
                    attrs.insert(0, round(xyz[2], 2))  # elevation
                    attrs.insert(0, label)
                    feat = QgsFeature()
                    geom = QgsGeometry(QgsPoint(*xyz))
                    feat.setGeometry(geom)
                    feat.setAttributes(attrs)
                    features.append(feat)

                station_layer.dataProvider().addFeatures(features)
                layers.append(station_layer)

            if include_legs and self.leg_list:  # leg layer

                leg_layer = self.add_layer('legs', 'LineStringZ')

                attrs = [
                    QgsField(self.leg_attr[k], QVariant.Int)
                    for k in self.leg_flags
                ]
                if nlehv:
                    [
                        attrs.insert(0, QgsField(s, QVariant.Double))
                        for s in self.error_fields
                    ]
                    attrs.insert(0, QgsField('NLEGS', QVariant.Int))
                attrs.insert(0, QgsField('DATE2', QVariant.Date))
                attrs.insert(0, QgsField('DATE1', QVariant.Date))
                attrs.insert(0, QgsField('STYLE', QVariant.String))
                attrs.insert(0, QgsField('ELEVATION', QVariant.Double))
                attrs.insert(0, QgsField('NAME', QVariant.String))
                leg_layer.dataProvider().addAttributes(attrs)
                leg_layer.updateFields()

                features = []

                for legs, nlehv in self.leg_list:
                    for (xyz_pair, label, style, from_date, to_date,
                         flag) in legs:
                        elev = 0.5 * sum([0.01 * xyz[2] for xyz in xyz_pair])
                        points = []
                        for xyz in xyz_pair:
                            xyz = [0.01 * v for v in xyz]
                            points.append(QgsPoint(*xyz))
                        attrs = [1 if flag & k else 0 for k in self.leg_flags]
                        if nlehv:
                            [
                                attrs.insert(0, 0.01 * v)
                                for v in reversed(nlehv[1:5])
                            ]
                            attrs.insert(0, nlehv[0])
                        attrs.insert(0, to_date)
                        attrs.insert(0, from_date)
                        attrs.insert(0, self.style_type[style])
                        attrs.insert(0, round(elev, 2))
                        attrs.insert(0, label)
                        linestring = QgsLineString()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        features.append(feat)

                leg_layer.dataProvider().addFeatures(features)
                layers.append(leg_layer)

            # Now do wall features if asked

            if (include_traverses or include_xsections or include_walls
                    or include_polygons) and self.xsect_list:

                trav_features = []
                wall_features = []
                xsect_features = []
                quad_features = []

                for xsect in self.xsect_list:

                    if len(xsect) < 2:  # if there's only one station ..
                        continue  # .. give up as we don't know which way to face

                    centerline = [
                    ]  # will contain the station position and LRUD data

                    for label, lrud in xsect:
                        xyz = self.station_xyz[
                            label]  # look up coordinates from label
                        lrud_or_zero = tuple([max(0, v) for v in lrud
                                              ])  # deal with missing data
                        centerline.append(
                            xyz + lrud_or_zero)  # and collect as 7-uple

                    direction = [
                    ]  # will contain the corresponding direction vectors

                    # The calculations below use integers for xyz and lrud, and
                    # conversion to metres is left to the end.  Then dh2 is an
                    # integer and the test for a plumb is safely dh2 = 0.

                    # The directions are unit vectors optionally weighted by
                    # cos(inclination) = dh/dl where dh^2 = dx^2 + dy^2 (note, no dz^2),
                    # and dl^2 = dh^2 + dz^2.  The normalisation is correspondingly
                    # either 1/dh, or 1/dh * dh/dl = 1/dl.

                    for i, xyzlrud in enumerate(centerline):
                        x, y, z = xyzlrud[0:3]
                        if i > 0:
                            dx, dy, dz = x - xp, y - yp, z - zp
                            dh2 = dx * dx + dy * dy  # integer horizontal displacement (mm^2)
                            norm = sqrt(dh2 + dz *
                                        dz) if use_clino_wgt else sqrt(dh2)
                            dx, dy = (dx / norm, dy /
                                      norm) if dh2 > 0 and norm > 0 else (0, 0)
                            direction.append((dx, dy))
                        xp, yp, zp = x, y, z

                    left_wall = []
                    right_wall = []
                    up_down = []

                    # We build the walls by walking through the list
                    # of stations and directions, with simple defaults
                    # for the start and end stations

                    for i, (x, y, z, l, r, u, d) in enumerate(centerline):
                        d1x, d1y = direction[i - 1] if i > 0 else (0, 0)
                        d2x, d2y = direction[i] if i + 1 < len(
                            centerline) else (0, 0)
                        dx, dy = d1x + d2x, d1y + d2y  # mean (sum of) direction vectors
                        norm = sqrt(dx * dx +
                                    dy * dy)  # normalise to unit vector
                        ex, ey = (dx / norm, dy / norm) if norm > 0 else (0, 0)
                        # Convert to metres when saving the points
                        left_wall.append((0.01 * (x - l * ey),
                                          0.01 * (y + l * ex), 0.01 * z))
                        right_wall.append((0.01 * (x + r * ey),
                                           0.01 * (y - r * ex), 0.01 * z))
                        up_down.append((0.01 * u, 0.01 * d))

                    # Mean elevation of centerline, used for elevation attribute

                    elev = 0.01 * sum([xyzlrud[2] for xyzlrud in centerline
                                       ]) / len(centerline)
                    attrs = [round(elev, 2)]

                    # Now create the feature sets - first the centerline traverse

                    points = []

                    for xyzlrud in centerline:
                        xyz = [0.01 * v for v in xyzlrud[0:3]
                               ]  # These were mm, convert to metres
                        points.append(QgsPoint(*xyz))

                    linestring = QgsLineString()
                    linestring.setPoints(points)
                    feat = QgsFeature()
                    geom = QgsGeometry(linestring)
                    feat.setGeometry(geom)
                    feat.setAttributes(attrs)
                    trav_features.append(feat)

                    # The walls as line strings

                    for wall in (left_wall, right_wall):

                        points = [QgsPoint(*xyz) for xyz in wall]
                        linestring = QgsLineString()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        wall_features.append(feat)

                    # Slightly more elaborate, pair up points on left
                    # and right walls, and build a cross section as a
                    # 2-point line string, and a quadrilateral polygon
                    # with a closed 5-point line string for the
                    # exterior ring.  Note that QGIS polygons are
                    # supposed to have their points ordered clockwise.

                    for i, xyz_pair in enumerate(zip(left_wall, right_wall)):

                        elev = 0.01 * centerline[i][
                            2]  # elevation of station in centerline
                        attrs = [round(elev, 2)]
                        points = [QgsPoint(*xyz) for xyz in xyz_pair]
                        linestring = QgsLineString()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        xsect_features.append(feat)

                        if i > 0:
                            elev = 0.5 * (prev_xyz_pair[0][2] + xyz_pair[0][2]
                                          )  # average elevation
                            attrs = [round(elev, 2)]
                            if include_up_down:  # average up / down
                                attrs += [
                                    0.5 * (v1 + v2)
                                    for (v1,
                                         v2) in zip(up_down[i - 1], up_down[i])
                                ]
                            points = [
                            ]  # will contain the exterior 5-point ring, as follows...
                            for xyz in tuple(
                                    reversed(prev_xyz_pair)) + xyz_pair + (
                                        prev_xyz_pair[1], ):
                                points.append(QgsPoint(*xyz))
                            linestring = QgsLineString()
                            linestring.setPoints(points)
                            polygon = QgsPolygon()
                            polygon.setExteriorRing(linestring)
                            feat = QgsFeature()
                            geom = QgsGeometry(polygon)
                            feat.setGeometry(geom)
                            feat.setAttributes(attrs)
                            quad_features.append(feat)

                        prev_xyz_pair = xyz_pair

                # End of processing xsect_list - now add features to requested layers

                attrs = [QgsField('ELEVATION',
                                  QVariant.Double)]  # common to all

                if include_traverses and trav_features:  # traverse layer
                    travs_layer = self.add_layer('traverses', 'LineStringZ')
                    travs_layer.dataProvider().addAttributes(attrs)
                    travs_layer.updateFields()
                    travs_layer.dataProvider().addFeatures(trav_features)
                    layers.append(travs_layer)

                if include_xsections and xsect_features:  # xsection layer
                    xsects_layer = self.add_layer('xsections', 'LineStringZ')
                    xsects_layer.dataProvider().addAttributes(attrs)
                    xsects_layer.updateFields()
                    xsects_layer.dataProvider().addFeatures(xsect_features)
                    layers.append(xsects_layer)

                if include_walls and wall_features:  # wall layer
                    walls_layer = self.add_layer('walls', 'LineStringZ')
                    walls_layer.dataProvider().addAttributes(attrs)
                    walls_layer.updateFields()
                    walls_layer.dataProvider().addFeatures(wall_features)
                    layers.append(walls_layer)

                if include_up_down:  # add fields if requested for polygons
                    attrs += [
                        QgsField(s, QVariant.Double)
                        for s in ('MEAN_UP', 'MEAN_DOWN')
                    ]

                if include_polygons and quad_features:  # polygon layer
                    quads_layer = self.add_layer('polygons', 'PolygonZ')
                    quads_layer.dataProvider().addAttributes(attrs)
                    quads_layer.updateFields()
                    quads_layer.dataProvider().addFeatures(quad_features)
                    layers.append(quads_layer)

            # All layers have been created, now update extents and add to QGIS registry

            if layers:
                [layer.updateExtents() for layer in layers]
                QgsProject.instance().addMapLayers(layers)

            # Write to GeoPackage if requested

            if gpkg_file:
                opts = [
                    QgsVectorFileWriter.CreateOrOverwriteFile,
                    QgsVectorFileWriter.CreateOrOverwriteLayer
                ]
                for i, layer in enumerate(layers):
                    options = QgsVectorFileWriter.SaveVectorOptions()
                    options.actionOnExistingFile = opts[int(
                        i > 0)]  # create file or layer
                    layer_name = layer.name()
                    match = search(
                        ' - ([a-z]*)',
                        layer_name)  # ie, extract 'legs', 'stations', etc
                    options.layerName = str(
                        match.group(1)) if match else layer_name
                    writer = QgsVectorFileWriter.writeAsVectorFormat(
                        layer, gpkg_file, options)
                    if writer:
                        msg = "'{}' -> {} in {}".format(
                            layer_name, options.layerName, gpkg_file)
                        QgsMessageLog.logMessage(msg,
                                                 tag='Import .3d',
                                                 level=Qgis.Info)
                    options, writer = None, None
예제 #21
0
def build_layer_table(layer_list=None, only_raster_boundingbox=True):
    """Build a table of layer properties.
    Can be used in conjunction with selecting layers to exclude from mapcomboboxes

    Layer_list: default  None
                if None then it will build the table from all layers in the QGIS project
                otherwise it will use the list.
    
    only_raster_boundingbox: default False 
                    create a bounding box from the raster data 
                   ie removing nodata from polygon. 
                   This will slow it down if large numbers of rasters are present.
    """

    dest_crs = QgsProject.instance().crs()

    gdf_layers = gpd.GeoDataFrame(columns=[
        'layer', 'layer_name', 'layer_id', 'layer_type', 'source', 'format',
        'epsg', 'crs_name', 'is_projected', 'extent', 'provider', 'geometry'
    ],
                                  geometry='geometry',
                                  crs=dest_crs.authid())  # pd.DataFrame()

    if layer_list is None or len(layer_list) == 0:
        layermap = QgsProject.instance().mapLayers().values()

    else:
        layermap = layer_list

    new_rows = []

    for layer in layermap:
        if layer.type() not in [
                QgsMapLayer.VectorLayer, QgsMapLayer.RasterLayer
        ]:
            continue

        if layer.providerType() not in ['ogr', 'gdal', 'delimitedtext']:
            continue

        if layer.type() == QgsMapLayer.VectorLayer:
            format = layer.dataProvider().storageType()
        else:
            format = None

        if layer.crs().isValid() and layer.crs().authid() == '':
            # Try and convert older style coordinates systems
            # were correctly definied in QGIS 2 as GDA94 / MGA zone 54
            # but get interpreted in QGIS 3 as  Unknown CRS: BOUNDCRS[SOURCECRS[PROJCRS["GDA94 / MGA zone 54",.....

            layer_crs = QgsCoordinateReferenceSystem()
            if not layer_crs.createFromProj(layer.crs().toWkt()):
                #print('Could not match a coordinate system for {}'.format(layer.id()))
                layer_crs = layer.crs()

                # could apply to the layer, but what if it's wrong....
                #layer.setCrs(layer_crs)

        else:
            layer_crs = layer.crs()

        # project the bounding box extents to be the same as the qgis project.
        if layer_crs.authid() != dest_crs.authid():
            transform = QgsCoordinateTransform(layer_crs, dest_crs,
                                               QgsProject.instance())
            prj_ext = transform.transformBoundingBox(layer.extent())
        else:
            prj_ext = layer.extent()

        row_dict = {
            'layer': layer,
            'layer_name': layer.name(),
            'layer_id': layer.id(),
            'layer_type': layerTypes[layer.type()],
            'format': format,
            'source': get_layer_source(layer),
            'epsg': layer_crs.authid(),
            'crs_name': layer_crs.description(),
            'is_projected': not layer_crs.isGeographic(),
            'provider': layer.providerType(),
            'geometry': wkt.loads(prj_ext.asWktPolygon())
        }

        # 'extent': prj_ext.asWktPolygon(),

        if layer.type() == QgsMapLayer.RasterLayer:
            pixel_size = get_pixel_size(layer)
            if not only_raster_boundingbox:
                with rasterio.open(get_layer_source(layer)) as src:
                    msk = src.dataset_mask()  # 0 = nodata 255=valid
                    rast_shapes = rasterio.features.shapes(
                        np.ma.masked_equal(np.where(msk > 0, 1, 0), 0),
                        transform=src.transform)
                try:
                    results = ({
                        'properties': {
                            'raster_val': v
                        },
                        'geometry': s
                    } for i, (s, v) in enumerate(rast_shapes))

                    geoms = list(results)
                    gpd_rPoly = gpd.GeoDataFrame.from_features(
                        geoms, crs=layer.crs().authid())
                    dest_crs.authid().replace('epgs:', '')
                    gpd_rPoly.to_crs(dest_crs.authid().replace('epgs:', ''),
                                     inplace=True)
                    row_dict.update({'geometry': gpd_rPoly.unary_union})

                    del gpd_rPoly, results, msk, rast_shapes
                except:
                    pass

            row_dict.update({
                'bandcount':
                layer.bandCount(),
                'datatype':
                dataTypes[layer.dataProvider().dataType(1)],
                'pixel_size':
                pixel_size[0],
                'pixel_text':
                '{} {}'.format(*pixel_size),
            })

        new_rows.append(row_dict)


#    gdf_layers = gpd.GeoDataFrame(new_rows, geometry='extent')

    if len(new_rows) == 0:
        return gdf_layers

    # for pandas 0.23.4 add sort=False to prevent row and column orders to change.
    try:
        gdf_layers = gdf_layers.append(new_rows, ignore_index=True, sort=False)
    except:
        gdf_layers = gdf_layers.append(new_rows, ignore_index=True)

    #df_layers.set_geometry('geometry')
    return gdf_layers
class ResampleImageToBlockDialog(QtGui.QDialog, FORM_CLASS):
    """Extract statistics from a list of rasters at set locations."""
    toolKey = 'ResampleImageBandDialog'

    def __init__(self, iface, parent=None):

        super(ResampleImageToBlockDialog, self).__init__(parent)

        # Set up the user interface from Designer.
        self.setupUi(self)

        self.iface = iface
        self.DISP_TEMP_LAYERS = read_setting(PLUGIN_NAME + '/DISP_TEMP_LAYERS',
                                             bool)
        self.DEBUG = config.get_debug_mode()

        # Catch and redirect python errors directed at the log messages python error tab.
        QgsMessageLog.instance().messageReceived.connect(errorCatcher)

        if not os.path.exists(TEMPDIR):
            os.mkdir(TEMPDIR)

        # Setup for validation messagebar on gui-----------------------------
        self.messageBar = QgsMessageBar(
            self)  # leave this message bar for bailouts
        self.validationLayout = QtGui.QFormLayout(self)  # new layout to gui

        if isinstance(self.layout(), (QtGui.QFormLayout, QtGui.QGridLayout)):
            # create a validation layout so multiple messages can be added and cleaned up.
            self.layout().insertRow(0, self.validationLayout)
            self.layout().insertRow(0, self.messageBar)
        else:
            self.layout().insertWidget(
                0,
                self.messageBar)  # for use with Vertical/horizontal layout box

        self.outQgsCRS = None

        self.exclude_map_layers()
        self.updateRaster()
        self.updateUseSelected()
        self.autoSetCoordinateSystem()

        # GUI Runtime Customisation -----------------------------------------------
        self.setWindowIcon(
            QtGui.QIcon(':/plugins/pat/icons/icon_resampleToBlock.svg'))
        self.chkAddToDisplay.setChecked(False)
        self.add_blank_field_to_cbo()
        # self.chkAddToDisplay.hide()

    def cleanMessageBars(self, AllBars=True):
        """Clean Messages from the validation layout.
        Args:
            AllBars (bool): Remove All bars including those which haven't timed-out. Defaults to True
        """
        layout = self.validationLayout
        for i in reversed(range(layout.count())):
            # when it timed out the row becomes empty....
            if layout.itemAt(i).isEmpty():
                # .removeItem doesn't always work. so takeAt(pop) it instead
                item = layout.takeAt(i)
            elif AllBars:  # ie remove all
                item = layout.takeAt(i)
                # also have to remove any widgets associated with it.
                if item.widget() is not None:
                    item.widget().deleteLater()

    def send_to_messagebar(self,
                           message,
                           title='',
                           level=QgsMessageBar.INFO,
                           duration=5,
                           exc_info=None,
                           core_QGIS=False,
                           addToLog=False,
                           showLogPanel=False):
        """ Add a message to the forms message bar.

        Args:
            message (str): Message to display
            title (str): Title of message. Will appear in bold. Defaults to ''
            level (QgsMessageBarLevel): The level of message to log. Defaults to QgsMessageBar.INFO
            duration (int): Number of seconds to display message for. 0 is no timeout. Defaults to 5
            core_QGIS (bool): Add to QGIS interface rather than the dialog
            addToLog (bool): Also add message to Log. Defaults to False
            showLogPanel (bool): Display the log panel
            exc_info () : Information to be used as a traceback if required

        """

        if core_QGIS:
            newMessageBar = self.iface.messageBar()
        else:
            newMessageBar = QgsMessageBar(self)

        widget = newMessageBar.createMessage(title, message)

        if showLogPanel:
            button = QPushButton(widget)
            button.setText('View')
            button.setContentsMargins(0, 0, 0, 0)
            button.setFixedWidth(35)
            button.pressed.connect(openLogPanel)
            widget.layout().addWidget(button)

        newMessageBar.pushWidget(widget, level, duration=duration)

        if not core_QGIS:
            rowCount = self.validationLayout.count()
            self.validationLayout.insertRow(rowCount + 1, newMessageBar)

        if addToLog:
            if level == 1:  # 'WARNING':
                LOGGER.warning(message)
            elif level == 2:  # 'CRITICAL':
                # Add a traceback to log only for bailouts only
                if exc_info is not None:
                    exc_type, exc_value, exc_traceback = sys.exc_info()
                    mess = str(traceback.format_exc())
                    message = message + '\n' + mess

                LOGGER.critical(message)
            else:  # INFO = 0
                LOGGER.info(message)

    def exclude_map_layers(self):
        """ Run through all loaded layers to find ones which should be excluded. In this case exclude services."""

        exVlayer_list = []
        exRlayer_list = []
        for layer in self.iface.legendInterface().layers():
            if layer.type() == QgsMapLayer.RasterLayer:
                if layer.providerType() != 'gdal':
                    exRlayer_list.append(layer)

            elif layer.type() == QgsMapLayer.VectorLayer:
                if layer.providerType() != 'ogr':
                    exVlayer_list.append(layer)

        self.mcboRasterLayer.setExceptedLayerList(exRlayer_list)
        if len(exRlayer_list) > 0:
            pass

        if len(exVlayer_list) > 0:
            self.mcboPolygonLayer.setExceptedLayerList(exVlayer_list)

    def updateRaster(self):
        if self.mcboRasterLayer.currentLayer() is None: return

        layer = self.mcboRasterLayer.currentLayer()
        provider = layer.dataProvider()

        if provider.srcHasNoDataValue(1):
            self.spnNoDataVal.setValue(provider.srcNoDataValue(1))
        elif len(provider.userNoDataValues(1)) > 0:
            self.spnNoDataVal.setValue(provider.userNoDataValues(1)[0].min())
        else:
            self.spnNoDataVal.setValue(0)

        # add a band list to the drop down box
        bandCount = self.mcboRasterLayer.currentLayer().bandCount()
        band_list = ['Band {: >2}'.format(i) for i in range(1, bandCount + 1)]
        self.cboBand.setMaxCount(bandCount + 1)
        self.cboBand.clear()
        self.cboBand.addItems([u''] + sorted(band_list))

    def updateUseSelected(self):
        """Update use selected checkbox if active layer has a feature selection"""

        self.chkUseSelected.setChecked(False)

        if self.mcboPolygonLayer.count() == 0:
            return

        polygon_lyr = self.mcboPolygonLayer.currentLayer()
        self.mFieldComboBox.setLayer(polygon_lyr)
        if len(polygon_lyr.selectedFeatures()) > 0:
            self.chkUseSelected.setText(
                'Use the {} selected feature(s) ?'.format(
                    len(polygon_lyr.selectedFeatures())))
            self.chkUseSelected.setEnabled(True)
        else:
            self.chkUseSelected.setText('No features selected')
            self.chkUseSelected.setEnabled(False)

    def autoSetCoordinateSystem(self):
        if self.mcboRasterLayer.count() == 0:
            return
        self.cleanMessageBars()
        raster_lyr = self.mcboRasterLayer.currentLayer()

        raster_utm_crs = crs.getProjectedCRSForXY(
            raster_lyr.extent().xMinimum(),
            raster_lyr.extent().yMinimum(),
            int(raster_lyr.crs().authid().replace('EPSG:', '')))
        self.outQgsCRS = None

        if raster_utm_crs is not None:
            raster_crs = QgsCoordinateReferenceSystem('EPSG:{}'.format(
                raster_utm_crs.epsg_number))
            self.outQgsCRS = raster_crs

        if self.outQgsCRS is not None:
            self.lblOutCRS.setText('{}  -  {}'.format(
                self.outQgsCRS.description(), self.outQgsCRS.authid()))
            self.lblOutCRSTitle.setStyleSheet('color:black')
            self.lblOutCRS.setStyleSheet('color:black')
        else:
            self.lblOutCRSTitle.setStyleSheet('color:red')
            self.lblOutCRS.setStyleSheet('color:red')
            self.lblOutCRS.setText('Unspecified')
            self.send_to_messagebar(
                'Auto detect coordinate system Failed. Check coordinate system of input raster layer',
                level=QgsMessageBar.CRITICAL,
                duration=5)
        return

    def add_blank_field_to_cbo(self, set=True):
        """ Add a blank string to the field combo box.  Fixed in qgis 3"""

        if self.mFieldComboBox.findText('', QtCore.Qt.MatchFixedString) == -1:
            self.mFieldComboBox.addItem(u'')
            if set == True:
                self.mFieldComboBox.setField(u'')

    def on_mcboRasterLayer_layerChanged(self):
        self.updateRaster()
        self.autoSetCoordinateSystem()

    def on_mcboPolygonLayer_layerChanged(self):
        self.updateUseSelected()
        self.autoSetCoordinateSystem()

        # ToDo: QGIS 3 implement QgsMapLayerComboBox.allowEmptyLayer() instead of chkUsePoly checkbox
        self.chkUsePoly.setChecked(True)

        self.add_blank_field_to_cbo()

    @QtCore.pyqtSlot(int)
    def on_chkUsePoly_stateChanged(self, state):
        self.add_blank_field_to_cbo()

        self.mFieldComboBox.setEnabled(state)
        self.lblGroupByField.setEnabled(state)

#     def on_mFieldComboBox_fieldChanged(self, field):
#         # Problem : after selecting a field, the blank is removed from the pick list.
#         # Solution: Add it again.... but this doesn't work.
#         if self.mFieldComboBox.findText('', QtCore.Qt.MatchFixedString) == -1:
#             # work around for not having a physical blank in the list. Fixed in qgis 3
#             self.mFieldComboBox.addItem(u'')

    def on_chkUseSelected_stateChanged(self, state):
        if self.chkUseSelected.isChecked():
            self.chkUsePoly.setChecked(True)

    @QtCore.pyqtSlot(name='on_cmdOutCRS_clicked')
    def on_cmdOutCRS_clicked(self):
        dlg = QgsGenericProjectionSelector(self)
        dlg.setMessage(self.tr('Select coordinate system'))
        if dlg.exec_():
            if dlg.selectedAuthId() != '':
                self.outQgsCRS = QgsCoordinateReferenceSystem(
                    dlg.selectedAuthId())

                if self.outQgsCRS.geographicFlag():
                    self.outQgsCRS = None
                    self.send_to_messagebar(unicode(
                        self.
                        tr("Geographic coordinate systems are not allowed. Resetting to default.."
                           )),
                                            level=QgsMessageBar.WARNING,
                                            duration=5)
            else:
                self.outQgsCRS = None

            if self.outQgsCRS is None:
                self.autoSetCoordinateSystem()

            self.lblOutCRSTitle.setStyleSheet('color:black')
            self.lblOutCRS.setStyleSheet('color:black')
            self.lblOutCRS.setText(
                self.tr('{}  -  {}'.format(self.outQgsCRS.description(),
                                           self.outQgsCRS.authid())))

    @QtCore.pyqtSlot(name='on_cmdOutputFolder_clicked')
    def on_cmdOutputFolder_clicked(self):
        self.messageBar.clearWidgets()
        if self.lneOutputFolder.text() is None:
            outFolder = ''
        else:
            outFolder = self.lneOutputFolder.text()

        if outFolder == '':
            outFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey +
                                     "/LastOutFolder")
            if outFolder is None or not os.path.exists(outFolder):
                outFolder = read_setting(PLUGIN_NAME + '/BASE_OUT_FOLDER')

        s = QtGui.QFileDialog.getExistingDirectory(
            self,
            self.
            tr("Save output files to a folder. A sub-folder will be created from the image name"
               ), outFolder, QtGui.QFileDialog.ShowDirsOnly)

        self.cleanMessageBars(self)
        if s == '' or s is None:
            return

        s = os.path.normpath(s)

        self.lblOutputFolder.setStyleSheet('color:black')
        self.lneOutputFolder.setStyleSheet('color:black')
        self.lneOutputFolder.setText(s)
        write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastOutFolder", s)

    def validate(self):
        """Check to see that all required gui elements have been entered and are valid."""
        self.messageBar.clearWidgets()
        self.cleanMessageBars(AllBars=True)
        try:
            errorList = []

            if self.mcboRasterLayer.currentLayer() is None:
                self.lblRasterLayer.setStyleSheet('color:red')
                errorList.append(self.tr("Input image layer required."))
            else:
                self.lblRasterLayer.setStyleSheet('color:black')

            if self.cboBand.currentText() == '':
                self.lblBand.setStyleSheet('color:red')
                errorList.append(self.tr("Input band selection required."))
            else:
                self.lblBand.setStyleSheet('color:black')

            if self.dsbPixelSize.value() <= 0:
                self.lblPixelSize.setStyleSheet('color:red')
                errorList.append(self.tr("Pixel size must be greater than 0."))
            else:
                self.lblPixelSize.setStyleSheet('color:black')

            if self.outQgsCRS is None:
                self.lblOutCRSTitle.setStyleSheet('color:red')
                self.lblOutCRS.setStyleSheet('color:red')
                errorList.append(
                    self.tr("Select output projected coordinate system"))
            else:
                if self.outQgsCRS.geographicFlag():
                    self.lblOutCRSTitle.setStyleSheet('color:red')
                    self.lblOutCRS.setStyleSheet('color:red')
                    errorList.append(
                        self.
                        tr("Output projected coordinate system (not geographic) required"
                           ))
                else:
                    self.lblOutCRSTitle.setStyleSheet('color:black')
                    self.lblOutCRS.setStyleSheet('color:black')

            if self.lneOutputFolder.text() == '':
                self.lblOutputFolder.setStyleSheet('color:red')
                errorList.append(self.tr("Select output data folder"))
            elif not os.path.exists(self.lneOutputFolder.text()):
                self.lneOutputFolder.setStyleSheet('color:red')
                self.lblOutputFolder.setStyleSheet('color:red')
                errorList.append(self.tr("Output data folder does not exist"))
            else:
                self.lblOutputFolder.setStyleSheet('color:black')
                self.lneOutputFolder.setStyleSheet('color:black')

            if len(errorList) > 0:
                raise ValueError(errorList)

        except ValueError as e:
            self.cleanMessageBars(True)
            if len(errorList) > 0:
                for i, ea in enumerate(errorList):
                    self.send_to_messagebar(unicode(ea),
                                            level=QgsMessageBar.WARNING,
                                            duration=(i + 1) * 5)
                return False

        return True

    def accept(self, *args, **kwargs):
        try:

            if not self.validate():
                return False

            # disable form via a frame, this will still allow interaction with the message bar
            self.fraMain.setDisabled(True)

            # clean gui and Qgis messagebars
            self.cleanMessageBars(True)

            # Change cursor to Wait cursor
            QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
            self.iface.mainWindow().statusBar().showMessage(
                'Processing {}'.format(self.windowTitle()))
            LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(),
                                                     st='*' * 50))

            self.send_to_messagebar(
                "Please wait.. QGIS will be locked... See log panel for progress.",
                level=QgsMessageBar.WARNING,
                duration=0,
                addToLog=False,
                core_QGIS=False,
                showLogPanel=True)

            # Add settings to log
            settingsStr = 'Parameters:---------------------------------------'
            settingsStr += '\n    {:20}\t{}'.format(
                'Image layer:',
                self.mcboRasterLayer.currentLayer().name())
            settingsStr += '\n    {:20}\t{}'.format('Image Band:',
                                                    self.cboBand.currentText())
            settingsStr += '\n    {:20}\t{}'.format('Image nodata value:',
                                                    self.spnNoDataVal.value())

            if self.chkUsePoly.isChecked():
                if self.chkUseSelected.isChecked():
                    settingsStr += '\n    {:20}\t{} with {} selected features'.format(
                        'Layer:',
                        self.mcboPolygonLayer.currentLayer().name(),
                        len(self.mcboPolygonLayer.currentLayer().
                            selectedFeatures()))
                else:
                    settingsStr += '\n    {:20}\t{}'.format(
                        'Boundary layer:',
                        self.mcboPolygonLayer.currentLayer().name())

                if self.mFieldComboBox.currentField():
                    settingsStr += '\n    {:20}\t{}'.format(
                        'Block ID field:', self.mFieldComboBox.currentField())
            else:
                settingsStr += '\n    {:20}\t{}'.format('Boundary layer:', '')
                settingsStr += '\n    {:20}\t{}'.format('Block ID field:', '')

            settingsStr += '\n    {:20}\t{}'.format('Resample pixel size: ',
                                                    self.dsbPixelSize.value())

            settingsStr += '\n    {:30}\t{}'.format(
                'Output Coordinate System:', self.lblOutCRS.text())
            settingsStr += '\n    {:30}\t{}\n'.format(
                'Output Folder:', self.lneOutputFolder.text())

            LOGGER.info(settingsStr)

            lyrRaster = self.mcboRasterLayer.currentLayer()

            if self.chkUsePoly.isChecked():
                lyrBoundary = self.mcboPolygonLayer.currentLayer()

                if self.chkUseSelected.isChecked():
                    savePlyName = lyrBoundary.name() + '_poly.shp'
                    filePoly = os.path.join(TEMPDIR, savePlyName)
                    if os.path.exists(filePoly): removeFileFromQGIS(filePoly)

                    QgsVectorFileWriter.writeAsVectorFormat(lyrBoundary,
                                                            filePoly,
                                                            "utf-8",
                                                            lyrBoundary.crs(),
                                                            "ESRI Shapefile",
                                                            onlySelected=True)

                    if self.DISP_TEMP_LAYERS:
                        addVectorFileToQGIS(filePoly,
                                            layer_name=os.path.splitext(
                                                os.path.basename(filePoly))[0],
                                            group_layer_name='DEBUG',
                                            atTop=True)
                else:
                    filePoly = lyrBoundary.source()

            band_num = [int(self.cboBand.currentText().replace('Band ', ''))]
            files = resample_bands_to_block(
                lyrRaster.source(),
                self.dsbPixelSize.value(),
                self.lneOutputFolder.text(),
                band_nums=band_num,
                image_epsg=int(lyrRaster.crs().authid().replace('EPSG:', '')),
                image_nodata=self.spnNoDataVal.value(),
                polygon_shapefile=filePoly
                if self.chkUsePoly.isChecked() else None,
                groupby=self.mFieldComboBox.currentField()
                if self.mFieldComboBox.currentField() else None,
                out_epsg=int(self.outQgsCRS.authid().replace('EPSG:', '')))

            if self.chkAddToDisplay.isChecked():
                for ea_file in files:
                    removeFileFromQGIS(ea_file)
                    addRasterFileToQGIS(ea_file,
                                        group_layer_name=os.path.basename(
                                            os.path.dirname(ea_file)),
                                        atTop=False)

            self.cleanMessageBars(True)
            self.fraMain.setDisabled(False)

            self.iface.mainWindow().statusBar().clearMessage()
            self.iface.messageBar().popWidget()
            QtGui.qApp.restoreOverrideCursor()
            return super(ResampleImageToBlockDialog,
                         self).accept(*args, **kwargs)

        except Exception as err:

            QtGui.qApp.restoreOverrideCursor()
            self.iface.mainWindow().statusBar().clearMessage()
            self.cleanMessageBars(True)
            self.fraMain.setDisabled(False)

            self.send_to_messagebar(str(err),
                                    level=QgsMessageBar.CRITICAL,
                                    duration=0,
                                    addToLog=True,
                                    core_QGIS=False,
                                    showLogPanel=True,
                                    exc_info=sys.exc_info())

            return False  # leave dialog open
예제 #23
0
class ConnectionWidget(QtGui.QWidget, FORM_CLASS):
    connectionChanged = pyqtSignal()
    problemOccurred = pyqtSignal(str)
    dbChanged = pyqtSignal(AbstractDb)
    styleChanged = pyqtSignal(dict)
    def __init__(self, parent = None):
        """Constructor."""
        super(ConnectionWidget, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.setInitialState()
        self.serverWidget.populateServersCombo()
        self.serverWidget.abstractDbLoaded.connect(self.getDatabasesFromServer)
        self.serverWidget.clearWidgets.connect(self.clearAll)
        
         
    def __del__(self):
        """
        Closes the database
        """
        self.closeDatabase()

    def closeDatabase(self):
        """
        Closes the current database
        """
        if self.abstractDb:
            del self.abstractDb
            self.abstractDb = None
                 
    def clearAll(self):
        """
        Resets the initial state
        """
        self.filename = ''
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        
        self.abstractDb = None
        self.isSpatialite = False
        self.abstractDbFactory = DbFactory()
        self.utils = Utils()

        #populating the postgis combobox
        self.comboBoxPostgis.clear()
        self.spatialiteFileEdit.setReadOnly(True)   
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setReadOnly(True)   
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setReadOnly(True)      

    def setInitialState(self):
        """
        Sets the initial state
        """
        self.filename = ''
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        
        self.abstractDb = None
        self.isSpatialite = False
        self.tabWidget.setCurrentIndex(0)
        self.abstractDbFactory = DbFactory()
        self.utils = Utils()
        self.serverWidget.serversCombo.setCurrentIndex(0)

        #populating the postgis combobox
        self.comboBoxPostgis.clear()
        self.spatialiteFileEdit.setReadOnly(True)   
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setReadOnly(True)   
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setReadOnly(True)      

    @pyqtSlot(int)
    def on_comboBoxPostgis_currentIndexChanged(self):
        """
        Updates database information when the combo box changes
        """
        if self.comboBoxPostgis.currentIndex() > 0:
            self.postGISCrsEdit.setText('')
            self.postGISCrsEdit.setReadOnly(True)
            self.edgvPostgisVersionEdit.setText('')
            self.edgvPostgisVersionEdit.setReadOnly(True)  
            self.loadDatabase()
            self.connectionChanged.emit()
        
    @pyqtSlot(bool)
    def on_pushButtonOpenFile_clicked(self):  
        """
        Loads a spatialite database
        """
        self.loadDatabase()
        if self.isDBConnected():
            self.connectionChanged.emit()
        
    @pyqtSlot(int)
    def on_tabWidget_currentChanged(self):
        """
        Changes the tab to work with spatialite or postgis databases
        """
        self.filename = ''
        self.comboBoxPostgis.clear()
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        self.dbVersion = ''
        self.serverWidget.serversCombo.setCurrentIndex(0)
        self.spatialiteFileEdit.setReadOnly(True)
        self.spatialiteFileEdit.setText(self.filename)
        self.postGISCrsEdit.setText('')
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setText('')
        self.spatialiteCrsEdit.setReadOnly(True)   
        self.edgvSpatialiteVersionEdit.setText('')
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setText('')
        self.edgvPostgisVersionEdit.setReadOnly(True)
        self.mGroupBox.setTitle(self.tr('Database connection'))
        
        #Setting the database type
        if self.tabWidget.currentIndex() == 1:
            self.isSpatialite = True
        else:
            self.isSpatialite = False

    def loadDatabase(self):
        """
        Loads the selected database
        """
        self.closeDatabase()
        try:
            if self.isSpatialite:
                self.abstractDb = self.abstractDbFactory.createDbFactory('QSQLITE')
                self.abstractDb.connectDatabase()
                self.spatialiteFileEdit.setText(self.abstractDb.db.databaseName())
                self.edgvSpatialiteVersionEdit.setText(self.abstractDb.getDatabaseVersion())
                    
            else:
                self.abstractDb = self.abstractDbFactory.createDbFactory('QPSQL')
                (host, port, user, password) = self.serverWidget.getServerParameters()
                dbName = self.comboBoxPostgis.currentText()
                self.abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password)
                self.edgvPostgisVersionEdit.setText(self.abstractDb.getDatabaseVersion())
                serverName = self.serverWidget.serversCombo.currentText()
                newText = dbName + self.tr(' on ') + serverName 
                self.mGroupBox.setToolTip(newText)
                # self.mGroupBox.setTitle(newText)

            self.abstractDb.checkAndOpenDb()
            self.dbLoaded = True
            self.dbVersion = self.abstractDb.getDatabaseVersion()
            self.abstractDb.checkAndCreateStyleTable()
            self.styles = self.abstractDb.getStyleDict(self.dbVersion)
            self.styleChanged.emit(self.styles)
            self.dbChanged.emit(self.abstractDb)
            if self.dbVersion == '-1':
                self.problemOccurred.emit(self.tr('This is not a valid DsgTools database!'))
            else:
                self.setCRS()
        except Exception as e:
            self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL)   

    def setCRS(self):
        """
        Sets the CRS information
        """
        try:
            self.epsg = self.abstractDb.findEPSG()
            if self.epsg == -1:
                self.problemOccurred.emit(self.tr('Coordinate Reference System not set or invalid!'))
            else:
                self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
                if self.isSpatialite:
                    self.spatialiteCrsEdit.setText(self.crs.description())
                    self.spatialiteCrsEdit.setReadOnly(True)
                else:
                    self.postGISCrsEdit.setText(self.crs.description())
                    self.postGISCrsEdit.setReadOnly(True)
        except Exception as e:
            self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL)

        
    def isDBConnected(self):
        """
        Checks if the database is already loaded
        """
        return self.dbLoaded
        
    def getDBVersion(self):
        """
        Gets the database version
        """
        ret = ''
        try:
            ret = self.abstractDb.getDatabaseVersion()
        except Exception as e:
            self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
        return ret
    
    def getQmlPath(self):
        """
        Gets the QML path
        """
        ret = ''
        try:
            ret = self.abstractDb.getQmlDir()
        except Exception as e:
            self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
        return ret
    
    def getDatabasesFromServer(self):
        """
        Gets databases from server
        """  
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            if self.serverWidget.abstractDb:
                dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(parentWidget = self)
                dbList.sort()
                self.comboBoxPostgis.clear()
                self.comboBoxPostgis.addItem(self.tr('Select Database'))
                for db, version in dbList:
                    self.comboBoxPostgis.addItem(db)
                
            else:
                self.setInitialState()
                return
        except Exception as e:
            QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
            self.setInitialState()
            self.setInitialState()
        QApplication.restoreOverrideCursor()
예제 #24
0
class PreVesperDialog(QtGui.QDialog, FORM_CLASS):
    """Dialog to prepare data and run vesper kriging"""
    toolKey = 'PreVesperDialog'

    def __init__(self, iface, parent=None):

        super(PreVesperDialog, self).__init__(iface.mainWindow())

        # Set up the user interface from Designer.
        self.setupUi(self)

        # The qgis interface
        self.iface = iface
        self.DISP_TEMP_LAYERS = read_setting(
            PLUGIN_NAME + '/DISP_TEMP_LAYERS', bool)
        self.DEBUG = config.get_debug_mode()

        # Catch and redirect python errors directed at the log messages python
        # error tab.
        QgsMessageLog.instance().messageReceived.connect(errorCatcher)

        if not os.path.exists(TEMPDIR):
            os.mkdir(TEMPDIR)

        # Setup for validation messagebar on gui-----------------------------
        self.setWindowIcon(QtGui.QIcon(
            ':/plugins/pat/icons/icon_vesperKriging.svg'))

        self.validationLayout = QtGui.QFormLayout(self)
        # source: https://nathanw.net/2013/08/02/death-to-the-message-box-use-the-qgis-messagebar/
        # Add the error messages to top of form via a message bar.
        # leave this message bar for bailouts
        self.messageBar = QgsMessageBar(self)

        if isinstance(self.layout(), (QtGui.QFormLayout, QtGui.QGridLayout)):
            # create a validation layout so multiple messages can be added and
            # cleaned up.
            self.layout().insertRow(0, self.validationLayout)
            self.layout().insertRow(0, self.messageBar)
        else:
            # for use with Vertical/horizontal layout box
            self.layout().insertWidget(0, self.messageBar)

        # Set Class default variables -------------------------------------
        self.vesp_dict = None
        self.in_qgscrs = None
        self.dfCSV = None

        # this is a validation flag
        self.OverwriteCtrlFile = False
        self.cboMethod.addItems(
            ['High Density Kriging', 'Low Density Kriging (Advanced)'])

        # To allow only integers for the min number of pts.
        self.onlyInt = QIntValidator()
        self.lneMinPoint.setValidator(self.onlyInt)

        self.vesper_exe = check_vesper_dependency()
        if self.vesper_exe is None or self.vesper_exe == '':
            self.gbRunVesper.setTitle(
                'WARNING:Vesper not found please configure using the about dialog.')
            self.gbRunVesper.setChecked(False)
            self.gbRunVesper.setCheckable(False)
            self.gbRunVesper.setEnabled(False)

    def cleanMessageBars(self, AllBars=True):
        """Clean Messages from the validation layout.
        Args:
            AllBars (bool): Remove All bars including. Defaults to True
        """
        layout = self.validationLayout
        for i in reversed(range(layout.count())):
            # when it timed out the row becomes empty....
            if layout.itemAt(i).isEmpty():
                # .removeItem doesn't always work. so takeAt(pop) it instead
                item = layout.takeAt(i)
            elif AllBars:  # ie remove all
                item = layout.takeAt(i)
                # also have to remove any widgets associated with it.
                if item.widget() is not None:
                    item.widget().deleteLater()

    def send_to_messagebar(self, message, title='', level=QgsMessageBar.INFO, duration=5,
                           exc_info=None, core_QGIS=False, addToLog=False, showLogPanel=False):
        """ Add a message to the forms message bar.

        Args:
            message (str): Message to display
            title (str): Title of message. Will appear in bold. Defaults to ''
            level (QgsMessageBarLevel): The level of message to log. Defaults to QgsMessageBar.INFO
            duration (int): Number of seconds to display message for. 0 is no timeout. Defaults to 5
            core_QGIS (bool): Add to QGIS interface rather than the dialog
            addToLog (bool): Also add message to Log. Defaults to False
            showLogPanel (bool): Display the log panel
            exc_info () : Information to be used as a traceback if required

        """

        if core_QGIS:
            newMessageBar = self.iface.messageBar()
        else:
            newMessageBar = QgsMessageBar(self)

        widget = newMessageBar.createMessage(title, message)

        if showLogPanel:
            button = QPushButton(widget)
            button.setText('View')
            button.setContentsMargins(0, 0, 0, 0)
            button.setFixedWidth(35)
            button.pressed.connect(openLogPanel)
            widget.layout().addWidget(button)

        newMessageBar.pushWidget(widget, level, duration=duration)

        if not core_QGIS:
            rowCount = self.validationLayout.count()
            self.validationLayout.insertRow(rowCount + 1, newMessageBar)

        if addToLog:
            if level == 1:  # 'WARNING':
                LOGGER.warning(message)
            elif level == 2:  # 'CRITICAL':
                # Add a traceback to log only for bailouts only
                if exc_info is not None:
                    exc_type, exc_value, exc_traceback = sys.exc_info()
                    mess = str(traceback.format_exc())
                    message = message + '\n' + mess

                LOGGER.critical(message)
            else:  # INFO = 0
                LOGGER.info(message)

    def updateCtrlFileName(self):
        if self.chkAutoCtrlFileName.isChecked():
            ctrl_name = os.path.splitext(
                os.path.basename(self.lneInCSVFile.text()))[0]
            ctrl_name = ctrl_name.replace('_normtrimmed', '')
            fld = ''

            if self.cboKrigColumn.currentText() != '':
                # convert field name to something meaningful if it contains
                # invalid chars, ie degC
                fld = unidecode(self.cboKrigColumn.currentText())

                # remove field from filename, then add it according to the naming
                #  convention to avoid duplications.
                # flags=re.I is for a case insensitive find and replace
                ctrl_name = re.sub(fld, '', ctrl_name, flags=re.I)

                # and again with invalid characters removed. Only allow
                # alpha-numeric Underscores and hyphens
                fld = re.sub('[^A-Za-z0-9_-]+', '', fld)
                ctrl_name = re.sub(fld, '', ctrl_name, flags=re.I)

                # and again with the field truncated to 10 chars
                fld = fld[:10]
                ctrl_name = re.sub(fld, '', ctrl_name, flags=re.I)

            if self.cboMethod.currentText() == 'High Density Kriging':
                krig_type = 'HighDensity'
            else:
                krig_type = 'LowDensity'

            # add the chosen field name to the control filename
            ctrl_name = '{}_{}_{}_control'.format(ctrl_name[:20], krig_type, fld)

            # only allow alpha-numeric Underscores and hyphens
            ctrl_name = re.sub('[^A-Za-z0-9_-]+', '', ctrl_name)

            # replace more than one instance of underscore with a single one.
            # ie'file____norm__control___yield_h__' to
            # 'file_norm_control_yield_h_'
            ctrl_name = re.sub(r"_+", "_", ctrl_name)
            self.lneCtrlFile.setText(ctrl_name + '.txt')

    @QtCore.pyqtSlot(int)
    def on_cboKrigColumn_currentIndexChanged(self, index):
        if self.cboKrigColumn.currentText() != '':
            self.lblKrigColumn.setStyleSheet('color:black')
        if self.chkAutoCtrlFileName.isChecked():
            self.updateCtrlFileName()

    @QtCore.pyqtSlot(name='on_cmdInCSVFile_clicked')
    def on_cmdInCSVFile_clicked(self):
        self.lneInCSVFile.clear()
        self.messageBar.clearWidgets()
        self.cboMethod.setCurrentIndex(0)
        self.dfCSV = None

        inFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastCSVFolder")
        if inFolder is None or not os.path.exists(inFolder):
            inFolder = read_setting(PLUGIN_NAME + '/BASE_IN_FOLDER')

        s = QtGui.QFileDialog.getOpenFileName(self,
                                              caption=self.tr("Select a CSV file to krige"),
                                              directory=inFolder,
                                              filter='{}  (*.csv);;{}  (*.*);;'.format(
                                                  self.tr("Comma delimited files"),
                                                  self.tr("All Files"))
                                              )

        self.cleanMessageBars(self)
        self.lneInCSVFile.clear()

        # validate files first
        overlaps, message = self.validate_csv_grid_files(s, self.lneInGridFile.text())

        if not overlaps or message is not None:
            self.lblInCSVFile.setStyleSheet('color:red')
            self.lneInCSVFile.setStyleSheet('color:red')

            self.send_to_messagebar(message,
                                    level=QgsMessageBar.CRITICAL,
                                    duration=0, addToLog=True, showLogPanel=True,
                                    exc_info=sys.exc_info())
            return

        s = os.path.normpath(s)
        self.lblInCSVFile.setStyleSheet('color:black')
        self.lneInCSVFile.setStyleSheet('color:black')
        self.lneInCSVFile.setText(s)

        descCSV = describe.CsvDescribe(s)
        self.dfCSV = descCSV.open_pandas_dataframe(nrows=150)

        if len(self.dfCSV) <= 100:
            self.lneMinPoint.clear()
            QMessageBox.warning(self, 'Cannot Krige', 'Kriging is not advised for less '
                                                      'than 100 points')

        self.lneMinPoint.clear()
        self.cboKrigColumn.clear()

        coord_cols = predictCoordinateColumnNames(self.dfCSV.columns)
        epsgcols = [col for col in self.dfCSV.columns if 'EPSG' in col.upper()]

        field_names = list(self.dfCSV.drop(coord_cols + epsgcols, axis=1)
                           .select_dtypes(include=[np.number]).columns.values)

        self.cboKrigColumn.addItems([''] + field_names)

        # To set a coordinate system for vesper2raster, try and get it from
        # a column in the data.
        epsg = 0
        if len(epsgcols) > 0:
            for col in epsgcols:
                if self.dfCSV.iloc[0][col] > 0:
                    epsg = int(self.dfCSV.iloc[0][col])
                    break

        if epsg > 0:
            self.in_qgscrs = QgsCoordinateReferenceSystem("EPSG:{}".format(epsg))
            self.lblInCRS.setText('{}  -  {}'.format(self.in_qgscrs.description(),
                                                     self.in_qgscrs.authid()))
        else:
            self.lblInCRS.setText('Unspecified')

        write_setting(PLUGIN_NAME + "/" + self.toolKey +
                      "/LastCSVFolder", os.path.dirname(s))
        del descCSV
        self.updateCtrlFileName()

    @QtCore.pyqtSlot(name='on_cmdInGridFile_clicked')
    def on_cmdInGridFile_clicked(self):
        self.lneInGridFile.clear()
        self.messageBar.clearWidgets()

        inFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastVesperGridFolder")

        if inFolder is None or not os.path.exists(inFolder):

            inFolder = read_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastCSVFolder")

            if inFolder is None or not os.path.exists(inFolder):
                inFolder = read_setting(PLUGIN_NAME + '/BASE_IN_FOLDER')

        s = QtGui.QFileDialog.getOpenFileName(self, caption=self.tr("Choose the Vesper Grid File"),
                                              directory=inFolder,
                                              filter='{}  (*_v.txt);;{}  (*.*);;'.format(
                                                  self.tr("Vesper Grid File(s)"),
                                                  self.tr("All Files"))
                                              )

        self.cleanMessageBars(self)
        s = os.path.normpath(s)

        self.lneInGridFile.clear()
        self.lneInGridFile.setStyleSheet('color:red')
        self.lblInGridFile.setStyleSheet('color:red')

        overlaps, message = self.validate_csv_grid_files(self.lneInCSVFile.text(), s)

        if overlaps or message is None:
            self.lneInGridFile.setStyleSheet('color:black')
            self.lblInGridFile.setStyleSheet('color:black')
            if overlaps:
                self.lneInGridFile.setText(s)
                write_setting(PLUGIN_NAME + "/" + self.toolKey + "/LastVesperGridFolder",
                              os.path.dirname(s))
        else:
            self.send_to_messagebar(message,
                                    level=QgsMessageBar.CRITICAL,
                                    duration=0, addToLog=True, showLogPanel=True,
                                    exc_info=sys.exc_info())

    @QtCore.pyqtSlot(name='on_cmdVariogramFile_clicked')
    def on_cmdVariogramFile_clicked(self):
        self.lneVariogramFile.clear()
        self.messageBar.clearWidgets()

        inFolder = read_setting(
            PLUGIN_NAME + "/" + self.toolKey + "/LastVariogramFolder")
        if inFolder is None or not os.path.exists(inFolder):
            inFolder = read_setting(
                PLUGIN_NAME + "/" + self.toolKey + "/LastVariogramFolder")
            if inFolder is None or not os.path.exists(inFolder):
                inFolder = read_setting(PLUGIN_NAME + '/BASE_IN_FOLDER')

        s = QtGui.QFileDialog.getOpenFileName(self,
                                              caption=self.tr("Choose the Vesper Variogram File"),
                                              directory=inFolder,
                                              filter='{}  (*.txt);;{}  (*.*);;'.format(
                                                  self.tr("Variogram Text File(s)"),
                                                  self.tr("All Files"))
                                              )

        self.cleanMessageBars(self)
        if s == '':
            self.lneVariogramFile.setStyleSheet('color:red')
            self.lblVariogramFile.setStyleSheet('color:red')
            return

        if 'Variogram Model' not in open(s).read():
            self.lneVariogramFile.setStyleSheet('color:red')
            self.lblVariogramFile.setStyleSheet('color:red')
            self.send_to_messagebar("Invalid Variogram File", level=QgsMessageBar.CRITICAL,
                                    duration=0, addToLog=True, showLogPanel=True,
                                    exc_info=sys.exc_info())
            # self.lneVariogramFile.clear()
            return

        s = os.path.normpath(s)
        self.lblVariogramFile.setStyleSheet('color:black')
        self.lneVariogramFile.setStyleSheet('color:black')
        self.lneVariogramFile.setText(s)
        write_setting(PLUGIN_NAME + "/" + self.toolKey +
                      "/LastVariogramFolder", os.path.dirname(s))

    @QtCore.pyqtSlot(name='on_cmdVesperFold_clicked')
    def on_cmdVesperFold_clicked(self):
        self.messageBar.clearWidgets()

        if self.lneVesperFold.text() is None:
            outFolder = ''
        else:
            outFolder = self.lneVesperFold.text()

        if outFolder == '':
            outFolder = read_setting(
                PLUGIN_NAME + "/" + self.toolKey + "/LastVesperOutFolder")
            if outFolder is None or not os.path.exists(outFolder):
                outFolder = read_setting(PLUGIN_NAME + '/BASE_OUT_FOLDER')

        s = QtGui.QFileDialog.getExistingDirectory(self, self.tr(
            "Vesper processing folder. A Vesper sub-folder will be created."), outFolder,
                                                   QtGui.QFileDialog.ShowDirsOnly)

        self.cleanMessageBars(self)
        if s == '' or s is None:
            return

        s = os.path.normpath(s)
        self.lblVesperFold.setStyleSheet('color:black')
        self.lneVesperFold.setStyleSheet('color:black')
        self.lneVesperFold.setText(s)
        write_setting(PLUGIN_NAME + "/" + self.toolKey +
                      "/LastVesperOutFolder", s)

    @QtCore.pyqtSlot(int)
    def on_chkAutoCtrlFileName_stateChanged(self, state):
        self.updateCtrlFileName()

    @QtCore.pyqtSlot(name='on_cmdInCRS_clicked')
    def on_cmdInCRS_clicked(self):
        self.messageBar.clearWidgets()

        dlg = QgsGenericProjectionSelector(self)
        dlg.setMessage('Select coordinate system for the Vesper raster files')
        if dlg.exec_():
            if dlg.selectedAuthId() != '':
                self.in_qgscrs = QgsCoordinateReferenceSystem(dlg.selectedAuthId())
                if self.in_qgscrs == 'Unspecified' or self.in_qgscrs == '':
                    self.lblInCRS.setText('Unspecified')
                    self.lblOutCRS.setText('Unspecified')
                else:
                    self.lblInCRS.setText('{}  -  {}'.format(self.in_qgscrs.description(),
                                                             self.in_qgscrs.authid()))
                    self.lblInCRS.setStyleSheet('color:black;background:transparent;')
                    self.lblInCRSTitle.setStyleSheet('color:black')

        self.cleanMessageBars(self)

    @QtCore.pyqtSlot(int)
    def on_cboMethod_currentIndexChanged(self, index):
        self.stackedWidget.setCurrentIndex(index)
        self.updateCtrlFileName()
        if self.dfCSV is None:
            return

        if len(self.dfCSV) <= 100:
            self.cleanMessageBars(self)
            self.lneMinPoint.clear()
            QMessageBox.warning(
                self, 'Cannot Krige', 'Kriging is not advised for less than 100 points')

        if 'Low Density Kriging' in self.cboMethod.currentText():
            if len(self.dfCSV) <= 150:  # only partial file opened so open it all
                descCSV = describe.CsvDescribe(self.lneInCSVFile.text())
                self.dfCSV = descCSV.open_pandas_dataframe()
            self.lblRowCount.setText("The maximum number of points is {}.".format(len(self.dfCSV)))
            self.lneMinPoint.setText(str(len(self.dfCSV) - 2))
        else:
            self.lneMinPoint.clear()
            self.lblRowCount.setText('')

    def parse_variogram_file(self):

        vario_values = {}

        for line in open(self.lneVariogramFile.text()):
            # reset some text to control file tags
            line = line.replace('C0', 'CO')
            line = line.replace('Variogram Model', 'modtyp').strip()

            if set(':=.').intersection(set(line)):
                for ea in ['=', ':', ' ']:
                    if ea in line:
                        key, val = line.split(ea, 1)
                        break

                # sort out the numerics from the strings
                try:
                    key = int(float(key)) if int(
                        float(key)) == float(key) else float(key)
                except ValueError:
                    key = key.strip()

                try:
                    val = int(float(val)) if int(
                        float(val)) == float(val) else float(val)
                except ValueError:
                    val = val.strip()

                # only return keys required for the control file.
                # and key in VESPER_OPTIONS.keys():
                if isinstance(key, basestring):
                    vario_values[key] = val

        return vario_values

    def validate_csv_grid_files(self, csv_file, grid_file, show_msgbox=True):
        """ validate the csv and grid files and check for overlap assuming that they are
        of the same coordinate system if True then message will be blank else a message
        will be generated
        """

        overlaps = False

        if csv_file != '':
            if not os.path.exists(csv_file):
                return False, 'CSV file does not exist'
            else:
                try:
                    df_csv = pd.read_csv(csv_file)
                    csvX, csvY = predictCoordinateColumnNames(df_csv.columns)
                    csv_bbox = box(df_csv[csvX].min(), df_csv[csvY].min(),
                                   df_csv[csvX].max(), df_csv[csvY].max())

                except Exception as err:
                    self.lblInCSVFile.setStyleSheet('color:red')
                    self.lneInCSVFile.setStyleSheet('color:red')
                    return False, 'Invalid CSV file'

        if grid_file != '':
            if not os.path.exists(grid_file):
                return False, 'Grid file does not exist'
            else:
                try:
                    df_grid = pd.read_table(grid_file, names=['X', 'Y'],
                                            delimiter=' ', skipinitialspace=True)

                    grid_bbox = box(df_grid['X'].min(), df_grid['Y'].min(),
                                    df_grid['X'].max(), df_grid['Y'].max())

                except Exception as err:
                    self.lblInGridFile.setStyleSheet('color:red')
                    self.lneInGridFile.setStyleSheet('color:red')
                    return False, 'Invalid VESPER grid file'

        # only continue if both inputs aren't blank
        if csv_file == '' or grid_file == '':
            # if one or the other is blank keep validate as true or it wont write to the GUI
            return True, None

        if csv_file == grid_file:
            return False, "VESPER grid file and CSV file cannot be the same file"

        # now we can check for overlap

        if self.in_qgscrs:
            epsg = self.in_qgscrs.authid()
        else:
            epsg = ''

        overlaps = check_for_overlap(csv_bbox.to_wkt(), grid_bbox.to_wkt(), epsg, epsg)
        if not overlaps:
            message = 'There is no overlap between the VESPER Grid file and the CSV file.\n' \
                      'Please check input files and coordinate systems'

            if show_msgbox:
                QMessageBox.warning(self, 'No Overlap', message)

            self.lblInGridFile.setStyleSheet('color:red')
            self.lneInGridFile.setStyleSheet('color:red')
            self.lblInCSVFile.setStyleSheet('color:red')
            self.lneInCSVFile.setStyleSheet('color:red')
        else:
            message = None
            self.lblInGridFile.setStyleSheet('color:black')
            self.lneInGridFile.setStyleSheet('color:black')
            self.lblInCSVFile.setStyleSheet('color:black')
            self.lneInCSVFile.setStyleSheet('color:black')

        return overlaps, message

    def validate(self):
        """Check to see that all required gui elements have been entered and are valid."""
        try:
            self.messageBar.clearWidgets()
            self.cleanMessageBars(AllBars=True)
            errorList = []

            if self.lneInCSVFile.text() is None or self.lneInCSVFile.text() == '':
                self.lblInCSVFile.setStyleSheet('color:red')
                self.lneInCSVFile.setStyleSheet('color:red')
                errorList.append(self.tr("Select an input csv data file"))
            elif not os.path.exists(self.lneInCSVFile.text()):
                self.lblInCSVFile.setStyleSheet('color:red')
                self.lneInCSVFile.setStyleSheet('color:red')
                errorList.append(self.tr("Input csv data file does not exist"))
            else:
                self.lblInCSVFile.setStyleSheet('color:black')
                self.lneInCSVFile.setStyleSheet('color:black')

            if self.lneInGridFile.text() is None or self.lneInGridFile.text() == '':
                self.lblInGridFile.setStyleSheet('color:red')
                self.lneInGridFile.setStyleSheet('color:red')
                errorList.append(self.tr("Select a Vesper grid file"))
            elif not os.path.exists(self.lneInGridFile.text()):
                self.lblInGridFile.setStyleSheet('color:red')
                self.lneInGridFile.setStyleSheet('color:red')
                errorList.append(self.tr("Vesper grid file does not exists."))
            else:
                self.lblInGridFile.setStyleSheet('color:black')
                self.lneInGridFile.setStyleSheet('color:black')

            if self.in_qgscrs is None:
                self.lblInCRSTitle.setStyleSheet('color:red')
                self.lblInCRS.setStyleSheet('color:red;background:transparent;')
                errorList.append(self.tr("Select a coordinate system"))
            else:
                self.lblInCRSTitle.setStyleSheet('color:black')
                self.lblInCRS.setStyleSheet('color:black;background:transparent;')

            pass_check, message = self.validate_csv_grid_files(self.lneInCSVFile.text(),
                                                               self.lneInGridFile.text())
            if not pass_check:
                errorList.append(self.tr(message))
                # errorList.append(self.tr("Input csv file and grid file do not overlap. Could be "
                #                          "due to differing coordinate systems or invalid files"))

            if self.cboKrigColumn.currentText() == '':
                self.lblKrigColumn.setStyleSheet('color:red')
                errorList.append(self.tr("Select a column to krige"))
            else:
                self.lblKrigColumn.setStyleSheet('color:black')

            if self.cboMethod.currentText() != 'High Density Kriging':

                if self.lneVariogramFile.text() is None or self.lneVariogramFile.text() == '':
                    self.lblVariogramFile.setStyleSheet('color:red')
                    self.lneVariogramFile.setStyleSheet('color:red')
                    errorList.append(self.tr("Select a variogram text file"))
                elif not os.path.exists(self.lneVariogramFile.text()):
                    self.lblVariogramFile.setStyleSheet('color:red')
                    self.lneVariogramFile.setStyleSheet('color:red')
                    errorList.append(self.tr("Variogram text file does not exists."))
                else:
                    self.lblVariogramFile.setStyleSheet('color:black')
                    self.lneVariogramFile.setStyleSheet('color:black')

                if int(self.lneMinPoint.text()) >= len(self.dfCSV):
                    self.lneMinPoint.setStyleSheet('color:red')
                    self.lneMinPoint.setStyleSheet('color:red')
                    errorList.append(
                        self.tr("Minimum number of points should be at least "
                                "2 less than the dataset count"))
                else:
                    self.lneMinPoint.setStyleSheet('color:black')
                    self.lneMinPoint.setStyleSheet('color:black')

            if self.lneVesperFold.text() == '':
                self.lblVesperFold.setStyleSheet('color:red')
                errorList.append(self.tr("Select output Vesper data folder"))
            elif not os.path.exists(self.lneVesperFold.text()):
                self.lneVesperFold.setStyleSheet('color:red')
                errorList.append(
                    self.tr("Output Vesper data folder does not exist"))
            else:
                self.lblVesperFold.setStyleSheet('color:black')
                self.lneVesperFold.setStyleSheet('color:black')

            ctrl_file = os.path.join(self.lneVesperFold.text(), self.lneCtrlFile.text())

            if os.path.exists(ctrl_file):
                message = 'Vesper Control File {} already exists. Do you want to' \
                          ' overwrite?'.format(self.lneCtrlFile.text())

                reply = QMessageBox.question(
                    self, 'Control File', message, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
                if reply == QtGui.QMessageBox.Yes:
                    self.overwrite_ctrl_file = True
                    self.lblVesperFold.setStyleSheet('color:black')
                else:
                    self.overwrite_ctrl_file = False
                    self.lblCtrlFile.setStyleSheet('color:red')
                    errorList.append(
                        self.tr("Output control file exists please choose a different name"))

            if len(errorList) > 0:
                raise ValueError(errorList)

        except ValueError as e:
            self.cleanMessageBars(True)
            if len(errorList) > 0:
                for i, ea in enumerate(errorList):
                    self.send_to_messagebar(
                        unicode(ea), level=QgsMessageBar.WARNING, duration=(i + 1) * 5)
                return False

        return True

    def accept(self, *args, **kwargs):
        if not self.validate():
            return False

        try:
            self.cleanMessageBars(True)

            message = '- and run VESPER' if self.gbRunVesper.isChecked() else ''
            LOGGER.info('{st}\nProcessing {} {}'.format(
                self.windowTitle(), message, st='*' * 50))

            # Add settings to log
            settingsStr = 'Parameters:---------------------------------------'
            settingsStr += '\n    {:30}\t{}'.format('Data File:', self.lneInCSVFile.text())
            settingsStr += '\n    {:30}\t{}'.format('Krige Column:',
                                                    self.cboKrigColumn.currentText())
            settingsStr += '\n    {:30}\t{}'.format('Grid File:', self.lneInGridFile.text())
            settingsStr += '\n    {:30}\t{}'.format('Output Vesper Folder:',
                                                    self.lneVesperFold.text())
            settingsStr += '\n    {:30}\t{}'.format(self.cboMethod.currentText(), '')

            if self.cboMethod.currentText() == 'High Density Kriging':
                settingsStr += '\n    {:30}\t{}'.format('Block Kriging Size:',
                                                        int(self.dsbBlockKrigSize.value()))

            else:
                settingsStr += '\n    {:30}\t{}'.format('Variogram File:',
                                                        self.lneVariogramFile.text())
                settingsStr += '\n    {:30}\t{}'.format('Min Point Number:',
                                                        self.lneMinPoint.text())

            settingsStr += '\n    {:30}\t{}'.format(
                'Display Vesper Graphics:', self.chkDisplayGraphics.isChecked())

            settingsStr += '\n    {:30}\t{}'.format(
                'Run Vesper Now:', self.gbRunVesper.isChecked())

            if self.gbRunVesper.isChecked():
                settingsStr += '\n    {:30}\t{}'.format('Import Vesper Files to Rasters:',
                                                        self.chkVesper2Raster.isChecked())
                if self.chkVesper2Raster.isChecked():
                    settingsStr += '\n    {:30}\t{}'.format(
                        'Vesper Files Coordinate System:', self.lblInCRS.text())

            LOGGER.info(settingsStr)

            # get a fresh dataframe for the input csv file
            self.dfCSV = pd.read_csv(self.lneInCSVFile.text())

            vc = VesperControl()

            if self.cboMethod.currentText() == 'High Density Kriging':
                vc.update(xside=int(self.dsbBlockKrigSize.value()),
                          yside=int(self.dsbBlockKrigSize.value()))
            else:
                # from the variogram text file find and update the control file keys
                vario = self.parse_variogram_file()

                vesp_keys = {key: val for key, val in vario.items() if key in vc}
                vc.update(vesp_keys)

                # apply the other keys.
                vc.update({'jpntkrg': 1,
                           'jlockrg': 0,
                           'minpts': int(self.lneMinPoint.text()),
                           'maxpts': len(self.dfCSV),
                           'jcomvar': 0,
                           })
            epsg = int(self.in_qgscrs.authid().replace('EPSG:', ''))
            bat_file, ctrl_file = prepare_for_vesper_krige(self.dfCSV,
                                                           self.cboKrigColumn.currentText(),
                                                           self.lneInGridFile.text(),
                                                           self.lneVesperFold.text(),
                                                           control_textfile=self.lneCtrlFile.text(),
                                                           coord_columns=[],
                                                           epsg=epsg,
                                                           display_graphics=self.chkDisplayGraphics.isChecked(),
                                                           control_options=vc)

            epsg = 0
            if self.in_qgscrs is not None and self.chkVesper2Raster.isChecked():
                epsg = int(self.in_qgscrs.authid().replace('EPSG:', ''))

            if self.gbRunVesper.isChecked():
                # Add to vesper queue
                self.vesp_dict = {'control_file': ctrl_file, 'epsg': epsg}

            else:
                message = 'Successfully created files for Vesper kriging. ' \
                          'The control file is {}'.format(ctrl_file)
                self.send_to_messagebar(message, level=QgsMessageBar.SUCCESS, duration=0,
                                        addToLog=True, core_QGIS=True)
                LOGGER.info('Successfully created files for Vesper kriging')

            QtGui.qApp.restoreOverrideCursor()
            return super(PreVesperDialog, self).accept(*args, **kwargs)

        except Exception as err:
            QtGui.qApp.restoreOverrideCursor()
            self.cleanMessageBars(True)
            self.send_to_messagebar(str(err), level=QgsMessageBar.CRITICAL, duration=0,
                                    addToLog=True, showLogPanel=True, exc_info=sys.exc_info())
            return False
예제 #25
0
class Dialog(QDialog, Ui_Dialog):
    def __init__(self, iface):
        QDialog.__init__(self, iface.mainWindow())
        self.iface = iface
        self.setupUi(self)
        self.toolOut.setEnabled(False)
        self.toolOut.setVisible(False)
        self.outShape.setEnabled(False)
        self.outShape.setVisible(False)
        self.label_2.setVisible(False)
        self.label_2.setEnabled(False)
        self.setWindowTitle(self.tr("Define current projection"))
        self.buttonOk = self.buttonBox_2.button(QDialogButtonBox.Ok)
        QObject.connect(self.btnProjection, SIGNAL("clicked()"),
                        self.outProjFile)
        QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"),
                        self.updateProj1)
        QObject.connect(self.cmbLayer, SIGNAL("currentIndexChanged(QString)"),
                        self.updateProj2)
        # populate layer list
        self.progressBar.setValue(0)
        layers = ftools_utils.getLayerNames(
            [QGis.Point, QGis.Line, QGis.Polygon])
        self.inShape.addItems(layers)
        self.cmbLayer.addItems(layers)

        self.crs = None

    def updateProj1(self, layerName):
        self.inRef.clear()
        tempLayer = ftools_utils.getVectorLayerByName(layerName)
        crs = tempLayer.dataProvider().crs()
        if crs.isValid():
            self.inRef.insert(crs.authid() + " - " + crs.description())
        else:
            self.inRef.insert(self.tr("Missing or invalid CRS"))

    def updateProj2(self, layerName):
        self.outRef.clear()
        tempLayer = ftools_utils.getVectorLayerByName(layerName)
        crs = tempLayer.dataProvider().crs()
        if crs.isValid():
            self.outRef.insert(crs.authid() + " - " + crs.description())
        else:
            self.outRef.insert(self.tr("Missing or invalid CRS"))

    def accept(self):
        self.buttonOk.setEnabled(False)
        if self.inShape.currentText() == "":
            QMessageBox.information(self, self.tr("Define current projection"),
                                    self.tr("No input shapefile specified"))
        elif self.txtProjection.text() == "" and self.rdoProjection.isChecked(
        ):
            QMessageBox.information(
                self, self.tr("Define current projection"),
                self.tr("Please specify spatial reference system"))
        elif self.cmbLayer.currentText() == "" and self.rdoLayer.isChecked():
            QMessageBox.information(
                self, self.tr("Define current projection"),
                self.tr("Please specify spatial reference system"))
        else:
            self.progressBar.setValue(5)
            inName = self.inShape.currentText()
            self.progressBar.setValue(10)
            vLayer = ftools_utils.getVectorLayerByName(inName)
            self.progressBar.setValue(30)
            if vLayer == "Error":
                QMessageBox.information(
                    self, self.tr("Define current projection"),
                    self.tr(
                        "Cannot define projection for PostGIS data...yet!"))
            else:
                srsDefine = None
                if self.rdoProjection.isChecked():
                    srsDefine = self.crs
                else:
                    destLayer = ftools_utils.getVectorLayerByName(
                        self.cmbLayer.currentText())
                    srsDefine = destLayer.crs()
                if srsDefine == vLayer.crs():
                    responce = QMessageBox.question(
                        self, self.tr("Define current projection"),
                        self.
                        tr("Identical output spatial reference system chosen\n\nAre you sure you want to proceed?"
                           ), QMessageBox.Yes, QMessageBox.No,
                        QMessageBox.NoButton)
                    if responce == QMessageBox.No:
                        self.progressBar.setValue(0)
                        self.buttonOk.setEnabled(True)
                        return
                provider = vLayer.dataProvider()
                self.progressBar.setValue(35)
                inPath = provider.dataSourceUri()
                p = re.compile("\|.*")
                inPath = p.sub("", inPath)
                self.progressBar.setValue(40)
                if inPath.endswith(".shp"):
                    inPath = inPath[:-4]
                self.progressBar.setValue(55)
                if not srsDefine.isValid():
                    QMessageBox.information(
                        self, self.tr("Define current projection"),
                        self.tr(
                            "Output spatial reference system is not valid"))
                else:
                    self.progressBar.setValue(60)
                    outputWkt = srsDefine.toWkt()
                    self.progressBar.setValue(65)
                    outputFile = QFile(inPath + ".prj")
                    outputFile.open(QIODevice.WriteOnly | QIODevice.Text)
                    outputPrj = QTextStream(outputFile)
                    outputPrj << outputWkt
                    outputPrj.flush()
                    outputFile.close()
                    self.progressBar.setValue(70)
                    checkFile = QFile(inPath + ".qpj")
                    if checkFile.exists():
                        checkFile.open(QIODevice.WriteOnly | QIODevice.Text)
                        outputPrj = QTextStream(checkFile)
                        outputPrj << outputWkt
                        outputPrj.flush()
                        checkFile.close()
                    self.progressBar.setValue(95)
                    vLayer.setCrs(srsDefine)
                    self.progressBar.setValue(100)
                    QMessageBox.information(
                        self, self.tr("Define current projection"),
                        self.tr("Defined Projection For:\n%s.shp") % (inPath))
        self.progressBar.setValue(0)
        self.buttonOk.setEnabled(True)

    def outProjFile(self):
        header = "Define layer CRS:"
        sentence1 = self.tr(
            "Please select the projection system that defines the current layer."
        )
        sentence2 = self.tr(
            "Layer CRS information will be updated to the selected CRS.")
        projSelector = QgsGenericProjectionSelector(self)
        projSelector.setMessage("<h2>%s</h2>%s <br/> %s" %
                                (header, sentence1, sentence2))
        if projSelector.exec_():
            self.crs = QgsCoordinateReferenceSystem(
                projSelector.selectedCrsId(),
                QgsCoordinateReferenceSystem.InternalCrsId)
            print "AUTHID", projSelector.selectedAuthId()
            if len(projSelector.selectedAuthId()) == 0:
                QMessageBox.information(self,
                                        self.tr("Export to new projection"),
                                        self.tr("No Valid CRS selected"))
                return
            else:
                self.txtProjection.clear()
                self.txtProjection.insert(self.crs.authid() + " - " +
                                          self.crs.description())
        else:
            return
class rasterLayerPropertyDlg(QDialog):
    '''
    classdocs
    '''
    def __init__(self, parent, layer):
        '''
        Constructor
        '''
        QDialog.__init__(self, parent)
        self.resize(200, 200)

        self.rasterLayer = layer

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)

        verticalLayout = QVBoxLayout(self)
        verticalLayout.setObjectName("verticalLayout")
        stackedWidget = QStackedWidget(self)
        stackedWidget.setObjectName("stackedWidget")
        pageRender = QWidget(stackedWidget)
        pageRender.setObjectName("pageRender")
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(pageRender.sizePolicy().hasHeightForWidth())
        pageRender.setSizePolicy(sizePolicy)

        horizontalLayout = QHBoxLayout(pageRender)
        horizontalLayout.setObjectName("horizontalLayout")
        frameRender = QFrame(pageRender)
        frameRender.setObjectName("frameRender")
        frameRender.setFrameShape(QFrame.StyledPanel)
        frameRender.setFrameShadow(QFrame.Raised)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(frameRender.sizePolicy().hasHeightForWidth())
        frameRender.setSizePolicy(sizePolicy)
        self.vLayoutFrameRender = QVBoxLayout(frameRender)
        self.vLayoutFrameRender.setObjectName("vLayoutFrameRender")

        horizontalLayout.addWidget(frameRender)
        self.cmbRendererType = ComboBoxPanel(frameRender)
        self.cmbRendererType.Caption = "Render Type"
        self.cmbRendererType.LabelWidth = 70
        self.cmbRendererType.Items = ["Mutiband color", "Paletted", "Singleband gray", "Singleband pseudocolor"]
        self.connect(self.cmbRendererType, SIGNAL("Event_0"), self.cmbRendererType_currentIndexChanged)

        self.vLayoutFrameRender.addWidget(self.cmbRendererType)
        self.gbRenderer = GroupBox(frameRender)
        self.gbRenderer.Caption = self.cmbRendererType.SelectedItem
        self.vLayoutFrameRender.addWidget(self.gbRenderer)

        self.qgsMultiBandColorRendererWidget = QgsMultiBandColorRendererWidget(self.rasterLayer)
        self.qgsPalettedRendererWidget = QgsPalettedRendererWidget(self.rasterLayer)
        self.qgsSingleBandGrayRendererWidget = QgsSingleBandGrayRendererWidget(self.rasterLayer)
        self.qgsSingleBandPseudoColorRendererWidget = QgsSingleBandPseudoColorRendererWidget(self.rasterLayer)


        self.gbRenderer.Add = self.qgsMultiBandColorRendererWidget
        self.gbRenderer.Add = self.qgsPalettedRendererWidget
        self.gbRenderer.Add = self.qgsSingleBandGrayRendererWidget
        self.gbRenderer.Add = self.qgsSingleBandPseudoColorRendererWidget

        self.qgsPalettedRendererWidget.setVisible(False)
        self.qgsSingleBandGrayRendererWidget.setVisible(False)
        self.qgsSingleBandPseudoColorRendererWidget.setVisible(False)

        stackedWidget.addWidget(pageRender)
        # page_2 = QWidget()
        # page_2.setObjectName("page_2")
        # stackedWidget.addWidget(page_2)

        verticalLayout.addWidget(stackedWidget)

        buttonBox = QDialogButtonBox(self)
        buttonBox.setObjectName("buttonBox")
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Apply)
        btnApply = buttonBox.button(QDialogButtonBox.Apply)
        btnApply.clicked.connect(self.btnApply_clicked)
        verticalLayout.addWidget(buttonBox)


        # retranslateUi(Dialog)
        buttonBox.accepted.connect(self.OK)
        buttonBox.rejected.connect(self.reject)

        if self.rasterLayer.renderer().bandCount() == 1:
            self.cmbRendererType.SelectedIndex = 2
        elif self.rasterLayer.renderer().bandCount() > 1:
            self.cmbRendererType.SelectedIndex = 0

        # QObject.connect(buttonBox, SIGNAL("accepted()"), self, SLOT(accept()))
        # QObject.connect(buttonBox, SIGNAL("rejected()"), self, SLOT(reject()))
    def cmbRendererType_currentIndexChanged(self):

        if self.cmbRendererType.SelectedIndex == 0:
            self.qgsPalettedRendererWidget.setVisible(False)
            self.qgsSingleBandGrayRendererWidget.setVisible(False)
            self.qgsSingleBandPseudoColorRendererWidget.setVisible(False)
            # self.resize(200, 200)
            self.qgsMultiBandColorRendererWidget.setVisible(True)
        elif self.cmbRendererType.SelectedIndex == 1:
            self.qgsMultiBandColorRendererWidget.setVisible(False)
            self.qgsSingleBandGrayRendererWidget.setVisible(False)
            self.qgsSingleBandPseudoColorRendererWidget.setVisible(False)
            # self.resize(200, 200)
            self.qgsPalettedRendererWidget.setVisible(True)
        elif self.cmbRendererType.SelectedIndex == 2:
            self.qgsMultiBandColorRendererWidget.setVisible(False)
            self.qgsPalettedRendererWidget.setVisible(False)
            self.qgsSingleBandPseudoColorRendererWidget.setVisible(False)
            # self.resize(200, 200)
            self.qgsSingleBandGrayRendererWidget.setVisible(True)
        else:
            self.qgsMultiBandColorRendererWidget.setVisible(False)
            self.qgsPalettedRendererWidget.setVisible(False)
            self.qgsSingleBandGrayRendererWidget.setVisible(False)
            self.qgsSingleBandPseudoColorRendererWidget.setVisible(True)

        self.resize(200, 200)
        self.gbRenderer.Caption = self.cmbRendererType.SelectedItem


    def selectCrs(self):
        projectionDlg = QgsGenericProjectionSelector(self)
        projectionDlg.setSelectedAuthId(self.mCrs.authid())
        if projectionDlg.exec_():
            self.mCrs = QgsCoordinateReferenceSystem(projectionDlg.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId)
            self.ui.txtCrs.setText(self.mCrs.authid() + " - " + self.mCrs.description())
    def changeStackWidget(self, index):
        self.ui.stackedWidget.setCurrentIndex(index)
    def btnApply_clicked(self):
        if self.cmbRendererType.SelectedIndex == 0:
            self.rasterLayer.setRenderer(self.qgsMultiBandColorRendererWidget.renderer())
        elif self.cmbRendererType.SelectedIndex == 1:
            self.rasterLayer.setRenderer(self.qgsPalettedRendererWidget.renderer())
        elif self.cmbRendererType.SelectedIndex == 2:
            self.rasterLayer.setRenderer(self.qgsSingleBandGrayRendererWidget.renderer())
        else:
            self.rasterLayer.setRenderer(self.qgsSingleBandPseudoColorRendererWidget.renderer())
        self.rasterLayer.triggerRepaint()
    def OK(self):
        self.btnApply_clicked()
        QDialog.accept(self)
    def initializeExistingGeoreferencing(self, dataset, georef):
        # georef can have scaling, rotation or translation
        rotation = 180 / math.pi * -math.atan2(georef[4], georef[1])
        sx = math.sqrt(georef[1] ** 2 + georef[4] ** 2)
        sy = math.sqrt(georef[2] ** 2 + georef[5] ** 2)
        i_center_x = self.image.width() / 2
        i_center_y = self.image.height() / 2
        center = QgsPointXY(
            georef[0] + georef[1] * i_center_x + georef[2] * i_center_y,
            georef[3] + georef[4] * i_center_x + georef[5] * i_center_y,
        )

        qDebug(repr(rotation) + " " + repr((sx, sy)) + " " + repr(center))

        self.setRotation(rotation)
        self.setCenter(center)
        # keep yScale positive
        self.setScale(sx, sy)
        self.commitTransformParameters()

        crs_wkt = dataset.GetProjection()
        message_shown = False
        if crs_wkt:
            qcrs = QgsCoordinateReferenceSystem(crs_wkt)
            # TODO check change
            if qcrs.description() != self.crs().description():
                # reproject
                try:
                    self.reprojectTransformParameters(qcrs, self.crs())
                    self.commitTransformParameters()
                    self.showBarMessage(
                        "Transform parameters changed: ",
                        "Found existing georeferencing in raster but "
                        "its CRS does not match the CRS of the map. "
                        "Reprojected the extent.",
                        Qgis.Warning,
                        25,
                    )
                    message_shown = True
                except Exception as ex:
                    QgsMessageLog.logMessage(repr(ex))
                    self.showBarMessage(
                        "CRS does not match",
                        "Found existing georeferencing in raster but "
                        "its CRS does not match the CRS of the map. "
                        "Unable to reproject.",
                        Qgis.Warning,
                        5,
                    )
                    message_shown = True
        # if no projection info, assume it is the same CRS
        # as the map and no warning
        if not message_shown:
            self.showBarMessage(
                "Georeferencing loaded",
                "Found existing georeferencing in raster",
                Qgis.Info,
                3,
            )

        # zoom (assume the user wants to work on the image)
        self.iface.mapCanvas().setExtent(self.extent())
예제 #28
0
class layerSaveAsDlg(QDialog):
    '''
    classdocs
    '''
    def __init__(self, parent, layer):
        '''
        Constructor
        '''
        QDialog.__init__(self, parent)
        self.ui = ui_layerSaveAsDlg()
        self.ui.setupUi(self)
        #         self.layerSet = layerSet
        self.baseLayer = layer
        self.shpFormats = ["ESRI Shapefile", "GeoJSON"]
        self.fileTypes = ["ESRI Shape file(*.shp )", "GeoJSON(*.geojson)"]
        self.crsList = ["Layer CRS", "Project CRS", "Selected CRS"]
        self.ui.cmbFormat.addItems(self.shpFormats)
        self.ui.cmbCrs.addItems(self.crsList)
        self.ui.btnBrowse.clicked.connect(self.browse)
        self.ui.txtCrs.setText("WGS 84")
        self.ui.txtCrs.setEnabled(False)
        #         self.ui.cmbFormat.currentIndexChanged.connect(self.enableTxtAPV)
        self.ui.cmbCrs.currentIndexChanged.connect(self.crsSelectChange)
        self.ui.btnChange.clicked.connect(self.crsChange)
        self.ui.buttonBox.accepted.connect(self.saveLayer)
        self.crs = QgsCoordinateReferenceSystem(
            4326, QgsCoordinateReferenceSystem.EpsgCrsId)

    def browse(self):
        type1 = self.fileTypes[self.ui.cmbFormat.currentIndex()]
        filePath = QFileDialog.getSaveFileName(
            self, "Save layer as...", QCoreApplication.applicationDirPath(),
            type1)
        self.ui.txtSavePath.setText(filePath)

    def crsSelectChange(self):
        if self.ui.cmbCrs.currentIndex() == 2:
            self.ui.txtCrs.setEnabled(True)
        else:
            self.ui.txtCrs.setEnabled(False)

    def crsChange(self):
        projectionDlg = QgsGenericProjectionSelector(self)
        projectionDlg.exec_()
        #         print projectionDlg.selectedCrsId()
        srs = QgsCoordinateReferenceSystem(
            projectionDlg.selectedCrsId(),
            QgsCoordinateReferenceSystem.InternalCrsId)
        self.mCRS = srs.srsid()
        self.crs = QgsCoordinateReferenceSystem()
        self.crs.createFromId(self.mCRS,
                              QgsCoordinateReferenceSystem.InternalCrsId)
        #         authId = projectionDlg.selectedAuthId()
        #         crsId = projectionDlg.selectedCrsId()
        #         if authId != "":
        #             if authId[:4] != "EPSG":
        #                 self.crs = QgsCoordinateReferenceSystem(crsId, QgsCoordinateReferenceSystem.InternalCrsId)
        #             else:
        #                 self.crs = QgsCoordinateReferenceSystem(crsId, QgsCoordinateReferenceSystem.EpsgCrsId)
        self.ui.cmbCrs.setCurrentIndex(2)
        self.ui.txtCrs.setText(self.crs.description())

    def saveLayer(self):
        destCrs = None
        ct = QgsCoordinateTransform()
        if self.ui.txtSavePath.text() == "":
            QMessageBox.warning(self, "Error", "Please input save file path")
            return
        else:
            if self.ui.cmbCrs.currentIndex() == 0:
                if self.baseLayer.crs() is None:
                    destCrs = QgsCoordinateReferenceSystem(
                        4326, QgsCoordinateReferenceSystem.EpsgCrsId)
#                     er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs, self.ui.cmbFormat.currentText())
                else:
                    destCrs = self.baseLayer.crs()
                    print destCrs.authid()
#                     er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", self.baseLayer.crs(), self.ui.cmbFormat.currentText())
            elif self.ui.cmbCrs.currentIndex() == 1:
                destCrs = define._canvas.mapSettings().destinationCrs()
                if destCrs is None:
                    destCrs = QgsCoordinateReferenceSystem(
                        4326, QgsCoordinateReferenceSystem.EpsgCrsId)
#                     er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs, self.ui.cmbFormat.currentText())
#                 else:
#                     er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs, self.ui.cmbFormat.currentText())

            else:
                destCrs = QgsCoordinateReferenceSystem(
                    self.mCRS, QgsCoordinateReferenceSystem.InternalCrsId)

            if destCrs != self.baseLayer.crs():
                ct = QgsCoordinateTransform(self.baseLayer.crs(), destCrs)
            er = QgsVectorFileWriter.writeAsVectorFormat(
                self.baseLayer, self.ui.txtSavePath.text(), "utf-8", destCrs,
                self.ui.cmbFormat.currentText())

            #                 er = QgsVectorFileWriter.writeAsVectorFormat(self.baseLayer, self.ui.txtSavePath.text(), "utf-8", self.crs, self.ui.cmbFormat.currentText())
            QMessageBox.information(
                self, "Successful",
                "Export to vector file has been completed. ")
        QDialog.accept(self)
예제 #29
0
class LoadByCategory(QtGui.QDialog, load_by_category_dialog.Ui_LoadByCategory):
    def __init__(self, parent=None):
        """Constructor."""
        super(LoadByCategory, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.filename = ""
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        self.categories = []
        self.selectedClasses = []

        self.point = []
        self.line = []
        self.polygon = []
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []

        #Sql factory generator
        self.isSpatialite = True

        self.setupUi(self)
        self.tabWidget.setCurrentIndex(0)
        self.factory = SqlGeneratorFactory()
        self.gen = self.factory.createSqlGenerator(self.isSpatialite)
        self.utils = Utils()

        self.parentTreeNode = None

        self.comboBoxPostgis.setCurrentIndex(0)
        self.checkBoxPoint.setCheckState(0)
        self.checkBoxLine.setCheckState(0)
        self.checkBoxPolygon.setCheckState(0)
        self.checkBoxAll.setCheckState(0)

        self.bar = QgsMessageBar()
        self.setLayout(QtGui.QGridLayout(self))
        self.layout().setContentsMargins(0,0,0,0)
        self.layout().setAlignment(QtCore.Qt.AlignTop)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        self.bar.setSizePolicy(sizePolicy)
        self.layout().addWidget(self.bar, 0,0,1,1)

        #Objects Connections
        QtCore.QObject.connect(self.pushButtonOpenFile, QtCore.SIGNAL(("clicked()")), self.loadDatabase)
        QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel)
        QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected)
        QtCore.QObject.connect(self.tabWidget,QtCore.SIGNAL(("currentChanged(int)")), self.restoreInitialState)
        QtCore.QObject.connect(self.pushButtonSelectAll, QtCore.SIGNAL(("clicked()")), self.selectAll)
        QtCore.QObject.connect(self.pushButtonDeselectAll, QtCore.SIGNAL(("clicked()")), self.deselectAll)
        QtCore.QObject.connect(self.pushButtonSelectOne, QtCore.SIGNAL(("clicked()")), self.selectOne)
        QtCore.QObject.connect(self.pushButtonDeselectOne, QtCore.SIGNAL(("clicked()")), self.deselectOne)
        QtCore.QObject.connect(self.checkBoxAll, QtCore.SIGNAL(("stateChanged(int)")), self.setAllGroup)

        self.db = None
        #populating the postgis combobox
        self.populatePostGISConnectionsCombo()

    def __del__(self):
        self.closeDatabase()

    def closeDatabase(self):
        if self.db:
            self.db.close()
            self.db = None

    def restoreInitialState(self):
        self.filename = ""
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        self.categories = []
        self.selectedClasses = []
        self.spatialiteFileEdit.setText(self.filename)
        self.postGISCrsEdit.setText('')
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setText('')
        self.spatialiteCrsEdit.setReadOnly(True)
        self.listWidgetCategoryFrom.clear()
        self.listWidgetCategoryTo.clear()

        self.point = []
        self.line = []
        self.polygon = []
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []
        self.parentTreeNode = None

        #Setting the database type
        if self.tabWidget.currentIndex() == 0:
            self.isSpatialite = True
        else:
            self.isSpatialite = False

        #getting the sql generator according to the database type
        self.gen = self.factory.createSqlGenerator(self.isSpatialite)
        self.comboBoxPostgis.setCurrentIndex(0)
        self.checkBoxPoint.setCheckState(0)
        self.checkBoxLine.setCheckState(0)
        self.checkBoxPolygon.setCheckState(0)
        self.checkBoxAll.setCheckState(0)

    def updateBDField(self):
        if self.dbLoaded == True:
            self.spatialiteFileEdit.setText(self.filename)
        else:
            self.filename = ""
            self.spatialiteFileEdit.setText(self.filename)

    def getDatabaseVersion(self):
        self.dbVersion = self.utils.getDatabaseVersion(self.db)
        self.qmlPath = self.utils.getQmlDir(self.db)

    def listCategoriesFromDatabase(self):
        self.listWidgetCategoryFrom.clear()
        self.listWidgetCategoryTo.clear()
        sql = self.gen.getTablesFromDatabase()
        query = QSqlQuery(sql, self.db)

        self.getDatabaseVersion()

        while query.next():
            if self.isSpatialite:
                tableName = query.value(0)
                layerName = tableName
                split = tableName.split('_')
                if len(split) < 2:
                    continue
                if self.dbVersion == '3.0' or self.dbVersion == '2.1.3':
                    schema = split[0]
                    category = split[1]
                    categoryName = schema+'.'+category
                else:
                    categoryName = split[0] #done this way to have back compatibility with spatialites already in production

            else:
                tableSchema = query.value(0)
                tableName = query.value(1)
                split = tableName.split('_')
                category = split[0]
                categoryName = tableSchema+'.'+category
                layerName = tableSchema+'.'+tableName

            if layerName.split("_")[-1] == "p":
                self.point.append(layerName)
            if layerName.split("_")[-1] == "l":
                self.line.append(layerName)
            if layerName.split("_")[-1] == "a":
                self.polygon.append(layerName)

            if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" \
                or tableName.split("_")[-1] == "a":
                self.insertIntoListView(categoryName)
        self.listWidgetCategoryFrom.sortItems()
        self.setCRS()

    def insertIntoListView(self, item_name):
        found = self.listWidgetCategoryFrom.findItems(item_name, Qt.MatchExactly)
        if len(found) == 0:
            item = QtGui.QListWidgetItem(item_name)
            self.listWidgetCategoryFrom.addItem(item)

    def selectAll(self):
        tam = self.listWidgetCategoryFrom.__len__()
        for i in range(tam+1,1,-1):
            item = self.listWidgetCategoryFrom.takeItem(i-2)
            self.listWidgetCategoryTo.addItem(item)
        self.listWidgetCategoryTo.sortItems()

    def deselectAll(self):
        tam = self.listWidgetCategoryTo.__len__()
        for i in range(tam+1,1,-1):
            item = self.listWidgetCategoryTo.takeItem(i-2)
            self.listWidgetCategoryFrom.addItem(item)
        self.listWidgetCategoryFrom.sortItems()

    def selectOne(self):
        listedItems = self.listWidgetCategoryFrom.selectedItems()
        for i in listedItems:
            item = self.listWidgetCategoryFrom.takeItem(self.listWidgetCategoryFrom.row(i))
            self.listWidgetCategoryTo.addItem(item)
        self.listWidgetCategoryTo.sortItems()

    def deselectOne(self):
        listedItems = self.listWidgetCategoryTo.selectedItems()
        for i in listedItems:
            item = self.listWidgetCategoryTo.takeItem(self.listWidgetCategoryTo.row(i))
            self.listWidgetCategoryFrom.addItem(item)
        self.listWidgetCategoryFrom.sortItems()


    def setAllGroup(self):
        if self.checkBoxAll.isChecked():
            self.checkBoxPoint.setCheckState(2)
            self.checkBoxLine.setCheckState(2)
            self.checkBoxPolygon.setCheckState(2)
        else:
            self.checkBoxPoint.setCheckState(0)
            self.checkBoxLine.setCheckState(0)
            self.checkBoxPolygon.setCheckState(0)

    def setCRS(self):
        try:
            self.epsg = self.utils.findEPSG(self.db)
            if self.epsg == -1:
                self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING)
            else:
                self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
                if self.isSpatialite:
                    self.spatialiteCrsEdit.setText(self.crs.description())
                    self.spatialiteCrsEdit.setReadOnly(True)
                else:
                    self.postGISCrsEdit.setText(self.crs.description())
                    self.postGISCrsEdit.setReadOnly(True)
        except:
            pass

    @pyqtSlot(int)
    def on_comboBoxPostgis_currentIndexChanged(self):
        if self.comboBoxPostgis.currentIndex() > 0:
            self.loadDatabase()

    def loadDatabase(self):
        self.closeDatabase()

        if self.isSpatialite:
            (self.filename, self.db) = self.utils.getSpatialiteDatabase()
            if self.filename:
                self.spatialiteFileEdit.setText(self.filename)
        else:
            self.db = self.utils.getPostGISDatabase(self.comboBoxPostgis.currentText())
        try:
            if not self.db.open():
                QgsMessageLog.logMessage(self.db.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
            else:
                self.dbLoaded = True
                self.listCategoriesFromDatabase()
        except:
            pass

    def populatePostGISConnectionsCombo(self):
        self.comboBoxPostgis.clear()
        self.comboBoxPostgis.addItem("Select Database")
        self.comboBoxPostgis.addItems(self.utils.getPostGISConnections())

    def cancel(self):
        self.restoreInitialState()
        self.close()

    def getSelectedItems(self):
        lista = self.classesListWidget.selectedItems()
        self.selectedClasses = []
        tam = len(lista)
        for i in range(tam):
            self.selectedClasses.append(lista[i].text())
        self.selectedClasses.sort()

    def okSelected(self):
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

            if self.checkBoxOnlyWithElements.isChecked():
                self.setLayersWithElements()
                ponto = self.pointWithElement
                linha = self.lineWithElement
                area = self.polygonWithElement
            else:
                ponto = self.point
                linha = self.line
                area = self.polygon

            if self.db and self.crs and len(self.listWidgetCategoryTo)>0:
                categoriasSelecionadas = []
                for i in range(self.listWidgetCategoryTo.__len__()):
                    categoriasSelecionadas.append(self.listWidgetCategoryTo.item(i).text())

                try:
                    if self.checkBoxPoint.isChecked():
                        self.loadLayers('p',categoriasSelecionadas,ponto)
                    if self.checkBoxLine.isChecked():
                        self.loadLayers('l',categoriasSelecionadas,linha)
                    if self.checkBoxPolygon.isChecked():
                        self.loadLayers('a',categoriasSelecionadas,area)
                    if self.checkBoxPoint.isChecked()== False and self.checkBoxLine.isChecked() == False and self.checkBoxPolygon.isChecked() == False:
                        self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one type of layer!"), level=QgsMessageBar.WARNING)
                    else:
                        self.restoreInitialState()
                        self.close()
                except:
                    qgis.utils.iface.messageBar().pushMessage(self.tr("CRITICAL!"), self.tr("Problem loading the categories!"), level=QgsMessageBar.CRITICAL)
                    pass
            else:
                if self.db and not self.crs:
                    self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL)
                if not self.db and not self.crs:
                    self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Database not loaded properly!"), level=QgsMessageBar.CRITICAL)
                    self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL)
                if len(self.listWidgetCategoryTo)==0:
                    self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one category!"), level=QgsMessageBar.WARNING)
                categoriasSelecionadas = []
                self.pointWithElement = []
                self.lineWithElement = []
                self.polygonWithElement = []

            QApplication.restoreOverrideCursor()
        except:
            QApplication.restoreOverrideCursor()

    def loadLayers(self, type, categories, layer_names):
        if self.isSpatialite:
            self.loadSpatialiteLayers(type, categories, layer_names)
        else:

            self.loadPostGISLayers(type, categories, layer_names)

    def setLayersWithElements(self):
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []

        pontoAux = self.countElements(self.point)
        linhaAux = self.countElements(self.line)
        areaAux = self.countElements(self.polygon)

        for i in pontoAux:
            if i[1] > 0:
                self.pointWithElement.append(i[0])

        for i in linhaAux:
            if i[1] > 0:
                self.lineWithElement.append(i[0])

        for i in areaAux:
            if i[1] > 0:
                self.polygonWithElement.append(i[0])

    def countElements(self, layers):
        listaQuantidades = []
        for layer in layers:
            sql = self.gen.getElementCountFromLayer(layer)
            query = QSqlQuery(sql,self.db)
            query.next()
            number = query.value(0)
            if not query.exec_(sql):
                QgsMessageLog.logMessage(self.tr("Problem counting elements: ")+query.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
            listaQuantidades.append([layer, number])
        return listaQuantidades

    def loadPostGISLayers(self, type, categories, layer_names):
        (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText())
        uri = QgsDataSourceURI()
        uri.setConnection(str(host),str(port), str(database), str(user), str(password))
        geom_column = 'geom'
        if self.parentTreeNode is None:
            self.parentTreeNode = qgis.utils.iface.legendInterface (). addGroup (database, -1)

        if type == 'p':
            idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Ponto", True,self.parentTreeNode)
            for categoria in categories:
                self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column)
        if type == 'l':
            idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Linha", True,self.parentTreeNode)
            for categoria in categories:
                self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column)
        if type == 'a':
            idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Area", True,self.parentTreeNode)
            for categoria in categories:
                self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column)

    def preparePostGISToLoad(self, uri, categoria, layer_names, idGrupo, geom_column):
        idSubgrupo = qgis.utils.iface.legendInterface().addGroup(categoria, True, idGrupo)
        layer_names.sort(reverse=True)
        for layer_name in layer_names:
            split = layer_name.split('_')
            category = split[0]
            schema = category.split('.')[0]
            name = layer_name.replace(schema+'.', '')
            if category == categoria:
                sql = self.gen.loadLayerFromDatabase(layer_name)
                uri.setDataSource(schema, name, geom_column, sql, 'id')
                uri.disableSelectAtId(True)
                self.loadEDGVLayer(uri, name, 'postgres', idSubgrupo)

    def prepareSpatialiteToLoad(self, uri, categoria, layer_names, idGrupo, geom_column):
        idSubgrupo = qgis.utils.iface.legendInterface().addGroup(categoria, True, idGrupo)
        layer_names.sort(reverse=True)
        for layer_name in layer_names:
            split = layer_name.split('_')
            if self.dbVersion == '3.0' or self.dbVersion == '2.1.3':
                category = split[0]+'.'+split[1]
            else:
                category = split[0]
            if category == categoria:
                uri.setDataSource('', layer_name, geom_column)
                self.loadEDGVLayer(uri, layer_name, 'spatialite', idSubgrupo)

    def loadSpatialiteLayers(self, type, categories, layer_names):
        uri = QgsDataSourceURI()
        uri.setDatabase(self.filename)
        geom_column = 'GEOMETRY'

        if self.parentTreeNode is None:
            self.parentTreeNode = qgis.utils.iface.legendInterface(). addGroup(self.filename.split('.sqlite')[0].split('/')[-1], -1)

        if type == 'p':
            idGrupo = qgis.utils.iface.legendInterface(). addGroup("Ponto", True, self.parentTreeNode)
            for categoria in categories:
                self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column)
        if type == 'l':
            idGrupo = qgis.utils.iface.legendInterface(). addGroup("Linha", True, self.parentTreeNode)
            for categoria in categories:
                self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column)
        if type == 'a':
            idGrupo = qgis.utils.iface.legendInterface(). addGroup("Area", True, self.parentTreeNode)
            for categoria in categories:
                self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column)

    def loadEDGVLayer(self, uri, layer_name, provider, idSubgrupo):
        vlayer = QgsVectorLayer(uri.uri(), layer_name, provider)
        vlayer.setCrs(self.crs)
        QgsMapLayerRegistry.instance().addMapLayer(vlayer) #added due to api changes
        if self.isSpatialite and (self.dbVersion == '3.0' or self.dbVersion == '2.1.3'):
            lyr = '_'.join(layer_name.replace('\r', '').split('_')[1::])
        else:
            lyr = layer_name.replace('\r','')
        vlayerQml = os.path.join(self.qmlPath, lyr+'.qml')
        vlayer.loadNamedStyle(vlayerQml, False)
        QgsMapLayerRegistry.instance().addMapLayer(vlayer)
        qgis.utils.iface.legendInterface().moveLayer(vlayer, idSubgrupo)
        if not vlayer.isValid():
            QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
예제 #30
0
class LoadByCategory(QtGui.QDialog, FORM_CLASS):
    def __init__(self, codeList, parent=None):
        """Constructor."""
        super(LoadByCategory, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)

        self.categories = []
        self.selectedClasses = []
 
        self.point = []
        self.line = []
        self.polygon = []
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []
 
        self.parentTreeNode = None
 
        self.checkBoxPoint.setCheckState(0)
        self.checkBoxLine.setCheckState(0)
        self.checkBoxPolygon.setCheckState(0)
        self.checkBoxAll.setCheckState(0)
 
        self.bar = QgsMessageBar()
        self.setLayout(QtGui.QGridLayout(self))
        self.layout().setContentsMargins(0,0,0,0)
        self.layout().setAlignment(QtCore.Qt.AlignTop)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        self.bar.setSizePolicy(sizePolicy)
        self.layout().addWidget(self.bar, 0,0,1,1)
 
        #Objects Connections
        self.widget.connectionChanged.connect(self.listCategoriesFromDatabase)
        self.widget.problemOccurred.connect(self.pushMessage)
        
        self.pushButtonCancel.clicked.connect(self.cancel)
        self.pushButtonOk.clicked.connect(self.okSelected)
        self.pushButtonSelectAll.clicked.connect(self.selectAll)
        self.pushButtonDeselectAll.clicked.connect(self.deselectAll)
        self.pushButtonSelectOne.clicked.connect(self.selectOne)
        self.pushButtonDeselectOne.clicked.connect(self.deselectOne)
        self.checkBoxAll.stateChanged.connect(self.setAllGroup)
        
        self.widget.tabWidget.currentChanged.connect(self.restoreInitialState)
        
        self.codeList = codeList
        self.layerFactory = LayerFactory()
 
    def restoreInitialState(self):
        self.categories = []
        self.selectedClasses = []
        self.listWidgetCategoryFrom.clear()
        self.listWidgetCategoryTo.clear()

        self.point = []
        self.line = []
        self.polygon = []
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []
        self.parentTreeNode = None

        self.checkBoxPoint.setCheckState(0)
        self.checkBoxLine.setCheckState(0)
        self.checkBoxPolygon.setCheckState(0)
        self.checkBoxAll.setCheckState(0)

    def listCategoriesFromDatabase(self):
        self.listWidgetCategoryFrom.clear()
        self.listWidgetCategoryTo.clear()

        self.dbVersion = self.widget.getDBVersion()
        self.qmlPath = self.widget.getQmlPath()
        classes = self.widget.abstractDb.listGeomClassesFromDatabase()
        for table in classes:
            schema, layerName = self.widget.abstractDb.getTableSchema(table)
            category = layerName.split('_')[0]
            categoryName = schema+'.'+category
            if layerName.split("_")[-1] == "p":
                self.point.append(table)
            if layerName.split("_")[-1] == "l":
                self.line.append(table)
            if layerName.split("_")[-1] == "a":
                self.polygon.append(table)

            self.insertIntoListView(categoryName)
        self.listWidgetCategoryFrom.sortItems()
        self.setCRS()

    def insertIntoListView(self, item_name):
        found = self.listWidgetCategoryFrom.findItems(item_name, Qt.MatchExactly)
        if len(found) == 0:
            item = QtGui.QListWidgetItem(item_name)
            self.listWidgetCategoryFrom.addItem(item)

    def selectAll(self):
        tam = self.listWidgetCategoryFrom.__len__()
        for i in range(tam+1,1,-1):
            item = self.listWidgetCategoryFrom.takeItem(i-2)
            self.listWidgetCategoryTo.addItem(item)
        self.listWidgetCategoryTo.sortItems()

    def deselectAll(self):
        tam = self.listWidgetCategoryTo.__len__()
        for i in range(tam+1,1,-1):
            item = self.listWidgetCategoryTo.takeItem(i-2)
            self.listWidgetCategoryFrom.addItem(item)
        self.listWidgetCategoryFrom.sortItems()

    def selectOne(self):
        listedItems = self.listWidgetCategoryFrom.selectedItems()
        for i in listedItems:
            item = self.listWidgetCategoryFrom.takeItem(self.listWidgetCategoryFrom.row(i))
            self.listWidgetCategoryTo.addItem(item)
        self.listWidgetCategoryTo.sortItems()

    def deselectOne(self):
        listedItems = self.listWidgetCategoryTo.selectedItems()
        for i in listedItems:
            item = self.listWidgetCategoryTo.takeItem(self.listWidgetCategoryTo.row(i))
            self.listWidgetCategoryFrom.addItem(item)
        self.listWidgetCategoryFrom.sortItems()

    def setAllGroup(self):
        if self.checkBoxAll.isChecked():
            self.checkBoxPoint.setCheckState(2)
            self.checkBoxLine.setCheckState(2)
            self.checkBoxPolygon.setCheckState(2)
        else:
            self.checkBoxPoint.setCheckState(0)
            self.checkBoxLine.setCheckState(0)
            self.checkBoxPolygon.setCheckState(0)
            
    def pushMessage(self, msg):
        self.bar.pushMessage('', msg, level=QgsMessageBar.WARNING)

    def setCRS(self):
        try:
            self.epsg = self.utils.findEPSG(self.db)
            if self.epsg == -1:
                self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING)
            else:
                self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
                if self.isSpatialite:
                    self.spatialiteCrsEdit.setText(self.crs.description())
                    self.spatialiteCrsEdit.setReadOnly(True)
                else:
                    self.postGISCrsEdit.setText(self.crs.description())
                    self.postGISCrsEdit.setReadOnly(True)
        except:
            pass

    def cancel(self):
        self.restoreInitialState()
        self.close()

    def getSelectedItems(self):
        lista = self.classesListWidget.selectedItems()
        self.selectedClasses = []
        tam = len(lista)
        for i in range(tam):
            self.selectedClasses.append(lista[i].text())
        self.selectedClasses.sort()

    def okSelected(self):
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
    
            if self.checkBoxOnlyWithElements.isChecked():
                self.setLayersWithElements()
                ponto = self.pointWithElement
                linha = self.lineWithElement
                area = self.polygonWithElement
            else:
                ponto = self.point
                linha = self.line
                area = self.polygon
    
            if len(self.listWidgetCategoryTo)>0:
                categoriasSelecionadas = []
                for i in range(self.listWidgetCategoryTo.__len__()):
                    categoriasSelecionadas.append(self.listWidgetCategoryTo.item(i).text())
    
                if self.checkBoxPoint.isChecked():
                    self.loadLayers('p', categoriasSelecionadas, ponto)
                if self.checkBoxLine.isChecked():
                    self.loadLayers('l', categoriasSelecionadas, linha)
                if self.checkBoxPolygon.isChecked():
                    self.loadLayers('a', categoriasSelecionadas, area)
                if self.checkBoxPoint.isChecked()== False and self.checkBoxLine.isChecked() == False and self.checkBoxPolygon.isChecked() == False:
                    self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one type of layer!"), level=QgsMessageBar.WARNING)
                else:
                    self.restoreInitialState()
                    self.close()
            else:
                if self.widget.db and not self.widget.crs:
                    self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL)
                if not self.widget.db and not self.widget.crs:
                    self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Database not loaded properly!"), level=QgsMessageBar.CRITICAL)
                    self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL)
                if len(self.listWidgetCategoryTo)==0:
                    self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one category!"), level=QgsMessageBar.WARNING)
                categoriasSelecionadas = []
                self.pointWithElement = []
                self.lineWithElement = []
                self.polygonWithElement = []
    
            QApplication.restoreOverrideCursor()
        except:
            QApplication.restoreOverrideCursor()

    def setLayersWithElements(self):
        self.pointWithElement = []
        self.lineWithElement = []
        self.polygonWithElement = []

        pontoAux = self.widget.abstractDb.countElements(self.point)
        linhaAux = self.widget.abstractDb.countElements(self.line)
        areaAux = self.widget.abstractDb.countElements(self.polygon)

        for i in pontoAux:
            if i[1] > 0:
                self.pointWithElement.append(i[0])

        for i in linhaAux:
            if i[1] > 0:
                self.lineWithElement.append(i[0])

        for i in areaAux:
            if i[1] > 0:
                self.polygonWithElement.append(i[0])

    def loadLayers(self, type, categories, table_names):
        dbName = self.widget.abstractDb.getDatabaseName()
        groupList = qgis.utils.iface.legendInterface().groups()
        groupRelationshipList = qgis.utils.iface.legendInterface().groupLayerRelationship()
        if dbName not in groupList:
            self.parentTreeNode = qgis.utils.iface.legendInterface (). addGroup (dbName, -1)
        else:
            self.parentTreeNode = groupList.index(dbName)

        if type == 'p':
            if len(groupList[self.parentTreeNode::]) == 0:
                idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Point'), True,self.parentTreeNode)
            elif self.tr('Point') not in groupRelationshipList[self.parentTreeNode][1]:
                idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Point'), True,self.parentTreeNode)
            else:
                idGrupo = groupList[self.parentTreeNode::].index(self.tr('Point'))
            for category in categories:
                self.prepareLayer(category, table_names, idGrupo)
        if type == 'l':
            if len(groupList[self.parentTreeNode::]) == 0:
                idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Line'), True,self.parentTreeNode)
            elif self.tr('Line') not in groupRelationshipList[self.parentTreeNode][1]:
                idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Line'), True,self.parentTreeNode)
            else:
                idGrupo = groupList[self.parentTreeNode::].index(self.tr('Line'))
            for category in categories:
                self.prepareLayer(category, table_names, idGrupo)
        if type == 'a':
            if len(groupList[self.parentTreeNode::]) == 0:
                idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Area'), True,self.parentTreeNode)
            elif self.tr('Area') not in groupRelationshipList[self.parentTreeNode][1]:
                idGrupo = qgis.utils.iface.legendInterface (). addGroup (self.tr('Area'), True,self.parentTreeNode)
            else:
                idGrupo = groupList[self.parentTreeNode::].index(self.tr('Area'))
            for category in categories:
                self.prepareLayer(category, table_names, idGrupo)
                
    def prepareLayer(self, category, table_names, idGrupo):
        idSubgrupo = qgis.utils.iface.legendInterface().addGroup(category, True, idGrupo)
        table_names.sort(reverse=True)
        for table_name in table_names:
            schema, layerName = self.widget.abstractDb.getTableSchema(table_name)
            if (category.split('.')[1] == layerName.split('_')[0]) and (category.split('.')[0] == schema):
                edgvLayer = self.layerFactory.makeLayer(self.widget.abstractDb, self.codeList, table_name)
                edgvLayer.load(self.widget.crs, idSubgrupo)
예제 #31
0
파일: crs.py 프로젝트: taesa-tec/0044-CQFS
""""
https://docs.qgis.org/2.18/en/docs/pyqgis_developer_cookbook/crs.html
"""
from qgis.core import QgsCoordinateReferenceSystem
from osgeo import osr


if __name__ == '__console__':
    print("-----------------------------------------------\n\n")
    # PostGIS SRID 4326 is allocated for WGS84
    # If not specified otherwise in second parameter, PostGIS SRID is used by default.
    crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.PostgisCrsId)
    print("Valid: ", crs.isValid())
    print("QGIS CRS ID:", crs.srsid())
    print("EPSG ID:", crs.authid())
    print("Description:", crs.description())
    print("Projection Acronym:", crs.projectionAcronym())
    print("Ellipsoid Acronym:", crs.ellipsoidAcronym())
    print("Proj4 String:", crs.toProj4())
    # check whether it's geographic or projected coordinate system
    print("Is geographic:", crs.geographicFlag())
    # check type of map units in this CRS (values defined in QGis::units enum)
    print("Map units:", crs.mapUnits())
    print("-----------------------------------------------\n\n")

    wkt = '''GEOGCS["WGS84", DATUM["WGS84", SPHEROID["WGS84", 6378137.0, 298.257223563]],
                PRIMEM["Greenwich", 0.0],
                UNIT["degree", 0.017453292519943295],
                AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]'''
    crs = QgsCoordinateReferenceSystem(wkt)
    print("Valid: ", crs.isValid())
예제 #32
0
class CriaSpatialiteDialog(QtGui.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(CriaSpatialiteDialog, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)

        self.filepath = ""
        self.carregado = False
        self.coordSysDefinido = False
        self.epsgCriaSpatialite = 0
        self.srsCriaSpatialite = ''
        self.sqliteFileName = ''

        self.bar = QgsMessageBar()
        self.setLayout(QtGui.QGridLayout(self))
        self.layout().setContentsMargins(0,0,0,0)
        self.layout().setAlignment(QtCore.Qt.AlignTop)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        self.bar.setSizePolicy(sizePolicy)
        self.layout().addWidget(self.bar, 0,0,1,1)

        QtCore.QObject.connect(self.pushButtonBuscarPastaDestinoCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.definePastaDestino)
        QtCore.QObject.connect(self.pushButtonBuscarSistCoordCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.setaSistCoordCriaSpatialite)
        QtCore.QObject.connect(self.pushButtonOkCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.okselecionadoCriaSpatialite)

    def getTemplateLocation(self):
        currentPath = os.path.dirname(__file__)
        if self.versionComboBox.currentText() == '2.1.3':
            edgvPath = os.path.join(currentPath, 'template', '213', 'seed_edgv213.sqlite')
        elif self.versionComboBox.currentText() == 'FTer_2a_Ed':
            edgvPath = os.path.join(currentPath, 'template', 'FTer_2a_Ed', 'seed_edgvfter_2a_ed.sqlite')
        return edgvPath

    def restauraInicio(self):
        self.filepath = ""
        self.carregado = False
        self.coordSysDefinido = False
        self.epsgCriaSpatialite = 0
        self.srsCriaSpatialite = ''
        self.sqliteFileName = ''
        self.pastaDestinoCriaSpatialiteLineEdit.setText("")
        self.coordSysCriaSpatialiteLineEdit.setText("")
        self.nomeLineEdit.setText("")

    def definePastaDestino(self):
        fd = QtGui.QFileDialog()
        self.filepath = fd.getExistingDirectory()
        if self.filepath <> "":
            self.carregado = True
            self.pastaDestinoCriaSpatialiteLineEdit.setText(self.filepath)

    def setaSistCoordCriaSpatialite(self):
        projSelector = QgsGenericProjectionSelector()
        projSelector.setMessage(theMessage=self.tr('Please, select the coordinate system'))
        projSelector.exec_()
        try:
            self.epsgCriaSpatialite = int(projSelector.selectedAuthId().split(':')[-1])
            self.srsCriaSpatialite = QgsCoordinateReferenceSystem(self.epsgCriaSpatialite, QgsCoordinateReferenceSystem.EpsgCrsId)
            if self.srsCriaSpatialite <> "":
                self.coordSysDefinido = True
                self.coordSysCriaSpatialiteLineEdit.setText(self.srsCriaSpatialite.description())
        except:
            self.bar.pushMessage("", self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING)
            pass

    def copiaSemente(self,destino,srid):
        f = open(self.getTemplateLocation(),'rb')
        g = open(destino,'wb')
        x = f.readline()
        while x:
            g.write(x)
            x = f.readline()

        g.close()

        con = sqlite3.connect(destino)
        cursor = con.cursor()
        srid_sql = (srid,)
        cursor.execute("UPDATE geometry_columns SET srid=?",srid_sql)
        con.commit()
        con.close()

    def okselecionadoCriaSpatialite(self):
        if self.carregado and self.coordSysDefinido and len(self.nomeLineEdit.text()) > 0:
            try:
                self.sqliteFileName = self.filepath+'/'+self.nomeLineEdit.text()+'.sqlite'
                destino = self.sqliteFileName
                self.copiaSemente(destino,self.epsgCriaSpatialite)
                self.close()
                self.restauraInicio()
                QtGui.QMessageBox.information(self, self.tr('Information'), self.tr('Spatialite created successfully!'))
            except:
                qgis.utils.iface.messageBar().pushMessage(self.tr("Error!"), self.tr("Problem creating the database!"), level=QgsMessageBar.CRITICAL)
                self.restauraInicio()
                pass
        else:
            if self.coordSysDefinido == False:
                self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING)
            if self.carregado == False:
                self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select a folder to save the database'), level=QgsMessageBar.CRITICAL)
            if len(self.nomeLineEdit.text()) == 0:
                self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, fill the file name.'), level=QgsMessageBar.CRITICAL)
예제 #33
0
파일: connector.py 프로젝트: GeoCat/QGIS
 def getSpatialRefInfo(self, srid):
     crs = QgsCoordinateReferenceSystem(srid)
     return crs.description()
예제 #34
0
class ConnectionWidget(QtGui.QWidget, FORM_CLASS):
    connectionChanged = pyqtSignal()
    problemOccurred = pyqtSignal(str)
    
    def __init__(self, parent = None):
        """Constructor."""
        super(ConnectionWidget, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        
        self.setInitialState()
         
    def __del__(self):
        self.closeDatabase()

    def closeDatabase(self):
        if self.abstractDb:
            del self.abstractDb
            self.abstractDb = None

    def setInitialState(self):
        self.filename = ''
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        
        self.abstractDb = None
        self.isSpatialite = True
        self.tabWidget.setCurrentIndex(0)
        self.abstractDbFactory = DbFactory()
        self.utils = Utils()

        #populating the postgis combobox
        self.comboBoxPostgis.setCurrentIndex(0)
        self.populatePostGISConnectionsCombo()
        self.spatialiteFileEdit.setReadOnly(True)   
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setReadOnly(True)   
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setReadOnly(True)       

    @pyqtSlot(int)
    def on_comboBoxPostgis_currentIndexChanged(self):
        if self.comboBoxPostgis.currentIndex() > 0:
            self.postGISCrsEdit.setText('')
            self.postGISCrsEdit.setReadOnly(True)
            self.edgvPostgisVersionEdit.setText('')
            self.edgvPostgisVersionEdit.setReadOnly(True)  
            self.loadDatabase()
            self.connectionChanged.emit()
        
    @pyqtSlot(bool)
    def on_pushButtonOpenFile_clicked(self):  
        self.loadDatabase()
        if self.isDBConnected():
            self.connectionChanged.emit()
        
    @pyqtSlot(int)
    def on_tabWidget_currentChanged(self):
        self.filename = ''
        self.comboBoxPostgis.setCurrentIndex(0)
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        self.dbVersion = ''
        
        self.spatialiteFileEdit.setReadOnly(True)
        self.spatialiteFileEdit.setText(self.filename)
        self.postGISCrsEdit.setText('')
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setText('')
        self.spatialiteCrsEdit.setReadOnly(True)   
        self.edgvSpatialiteVersionEdit.setText('')
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setText('')
        self.edgvPostgisVersionEdit.setReadOnly(True)     
        
        
        #Setting the database type
        if self.tabWidget.currentIndex() == 0:
            self.isSpatialite = True
        else:
            self.isSpatialite = False

    def loadDatabase(self):
        self.closeDatabase()
        if self.isSpatialite:
            self.abstractDb = self.abstractDbFactory.createDbFactory('QSQLITE')
            self.abstractDb.connectDatabase()
            self.spatialiteFileEdit.setText(self.abstractDb.db.databaseName())
            self.edgvSpatialiteVersionEdit.setText(self.abstractDb.getDatabaseVersion())
                
        else:
            self.abstractDb = self.abstractDbFactory.createDbFactory('QPSQL')
            self.abstractDb.connectDatabase(self.comboBoxPostgis.currentText())
            self.edgvPostgisVersionEdit.setText(self.abstractDb.getDatabaseVersion())
        try:
            self.abstractDb.checkAndOpenDb()
            self.dbLoaded = True
            self.dbVersion = self.abstractDb.getDatabaseVersion()
            if self.dbVersion == '-1':
                self.problemOccurred.emit(self.tr('This is not a valid DsgTools database!'))
            else:
                self.setCRS()
        except Exception as e:
            QgsMessageLog.logMessage(e.args[0], "DSG Tools Plugin", QgsMessageLog.CRITICAL)    

    def setCRS(self):
        try:
            self.epsg = self.abstractDb.findEPSG()
            if self.epsg == -1:
                self.problemOccurred.emit(self.tr('Coordinate Reference System not set or invalid!'))
            else:
                self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
                if self.isSpatialite:
                    self.spatialiteCrsEdit.setText(self.crs.description())
                    self.spatialiteCrsEdit.setReadOnly(True)
                else:
                    self.postGISCrsEdit.setText(self.crs.description())
                    self.postGISCrsEdit.setReadOnly(True)
        except:
            pass

    def populatePostGISConnectionsCombo(self):
        self.comboBoxPostgis.clear()
        self.comboBoxPostgis.addItem(self.tr('Select Database'))
        self.comboBoxPostgis.addItems(self.getPostGISConnections())
        
    def isDBConnected(self):
        return self.dbLoaded
        
    def getDBVersion(self):
        return self.abstractDb.getDatabaseVersion()
    
    def getQmlPath(self):
        return self.abstractDb.getQmlDir()
        
    @pyqtSlot(bool)
    def on_addConnectionButton_clicked(self):  
        newConnectionDialog =  ServerDBExplorer(self)
        retvalue = newConnectionDialog.exec_()
        self.populatePostGISConnectionsCombo()
        return retvalue
    
    def getPostGISConnections(self):
        settings = QSettings()
        settings.beginGroup('PostgreSQL/connections')
        currentConnections = settings.childGroups()
        settings.endGroup()
        return currentConnections
예제 #35
0
    def processAlgorithm(self, parameters, context, feedback):

        pasta = self.parameterAsFile(parameters, self.FOLDER, context)
        if not pasta:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.FOLDER))

        subpasta = self.parameterAsBool(parameters, self.SUBFOLDER, context)

        formato = self.parameterAsString(parameters, self.FORMAT, context)

        geometria = self.parameterAsEnum(parameters, self.GEOMETRY, context)

        crs = self.parameterAsCrs(parameters, self.CRS, context)

        # OUTPUT
        GeomType = QgsWkbTypes.Point if geometria == 1 else QgsWkbTypes.Polygon
        Fields = QgsFields()
        itens = {
            self.tr('name', 'nome'): QVariant.String,
            self.tr('extension', 'extensão'): QVariant.String,
            self.tr('path', 'caminho'): QVariant.String,
            self.tr('resX'): QVariant.Double,
            self.tr('resY'): QVariant.Double,
            self.tr('n_cols'): QVariant.Int,
            self.tr('n_rows', 'n_lin'): QVariant.Int,
            self.tr('crs', 'src'): QVariant.String,
            self.tr('n_bands', 'n_bandas'): QVariant.Int,
            self.tr('dataType', 'tipoDado'): QVariant.String,
        }
        for item in itens:
            Fields.append(QgsField(item, itens[item]))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, Fields, GeomType, crs)
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        # Listar Arquivos
        feedback.pushInfo(
            self.tr('Checking files in the folder...',
                    'Checando arquivos na pasta...'))
        lista = []
        if subpasta:
            for root, dirs, files in os.walk(pasta, topdown=True):
                for name in files:
                    if name[-1 * len(formato):] == formato:
                        lista += [os.path.join(root, name)]
        else:
            for item in os.listdir(pasta):
                if item[-1 * len(formato):] == formato:
                    lista += [os.path.join(pasta, item)]

        total = 100.0 / len(lista) if len(lista) > 0 else 0

        # Obter dados dos arquivos listados
        feedback.pushInfo(
            self.tr('Creating raster files...',
                    'Criando inventário de arquivos raster...'))
        for current, file_path in enumerate(lista):
            image = gdal.Open(file_path)  # https://gdal.org/python/
            prj = image.GetProjection()  # wkt
            ulx, xres, xskew, uly, yskew, yres = image.GetGeoTransform()
            GDT = image.GetRasterBand(1).DataType
            n_bands = image.RasterCount
            cols = image.RasterXSize  # Number of columns
            rows = image.RasterYSize  # Number of rows
            CRS = QgsCoordinateReferenceSystem(prj)  # Create CRS
            image = None  # Close image

            # Creating BBox
            coord = [[
                QgsPointXY(ulx, uly),
                QgsPointXY(ulx + cols * xres, uly),
                QgsPointXY(ulx + cols * xres, uly + rows * yres),
                QgsPointXY(ulx, uly + rows * yres),
                QgsPointXY(ulx, uly)
            ]]
            geom = QgsGeometry.fromPolygonXY(coord)

            # CRS transformation
            coordinateTransformer = QgsCoordinateTransform()
            coordinateTransformer.setDestinationCrs(crs)
            coordinateTransformer.setSourceCrs(CRS)
            geom_transf = self.reprojectPoints(geom, coordinateTransformer)

            # Attributes
            path, file = os.path.split(file_path)
            name = os.path.splitext(file)[0]
            extension = os.path.splitext(file)[1]
            att = [
                name, extension, path,
                abs(xres),
                abs(yres), cols, rows,
                CRS.description(), n_bands,
                gdal.GetDataTypeName(GDT)
            ]

            # Saving feature
            feat = QgsFeature()
            feat.setGeometry(geom_transf.centroid()
                             ) if geometria == 1 else feat.setGeometry(
                                 geom_transf)  # centroid or polygon
            feat.setAttributes(att)
            sink.addFeature(feat, QgsFeatureSink.FastInsert)

            if feedback.isCanceled():
                break
            feedback.setProgress(int((current + 1) * total))

        feedback.pushInfo(
            self.tr('Operation completed successfully!',
                    'Operação finalizada com sucesso!'))
        feedback.pushInfo('Leandro França - Eng Cart')
        return {self.OUTPUT: dest_id}
예제 #36
0
class ConnectionWidget(QtGui.QWidget, FORM_CLASS):
    connectionChanged = pyqtSignal()
    problemOccurred = pyqtSignal(str)
    dbChanged = pyqtSignal(AbstractDb)
    styleChanged = pyqtSignal(dict)

    def __init__(self, parent=None):
        """Constructor."""
        super(ConnectionWidget, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.setInitialState()
        self.serverWidget.populateServersCombo()
        self.serverWidget.abstractDbLoaded.connect(self.getDatabasesFromServer)
        self.serverWidget.clearWidgets.connect(self.clearAll)

    def __del__(self):
        """
        Closes the database
        """
        self.closeDatabase()

    def closeDatabase(self):
        """
        Closes the current database
        """
        if self.abstractDb:
            del self.abstractDb
            self.abstractDb = None

    def clearAll(self):
        """
        Resets the initial state
        """
        self.filename = ''
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None

        self.abstractDb = None
        self.isSpatialite = False
        self.abstractDbFactory = DbFactory()
        self.utils = Utils()

        #populating the postgis combobox
        self.comboBoxPostgis.clear()
        self.spatialiteFileEdit.setReadOnly(True)
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setReadOnly(True)
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setReadOnly(True)

    def setInitialState(self):
        """
        Sets the initial state
        """
        self.filename = ''
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None

        self.abstractDb = None
        self.isSpatialite = False
        self.tabWidget.setCurrentIndex(0)
        self.abstractDbFactory = DbFactory()
        self.utils = Utils()
        self.serverWidget.serversCombo.setCurrentIndex(0)

        #populating the postgis combobox
        self.comboBoxPostgis.clear()
        self.spatialiteFileEdit.setReadOnly(True)
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setReadOnly(True)
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setReadOnly(True)

    @pyqtSlot(int)
    def on_comboBoxPostgis_currentIndexChanged(self):
        """
        Updates database information when the combo box changes
        """
        if self.comboBoxPostgis.currentIndex() > 0:
            self.postGISCrsEdit.setText('')
            self.postGISCrsEdit.setReadOnly(True)
            self.edgvPostgisVersionEdit.setText('')
            self.edgvPostgisVersionEdit.setReadOnly(True)
            self.loadDatabase()
            self.connectionChanged.emit()

    @pyqtSlot(bool)
    def on_pushButtonOpenFile_clicked(self):
        """
        Loads a spatialite database
        """
        self.loadDatabase()
        if self.isDBConnected():
            self.connectionChanged.emit()

    @pyqtSlot(int)
    def on_tabWidget_currentChanged(self):
        """
        Changes the tab to work with spatialite or postgis databases
        """
        self.filename = ''
        self.comboBoxPostgis.clear()
        self.dbLoaded = False
        self.epsg = 0
        self.crs = None
        self.dbVersion = ''
        self.serverWidget.serversCombo.setCurrentIndex(0)
        self.spatialiteFileEdit.setReadOnly(True)
        self.spatialiteFileEdit.setText(self.filename)
        self.postGISCrsEdit.setText('')
        self.postGISCrsEdit.setReadOnly(True)
        self.spatialiteCrsEdit.setText('')
        self.spatialiteCrsEdit.setReadOnly(True)
        self.edgvSpatialiteVersionEdit.setText('')
        self.edgvSpatialiteVersionEdit.setReadOnly(True)
        self.edgvPostgisVersionEdit.setText('')
        self.edgvPostgisVersionEdit.setReadOnly(True)
        self.mGroupBox.setTitle(self.tr('Database connection'))

        #Setting the database type
        if self.tabWidget.currentIndex() == 1:
            self.isSpatialite = True
        else:
            self.isSpatialite = False

    def loadDatabase(self):
        """
        Loads the selected database
        """
        self.closeDatabase()
        try:
            if self.isSpatialite:
                self.abstractDb = self.abstractDbFactory.createDbFactory(
                    'QSQLITE')
                self.abstractDb.connectDatabase()
                self.spatialiteFileEdit.setText(
                    self.abstractDb.db.databaseName())
                self.edgvSpatialiteVersionEdit.setText(
                    self.abstractDb.getDatabaseVersion())

            else:
                self.abstractDb = self.abstractDbFactory.createDbFactory(
                    'QPSQL')
                (host, port, user,
                 password) = self.serverWidget.getServerParameters()
                dbName = self.comboBoxPostgis.currentText()
                self.abstractDb.connectDatabaseWithParameters(
                    host, port, dbName, user, password)
                self.edgvPostgisVersionEdit.setText(
                    self.abstractDb.getDatabaseVersion())
                serverName = self.serverWidget.serversCombo.currentText()
                newText = dbName + self.tr(' on ') + serverName
                self.mGroupBox.setToolTip(newText)
                # self.mGroupBox.setTitle(newText)

            self.abstractDb.checkAndOpenDb()
            self.dbLoaded = True
            self.dbVersion = self.abstractDb.getDatabaseVersion()
            self.abstractDb.checkAndCreateStyleTable()
            self.styles = self.abstractDb.getStyleDict(self.dbVersion)
            self.styleChanged.emit(self.styles)
            self.dbChanged.emit(self.abstractDb)
            if self.dbVersion == '-1':
                self.problemOccurred.emit(
                    self.tr('This is not a valid DsgTools database!'))
            else:
                self.setCRS()
        except Exception as e:
            self.problemOccurred.emit(
                self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin",
                                     QgsMessageLog.CRITICAL)

    def setCRS(self):
        """
        Sets the CRS information
        """
        try:
            self.epsg = self.abstractDb.findEPSG()
            if self.epsg == -1:
                self.problemOccurred.emit(
                    self.tr('Coordinate Reference System not set or invalid!'))
            else:
                self.crs = QgsCoordinateReferenceSystem(
                    self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
                if self.isSpatialite:
                    self.spatialiteCrsEdit.setText(self.crs.description())
                    self.spatialiteCrsEdit.setReadOnly(True)
                else:
                    self.postGISCrsEdit.setText(self.crs.description())
                    self.postGISCrsEdit.setReadOnly(True)
        except Exception as e:
            self.problemOccurred.emit(
                self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin",
                                     QgsMessageLog.CRITICAL)

    def isDBConnected(self):
        """
        Checks if the database is already loaded
        """
        return self.dbLoaded

    def getDBVersion(self):
        """
        Gets the database version
        """
        ret = ''
        try:
            ret = self.abstractDb.getDatabaseVersion()
        except Exception as e:
            self.problemOccurred.emit(
                self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin",
                                     QgsMessageLog.CRITICAL)
        return ret

    def getQmlPath(self):
        """
        Gets the QML path
        """
        ret = ''
        try:
            ret = self.abstractDb.getQmlDir()
        except Exception as e:
            self.problemOccurred.emit(
                self.tr('A problem occurred! Check log for details.'))
            QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin",
                                     QgsMessageLog.CRITICAL)
        return ret

    def getDatabasesFromServer(self):
        """
        Gets databases from server
        """
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            if self.serverWidget.abstractDb:
                dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(
                    parentWidget=self)
                dbList.sort()
                self.comboBoxPostgis.clear()
                self.comboBoxPostgis.addItem(self.tr('Select Database'))
                for db, version in dbList:
                    self.comboBoxPostgis.addItem(db)

            else:
                self.setInitialState()
                return
        except Exception as e:
            QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
            self.setInitialState()
            self.setInitialState()
        QApplication.restoreOverrideCursor()
예제 #37
0
class QGISRedCreateProjectDialog(QDialog, FORM_CLASS):
    # Common variables
    iface = None
    NetworkName = ""
    ProjectDirectory = ""
    gplFile = ""
    TemporalFolder = "Temporal folder"

    def __init__(self, parent=None):
        """Constructor."""
        super(QGISRedCreateProjectDialog, self).__init__(parent)
        self.setupUi(self)
        self.btCreateProject.clicked.connect(self.createProject)
        self.btSelectDirectory.clicked.connect(self.selectDirectory)
        self.btSelectCRS.clicked.connect(self.selectCRS)
        # Variables:
        gplFolder = os.path.join(os.getenv('APPDATA'), "QGISRed")
        try:  # create directory if does not exist
            os.stat(gplFolder)
        except Exception:
            os.mkdir(gplFolder)
        self.gplFile = os.path.join(gplFolder, "qgisredprojectlist.gpl")

    def config(self, ifac, direct, netw, parent):
        self.iface = ifac
        self.parent = parent
        utils = QGISRedUtils(direct, netw, ifac)
        self.crs = utils.getProjectCrs()
        self.tbCRS.setText(self.crs.description())
        self.NetworkName = netw
        self.ProjectDirectory = direct
        self.tbNetworkName.setText(netw)
        self.tbProjectDirectory.setText(direct)
        self.tbProjectDirectory.setCursorPosition(0)

    def selectDirectory(self):
        selected_directory = QFileDialog.getExistingDirectory()
        if not selected_directory == "":
            self.tbProjectDirectory.setText(selected_directory)
            self.tbProjectDirectory.setCursorPosition(0)
            self.ProjectDirectory = selected_directory
            self.NetworkName = self.tbNetworkName.text()

    def selectCRS(self):
        projSelector = QgsGenericProjectionSelector()
        if projSelector.exec_():
            crsId = projSelector.crs().srsid()
            if not crsId == 0:
                self.crs = QgsCoordinateReferenceSystem()
                self.crs.createFromId(crsId, QgsCoordinateReferenceSystem.InternalCrsId)
                self.tbCRS.setText(self.crs.description())

    def validationsCreateProject(self):
        self.NetworkName = self.tbNetworkName.text()
        if len(self.NetworkName) == 0:
            self.iface.messageBar().pushMessage("Validations", "The network's name is not valid", level=1)
            return False
        self.ProjectDirectory = self.tbProjectDirectory.text()
        if len(self.ProjectDirectory) == 0 or self.ProjectDirectory == self.TemporalFolder:
            self.ProjectDirectory = tempfile._get_default_tempdir() + "\\" + next(tempfile._get_candidate_names())
        else:
            if not os.path.exists(self.ProjectDirectory):
                self.iface.messageBar().pushMessage("Validations", "The project directory does not exist", level=1)
                return False
            else:
                dirList = os.listdir(self.ProjectDirectory)
                layers = ["Pipes", "Junctions", "Tanks", "Reservoirs", "Valves", "Pumps", "IsolationValves", "Hydrants",
                          "WashoutValves", "AirReleaseValves", "ServiceConnections", "Manometers", "Flowmeters",
                          "Countermeters", "LevelSensors"]
                for layer in layers:
                    if self.NetworkName + "_" + layer + ".shp" in dirList:
                        message = "The project directory has some file to selected network's name"
                        self.iface.messageBar().pushMessage("Validations", message, level=1)
                        return False

        return True

    def createProject(self):
        # Validations
        isValid = self.validationsCreateProject()
        if isValid is True:
            epsg = self.crs.authid().replace("EPSG:", "")
            # Process
            QApplication.setOverrideCursor(Qt.WaitCursor)
            resMessage = GISRed.CreateProject(self.ProjectDirectory, self.NetworkName, epsg)
            QApplication.restoreOverrideCursor()

            # Message
            if resMessage == "True":
                self.iface.messageBar().pushMessage("Information", "Process successfully completed", level=3, duration=5)
                # Project manager list
                file = open(self.gplFile, "a+")
                QGISRedUtils().writeFile(file, self.NetworkName + ";" + self.ProjectDirectory + '\n')
                file.close()

                # open layers
                self.parent.openElementLayers(None, self.NetworkName, self.ProjectDirectory)
            elif resMessage == "False":
                self.iface.messageBar().pushMessage("Warning", "Some issues occurred in the process", level=1, duration=5)
            else:
                self.iface.messageBar().pushMessage("Error", resMessage, level=2, duration=5)

            self.close()
예제 #38
0
class Dialog(QDialog, Ui_Dialog):

    def __init__(self, iface):
        QDialog.__init__(self, iface.mainWindow())
        self.iface = iface
        self.setupUi(self)
        self.toolOut.setEnabled(False)
        self.toolOut.setVisible(False)
        self.outShape.setEnabled(False)
        self.outShape.setVisible(False)
        self.label_2.setVisible(False)
        self.label_2.setEnabled(False)
        self.setWindowTitle(self.tr("Define current projection"))
        self.buttonOk = self.buttonBox_2.button(QDialogButtonBox.Ok)
        QObject.connect(self.btnProjection, SIGNAL("clicked()"), self.outProjFile)
        QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.updateProj1)
        QObject.connect(self.cmbLayer, SIGNAL("currentIndexChanged(QString)"), self.updateProj2)
        # populate layer list
        self.progressBar.setValue(0)
        layers = ftools_utils.getLayerNames([QGis.Point, QGis.Line, QGis.Polygon])
        self.inShape.addItems(layers)
        self.cmbLayer.addItems(layers)

        self.crs = None

    def updateProj1(self, layerName):
        self.inRef.clear()
        tempLayer = ftools_utils.getVectorLayerByName(layerName)
        crs = tempLayer.dataProvider().crs()
        if crs.isValid():
            self.inRef.insert(crs.authid() + " - " + crs.description())
        else:
            self.inRef.insert(self.tr("Missing or invalid CRS"))

    def updateProj2(self, layerName):
        self.outRef.clear()
        tempLayer = ftools_utils.getVectorLayerByName(layerName)
        crs = tempLayer.dataProvider().crs()
        if crs.isValid():
            self.outRef.insert(crs.authid() + " - " + crs.description())
        else:
            self.outRef.insert(self.tr("Missing or invalid CRS"))

    def accept(self):
        self.buttonOk.setEnabled(False)
        if self.inShape.currentText() == "":
            QMessageBox.information(self, self.tr("Define current projection"), self.tr("No input shapefile specified"))
        elif self.txtProjection.text() == "" and self.rdoProjection.isChecked():
            QMessageBox.information(self, self.tr("Define current projection"), self.tr("Please specify spatial reference system"))
        elif self.cmbLayer.currentText() == "" and self.rdoLayer.isChecked():
            QMessageBox.information(self, self.tr("Define current projection"), self.tr("Please specify spatial reference system"))
        else:
            self.progressBar.setValue(5)
            inName = self.inShape.currentText()
            self.progressBar.setValue(10)
            vLayer = ftools_utils.getVectorLayerByName(inName)
            self.progressBar.setValue(30)
            if vLayer == "Error":
                QMessageBox.information(self, self.tr("Define current projection"), self.tr("Cannot define projection for PostGIS data...yet!"))
            else:
                srsDefine = None
                if self.rdoProjection.isChecked():
                    srsDefine = self.crs
                else:
                    destLayer = ftools_utils.getVectorLayerByName(self.cmbLayer.currentText())
                    srsDefine = destLayer.crs()
                if srsDefine == vLayer.crs():
                    responce = QMessageBox.question(self, self.tr("Define current projection"),
                                                    self.tr("Identical output spatial reference system chosen\n\nAre you sure you want to proceed?"),
                                                    QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
                    if responce == QMessageBox.No:
                        self.progressBar.setValue(0)
                        self.buttonOk.setEnabled(True)
                        return
                provider = vLayer.dataProvider()
                self.progressBar.setValue(35)
                inPath = provider.dataSourceUri()
                p = re.compile("\|.*")
                inPath = p.sub("", inPath)
                self.progressBar.setValue(40)
                if inPath.endswith(".shp"):
                    inPath = inPath[:-4]
                self.progressBar.setValue(55)
                if not srsDefine.isValid():
                    QMessageBox.information(self, self.tr("Define current projection"), self.tr("Output spatial reference system is not valid"))
                else:
                    self.progressBar.setValue(60)
                    outputWkt = srsDefine.toWkt()
                    self.progressBar.setValue(65)
                    outputFile = QFile(inPath + ".prj")
                    outputFile.open(QIODevice.WriteOnly | QIODevice.Text)
                    outputPrj = QTextStream(outputFile)
                    outputPrj << outputWkt
                    outputPrj.flush()
                    outputFile.close()
                    self.progressBar.setValue(70)
                    checkFile = QFile(inPath + ".qpj")
                    if checkFile.exists():
                        checkFile.open(QIODevice.WriteOnly | QIODevice.Text)
                        outputPrj = QTextStream(checkFile)
                        outputPrj << outputWkt
                        outputPrj.flush()
                        checkFile.close()
                    self.progressBar.setValue(95)
                    vLayer.setCrs(srsDefine)
                    self.progressBar.setValue(100)
                    QMessageBox.information(self, self.tr("Define current projection"),
                                            self.tr("Defined Projection For:\n%s.shp") % (inPath))
        self.progressBar.setValue(0)
        self.buttonOk.setEnabled(True)

    def outProjFile(self):
        header = "Define layer CRS:"
        sentence1 = self.tr("Please select the projection system that defines the current layer.")
        sentence2 = self.tr("Layer CRS information will be updated to the selected CRS.")
        projSelector = QgsGenericProjectionSelector(self)
        projSelector.setMessage("<h2>%s</h2>%s <br/> %s" % (header, sentence1, sentence2))
        if projSelector.exec_():
            self.crs = QgsCoordinateReferenceSystem(projSelector.selectedCrsId(), QgsCoordinateReferenceSystem.InternalCrsId)
            print "AUTHID", projSelector.selectedAuthId()
            if len(projSelector.selectedAuthId()) == 0:
                QMessageBox.information(self, self.tr("Export to new projection"), self.tr("No Valid CRS selected"))
                return
            else:
                self.txtProjection.clear()
                self.txtProjection.insert(self.crs.authid() + " - " + self.crs.description())
        else:
            return
예제 #39
0
class QGISRedImportDialog(QDialog, FORM_CLASS):
    # Common variables
    iface = None
    NewProject = True
    NetworkName = ""
    ProjectDirectory = ""
    InpFile = ""
    gplFile = ""
    TemporalFolder = "Temporal folder"
    ownMainLayers = ["Pipes", "Valves", "Pumps", "Junctions", "Tanks", "Reservoirs", "Demands", "Sources"]
    ownFiles = ["DefaultValues", "Options", "Rules", "Controls", "Curves", "Patterns"]

    def __init__(self, parent=None):
        """Constructor."""
        super(QGISRedImportDialog, self).__init__(parent)
        self.setupUi(self)
        gplFolder = os.path.join(os.getenv('APPDATA'), "QGISRed")
        try:  # create directory if does not exist
            os.stat(gplFolder)
        except Exception:
            os.mkdir(gplFolder)
        self.gplFile = os.path.join(gplFolder, "qgisredprojectlist.gpl")
        # INP
        self.btImportInp.clicked.connect(self.importInpProject)
        self.btSelectDirectory.clicked.connect(self.selectDirectory)
        self.btSelectCRS.clicked.connect(self.selectCRS)
        self.btSelectInp.clicked.connect(self.selectINP)
        # SHPs
        self.btSelectSHPDirectory.clicked.connect(self.selectSHPDirectory)
        self.cbPipeLayer.currentIndexChanged.connect(self.pipeLayerChanged)
        self.cbValveLayer.currentIndexChanged.connect(self.valveLayerChanged)
        self.cbPumpLayer.currentIndexChanged.connect(self.pumpLayerChanged)
        self.cbTankLayer.currentIndexChanged.connect(self.tankLayerChanged)
        self.cbReservoirLayer.currentIndexChanged.connect(self.reservoirLayerChanged)
        self.cbJunctionLayer.currentIndexChanged.connect(self.junctionLayerChanged)
        self.cbServiceConnectionLayer.currentIndexChanged.connect(self.serviceConnectionLayerChanged)
        self.btImportShps.clicked.connect(self.importShpProject)

    def config(self, ifac, direct, netw, parent):
        self.parent = parent
        self.iface = ifac

        utils = QGISRedUtils(direct, netw, ifac)
        self.crs = utils.getProjectCrs()
        self.tbCRS.setText(self.crs.description())
        self.ProcessDone = False
        self.InpFile = ""

        self.NetworkName = netw
        self.tbNetworkName.setText(netw)
        self.ProjectDirectory = direct
        self.tbProjectDirectory.setText(direct)
        self.tbProjectDirectory.setCursorPosition(0)
        self.tbTolerance.setText(str(0))

        self.NewProject = self.ProjectDirectory == self.TemporalFolder
        if not self.NewProject:
            self.setWindowTitle("QGISRed: Add data")
            icon_path = ':/plugins/QGISRed/images/iconAddData.png'
            self.setWindowIcon(QIcon(icon_path))
            self.lbProject.setVisible(False)
            self.tbProjectDirectory.setVisible(False)
            self.btSelectDirectory.setVisible(False)
            self.lbName.setVisible(False)
            self.tbNetworkName.setVisible(False)
            self.lbCrs.setVisible(False)
            self.tbCRS.setVisible(False)
            self.btSelectCRS.setVisible(False)
            self.tabWidget.removeTab(0)
            self.label_14.setVisible(False)
            self.label_15.setVisible(False)
            self.cbUnits.setVisible(False)
            self.cbHeadloss.setVisible(False)

    def selectDirectory(self):
        selected_directory = QFileDialog.getExistingDirectory()
        if not selected_directory == "":
            self.tbProjectDirectory.setText(selected_directory)
            self.tbProjectDirectory.setCursorPosition(0)
            self.ProjectDirectory = selected_directory
            self.NetworkName = self.tbNetworkName.text()

            dirList = os.listdir(self.ProjectDirectory)
            self.NewProject = True
            for name in self.ownMainLayers:
                if self.NetworkName + "_" + name + ".shp" in dirList:
                    self.NewProject = False
                    break

    def selectCRS(self):
        projSelector = QgsGenericProjectionSelector()
        if projSelector.exec_():
            crsId = projSelector.crs().srsid()
            if not crsId == 0:
                self.crs = QgsCoordinateReferenceSystem()
                self.crs.createFromId(crsId, QgsCoordinateReferenceSystem.InternalCrsId)
                self.tbCRS.setText(self.crs.description())

    def validationsCreateProject(self):
        self.NetworkName = self.tbNetworkName.text()
        if len(self.NetworkName) == 0:
            self.iface.messageBar().pushMessage("Validations", "The network's name is not valid", level=1)
            return False
        self.ProjectDirectory = self.tbProjectDirectory.text()
        if len(self.ProjectDirectory) == 0 or self.ProjectDirectory == self.TemporalFolder:
            self.ProjectDirectory = tempfile._get_default_tempdir() + "\\" + next(tempfile._get_candidate_names())
        else:
            if not os.path.exists(self.ProjectDirectory):
                self.iface.messageBar().pushMessage("Validations", "The project directory does not exist", level=1)
                return False
        return True

    def createProject(self):
        epsg = self.crs.authid().replace("EPSG:", "")
        units = self.cbUnits.currentText()
        headloss = self.cbHeadloss.currentText()
        # Process
        QApplication.setOverrideCursor(Qt.WaitCursor)
        resMessage = GISRed.CreateProject(self.ProjectDirectory, self.NetworkName, epsg, units, headloss)
        QApplication.restoreOverrideCursor()

        # Message
        if not resMessage == "True":
            if resMessage == "False":
                self.iface.messageBar().pushMessage("Warning", "Some issues occurred in the process", level=1, duration=5)
            else:
                self.iface.messageBar().pushMessage("Error", resMessage, level=2, duration=5)
            self.close()
            return False

        # Write .gql file
        file = open(self.gplFile, "a+")
        QGISRedUtils().writeFile(file, self.NetworkName + ";" + self.ProjectDirectory + '\n')
        file.close()
        return True

    def getInputGroup(self):
        inputGroup = QgsProject.instance().layerTreeRoot().findGroup("Inputs")
        if inputGroup is None:
            netGroup = QgsProject.instance().layerTreeRoot().findGroup(self.NetworkName)
            if netGroup is None:
                root = QgsProject.instance().layerTreeRoot()
                netGroup = root.insertGroup(0, self.NetworkName)
            inputGroup = netGroup.addGroup("Inputs")
        return inputGroup

    def setZoomExtent(self, exception=None, result=None):
        self.iface.mapCanvas().zoomToFullExtent()
        self.iface.mapCanvas().refresh()

    """INP SECTION"""

    def selectINP(self):
        qfd = QFileDialog()
        path = ""
        filter = "inp(*.inp)"
        f = QFileDialog.getOpenFileName(qfd, "Select INP file", path, filter)
        f = f[0]
        if not f == "":
            self.InpFile = f
            self.tbInpFile.setText(f)
            self.tbInpFile.setCursorPosition(0)

    def importInpProject(self):
        # Common validations
        isValid = self.validationsCreateProject()
        if isValid:
            # Validations INP
            self.InpFile = self.tbInpFile.text()
            if len(self.InpFile) == 0:
                self.iface.messageBar().pushMessage("Validations", "INP file is not valid", level=1)
                return
            else:
                if not os.path.exists(self.InpFile):
                    self.iface.messageBar().pushMessage("Validations", "INP file does not exist", level=1)
                    return

            self.close()
            # Process
            self.parent.zoomToFullExtent = True
            epsg = self.crs.authid().replace("EPSG:", "")
            QApplication.setOverrideCursor(Qt.WaitCursor)
            resMessage = GISRed.ImportFromInp(self.ProjectDirectory, self.NetworkName, self.parent.tempFolder, self.InpFile, epsg)
            QApplication.restoreOverrideCursor()
            self.parent.ProjectDirectory = self.ProjectDirectory
            self.parent.NetworkName = self.NetworkName

            # Write .gql file
            file = open(self.gplFile, "a+")
            QGISRedUtils().writeFile(file, self.NetworkName + ";" + self.ProjectDirectory + '\n')
            file.close()

            # Open files
            self.parent.processCsharpResult(resMessage, "")

    """SHPS SECTION"""

    def selectSHPDirectory(self):
        selected_directory = QFileDialog.getExistingDirectory()
        if selected_directory == "":
            return

        self.tbShpDirectory.setText(selected_directory)
        self.tbShpDirectory.setCursorPosition(0)

        dirList = os.listdir(selected_directory)
        self.cbPipeLayer.clear()
        self.cbPipeLayer.addItem("None")
        self.cbValveLayer.clear()
        self.cbValveLayer.addItem("None")
        self.cbPumpLayer.clear()
        self.cbPumpLayer.addItem("None")
        self.cbTankLayer.clear()
        self.cbTankLayer.addItem("None")
        self.cbReservoirLayer.clear()
        self.cbReservoirLayer.addItem("None")
        self.cbJunctionLayer.clear()
        self.cbJunctionLayer.addItem("None")
        self.cbServiceConnectionLayer.clear()
        self.cbServiceConnectionLayer.addItem("None")
        for file in dirList:
            if ".shp" in file:
                layerPath = os.path.join(self.tbShpDirectory.text(), file)
                vlayer = QgsVectorLayer(layerPath, "layer", "ogr")
                if not vlayer.isValid():
                    continue
                features = vlayer.getFeatures()
                # only check first feature
                for feature in features:
                    featureType = feature.geometry().type()
                    name = os.path.splitext(os.path.basename(file))[0]
                    if featureType == QgsWkbTypes.LineGeometry:
                        self.cbPipeLayer.addItem(name)
                        self.cbServiceConnectionLayer.addItem(name)
                    if featureType == QgsWkbTypes.LineGeometry or featureType == QgsWkbTypes.PointGeometry:
                        self.cbValveLayer.addItem(name)
                        self.cbPumpLayer.addItem(name)
                    if featureType == QgsWkbTypes.PointGeometry:
                        self.cbTankLayer.addItem(name)
                        self.cbReservoirLayer.addItem(name)
                        self.cbJunctionLayer.addItem(name)
                    break
                vlayer = None

    def selectComboBoxItem(self, combobox, options):
        for i in range(combobox.count()):
            fieldName = combobox.itemText(i).lower()
            if fieldName in options:
                combobox.setCurrentIndex(i)
                return

    def pipeLayerChanged(self):
        newItem = self.cbPipeLayer.currentText()
        self.cbPipe_Id.clear()
        self.cbPipe_Length.clear()
        self.cbPipe_Diameter.clear()
        self.cbPipe_LossCoef.clear()
        self.cbPipe_Tag.clear()
        self.cbPipe_Descr.clear()
        if newItem == "None":
            self.gbPipes.setEnabled(False)
            return

        self.gbPipes.setEnabled(True)

        pipeLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp")
        vlayer = QgsVectorLayer(pipeLayer, "Pipes layer", "ogr")
        if not vlayer.isValid():
            return
        field_names = [field.name() for field in vlayer.fields()]
        field_names.insert(0, "None")
        self.cbPipe_Id.addItems(field_names)
        self.cbPipe_Length.addItems(field_names)
        self.cbPipe_Diameter.addItems(field_names)
        self.cbPipe_LossCoef.addItems(field_names)
        self.cbPipe_Material.addItems(field_names)
        self.cbPipe_InstDate.addItems(field_names)
        self.cbPipe_Tag.addItems(field_names)
        self.cbPipe_Descr.addItems(field_names)

        self.selectComboBoxItem(self.cbPipe_Id, ["id"])
        self.selectComboBoxItem(self.cbPipe_Length, ["length", "longitud"])
        self.selectComboBoxItem(self.cbPipe_Diameter, ["diameter", "diam", "diametro", "diámetro"])
        self.selectComboBoxItem(self.cbPipe_LossCoef, ["losscoeff"])
        self.selectComboBoxItem(self.cbPipe_Material, ["material"])
        self.selectComboBoxItem(self.cbPipe_InstDate, ["instdate", "date", "fecha", "fecha_de_i"])
        self.selectComboBoxItem(self.cbPipe_Tag, ["tag"])
        self.selectComboBoxItem(self.cbPipe_Descr, ["descrip", "descr", "description", "descripcion", "descripción"])

    def valveLayerChanged(self):
        newItem = self.cbValveLayer.currentText()
        self.cbValve_Id.clear()
        self.cbValve_Diameter.clear()
        self.cbValve_Type.clear()
        self.cbValve_InitStat.clear()
        self.cbValve_Orient.clear()
        self.cbValve_Tag.clear()
        self.cbValve_Descr.clear()
        if newItem == "None":
            self.gbValves.setEnabled(False)
            return

        self.gbValves.setEnabled(True)

        valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp")
        vlayer = QgsVectorLayer(valveLayer, "Valves layer", "ogr")
        if not vlayer.isValid():
            return
        field_names = [field.name() for field in vlayer.fields()]
        field_names.insert(0, "None")
        self.cbValve_Id.addItems(field_names)
        self.cbValve_Diameter.addItems(field_names)
        self.cbValve_Type.addItems(field_names)
        self.cbValve_InitStat.addItems(field_names)
        self.cbValve_Orient.addItems(field_names)
        self.cbValve_Tag.addItems(field_names)
        self.cbValve_Descr.addItems(field_names)

        self.selectComboBoxItem(self.cbValve_Id, ["id"])
        self.selectComboBoxItem(self.cbValve_Diameter, ["diameter", "diam", "diametro", "diámetro"])
        self.selectComboBoxItem(self.cbValve_Type, ["type", "tipo"])
        self.selectComboBoxItem(self.cbValve_InitStat, ["inistatus"])
        self.selectComboBoxItem(self.cbValve_Orient, ["orientatio"])
        self.selectComboBoxItem(self.cbValve_Tag, ["tag"])
        self.selectComboBoxItem(self.cbValve_Descr, ["descrip", "descr", "description", "descripcion", "descripción"])

    def pumpLayerChanged(self):
        newItem = self.cbPumpLayer.currentText()
        self.cbPump_Id.clear()
        self.cbPump_Power.clear()
        self.cbPump_InitStat.clear()
        self.cbPump_Orient.clear()
        self.cbPump_Tag.clear()
        self.cbPump_Descr.clear()
        if newItem == "None":
            self.gbPumps.setEnabled(False)
            return

        self.gbPumps.setEnabled(True)

        valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp")
        vlayer = QgsVectorLayer(valveLayer, "Pumps layer", "ogr")
        if not vlayer.isValid():
            return
        field_names = [field.name() for field in vlayer.fields()]
        field_names.insert(0, "None")
        self.cbPump_Id.addItems(field_names)
        self.cbPump_Power.addItems(field_names)
        self.cbPump_InitStat.addItems(field_names)
        self.cbPump_Orient.addItems(field_names)
        self.cbPump_Tag.addItems(field_names)
        self.cbPump_Descr.addItems(field_names)

        self.selectComboBoxItem(self.cbPump_Id, ["id"])
        self.selectComboBoxItem(self.cbPump_Power, ["power", "potencia"])
        self.selectComboBoxItem(self.cbPump_InitStat, ["inistatus"])
        self.selectComboBoxItem(self.cbPump_Orient, ["orientatio"])
        self.selectComboBoxItem(self.cbPump_Tag, ["tag"])
        self.selectComboBoxItem(self.cbPump_Descr, ["descrip", "descr", "description", "descripcion", "descripción"])

    def tankLayerChanged(self):
        newItem = self.cbTankLayer.currentText()
        self.cbTank_Id.clear()
        self.cbTank_Elevat.clear()
        self.cbTank_MinLevel.clear()
        self.cbTank_MaxLevel.clear()
        self.cbTank_Diameter.clear()
        self.cbTank_ReactCoeff.clear()
        self.cbTank_Tag.clear()
        self.cbTank_Descr.clear()
        if newItem == "None":
            self.gbTanks.setEnabled(False)
            return

        self.gbTanks.setEnabled(True)

        valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp")
        vlayer = QgsVectorLayer(valveLayer, "Tanks layer", "ogr")
        if not vlayer.isValid():
            return
        field_names = [field.name() for field in vlayer.fields()]
        field_names.insert(0, "None")
        self.cbTank_Id.addItems(field_names)
        self.cbTank_Elevat.addItems(field_names)
        self.cbTank_MinLevel.addItems(field_names)
        self.cbTank_MaxLevel.addItems(field_names)
        self.cbTank_Diameter.addItems(field_names)
        self.cbTank_ReactCoeff.addItems(field_names)
        self.cbTank_Tag.addItems(field_names)
        self.cbTank_Descr.addItems(field_names)

        self.selectComboBoxItem(self.cbTank_Id, ["id"])
        self.selectComboBoxItem(self.cbTank_Elevat, ["elevation"])
        self.selectComboBoxItem(self.cbTank_MinLevel, ["minlevel"])
        self.selectComboBoxItem(self.cbTank_MaxLevel, ["maxlevel"])
        self.selectComboBoxItem(self.cbTank_Diameter, ["diameter", "diam", "diametro", "diámetro"])
        self.selectComboBoxItem(self.cbTank_ReactCoeff, ["reactcoef"])
        self.selectComboBoxItem(self.cbTank_Tag, ["tag"])
        self.selectComboBoxItem(self.cbTank_Descr, ["descrip", "descr", "description", "descripcion", "descripción"])

    def reservoirLayerChanged(self):
        newItem = self.cbReservoirLayer.currentText()
        self.cbReservoir_Id.clear()
        self.cbReservoir_TotHead.clear()
        self.cbReservoir_Tag.clear()
        self.cbReservoir_Descr.clear()
        if newItem == "None":
            self.gbReservoirs.setEnabled(False)
            return

        self.gbReservoirs.setEnabled(True)

        valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp")
        vlayer = QgsVectorLayer(valveLayer, "Reservoirs layer", "ogr")
        if not vlayer.isValid():
            return
        field_names = [field.name() for field in vlayer.fields()]
        field_names.insert(0, "None")
        self.cbReservoir_Id.addItems(field_names)
        self.cbReservoir_TotHead.addItems(field_names)
        self.cbReservoir_Tag.addItems(field_names)
        self.cbReservoir_Descr.addItems(field_names)

        self.selectComboBoxItem(self.cbReservoir_Id, ["id"])
        self.selectComboBoxItem(self.cbReservoir_TotHead, ["totalhead"])
        self.selectComboBoxItem(self.cbReservoir_Tag, ["tag"])
        self.selectComboBoxItem(self.cbReservoir_Descr, ["descrip", "descr", "description", "descripcion", "descripción"])

    def junctionLayerChanged(self):
        newItem = self.cbJunctionLayer.currentText()
        self.cbJunction_Id.clear()
        self.cbJunction_Elevation.clear()
        self.cbJunction_BaseDem.clear()
        self.cbJunction_Tag.clear()
        self.cbJunction_Descr.clear()
        if newItem == "None":
            self.gbJunctions.setEnabled(False)
            return

        self.gbJunctions.setEnabled(True)

        valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp")
        vlayer = QgsVectorLayer(valveLayer, "Juntions layer", "ogr")
        if not vlayer.isValid():
            return
        field_names = [field.name() for field in vlayer.fields()]
        field_names.insert(0, "None")
        self.cbJunction_Id.addItems(field_names)
        self.cbJunction_Elevation.addItems(field_names)
        self.cbJunction_BaseDem.addItems(field_names)
        self.cbJunction_Tag.addItems(field_names)
        self.cbJunction_Descr.addItems(field_names)

        self.selectComboBoxItem(self.cbJunction_Id, ["id"])
        self.selectComboBoxItem(self.cbJunction_Elevation, ["elevation"])
        self.selectComboBoxItem(self.cbJunction_BaseDem, ["basedem"])
        self.selectComboBoxItem(self.cbJunction_Tag, ["tag"])
        self.selectComboBoxItem(self.cbJunction_Descr, ["descrip", "descr", "description", "descripcion", "descripción"])

    def serviceConnectionLayerChanged(self):
        newItem = self.cbServiceConnectionLayer.currentText()
        self.cbServiceConnection_Id.clear()
        self.cbServiceConnection_Length.clear()
        self.cbServiceConnection_Diameter.clear()
        self.cbServiceConnection_Material.clear()
        self.cbServiceConnection_InstDate.clear()
        self.cbServiceConnection_Tag.clear()
        self.cbServiceConnection_Descr.clear()

        if newItem == "None":
            self.gbServiceConnection.setEnabled(False)
            return

        self.gbServiceConnection.setEnabled(True)

        valveLayer = os.path.join(self.tbShpDirectory.text(), newItem + ".shp")
        vlayer = QgsVectorLayer(valveLayer, "Pumps layer", "ogr")
        if not vlayer.isValid():
            return
        field_names = [field.name() for field in vlayer.fields()]
        field_names.insert(0, "None")
        self.cbServiceConnection_Id.addItems(field_names)
        self.cbServiceConnection_Length.addItems(field_names)
        self.cbServiceConnection_Diameter.addItems(field_names)
        self.cbServiceConnection_Material.addItems(field_names)
        self.cbServiceConnection_InstDate.addItems(field_names)
        self.cbServiceConnection_Tag.addItems(field_names)
        self.cbServiceConnection_Descr.addItems(field_names)

        self.selectComboBoxItem(self.cbServiceConnection_Id, ["id"])
        self.selectComboBoxItem(self.cbServiceConnection_Length, ["length", "longitud"])
        self.selectComboBoxItem(self.cbServiceConnection_Diameter, ["diameter", "diam", "diametro", "diámetro"])
        self.selectComboBoxItem(self.cbServiceConnection_Material, ["material"])
        self.selectComboBoxItem(self.cbServiceConnection_InstDate, ["instdate", "date", "fecha", "fecha_de_i"])
        self.selectComboBoxItem(self.cbServiceConnection_Tag, ["tag"])
        self.selectComboBoxItem(self.cbServiceConnection_Descr,
                                ["descrip", "descr", "description", "descripcion", "descripción"])

    def createShpsNames(self):
        shpFolder = self.tbShpDirectory.text()
        shpNames = ""

        name = self.cbPipeLayer.currentText()
        if not name == "None":
            shpNames = shpNames + "[PIPES]" + os.path.join(shpFolder, name) + ","
        name = self.cbValveLayer.currentText()
        if not name == "None":
            shpNames = shpNames + "[VALVES]" + os.path.join(shpFolder, name) + ","
        name = self.cbPumpLayer.currentText()
        if not name == "None":
            shpNames = shpNames + "[PUMPS]" + os.path.join(shpFolder, name) + ","
        name = self.cbTankLayer.currentText()
        if not name == "None":
            shpNames = shpNames + "[TANKS]" + os.path.join(shpFolder, name) + ","
        name = self.cbReservoirLayer.currentText()
        if not name == "None":
            shpNames = shpNames + "[RESERVOIRS]" + os.path.join(shpFolder, name) + ","
        name = self.cbJunctionLayer.currentText()
        if not name == "None":
            shpNames = shpNames + "[JUNCTIONS]" + os.path.join(shpFolder, name) + ","
        name = self.cbServiceConnectionLayer.currentText()
        if not name == "None":
            shpNames = shpNames + "[SERVICECONNECTIONS]" + os.path.join(shpFolder, name) + ","
        return shpNames

    def createShpFields(self):
        fields = ""

        name = self.cbPipeLayer.currentText()
        if not name == "None":
            fields = "[PIPES]"
            name = self.cbPipe_Id.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbPipe_Length.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbPipe_Diameter.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # RougCoeff
            name = self.cbPipe_Material.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbPipe_InstDate.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbPipe_LossCoef.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # InitStat
            fields = fields + ";"  # BulkCoef
            fields = fields + ";"  # WallCoef
            name = self.cbPipe_Tag.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbPipe_Descr.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"

            fields = fields + ","  # To separate layers

        name = self.cbValveLayer.currentText()
        if not name == "None":
            fields = fields + "[VALVES]"
            name = self.cbValve_Id.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbValve_Diameter.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbValve_Type.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # Setting
            fields = fields + ";"  # IdHeadLoss
            fields = fields + ";"  # LossCoef
            name = self.cbValve_InitStat.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbValve_Tag.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbValve_Descr.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            # fields = fields + ";" #Sector
            name = self.cbValve_Orient.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"

            fields = fields + ","  # To separate layers

        name = self.cbPumpLayer.currentText()
        if not name == "None":
            fields = fields + "[PUMPS]"
            name = self.cbPump_Id.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # IdHFCurve
            name = self.cbPump_Power.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # Speed
            fields = fields + ";"  # IdSpeedPat
            name = self.cbPump_InitStat.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # IdEfficCur
            fields = fields + ";"  # EnergPrice
            fields = fields + ";"  # IdPricePat
            name = self.cbPump_Tag.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbPump_Descr.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            # fields = fields + ";" #Sector
            name = self.cbPump_Orient.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"

            fields = fields + ","  # To separate layers

        name = self.cbTankLayer.currentText()
        if not name == "None":
            fields = fields + "[TANKS]"
            name = self.cbTank_Id.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbTank_Elevat.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # IniLevel
            name = self.cbTank_MinLevel.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbTank_MaxLevel.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbTank_Diameter.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # MinVolum
            fields = fields + ";"  # IdVolCur
            fields = fields + ";"  # MixMod
            fields = fields + ";"  # MixFrac
            name = self.cbTank_ReactCoeff.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # InitialQuality
            name = self.cbTank_Tag.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbTank_Descr.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"

            fields = fields + ","  # To separate layers

        name = self.cbReservoirLayer.currentText()
        if not name == "None":
            fields = fields + "[RESERVOIRS]"
            name = self.cbReservoir_Id.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbReservoir_TotHead.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # IdHeadPat
            fields = fields + ";"  # IniQual
            name = self.cbReservoir_Tag.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbReservoir_Descr.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"

            fields = fields + ","  # To separate layers

        name = self.cbJunctionLayer.currentText()
        if not name == "None":
            fields = fields + "[JUNCTIONS]"
            name = self.cbJunction_Id.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbJunction_Elevation.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbJunction_BaseDem.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            fields = fields + ";"  # IdDemPat
            fields = fields + ";"  # EmitCoef
            fields = fields + ";"  # IniQual
            name = self.cbJunction_Tag.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbJunction_Descr.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"

            fields = fields + ","  # To separate layers

        name = self.cbServiceConnectionLayer.currentText()
        if not name == "None":
            fields = fields + "[SERVICECONNECTIONS]"
            name = self.cbServiceConnection_Id.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbServiceConnection_Length.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbServiceConnection_Diameter.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbServiceConnection_Material.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbServiceConnection_InstDate.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbServiceConnection_Tag.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"
            name = self.cbServiceConnection_Descr.currentText()
            if not name == "None":
                fields = fields + name
            fields = fields + ";"

            fields = fields + ","  # To separate layers

        return fields

    def importShpProject(self):
        # Common validations
        isValid = self.validationsCreateProject()
        if isValid:
            # Validations SHP's
            if not os.path.exists(self.tbShpDirectory.text()):
                self.iface.messageBar().pushMessage("Validations",
                                                    "The SHPs folder is not valid or does not exist", level=1)
                return
            # Tolerance
            tolerance = self.tbTolerance.text()
            try:
                t = float(tolerance)
                if t < 0:
                    self.iface.messageBar().pushMessage("Validations", "Not valid Tolerance", level=1)
                    return
            except Exception:
                self.iface.messageBar().pushMessage("Validations", "Not numeric Tolerance", level=1)
                return
            # Fields
            fields = self.createShpFields()
            if fields == "":
                self.iface.messageBar().pushMessage("Validations", "Any SHP selected for importing", level=1)
                return

            # Process
            if self.NewProject:
                if not self.createProject():
                    return

            self.close()
            self.parent.zoomToFullExtent = True

            epsg = self.crs.authid().replace("EPSG:", "")
            shapes = self.createShpsNames()
            # fields = self.createShpFields()

            # Process
            QApplication.setOverrideCursor(Qt.WaitCursor)
            resMessage = GISRed.ImportFromShps(self.ProjectDirectory, self.NetworkName, self.parent.tempFolder,
                                               shapes, fields, epsg, tolerance)
            QApplication.restoreOverrideCursor()
            self.parent.ProjectDirectory = self.ProjectDirectory
            self.parent.NetworkName = self.NetworkName

            name = self.cbServiceConnectionLayer.currentText()
            if not name == "None":
                self.parent.complementaryLayers = ["ServiceConnections"]
            self.parent.processCsharpResult(resMessage, "")
예제 #40
0
class CriaSpatialiteDialog(QtGui.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(CriaSpatialiteDialog, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)

        self.filepath = ""
        self.carregado = False
        self.coordSysDefinido = False
        self.epsgCriaSpatialite = 0
        self.srsCriaSpatialite = ''
        self.sqliteFileName = ''

        self.bar = QgsMessageBar()
        self.setLayout(QtGui.QGridLayout(self))
        self.layout().setContentsMargins(0,0,0,0)
        self.layout().setAlignment(QtCore.Qt.AlignTop)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        self.bar.setSizePolicy(sizePolicy)
        self.layout().addWidget(self.bar, 0,0,1,1)

        QtCore.QObject.connect(self.pushButtonBuscarPastaDestinoCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.definePastaDestino)
        QtCore.QObject.connect(self.pushButtonBuscarSistCoordCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.setaSistCoordCriaSpatialite)
        QtCore.QObject.connect(self.pushButtonOkCriaSpatialite, QtCore.SIGNAL(("clicked()")), self.okselecionadoCriaSpatialite)

    def getTemplateLocation(self):
        """
        gets the template location
        """
        currentPath = os.path.dirname(__file__)
        if self.versionComboBox.currentText() == '2.1.3':
            edgvPath = os.path.join(currentPath, 'template', '213', 'seed_edgv213.sqlite')
        elif self.versionComboBox.currentText() == 'FTer_2a_Ed':
            edgvPath = os.path.join(currentPath, 'template', 'FTer_2a_Ed', 'seed_edgvfter_2a_ed.sqlite')
        elif self.versionComboBox.currentText() == '3.0':
            edgvPath = os.path.join(currentPath, 'template', '3', 'seed_edgv3.sqlite')
        return edgvPath

    def restauraInicio(self):
        """
        Stes the initial state
        """
        self.filepath = ""
        self.carregado = False
        self.coordSysDefinido = False
        self.epsgCriaSpatialite = 0
        self.srsCriaSpatialite = ''
        self.sqliteFileName = ''
        self.pastaDestinoCriaSpatialiteLineEdit.setText("")
        self.coordSysCriaSpatialiteLineEdit.setText("")
        self.nomeLineEdit.setText("")

    def definePastaDestino(self):
        """
        Defines destination folder
        """
        fd = QtGui.QFileDialog()
        self.filepath = fd.getExistingDirectory()
        if self.filepath <> "":
            self.carregado = True
            self.pastaDestinoCriaSpatialiteLineEdit.setText(self.filepath)

    def setaSistCoordCriaSpatialite(self):
        """
        Opens the CRS selector
        """
        projSelector = QgsGenericProjectionSelector()
        projSelector.setMessage(theMessage=self.tr('Please, select the coordinate system'))
        projSelector.exec_()
        try:
            self.epsgCriaSpatialite = int(projSelector.selectedAuthId().split(':')[-1])
            self.srsCriaSpatialite = QgsCoordinateReferenceSystem(self.epsgCriaSpatialite, QgsCoordinateReferenceSystem.EpsgCrsId)
            if self.srsCriaSpatialite <> "":
                self.coordSysDefinido = True
                self.coordSysCriaSpatialiteLineEdit.setText(self.srsCriaSpatialite.description())
        except:
            self.bar.pushMessage("", self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING)
            pass

    def copiaSemente(self, destino, srid):
        """
        Copies the spatialite seed template
        """
        f = open(self.getTemplateLocation(),'rb')
        g = open(destino,'wb')
        x = f.readline()
        while x:
            g.write(x)
            x = f.readline()

        g.close()

        con = sqlite3.connect(destino)
        cursor = con.cursor()
        srid_sql = (srid,)
        cursor.execute("UPDATE geometry_columns SET srid=?",srid_sql)
        con.commit()
        con.close()

    def okselecionadoCriaSpatialite(self):
        """
        Performs the database creation
        """
        if self.carregado and self.coordSysDefinido and len(self.nomeLineEdit.text()) > 0:
            try:
                self.sqliteFileName = self.filepath+'/'+self.nomeLineEdit.text()+'.sqlite'
                destino = self.sqliteFileName
                self.copiaSemente(destino,self.epsgCriaSpatialite)
                self.close()
                self.restauraInicio()
                QtGui.QMessageBox.information(self, self.tr('Information'), self.tr('Spatialite created successfully!'))
            except:
                qgis.utils.iface.messageBar().pushMessage(self.tr("Error!"), self.tr("Problem creating the database!"), level=QgsMessageBar.CRITICAL)
                self.restauraInicio()
                pass
        else:
            if self.coordSysDefinido == False:
                self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select the coordinate system'), level=QgsMessageBar.WARNING)
            if self.carregado == False:
                self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, select a folder to save the database'), level=QgsMessageBar.CRITICAL)
            if len(self.nomeLineEdit.text()) == 0:
                self.bar.pushMessage(self.tr("Warning!"), self.tr('Please, fill the file name.'), level=QgsMessageBar.CRITICAL)