Пример #1
0
    def add_postgres_layer(self, name, host, port, database_name, username,
                           schema, table, geom_col, id_col, ssl, qml_file_path,
                           sql_filter):
        """
            Add the database table in the QGis TOC and apply its associated QML.
            :param name: The name
            :type name: str
            :param host: The hostname
            :type host: str
            :param port: Aggregated data separated by "|". The first element is the port, the second is the ssl request
            specification (e.g. require, allow, disable, prefer)
            :type port: str
            :param database_name: The database name
            :type database_name: str
            :param username: The username for connecting to the database
            :type username: str
            :param schema: The database schema
            :type schema: str
            :param table: Aggregated data separated by "|". The first is the table name, the second is the sql filter
            :type table: str
            :param geom_col: The geometry column name
            :type geom_col: str
            :param id_col: The identifier column name
            :type id_col: str
            :param ssl: The SSL type request. Expected one of: require, allow, disable or prefer.
            :type ssl: str
            :param qml_file_path: The *.qml file path
            :type qml_file_path: str
            :param sql_filter: The SQL where condition
            :type sql_filter: str
        """
        qgs_logger = QgsApplication.messageLog()
        qgs_logger.logMessage('addWms: name = {}'.format(name),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: host = {}'.format(host),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: port = {}'.format(port),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage(
            'addWms: database_name = {}'.format(database_name),
            tag=configuration.LOGGER_TAG,
            level=Qgis.Info)
        qgs_logger.logMessage('addWms: username = {}'.format(username),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: schema = {}'.format(schema),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: table = {}'.format(table),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: geom_col = {}'.format(geom_col),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: id_col = {}'.format(id_col),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: ssl = {}'.format(ssl),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: self.session_user = {}'.format(
            str(self.session_user)),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage(
            'addWms: qml_file_path = {}'.format(qml_file_path),
            tag=configuration.LOGGER_TAG,
            level=Qgis.Info)
        qgs_logger.logMessage('addWms: sql_filter = {}'.format(sql_filter),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)

        uri = QgsDataSourceUri()
        ssl_mode = QgsDataSourceUri.SslAllow

        if ssl == "require":
            ssl_mode = QgsDataSourceUri.SslRequire
        if ssl == "allow":
            ssl_mode = QgsDataSourceUri.SslAllow
        if ssl == "disable":
            ssl_mode = QgsDataSourceUri.SslDisable
        if ssl == "prefer":
            ssl_mode = QgsDataSourceUri.SslPrefer

        # Set the connection
        uri.setConnection(str(host), str(port), str(database_name),
                          str(self.session_user), str(self.session_password),
                          ssl_mode)

        # In case the geometry column is not defined ignore as parameter, otherwise set it
        if str(geom_col) == "":
            uri.setDataSource(str(schema), str(table), None, sql_filter,
                              str(id_col))
        else:
            uri.setDataSource(str(schema), str(table), str(geom_col),
                              sql_filter, str(id_col))

        # Instantiate
        postgres_layer = QgsVectorLayer(uri.uri(), str(name), 'postgres')

        # In case the layer is valid, add to the QGis TOC
        if postgres_layer.isValid():
            QgsProject.instance().addMapLayer(postgres_layer)
            postgres_layer.loadNamedStyle(qml_file_path)
        else:
            par = "\nhost: " + str(host)\
                + "\nport: " + str(port)\
                + "\ndbname: " + str(database_name)\
                + "\nuser: "******"\nssl: " + str(ssl)\
                + "\nschema: " + str(schema)\
                + "\ntable: " + str(table) \
                + "\ngeom_col: " + str(geom_col) \
                + "\nid_col: " + str(id_col) \
                + "\npathQMLFile: " + str(qml_file_path) \
                + "\nsqlFilter: " + str(sql_filter)
            self.show_message(
                "Attenzione!", "Impossibile aggiungere la tabella " + name +
                " al progetto.\n" + par)
Пример #2
0
    def run(self):
        """Runs the logic behind the dialogs"""

        # 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:
            self.first_start = False
            # Start a dialog window
            self.dlg = PRW_Data_OpvragerDialog()
            self.dlg.OutputLocation.setStorageMode(1)
            self.dlg.OutputLocation.setFilePath(
                self.dlg.OutputLocation.defaultRoot())
            # Set a validator on the filename lineEdit so that no random signs can be put in.
            rx2 = QRegExp(r"^[\w\-. ]+$")
            filename_validator = QRegExpValidator(rx2)
            self.dlg.FileName.setValidator(filename_validator)

        # Show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Extracting values from the dialog form
            self.selected_layer = self.dlg.cmb_layer.currentLayer()
            self.dateMax = self.dlg.DateMax.date().toString('yyyy-MM-dd')
            self.dateMin = self.dlg.DateMin.date().toString('yyyy-MM-dd')
            self.shpExportBool = self.dlg.exportShapefile.isChecked()
            self.fileName = self.dlg.FileName.text()
            self.outputLocation = self.dlg.OutputLocation.filePath()

            source = self.selected_layer.source()
            uri = QgsDataSourceUri(source)
            try:
                # Check if a database is connected to the layer source
                assert uri.database(
                ), '"{layer}" heeft geen connectie met een database.'.format(
                    layer=self.selected_layer.name())
                assert self.selected_layer.selectedFeatureCount(
                ) != 0, 'Geen Objecten zijn geselecteerd in laag: "{layer}".'.format(
                    layer=self.selected_layer.name())
                assert self.fileName, 'Er is geen Excel uitvoernaam opgegeven.'
                assert self.outputLocation, 'Er is geen uitvoermap opgegeven.'
            except Exception as e:
                self.iface.messageBar().pushMessage("Error",
                                                    str(e),
                                                    level=2,
                                                    duration=5)
                raise e
                return

            savedUsername = uri.hasParam('username')
            savedPassword = uri.hasParam('password')

            host = uri.host()
            port = uri.port()
            database = uri.database()
            self.username = uri.username()
            self.password = uri.password()
            self.dsn = cora.makedsn(host=host,
                                    port=port,
                                    service_name=database)

            errorMessage = None
            # If we have a username and password try to connect, otherwise ask for credentials
            # If the connection fails store the error and show dialog screen for credentials input
            if savedUsername is True and savedPassword is True:
                try:
                    self.check_connection()
                    self.run_task()
                except cora.DatabaseError as e:
                    errorObj, = e.args
                    errorMessage = errorObj.message
                    success = 'false'
                    # Credentials loop
                    while success == 'false':
                        success, errorMessage = \
                            self.get_credentials(
                                host, port, self.database, message=errorMessage)
                    if success == 'exit':
                        pass
                    elif success == 'true':
                        self.run_task()
            else:
                success, errorMessage = \
                    self.get_credentials(
                        host, port, self.database, username=self.username, password=self.password)
                # Credentials loop
                while success == 'false':
                    success, errorMessage = \
                        self.get_credentials(
                            host, port, self.database, username=self.username, password=self.password, message=errorMessage)
                if success == 'exit':
                    pass
                elif success == 'true':
                    self.run_task()
Пример #3
0
    def __init__(self, iface, layer, parent=None):
        QWidget.__init__(self, parent)
        self.iface = iface
        self.layer = layer

        uri = QgsDataSourceUri(layer.source())
        dbplugin = None
        db = None
        if layer.dataProvider().name() == 'postgres':
            dbplugin = createDbPlugin('postgis', 'postgres')
        elif layer.dataProvider().name() == 'spatialite':
            dbplugin = createDbPlugin('spatialite', 'spatialite')
        elif layer.dataProvider().name() == 'oracle':
            dbplugin = createDbPlugin('oracle', 'oracle')
        elif layer.dataProvider().name() == 'virtual':
            dbplugin = createDbPlugin('vlayers', 'virtual')
        if dbplugin:
            dbplugin.connectToUri(uri)
            db = dbplugin.db

        self.dbplugin = dbplugin
        self.db = db
        self.filter = ""
        self.allowMultiColumnPk = isinstance(
            db, PGDatabase
        )  # at the moment only PostgreSQL allows a primary key to span multiple columns, spatialite doesn't
        self.aliasSubQuery = isinstance(
            db,
            PGDatabase)  # only PostgreSQL requires subqueries to be aliases
        self.setupUi(self)
        self.setWindowTitle(
            u"%s - %s [%s]" %
            (self.windowTitle(), db.connection().connectionName(),
             db.connection().typeNameString()))

        self.defaultLayerName = 'QueryLayer'

        if self.allowMultiColumnPk:
            self.uniqueColumnCheck.setText(
                self.trUtf8("Column(s) with unique values"))
        else:
            self.uniqueColumnCheck.setText(
                self.trUtf8("Column with unique values"))

        self.editSql.setFocus()
        self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.editSql.setMarginVisible(True)
        self.initCompleter()

        # allow copying results
        copyAction = QAction("copy", self)
        self.viewResult.addAction(copyAction)
        copyAction.setShortcuts(QKeySequence.Copy)

        copyAction.triggered.connect(self.copySelectedResults)

        self.btnExecute.clicked.connect(self.executeSql)
        self.btnSetFilter.clicked.connect(self.setFilter)
        self.btnClear.clicked.connect(self.clearSql)

        self.presetStore.clicked.connect(self.storePreset)
        self.presetDelete.clicked.connect(self.deletePreset)
        self.presetCombo.activated[str].connect(self.loadPreset)
        self.presetCombo.activated[str].connect(self.presetName.setText)

        self.updatePresetsCombobox()

        self.geomCombo.setEditable(True)
        self.geomCombo.lineEdit().setReadOnly(True)

        self.uniqueCombo.setEditable(True)
        self.uniqueCombo.lineEdit().setReadOnly(True)
        self.uniqueModel = QStandardItemModel(self.uniqueCombo)
        self.uniqueCombo.setModel(self.uniqueModel)
        if self.allowMultiColumnPk:
            self.uniqueCombo.setItemDelegate(QStyledItemDelegate())
            self.uniqueModel.itemChanged.connect(
                self.uniqueChanged)  # react to the (un)checking of an item
            self.uniqueCombo.lineEdit().textChanged.connect(
                self.uniqueTextChanged
            )  # there are other events that change the displayed text and some of them can not be caught directly

        self.layerTypeWidget.hide()  # show if load as raster is supported
        #self.loadLayerBtn.clicked.connect(self.loadSqlLayer)
        self.updateLayerBtn.clicked.connect(self.updateSqlLayer)
        self.getColumnsBtn.clicked.connect(self.fillColumnCombos)

        self.queryBuilderFirst = True
        self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif"))
        self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder)

        self.presetName.textChanged.connect(self.nameChanged)

        # Update from layer
        # Fisrtly the SQL from QgsDataSourceUri table
        sql = uri.table()
        if uri.keyColumn() == '_uid_':
            match = re.search(
                '^\(SELECT .+ AS _uid_,\* FROM \((.*)\) AS _subq_.+_\s*\)$',
                sql, re.S)
            if match:
                sql = match.group(1)
        else:
            match = re.search('^\((SELECT .+ FROM .+)\)$', sql, re.S)
            if match:
                sql = match.group(1)
        self.editSql.setText(sql)
        self.executeSql()

        # Then the columns
        self.geomCombo.setCurrentIndex(
            self.geomCombo.findText(uri.geometryColumn(), Qt.MatchExactly))
        if uri.keyColumn() != '_uid_':
            self.uniqueColumnCheck.setCheckState(Qt.Checked)
            if self.allowMultiColumnPk:
                itemsData = uri.keyColumn().split(',')
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.data() in itemsData:
                        item.setCheckState(Qt.Checked)
            else:
                keyColumn = uri.keyColumn()
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.data() == keyColumn:
                        self.uniqueCombo.setCurrentIndex(
                            self.uniqueModel.indexFromItem(item).row())

        # Finally layer name, filter and selectAtId
        self.layerNameEdit.setText(layer.name())
        self.filter = uri.sql()
        if uri.selectAtIdDisabled():
            self.avoidSelectById.setCheckState(Qt.Checked)
Пример #4
0
    def processAlgorithm(self, parameters, context, feedback):
        database = self.parameterAsVectorLayer(parameters, self.DATABASE,
                                               context)
        databaseuri = database.dataProvider().dataSourceUri()
        uri = QgsDataSourceUri(databaseuri)
        if uri.database() is '':
            if '|layername' in databaseuri:
                databaseuri = databaseuri[:databaseuri.find('|layername')]
            elif '|layerid' in databaseuri:
                databaseuri = databaseuri[:databaseuri.find('|layerid')]
            uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri))
        db = spatialite.GeoDB(uri)

        overwrite = self.parameterAsBool(parameters, self.OVERWRITE, context)
        createIndex = self.parameterAsBool(parameters, self.CREATEINDEX,
                                           context)
        convertLowerCase = self.parameterAsBool(parameters,
                                                self.LOWERCASE_NAMES, context)
        dropStringLength = self.parameterAsBool(parameters,
                                                self.DROP_STRING_LENGTH,
                                                context)
        forceSinglePart = self.parameterAsBool(parameters,
                                               self.FORCE_SINGLEPART, context)
        primaryKeyField = self.parameterAsString(parameters, self.PRIMARY_KEY,
                                                 context) or 'id'
        encoding = self.parameterAsString(parameters, self.ENCODING, context)

        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        table = self.parameterAsString(parameters, self.TABLENAME, context)
        if table:
            table.strip()
        if not table or table == '':
            table = source.sourceName()
            table = table.replace('.', '_')
        table = table.replace(' ', '').lower()
        providerName = 'spatialite'

        geomColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN,
                                            context)
        if not geomColumn:
            geomColumn = 'geom'

        options = {}
        if overwrite:
            options['overwrite'] = True
        if convertLowerCase:
            options['lowercaseFieldNames'] = True
            geomColumn = geomColumn.lower()
        if dropStringLength:
            options['dropStringConstraints'] = True
        if forceSinglePart:
            options['forceSinglePartGeometryType'] = True

        # Clear geometry column for non-geometry tables
        if source.wkbType() == QgsWkbTypes.NoGeometry:
            geomColumn = None

        uri = db.uri
        uri.setDataSource('', table, geomColumn, '', primaryKeyField)

        if encoding:
            options['fileEncoding'] = encoding

        exporter = QgsVectorLayerExporter(uri.uri(), providerName,
                                          source.fields(), source.wkbType(),
                                          source.sourceCrs(), overwrite,
                                          options)

        if exporter.errorCode() != QgsVectorLayerExporter.NoError:
            raise QgsProcessingException(
                self.tr('Error importing to Spatialite\n{0}').format(
                    exporter.errorMessage()))

        features = source.getFeatures()
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not exporter.addFeature(f, QgsFeatureSink.FastInsert):
                feedback.reportError(exporter.errorMessage())

            feedback.setProgress(int(current * total))

        exporter.flushBuffer()
        if exporter.errorCode() != QgsVectorLayerExporter.NoError:
            raise QgsProcessingException(
                self.tr('Error importing to Spatialite\n{0}').format(
                    exporter.errorMessage()))

        if geomColumn and createIndex:
            db.create_spatial_index(table, geomColumn)

        return {}
    def charge_vector_layers_periodo(self, cont_per):
        self.cont_per = str(cont_per)
        # Clean Qgis Map Later Registry
        # QgsMapLayerRegistry.instance().removeAllMapLayers()
        # Get the user input, starting with the table name
        # self.find_us_cutted(data)
        cfg_rel_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                    'config.cfg')
        file_path = '{}{}'.format(self.HOME, cfg_rel_path)
        conf = open(file_path, "r")
        con_sett = conf.read()
        conf.close()
        settings = Settings(con_sett)
        settings.set_configuration()

        if settings.SERVER == 'sqlite':
            sqliteDB_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                         'pyarchinit_db.sqlite')
            db_file_path = '{}{}'.format(self.HOME, sqliteDB_path)

            uri = QgsDataSourceUri()
            uri.setDatabase(db_file_path)

            cont_per_string = "cont_per = '" + self.cont_per + "' OR cont_per LIKE '" + self.cont_per + "/%' OR cont_per LIKE '%/" + self.cont_per + "' OR cont_per LIKE '%/" + self.cont_per + "/%'"

            uri.setDataSource('', 'pyarchinit_us_view', 'the_geom',
                              cont_per_string, "ROWID")
            layerUS = QgsVectorLayer(uri.uri(), 'pyarchinit_us_view',
                                     'spatialite')

            srs = QgsCoordinateReferenceSystem(
                self.SRS, QgsCoordinateReferenceSystem.PostgisCrsId)

            if layerUS.isValid():
                QMessageBox.warning(self, "TESTER", "OK Layer US valido",
                                    QMessageBox.Ok)

                # self.USLayerId = layerUS.getLayerID()
                # style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE, 'us_view.qml')
                style_path = QFileDialog.getOpenFileName(
                    self, 'Open file', self.LAYER_STYLE_PATH)
                layerUS.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerUS], True)
            else:
                QMessageBox.warning(self, "TESTER", "OK Layer US non valido",
                                    QMessageBox.Ok)

            uri.setDataSource('', 'pyarchinit_quote_view', 'the_geom',
                              cont_per_string, "ROWID")
            layerQUOTE = QgsVectorLayer(uri.uri(), 'pyarchinit_quote_view',
                                        'spatialite')

            if layerQUOTE.isValid():
                # self.USLayerId = layerUS.getLayerID()
                style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE,
                                           'quote_us_view.qml')
                layerQUOTE.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerQUOTE], True)

        elif settings.SERVER == 'postgres':
            uri = QgsDataSourceUri()
            # set host name, port, database name, username and password
            uri.setConnection(settings.HOST, settings.PORT, settings.DATABASE,
                              settings.USER, settings.PASSWORD)
            # cont_per_string =  "cont_per = '" + self.cont_per + "' OR cont_per LIKE '" + self.cont_per + "/%' OR cont_per LIKE '%/" + self.cont_per + "' OR cont_per LIKE '%/" + self.cont_per + "/%'"
            srs = QgsCoordinateReferenceSystem(
                self.SRS, QgsCoordinateReferenceSystem.PostgisCrsId)
            uri.setDataSource("public", "pyarchinit_archeozoo_view",
                              "the_geom", cont_per_string, "id")
            layerUS = QgsVectorLayer(uri.uri(), "Fauna", "postgres")
            if layerUS.isValid():
                layerUS.setCrs(srs)
                # self.USLayerId = layerUS.getLayerID()
                # style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml')
                style_path = QFileDialog.getOpenFileName(
                    self, 'Open file', self.LAYER_STYLE_PATH)
                layerUS.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerUS], True)
            uri.setDataSource("public", "pyarchinit_quote_view", "the_geom",
                              cont_per_string, "gid")
            layerQUOTE = QgsVectorLayer(uri.uri(),
                                        "Quote Unita' Stratigrafiche",
                                        "postgres")
            if layerQUOTE.isValid():
                layerQUOTE.setCrs(srs)
                style_path = '{}{}'.format(self.LAYER_STYLE_PATH,
                                           'stile_quote.qml')
                layerQUOTE.loadNamedStyle(style_path)
                try:
                    QgsProject.instance().addMapLayers([layerQUOTE], True)
                except Exception as e:
                    pass
    def charge_individui_us(self, data):
        # Clean Qgis Map Later Registry
        # QgsMapLayerRegistry.instance().removeAllMapLayers()
        # Get the user input, starting with the table name

        # self.find_us_cutted(data)

        cfg_rel_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                    'config.cfg')
        file_path = '{}{}'.format(self.HOME, cfg_rel_path)
        conf = open(file_path, "r")
        con_sett = conf.read()
        conf.close()

        settings = Settings(con_sett)
        settings.set_configuration()

        if settings.SERVER == 'sqlite':
            sqliteDB_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                         'pyarchinit_db.sqlite')
            db_file_path = '{}{}'.format(self.HOME, sqliteDB_path)

            gidstr = id_us = "id_us = '" + str(data[0]) + "'"
            if len(data) > 1:
                for i in range(len(data)):
                    gidstr += " OR id_us = '" + str(data[i]) + "'"

            uri = QgsDataSourceUri()
            uri.setDatabase(db_file_path)

            uri.setDataSource('', 'pyarchinit_us_view', 'Geometry', gidstr,
                              "gid")
            layerUS = QgsVectorLayer(uri.uri(), 'pyarchinit_us_view',
                                     'spatialite')
            ###################################################################�
            if layerUS.isValid():
                # self.USLayerId = layerUS.getLayerID()
                # style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE, 'us_caratterizzazioni.qml')
                # layerUS.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerUS], True)

            uri.setDataSource('', 'pyarchinit_quote_view', 'Geometry', gidstr,
                              "gid")
            layerQUOTE = QgsVectorLayer(uri.uri(), 'pyarchinit_quote_view',
                                        'spatialite')

            if layerQUOTE.isValid():
                QgsProject.instance().addMapLayers([layerQUOTE], True)

        elif settings.SERVER == 'postgres':

            uri = QgsDataSourceUri()
            # set host name, port, database name, username and password

            uri.setConnection(settings.HOST, settings.PORT, settings.DATABASE,
                              settings.USER, settings.PASSWORD)

            gidstr = id_us = "id_archzoo = " + str(data[0])
            if len(data) > 1:
                for i in range(len(data)):
                    gidstr += " OR id_archzoo = " + str(data[i])

            srs = QgsCoordinateReferenceSystem(
                self.SRS, QgsCoordinateReferenceSystem.PostgisCrsId)

            uri.setDataSource("public", "pyarchinit_archeozoo_view",
                              "the_geom", gidstr, "gid")
            layerUS = QgsVectorLayer(uri.uri(), "Fauna", "postgres")

            if layerUS.isValid():
                layerUS.setCrs(srs)
                # self.USLayerId = layerUS.getLayerID()
                # style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml')
                style_path = QFileDialog.getOpenFileName(
                    self, 'Open file', self.LAYER_STYLE_PATH)
                layerUS.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerUS], True)

            uri.setDataSource("public", "pyarchinit_quote_view", "the_geom",
                              gidstr, "gid")
            layerQUOTE = QgsVectorLayer(uri.uri(),
                                        "Quote Unita' Stratigrafiche",
                                        "postgres")

            if layerQUOTE.isValid():
                layerQUOTE.setCrs(srs)
                style_path = '{}{}'.format(self.LAYER_STYLE_PATH,
                                           'stile_quote.qml')
                layerQUOTE.loadNamedStyle(style_path)
                try:
                    QgsProject.instance().addMapLayers([layerQUOTE], True)
                except Exception as e:
                    pass
Пример #7
0
    def newEntranceLayer(self):

        vl = QgsVectorLayer("Point?crs=", "memory:Entrances", "memory")

        provider = vl.dataProvider()
        provider.addAttributes([
            QgsField(EntranceTool.id_attribute, QVariant.Int),
            QgsField(EntranceTool.category_attribute, QVariant.String),
            QgsField(EntranceTool.subcat_attribute, QVariant.String),
            QgsField(EntranceTool.level_attribute, QVariant.Double)
        ])
        if vl.crs().toWkt() == "":
            vl.setCrs(QgsProject.instance().crs())
        vl.updateFields()
        if self.entrancedlg.e_shp_radioButton.isChecked(
        ):  # layer_type == 'shapefile':

            path = self.entrancedlg.lineEditEntrances.text()
            if path and path != '':
                filename = os.path.basename(path)
                location = os.path.abspath(path)
                crs = QgsCoordinateReferenceSystem()
                crs.createFromSrid(3857)
                shph.createShapeFile(vl, path, crs)
                vl = self.iface.addVectorLayer(location, filename[:-4], "ogr")
            else:
                vl = 'invalid data source'

        elif self.entrancedlg.e_postgis_radioButton.isChecked():

            db_path = self.entrancedlg.lineEditEntrances.text()
            if db_path and db_path != '':

                (database, schema, table_name) = db_path.split(':')
                db_con_info = self.entrancedlg.dbsettings_dlg.available_dbs[
                    database]
                uri = QgsDataSourceUri()
                # passwords, usernames need to be empty if not provided or else connection will fail
                if 'service' in list(db_con_info.keys()):
                    uri.setConnection(db_con_info['service'], '', '', '')
                elif 'password' in list(db_con_info.keys()):
                    uri.setConnection(db_con_info['host'], db_con_info['port'],
                                      db_con_info['dbname'],
                                      db_con_info['user'],
                                      db_con_info['password'])
                else:
                    print(db_con_info)  # db_con_info['host']
                    uri.setConnection('', db_con_info['port'],
                                      db_con_info['dbname'], '', '')
                uri.setDataSource(schema, table_name, "geom")
                error = QgsVectorLayerExporter.exportLayer(
                    vl, uri.uri(), "postgres", vl.crs())
                if error[0] != QgsVectorLayerExporter.NoError:
                    print("Error when creating postgis layer: ", error[1])
                    vl = 'duplicate'
                else:
                    vl = QgsVectorLayer(uri.uri(), table_name, "postgres")
            else:
                vl = 'invalid data source'

        if vl == 'invalid data source':
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Specify output path!')
            msgBar.pushWidget(msg, Qgis.Info, 10)
        elif vl == 'duplicate':
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Fronatges layer already exists!')
            msgBar.pushWidget(msg, Qgis.Info, 10)
        elif not vl:
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Entrance layer failed to load!')
            msgBar.pushWidget(msg, Qgis.Info, 10)

        else:
            QgsProject.instance().addMapLayer(vl)
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Entrances layer created!')
            msgBar.pushWidget(msg, Qgis.Info, 10)
            vl.startEditing()

        self.updateEntranceLayer()
        self.entrancedlg.closePopUpEntrances()
Пример #8
0
    def accept(self):
        if self.mode == self.ASK_FOR_INPUT_MODE:
            # create the input layer (if not already done) and
            # update available options
            self.reloadInputLayer()

        # sanity checks
        if self.inLayer is None:
            QMessageBox.information(self, self.tr("Import to database"), self.tr("Input layer missing or not valid"))
            return

        if self.cboTable.currentText() == "":
            QMessageBox.information(self, self.tr("Import to database"), self.tr("Output table name is required"))
            return

        if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
            try:
                sourceSrid = self.editSourceSrid.text()
            except ValueError:
                QMessageBox.information(self, self.tr("Import to database"),
                                        self.tr("Invalid source srid: must be an integer"))
                return

        if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
            try:
                targetSrid = self.editTargetSrid.text()
            except ValueError:
                QMessageBox.information(self, self.tr("Import to database"),
                                        self.tr("Invalid target srid: must be an integer"))
                return

        # override cursor
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        # store current input layer crs and encoding, so I can restore it
        prevInCrs = self.inLayer.crs()
        prevInEncoding = self.inLayer.dataProvider().encoding()

        try:
            schema = self.outUri.schema() if not self.cboSchema.isEnabled() else self.cboSchema.currentText()
            table = self.cboTable.currentText()

            # get pk and geom field names from the source layer or use the
            # ones defined by the user
            srcUri = QgsDataSourceUri(self.inLayer.source())

            pk = srcUri.keyColumn() if not self.chkPrimaryKey.isChecked() else self.editPrimaryKey.text()
            if not pk:
                pk = self.default_pk

            if self.inLayer.hasGeometryType() and self.chkGeomColumn.isEnabled():
                geom = srcUri.geometryColumn() if not self.chkGeomColumn.isChecked() else self.editGeomColumn.text()
                if not geom:
                    geom = self.default_geom
            else:
                geom = None

            options = {}
            if self.chkLowercaseFieldNames.isEnabled() and self.chkLowercaseFieldNames.isChecked():
                pk = pk.lower()
                if geom:
                    geom = geom.lower()
                options['lowercaseFieldNames'] = True

            # get output params, update output URI
            self.outUri.setDataSource(schema, table, geom, "", pk)
            uri = self.outUri.uri(False)

            providerName = self.db.dbplugin().providerName()
            if self.chkDropTable.isChecked():
                options['overwrite'] = True

            if self.chkSinglePart.isEnabled() and self.chkSinglePart.isChecked():
                options['forceSinglePartGeometryType'] = True

            outCrs = QgsCoordinateReferenceSystem()
            if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
                targetSrid = int(self.editTargetSrid.text())
                outCrs = QgsCoordinateReferenceSystem(targetSrid)

            # update input layer crs and encoding
            if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
                sourceSrid = int(self.editSourceSrid.text())
                inCrs = QgsCoordinateReferenceSystem(sourceSrid)
                self.inLayer.setCrs(inCrs)

            if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked():
                enc = self.cboEncoding.currentText()
                self.inLayer.setProviderEncoding(enc)

            onlySelected = self.chkSelectedFeatures.isChecked()

            # do the import!
            ret, errMsg = QgsVectorLayerImport.importLayer(self.inLayer, uri, providerName, outCrs, onlySelected, False, options)
        except Exception as e:
            ret = -1
            errMsg = str(e)

        finally:
            # restore input layer crs and encoding
            self.inLayer.setCrs(prevInCrs)
            self.inLayer.setProviderEncoding(prevInEncoding)
            # restore cursor
            QApplication.restoreOverrideCursor()

        if ret != 0:
            output = QgsMessageViewer()
            output.setTitle(self.tr("Import to database"))
            output.setMessageAsPlainText(self.tr("Error {0}\n{1}").format(ret, errMsg))
            output.showMessage()
            return

        # create spatial index
        if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked():
            self.db.connector.createSpatialIndex((schema, table), geom)

        QMessageBox.information(self, self.tr("Import to database"), self.tr("Import was successful."))
        return QDialog.accept(self)
Пример #9
0
    def testExtentFromGeometryTable(self):
        """
        Check if the behavior of the mssql provider if extent is defined in the geometry_column table
        """
        # Create a layer
        layer = QgsVectorLayer(
            "Point?field=id:integer&field=fldtxt:string&field=fldint:integer",
            "layer", "memory")
        pr = layer.dataProvider()
        f1 = QgsFeature()
        f1.setAttributes([1, "test", 1])
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f2 = QgsFeature()
        f2.setAttributes([2, "test2", 3])
        f3 = QgsFeature()
        f3.setAttributes([3, "test2", NULL])
        f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(3, 2)))
        f4 = QgsFeature()
        f4.setAttributes([4, NULL, 3])
        f4.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(4, 3)))
        pr.addFeatures([f1, f2, f3, f4])
        uri = '{} table="qgis_test"."layer_extent_in_geometry_table" sql='.format(
            self.dbconn)
        QgsVectorLayerExporter.exportLayer(
            layer, uri, 'mssql', QgsCoordinateReferenceSystem('EPSG:4326'))

        layerUri = QgsDataSourceUri(uri)
        # Load and check if the layer is valid
        loadedLayer = QgsVectorLayer(layerUri.uri(), "valid", "mssql")
        self.assertTrue(loadedLayer.isValid())
        extent = loadedLayer.extent()
        self.assertEqual(extent.toString(1),
                         QgsRectangle(1.0, 2.0, 4.0, 3.0).toString(1))

        # Load with flag extent in geometry_columns table and check if the layer is still valid and extent doesn't change
        layerUri.setParam('extentInGeometryColumns', '1')
        loadedLayer = QgsVectorLayer(layerUri.uri(), "invalid", "mssql")
        self.assertTrue(loadedLayer.isValid())
        extent = loadedLayer.extent()
        self.assertEqual(extent.toString(1),
                         QgsRectangle(1.0, 2.0, 4.0, 3.0).toString(1))

        md = QgsProviderRegistry.instance().providerMetadata('mssql')
        conn = md.createConnection(self.dbconn, {})
        conn.addField(QgsField('qgis_xmin', QVariant.Double, 'FLOAT(24)'),
                      'dbo', 'geometry_columns')
        conn.addField(QgsField('qgis_xmax', QVariant.Double, 'FLOAT(24)'),
                      'dbo', 'geometry_columns')
        conn.addField(QgsField('qgis_ymin', QVariant.Double, 'FLOAT(24)'),
                      'dbo', 'geometry_columns')
        conn.addField(QgsField('qgis_ymax', QVariant.Double, 'FLOAT(24)'),
                      'dbo', 'geometry_columns')

        # try with empty attribute
        layerUri.setParam('extentInGeometryColumns', '1')
        loadedLayer = QgsVectorLayer(layerUri.uri(), "invalid", "mssql")
        self.assertTrue(loadedLayer.isValid())
        self.assertTrue(loadedLayer.isValid())
        extent = loadedLayer.extent()
        self.assertEqual(extent.toString(1),
                         QgsRectangle(1.0, 2.0, 4.0, 3.0).toString(1))

        conn.execSql(
            'UPDATE dbo.geometry_columns SET qgis_xmin=0, qgis_xmax=5.5, qgis_ymin=0.5, qgis_ymax=6 WHERE f_table_name=\'layer_extent_in_geometry_table\''
        )

        # try with valid attribute
        layerUri.setParam('extentInGeometryColumns', '1')
        loadedLayer = QgsVectorLayer(layerUri.uri(), "valid", "mssql")
        self.assertTrue(loadedLayer.isValid())
        extent = loadedLayer.extent()
        self.assertEqual(extent.toString(1),
                         QgsRectangle(0.0, 0.5, 5.5, 6.0).toString(1))
Пример #10
0
    def load_work_layers(self):

        def check_conn(host, port, database, user, password):
            try:
                conn = psycopg2.connect(host=host,port=port, database=database, user=user, password=password, connect_timeout=1)
                conn.close()
                #self.iface.messageBar().pushMessage(self.tr('Povezava uspešna'))
                return True
            except:
                #self.iface.messageBar().pushMessage(self.tr('Povezava neuspešna, napačen uporabnik ali geslo!'))
                return False


        host = parameters(self)[0]
        database =  parameters(self)[1]
        port =  parameters(self)[4]
        table = get_work_layers(self)
        uri = QgsDataSourceUri()
        root = QgsProject.instance().layerTreeRoot()

        self.host = parameters(self)[0]
        self.database =  parameters(self)[1]
        self.port =  parameters(self)[4]


        #Input authentication
        authcfg = self.dlg.mAuthConfigSelect.configId()
        auth_mgr = QgsApplication.authManager()
        auth_cfg = QgsAuthMethodConfig()
        auth_mgr.loadAuthenticationConfig(authcfg, auth_cfg, True)
        auth = auth_cfg.configMap()

        # Input Username, password
        user = self.dlg.user_input.text()
        password = self.dlg.pass_input.text()
        def auth_text(user, password):   
            authMgr = QgsApplication.authManager()    
            cfg = QgsAuthMethodConfig()
            cfg.setName(user)
            cfg.setMethod('Basic')
            cfg.setConfig('username', user)
            cfg.setConfig('password', password) 
            authMgr.storeAuthenticationConfig(cfg)
            return(cfg) 

        aut_meth = 0 

        if user:
            check_conn(host, port, database, user, password)
            authentication = auth_text(user, password)  
            aut_meth = 1

        elif auth_mgr:
            try:
                check_conn(host, port, database, auth["username"], auth["password"])
                authentication = auth_cfg
            except:
                pass
        else:
            self.iface.messageBar().pushMessage(self.tr("Napačen uporabnik ali geslo."), self.tr("Potrdi za javni dostop."), level=Qgis.Critical)
            text = self.tr('Uporabljam javni dostop:')
            uri.setConnection(host, port, database, None, None)
            (success, user, passwd) = QgsCredentials.instance().get(text, parameters(self)[3],  parameters(self)[2])  
            if success:
                if check_conn(host, port, database, user, passwd):
                    user = user
                    password = passwd  
                else:
                    check_conn(host, port, database, user, passwd) 
                    self.iface.messageBar().pushMessage(self.tr('Povezava neuspešna, napačen uporabnik ali geslo!'))

        #List of groups and layers
        w_layers = [r[1] for r in table.getFeatures()]         
        groups = [self.tr('Delovni sloji')]



        def load_wl(shema, table, geom, sql, fid):   
            if geom == '':
                geom = None
            uri.setConnection(self.host, self.port, self.database, "", "", QgsDataSourceUri.SslDisable,"")
            uri.setAuthConfigId(authentication.id())
            uri.setDataSource(shema, table, geom, sql, fid)
            layer=QgsVectorLayer (uri .uri(False), table, "postgres")
            return layer
      



        #Attribute form config for layer ZLS Int
        def field_to_value_relation(layer):
            fields = layer.fields()
            pattern = re.compile(r'Vrsta')
            fields_vrsta = [field for field in fields if pattern.match(field.name())]
            if len(fields_vrsta) > 0:
                config = {'AllowMulti': False,
                        'AllowNull': False,
                        'FilterExpression': 'Sloj = current_value(\'Sloj\') and  \"Opombe\" =\'kategorije\'',
                        'Key': 'Vrsta',
                        'Layer': layer.id(),
                        'NofColumns': 1,
                        'OrderByValue': False,
                        'UseCompleter': False,
                        'Value': 'Vrsta'}
                for field in fields_vrsta:
                    field_idx = fields.indexOf(field.name())
                    if field_idx >= 0:
                        try:             
                            widget_setup = QgsEditorWidgetSetup('ValueRelation',config)
                            layer.setEditorWidgetSetup(field_idx, widget_setup) 
                        except:
                            pass
                    else:
                        return False
            else:
                return False
            return True

        #Join fields function
        def field_join(t_layer, s_layer, t_field, s_field):
            joinObject = QgsVectorLayerJoinInfo()
            joinObject.setJoinFieldName(s_field)
            joinObject.setTargetFieldName(t_field)
            joinObject.setJoinLayerId(s_layer.id())
            joinObject.setUsingMemoryCache(True)
            joinObject.setJoinLayer(s_layer)
            t_layer.addJoin(joinObject)


        #Populate list of accessible layers
        layers_list = []
        for f in table.getFeatures():
            if f[3] != 'admin':
                print(f[2])
                try:
                    layer = load_wl(f[2], f[1], f[4], "", f[5])
                    if layer.isValid():
                        layers_list.append(layer)  
                except:
                    continue

        if not root.findGroup(self.tr('Delovni sloji')) and len(layers_list) != 0:
            w_group = root.addGroup(self.tr('Delovni sloji'))
        else:
            w_group = root.findGroup(self.tr('Delovni sloji'))

        # load layers
        for current, layer in enumerate(layers_list):
            QgsProject.instance().addMapLayer(layer, False)   
            w_group.insertChildNode(current, QgsLayerTreeLayer(layer))
            myLayerNode = root.findLayer(layer.id())
            myLayerNode.setExpanded(False)
            if layer.name() == 'ZLS Interpretacija_delovno':
                field_to_value_relation(layer)
        
        if aut_meth == 1:
            authMgr = QgsApplication.authManager()
            authMgr.removeAuthenticationConfig(authentication.id())  
Пример #11
0
 def uri(self):
     return QgsDataSourceUri("qgis")
Пример #12
0
 def testDataSourceUri(self):
     ds = QgsDataSourceUri()
     ds.setConnection(aHost='my_host', aPort='2322', aDatabase='my_db', aUsername='******', aPassword='******')
     self.assertEqual(ds.__repr__(), "<QgsDataSourceUri: dbname='my_db' host=my_host port=2322 user='******' password='******'>")
    def processAlgorithm(self, parameters, context, feedback):
        connection_name = self.parameterAsConnectionName(
            parameters, self.DATABASE, context)

        # resolve connection details to uri
        try:
            md = QgsProviderRegistry.instance().providerMetadata('postgres')
            conn = md.createConnection(connection_name)
        except QgsProviderConnectionException:
            raise QgsProcessingException(
                self.tr('Could not retrieve connection details for {}').format(
                    connection_name))

        schema = self.parameterAsSchema(parameters, self.SCHEMA, context)
        overwrite = self.parameterAsBoolean(parameters, self.OVERWRITE,
                                            context)
        createIndex = self.parameterAsBoolean(parameters, self.CREATEINDEX,
                                              context)
        convertLowerCase = self.parameterAsBoolean(parameters,
                                                   self.LOWERCASE_NAMES,
                                                   context)
        dropStringLength = self.parameterAsBoolean(parameters,
                                                   self.DROP_STRING_LENGTH,
                                                   context)
        forceSinglePart = self.parameterAsBoolean(parameters,
                                                  self.FORCE_SINGLEPART,
                                                  context)
        primaryKeyField = self.parameterAsString(parameters, self.PRIMARY_KEY,
                                                 context) or 'id'
        encoding = self.parameterAsString(parameters, self.ENCODING, context)

        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        table = self.parameterAsDatabaseTableName(parameters, self.TABLENAME,
                                                  context)
        if table:
            table.strip()
        if not table or table == '':
            table = source.sourceName()
            table = table.replace('.', '_')
        table = table.replace(' ', '')[0:62]
        providerName = 'postgres'

        geomColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN,
                                            context)
        if not geomColumn:
            geomColumn = 'geom'

        options = {}
        if overwrite:
            options['overwrite'] = True
        if convertLowerCase:
            options['lowercaseFieldNames'] = True
            geomColumn = geomColumn.lower()
        if dropStringLength:
            options['dropStringConstraints'] = True
        if forceSinglePart:
            options['forceSinglePartGeometryType'] = True

        # Clear geometry column for non-geometry tables
        if source.wkbType() == QgsWkbTypes.NoGeometry:
            geomColumn = None

        uri = QgsDataSourceUri(conn.uri())
        uri.setSchema(schema)
        uri.setTable(table)
        uri.setKeyColumn(primaryKeyField)
        uri.setGeometryColumn(geomColumn)

        if encoding:
            options['fileEncoding'] = encoding

        exporter = QgsVectorLayerExporter(uri.uri(), providerName,
                                          source.fields(), source.wkbType(),
                                          source.sourceCrs(), overwrite,
                                          options)

        if exporter.errorCode() != QgsVectorLayerExporter.NoError:
            raise QgsProcessingException(
                self.tr('Error importing to PostGIS\n{0}').format(
                    exporter.errorMessage()))

        features = source.getFeatures()
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not exporter.addFeature(f, QgsFeatureSink.FastInsert):
                feedback.reportError(exporter.errorMessage())

            feedback.setProgress(int(current * total))

        exporter.flushBuffer()
        if exporter.errorCode() != QgsVectorLayerExporter.NoError:
            raise QgsProcessingException(
                self.tr('Error importing to PostGIS\n{0}').format(
                    exporter.errorMessage()))

        if geomColumn and createIndex:
            try:
                options = QgsAbstractDatabaseProviderConnection.SpatialIndexOptions(
                )
                options.geometryColumnName = geomColumn
                conn.createSpatialIndex(schema, table, options)
            except QgsProviderConnectionException as e:
                raise QgsProcessingException(
                    self.tr('Error creating spatial index:\n{0}').format(e))

        try:
            conn.vacuum(schema, table)
        except QgsProviderConnectionException as e:
            feedback.reportError(
                self.tr('Error vacuuming table:\n{0}').format(e))

        return {}
Пример #14
0
def createVectorWriter(destination,
                       encoding,
                       fields,
                       geometryType,
                       crs,
                       context,
                       options=None):
    layer = None
    sink = None

    if encoding is None:
        settings = QgsSettings()
        encoding = settings.value('/Processing/encoding', 'System', str)

    if destination.startswith(MEMORY_LAYER_PREFIX):
        uri = QgsWkbTypes.displayString(geometryType) + "?uuid=" + str(
            uuid.uuid4())
        if crs.isValid():
            uri += '&crs=' + crs.authid()
        fieldsdesc = []
        for f in fields:
            qgsfield = _toQgsField(f)
            fieldsdesc.append(
                'field=%s:%s' %
                (qgsfield.name(),
                 TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string")))
        if fieldsdesc:
            uri += '&' + '&'.join(fieldsdesc)

        layer = QgsVectorLayer(uri, destination, 'memory')
        sink = layer.dataProvider()
        context.temporaryLayerStore().addMapLayer(layer, False)
    elif destination.startswith(POSTGIS_LAYER_PREFIX):
        uri = QgsDataSourceUri(destination[len(POSTGIS_LAYER_PREFIX):])
        connInfo = uri.connectionInfo()
        (success, user,
         passwd) = QgsCredentials.instance().get(connInfo, None, None)
        if success:
            QgsCredentials.instance().put(connInfo, user, passwd)
        else:
            raise GeoAlgorithmExecutionException(
                "Couldn't connect to database")
        try:
            db = postgis.GeoDB(host=uri.host(),
                               port=int(uri.port()),
                               dbname=uri.database(),
                               user=user,
                               passwd=passwd)
        except postgis.DbError as e:
            raise GeoAlgorithmExecutionException(
                "Couldn't connect to database:\n%s" % e.message)

        def _runSQL(sql):
            try:
                db._exec_sql_and_commit(str(sql))
            except postgis.DbError as e:
                raise GeoAlgorithmExecutionException(
                    'Error creating output PostGIS table:\n%s' % e.message)

        fields = [_toQgsField(f) for f in fields]
        fieldsdesc = ",".join(
            '%s %s' %
            (f.name(), TYPE_MAP_POSTGIS_LAYER.get(f.type(), "VARCHAR"))
            for f in fields)

        _runSQL("CREATE TABLE %s.%s (%s)" %
                (uri.schema(), uri.table().lower(), fieldsdesc))
        if geometryType != QgsWkbTypes.NullGeometry:
            _runSQL(
                "SELECT AddGeometryColumn('{schema}', '{table}', 'the_geom', {srid}, '{typmod}', 2)"
                .format(
                    table=uri.table().lower(),
                    schema=uri.schema(),
                    srid=crs.authid().split(":")[-1],
                    typmod=QgsWkbTypes.displayString(geometryType).upper()))

        layer = QgsVectorLayer(uri.uri(), uri.table(), "postgres")
        sink = layer.dataProvider()
        context.temporaryLayerStore().addMapLayer(layer, False)
    elif destination.startswith(SPATIALITE_LAYER_PREFIX):
        uri = QgsDataSourceUri(destination[len(SPATIALITE_LAYER_PREFIX):])
        try:
            db = spatialite.GeoDB(uri=uri)
        except spatialite.DbError as e:
            raise GeoAlgorithmExecutionException(
                "Couldn't connect to database:\n%s" % e.message)

        def _runSQL(sql):
            try:
                db._exec_sql_and_commit(str(sql))
            except spatialite.DbError as e:
                raise GeoAlgorithmExecutionException(
                    'Error creating output Spatialite table:\n%s' % str(e))

        fields = [_toQgsField(f) for f in fields]
        fieldsdesc = ",".join(
            '%s %s' %
            (f.name(), TYPE_MAP_SPATIALITE_LAYER.get(f.type(), "VARCHAR"))
            for f in fields)

        _runSQL("DROP TABLE IF EXISTS %s" % uri.table().lower())
        _runSQL("CREATE TABLE %s (%s)" % (uri.table().lower(), fieldsdesc))
        if geometryType != QgsWkbTypes.NullGeometry:
            _runSQL(
                "SELECT AddGeometryColumn('{table}', 'the_geom', {srid}, '{typmod}', 2)"
                .format(
                    table=uri.table().lower(),
                    srid=crs.authid().split(":")[-1],
                    typmod=QgsWkbTypes.displayString(geometryType).upper()))

        layer = QgsVectorLayer(uri.uri(), uri.table(), "spatialite")
        sink = layer.dataProvider()
        context.temporaryLayerStore().addMapLayer(layer, False)
    else:
        formats = QgsVectorFileWriter.supportedFiltersAndFormats()
        OGRCodes = {}
        for (key, value) in list(formats.items()):
            extension = str(key)
            extension = extension[extension.find('*.') + 2:]
            extension = extension[:extension.find(' ')]
            OGRCodes[extension] = value
        OGRCodes['dbf'] = "DBF file"

        extension = destination[destination.rfind('.') + 1:]

        if extension not in OGRCodes:
            extension = 'shp'
            destination = destination + '.shp'

        if geometryType == QgsWkbTypes.NoGeometry:
            if extension == 'shp':
                extension = 'dbf'
                destination = destination[:destination.rfind('.')] + '.dbf'
            if extension not in NOGEOMETRY_EXTENSIONS:
                raise GeoAlgorithmExecutionException(
                    "Unsupported format for tables with no geometry")

        qgsfields = QgsFields()
        for field in fields:
            qgsfields.append(_toQgsField(field))

        # use default dataset/layer options
        dataset_options = QgsVectorFileWriter.defaultDatasetOptions(
            OGRCodes[extension])
        layer_options = QgsVectorFileWriter.defaultLayerOptions(
            OGRCodes[extension])

        sink = QgsVectorFileWriter(destination, encoding, qgsfields,
                                   geometryType, crs, OGRCodes[extension],
                                   dataset_options, layer_options)
    return sink, destination, layer
Пример #15
0
    def add_layers(self):
        obs_db_existing = self.root.findGroup('Midvatten_OBS_DB')
        if obs_db_existing:
            position_index = 1
        else:
            position_index = 0

        MyGroup = qgis.core.QgsLayerTreeGroup(name=self.group_name,
                                              checked=True)
        self.root.insertChildNode(position_index, MyGroup)
        MySubGroup = MyGroup.addGroup('värdeförråd')
        uri = QgsDataSourceUri()
        uri.setDatabase(self.dbpath)
        canvas = self.iface.mapCanvas()
        layer_list = []
        layer_name_list = []
        layer_dict = dict()  # name as key and layer as value

        # first add all data domains (beginning with zz_ in the database)
        conn_ok, dd_tables = utils.sql_load_fr_db(
            "select name from sqlite_master where name like 'zz_%'",
            self.dbpath)
        if not conn_ok:
            return
        d_domain_tables = [str(dd_table[0]) for dd_table in dd_tables]
        for tablename in d_domain_tables:
            uristring = 'dbname="' + self.dbpath + '" table="' + tablename + '"'
            layer = QgsVectorLayer(uristring, tablename, 'spatialite')
            layer_list.append(layer)
            layer_name_list.append(layer.name())

        # Then some specific tables
        for tablename in ['tillromr_summaflode'
                          ]:  #, 'profil' # Implementera vid behov
            try:
                uristring = 'dbname="' + self.dbpath + '" ' + r"""table='{}'""".format(
                    tablename)
                layer = QgsVectorLayer(uristring, tablename, 'spatialite')
                layer_list.append(layer)
            except:
                pass

        #then load all spatial layers
        layers = default_layers(
        )  # ordered dict with layer-name:(zz_layer-name,layer_name_for_map_legend)
        for tablename, tup in list(layers.items()):
            try:
                uri.setDataSource('', tablename, 'geometry')
                layer = QgsVectorLayer(
                    uri.uri(), tablename, 'spatialite'
                )  # Adding the layer as 'spatialite' instead of ogr vector layer is preferred
                if layer.isValid():
                    layer_list.append(layer)
                    layer_name_list.append(layer.name())
                else:
                    qgis.utils.iface.messageBar().pushMessage(
                        "Warning",
                        "Table %s was not valid. DB probably created w old plugin version."
                        % str(tablename),
                        1,
                        duration=5)
            except:
                qgis.utils.iface.messageBar().pushMessage(
                    "Warning",
                    "Table %s not found in db. DB probably created w old plugin version."
                    % str(tablename),
                    1,
                    duration=5)
        #now loop over all the layers and set styles etc
        for layer in layer_list:
            QgsProject.instance().addMapLayers([layer], False)
            if layer.name() in d_domain_tables:
                MySubGroup.insertLayer(0, layer)
            else:
                MyGroup.insertLayer(0, layer)

            layer_dict[layer.name()] = layer

            #now try to load the style file
            stylefile = os.path.join(os.sep, os.path.dirname(__file__),
                                     "sql_strings",
                                     layer.name() + ".qml")
            try:
                layer.loadNamedStyle(stylefile)
            except:
                pass
            if layer.name() == 'gvmag':  #zoom to gvmag extent
                canvas.setExtent(layer.extent())
            else:
                pass

            if layer.name() in defs.unchecked_layers():
                #QgsProject.instance().layerTreeRoot().findLayer(layer.id()).setItemVisibilityChecked(False)
                MyGroup.findLayer(layer.id()).setItemVisibilityChecked(False)
                #w_lvls_last_geom.setItemVisibilityCheckedRecursive(False)

        MySubGroup.setExpanded(False)

        # fix value relations
        for lyr in list(layers.keys()):
            if lyr in layer_name_list:
                if not layers[lyr][0] == None:
                    #self.create_layer_value_relations(layer_dict[lyr], layer_dict[layers[lyr]], layer_dict[lyr].dataProvider().fieldNameIndex('typ'), 'typ','beskrivning')
                    self.create_layer_value_relations(
                        layer_dict[lyr], layer_dict[layers[lyr][0]],
                        layer_dict[lyr].dataProvider().fieldNameIndex('typ'),
                        'typ', 'beskrivning')

        #special fix for gvflode
        self.create_layer_value_relations(
            layer_dict['gvflode'], layer_dict['zz_gvmag'],
            layer_dict['gvflode'].dataProvider().fieldNameIndex('intermag'),
            'typ', 'beskrivning')
        for projektdependent_layer in ['profillinje'
                                       ]:  #, 'profil' # Implementera vid behov
            if projektdependent_layer in layer_dict:
                self.create_layer_value_relations(
                    layer_dict[projektdependent_layer],
                    layer_dict['zz_projekt'],
                    layer_dict[projektdependent_layer].dataProvider(
                    ).fieldNameIndex('projekt'), 'pkuid', 'namn')

        #last, rename to readable names in map legend
        for layer in layer_list:
            #for lyr in layers.keys():
            if layer.name() in layers:
                try:
                    layer.setLayerName(layers[layer.name()][1])
                except:
                    pass

        #finally refresh canvas
        canvas.refresh()
    def __init__(self, uri):
        DBConnector.__init__(self, uri)

        self.host = uri.host() or os.environ.get('PGHOST')
        self.port = uri.port() or os.environ.get('PGPORT')

        username = uri.username() or os.environ.get('PGUSER')
        password = uri.password() or os.environ.get('PGPASSWORD')

        # Do not get db and user names from the env if service is used
        if not uri.service():
            if username is None:
                username = os.environ.get('USER')
            self.dbname = uri.database() or os.environ.get(
                'PGDATABASE') or username
            uri.setDatabase(self.dbname)

        expandedConnInfo = self._connectionInfo()
        try:
            self.connection = psycopg2.connect(expandedConnInfo)
        except self.connection_error_types() as e:
            err = str(e)
            uri = self.uri()
            conninfo = uri.connectionInfo(False)

            for i in range(3):
                (ok, username, password) = QgsCredentials.instance().get(
                    conninfo, username, password, err)
                if not ok:
                    raise ConnectionError(e)

                if username:
                    uri.setUsername(username)

                if password:
                    uri.setPassword(password)

                newExpandedConnInfo = uri.connectionInfo(True)
                try:
                    self.connection = psycopg2.connect(newExpandedConnInfo)
                    QgsCredentials.instance().put(conninfo, username, password)
                except self.connection_error_types() as e:
                    if i == 2:
                        raise ConnectionError(e)

                    err = str(e)
                finally:
                    # remove certs (if any) of the expanded connectionInfo
                    expandedUri = QgsDataSourceUri(newExpandedConnInfo)

                    sslCertFile = expandedUri.param("sslcert")
                    if sslCertFile:
                        sslCertFile = sslCertFile.replace("'", "")
                        os.remove(sslCertFile)

                    sslKeyFile = expandedUri.param("sslkey")
                    if sslKeyFile:
                        sslKeyFile = sslKeyFile.replace("'", "")
                        os.remove(sslKeyFile)

                    sslCAFile = expandedUri.param("sslrootcert")
                    if sslCAFile:
                        sslCAFile = sslCAFile.replace("'", "")
                        os.remove(sslCAFile)
        finally:
            # remove certs (if any) of the expanded connectionInfo
            expandedUri = QgsDataSourceUri(expandedConnInfo)

            sslCertFile = expandedUri.param("sslcert")
            if sslCertFile:
                sslCertFile = sslCertFile.replace("'", "")
                os.remove(sslCertFile)

            sslKeyFile = expandedUri.param("sslkey")
            if sslKeyFile:
                sslKeyFile = sslKeyFile.replace("'", "")
                os.remove(sslKeyFile)

            sslCAFile = expandedUri.param("sslrootcert")
            if sslCAFile:
                sslCAFile = sslCAFile.replace("'", "")
                os.remove(sslCAFile)

        self.connection.set_isolation_level(
            psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)

        c = self._execute(None, u"SELECT current_user,current_database()")
        self.user, self.dbname = self._fetchone(c)
        self._close_cursor(c)

        self._checkSpatial()
        self._checkRaster()
        self._checkGeometryColumnsTable()
        self._checkRasterColumnsTable()
Пример #17
0
 def uri(self):
     return QgsDataSourceUri(self._uri.uri(False))
Пример #18
0
    def ogrConnectionStringAndFormatFromLayer(layer):
        provider = layer.dataProvider().name()
        if provider == 'spatialite':
            # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql=
            regex = re.compile("dbname='(.+)'")
            r = regex.search(str(layer.source()))
            ogrstr = r.groups()[0]
            format = 'SQLite'
        elif provider == 'postgres':
            # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999
            # user='******' password='******' sslmode=disable
            # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON
            # table="t4" (geom) sql=
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            conninfo = dsUri.connectionInfo()
            conn = None
            ok = False
            while not conn:
                try:
                    conn = psycopg2.connect(dsUri.connectionInfo())
                except psycopg2.OperationalError:
                    (ok, user, passwd) = QgsCredentials.instance().get(
                        conninfo, dsUri.username(), dsUri.password())
                    if not ok:
                        break

                    dsUri.setUsername(user)
                    dsUri.setPassword(passwd)

            if not conn:
                raise RuntimeError(
                    'Could not connect to PostgreSQL database - check connection info'
                )

            if ok:
                QgsCredentials.instance().put(conninfo, user, passwd)

            ogrstr = "PG:%s" % dsUri.connectionInfo()
            format = 'PostgreSQL'
        elif provider == 'mssql':
            #'dbname=\'db_name\' host=myHost estimatedmetadata=true
            # srid=27700 type=MultiPolygon table="dbo"."my_table"
            # #(Shape) sql='
            dsUri = layer.dataProvider().uri()
            ogrstr = 'MSSQL:'
            ogrstr += 'database={0};'.format(dsUri.database())
            ogrstr += 'server={0};'.format(dsUri.host())
            if dsUri.username() != "":
                ogrstr += 'uid={0};'.format(dsUri.username())
            else:
                ogrstr += 'trusted_connection=yes;'
            if dsUri.password() != '':
                ogrstr += 'pwd={0};'.format(dsUri.password())
            ogrstr += 'tables={0}'.format(dsUri.table())
            format = 'MSSQL'
        elif provider == "oracle":
            # OCI:user/password@host:port/service:table
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            ogrstr = "OCI:"
            if dsUri.username() != "":
                ogrstr += dsUri.username()
                if dsUri.password() != "":
                    ogrstr += "/" + dsUri.password()
                delim = "@"

            if dsUri.host() != "":
                ogrstr += delim + dsUri.host()
                delim = ""
                if dsUri.port() != "" and dsUri.port() != '1521':
                    ogrstr += ":" + dsUri.port()
                ogrstr += "/"
                if dsUri.database() != "":
                    ogrstr += dsUri.database()
            elif dsUri.database() != "":
                ogrstr += delim + dsUri.database()

            if ogrstr == "OCI:":
                raise RuntimeError(
                    'Invalid oracle data source - check connection info')

            ogrstr += ":"
            if dsUri.schema() != "":
                ogrstr += dsUri.schema() + "."

            ogrstr += dsUri.table()
            format = 'OCI'
        else:
            ogrstr = str(layer.source()).split("|")[0]
            path, ext = os.path.splitext(ogrstr)
            format = QgsVectorFileWriter.driverForExtension(ext)

        return ogrstr, '"' + format + '"'
Пример #19
0
 def publicUri(self):
     publicUri = QgsDataSourceUri.removePassword(self._uri.uri(False))
     return QgsDataSourceUri(publicUri)
    def loadMapPreview(self, gidstr):
        """ if has geometry column load to map canvas """
        layerToSet = []
        srs = QgsCoordinateReferenceSystem(
            self.SRS, QgsCoordinateReferenceSystem.PostgisCrsId)
        sqlite_DB_path = '{}{}{}'.format(self.HOME, os.sep,
                                         "pyarchinit_DB_folder")
        path_cfg = '{}{}{}'.format(sqlite_DB_path, os.sep, 'config.cfg')
        conf = open(path_cfg, "r")
        con_sett = conf.read()
        conf.close()
        settings = Settings(con_sett)
        settings.set_configuration()

        if settings.SERVER == 'postgres':
            uri = QgsDataSourceUri()
            # set host name, port, database name, username and password

            uri.setConnection(settings.HOST, settings.PORT, settings.DATABASE,
                              settings.USER, settings.PASSWORD)

            # layerUS
            uri.setDataSource("public", "pyarchinit_archeozoo_view",
                              "the_geom", gidstr, "id_archzoo")
            layerUS = QgsVectorLayer(uri.uri(), "Fauna", "postgres")

            if layerUS.isValid():
                # self.USLayerId = layerUS.getLayerID()
                # style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml')
                # layerUS.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerUS], False)
                layerToSet.append(layerUS)

                # layerQuote
            uri.setDataSource("public", "pyarchinit_quote_view", "the_geom",
                              gidstr, "id_us")
            layerQUOTE = QgsVectorLayer(uri.uri(), "Quote", "postgres")

            if layerQUOTE.isValid():
                # style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'stile_quote.qml')
                # layerQUOTE.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerQUOTE], False)
                layerToSet.append(layerQUOTE)

            return layerToSet

        elif settings.SERVER == 'sqlite':
            sqliteDB_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                         'pyarchinit_db.sqlite')
            db_file_path = '{}{}'.format(self.HOME, sqliteDB_path)
            uri = QgsDataSourceUri()
            uri.setDatabase(db_file_path)

            # layerQuote
            uri.setDataSource('', 'pyarchinit_quote_view', 'the_geom', gidstr,
                              "ROWID")
            layerQUOTE = QgsVectorLayer(uri.uri(), 'pyarchinit_quote_view',
                                        'spatialite')

            if layerQUOTE.isValid():
                ###QMessageBox.warning(self, "TESTER", "OK Layer Quote valido",#QMessageBox.Ok)
                style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE,
                                           'quote_us_view.qml')
                layerQUOTE.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerQUOTE], False)
                layerToSet.append(layerQUOTE)
            else:
                pass
                # QMessageBox.warning(self, "TESTER", "OK Layer Quote non valido",	 #QMessageBox.Ok)

            uri.setDataSource('', 'pyarchinit_us_view', 'the_geom', gidstr,
                              "ROWID")
            layerUS = QgsVectorLayer(uri.uri(), 'pyarchinit_us_view',
                                     'spatialite')

            if layerUS.isValid():
                # QMessageBox.warning(self, "TESTER", "OK ayer US valido",	 #QMessageBox.Ok)
                style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE,
                                           'us_view.qml')
                layerUS.loadNamedStyle(style_path)
                QgsProject.instance().addMapLayers([layerUS], False)
                layerToSet.append(layerQUOTE)
            else:
                pass
                # QMessageBox.warning(self, "TESTER", "NOT! Layer US not valid",#QMessageBox.Ok)

            return layerToSet
Пример #21
0
    def connect(self, parent=None):
        conn_name = self.connectionName()
        settings = QgsSettings()
        settings.beginGroup(u"/{0}/{1}".format(self.connectionSettingsKey(),
                                               conn_name))

        if not settings.contains("database"):  # non-existent entry?
            raise InvalidDataException(
                self.tr(
                    'There is no defined database connection "{0}".'.format(
                        conn_name)))

        from qgis.core import QgsDataSourceUri
        uri = QgsDataSourceUri()

        settingsList = ["host", "port", "database", "username", "password"]
        host, port, database, username, password = [
            settings.value(x, "", type=str) for x in settingsList
        ]

        # get all of the connection options

        useEstimatedMetadata = settings.value("estimatedMetadata",
                                              False,
                                              type=bool)
        uri.setParam('userTablesOnly',
                     str(settings.value("userTablesOnly", False, type=bool)))
        uri.setParam(
            'geometryColumnsOnly',
            str(settings.value("geometryColumnsOnly", False, type=bool)))
        uri.setParam(
            'allowGeometrylessTables',
            str(settings.value("allowGeometrylessTables", False, type=bool)))
        uri.setParam(
            'onlyExistingTypes',
            str(settings.value("onlyExistingTypes", False, type=bool)))
        uri.setParam(
            'includeGeoAttributes',
            str(settings.value("includeGeoAttributes", False, type=bool)))

        settings.endGroup()

        uri.setConnection(host, port, database, username, password)

        uri.setUseEstimatedMetadata(useEstimatedMetadata)

        err = u""
        try:
            return self.connectToUri(uri)
        except ConnectionError as e:
            err = str(e)

        # ask for valid credentials
        max_attempts = 3
        for i in range(max_attempts):
            (ok, username, password) = QgsCredentials.instance().get(
                uri.connectionInfo(False), username, password, err)

            if not ok:
                return False

            uri.setConnection(host, port, database, username, password)

            try:
                self.connectToUri(uri)
            except ConnectionError as e:
                if i == max_attempts - 1:  # failed the last attempt
                    raise e
                err = str(e)
                continue

            QgsCredentials.instance().put(uri.connectionInfo(False), username,
                                          password)

            return True

        return False
Пример #22
0
    def __init__(self,
                 host=None,
                 port=None,
                 dbname=None,
                 user=None,
                 passwd=None,
                 service=None,
                 uri=None):
        # Regular expression for identifiers without need to quote them
        self.re_ident_ok = re.compile(r"^\w+$")
        port = str(port)

        if uri:
            self.uri = uri
        else:
            self.uri = QgsDataSourceUri()
            if service:
                self.uri.setConnection(service, dbname, user, passwd)
            else:
                self.uri.setConnection(host, port, dbname, user, passwd)

        conninfo = self.uri.connectionInfo(False)
        err = None
        for i in range(4):
            expandedConnInfo = self.uri.connectionInfo(True)
            try:
                self.con = psycopg2.connect(expandedConnInfo)
                if err is not None:
                    QgsCredentials.instance().put(conninfo,
                                                  self.uri.username(),
                                                  self.uri.password())
                break
            except psycopg2.OperationalError as e:
                if i == 3:
                    raise DbError(str(e))

                err = str(e)
                user = self.uri.username()
                password = self.uri.password()
                (ok, user, password) = QgsCredentials.instance().get(
                    conninfo, user, password, err)
                if not ok:
                    raise DbError(
                        QCoreApplication.translate("PostGIS",
                                                   'Action canceled by user'))
                if user:
                    self.uri.setUsername(user)
                if password:
                    self.uri.setPassword(password)
            finally:
                # remove certs (if any) of the expanded connectionInfo
                expandedUri = QgsDataSourceUri(expandedConnInfo)

                sslCertFile = expandedUri.param("sslcert")
                if sslCertFile:
                    sslCertFile = sslCertFile.replace("'", "")
                    os.remove(sslCertFile)

                sslKeyFile = expandedUri.param("sslkey")
                if sslKeyFile:
                    sslKeyFile = sslKeyFile.replace("'", "")
                    os.remove(sslKeyFile)

                sslCAFile = expandedUri.param("sslrootcert")
                if sslCAFile:
                    sslCAFile = sslCAFile.replace("'", "")
                    os.remove(sslCAFile)

        self.has_postgis = self.check_postgis()
Пример #23
0
def load_config(dir_file_conf):
    """ Return the json configuration of the control. """
    with open(dir_file_conf) as json_data:
        file = json.load(json_data)
    return file

if __name__ == '__main__':
    args = get_args()
    params = ' '.join(sys.argv)

    # start qgis
    qgs = qgs_init(args.dirqgis)

    # uri conection db
    uri = QgsDataSourceUri()
    uri.setConnection(args.server, str(args.port), args.dbname, args.user, args.password)

    # load configuration
    f_config = load_config(args.conf)

    # initialization of variables
    l_ind = {}
    d_feat = {}
    l_continuity = f_config["continuidad"]
    fman = init_file_manager(args.output)
    consignment_geometry = get_geometry_layer(args.rem)

    l_ind, d_feat = create_indexes(f_config["indices"], uri, args)

    # iteration of layers to verify control 1, 2, 3
Пример #24
0
    def testCreateRenameDeleteTable(self):
        connection_name = 'testCreateRenameDeleteTable'
        plugin = createDbPlugin('gpkg')
        uri = QgsDataSourceUri()

        test_gpkg_new = os.path.join(self.basetestpath, 'testCreateRenameDeleteTable.gpkg')
        shutil.copy(self.test_gpkg, test_gpkg_new)

        uri.setDatabase(test_gpkg_new)
        self.assertTrue(plugin.addConnection(connection_name, uri))

        connection = createDbPlugin('gpkg', connection_name)
        connection.connect()

        db = connection.database()
        self.assertIsNotNone(db)

        tables = db.tables()
        self.assertEqual(len(tables), 1)
        table = tables[0]
        self.assertTrue(table.rename('newName'))
        self.assertEqual(table.name, 'newName')

        connection.reconnect()

        db = connection.database()
        tables = db.tables()
        self.assertEqual(len(tables), 1)
        table = tables[0]
        self.assertEqual(table.name, 'newName')

        fields = []
        geom = ['geometry', 'POINT', 4326, 3]
        field1 = TableField(table)
        field1.name = 'fid'
        field1.dataType = 'INTEGER'
        field1.notNull = True
        field1.primaryKey = True

        field2 = TableField(table)
        field2.name = 'str_field'
        field2.dataType = 'TEXT'
        field2.modifier = 20

        fields = [field1, field2]
        self.assertTrue(db.createVectorTable('newName2', fields, geom))

        tables = db.tables()
        self.assertEqual(len(tables), 2)
        new_table = tables[1]
        self.assertEqual(new_table.name, 'newName2')
        fields = new_table.fields()
        self.assertEqual(len(fields), 3)
        self.assertFalse(new_table.hasSpatialIndex())

        self.assertTrue(new_table.createSpatialIndex())
        self.assertTrue(new_table.hasSpatialIndex())

        self.assertTrue(new_table.delete())

        tables = db.tables()
        self.assertEqual(len(tables), 1)

        connection.remove()
Пример #25
0
    def processAlgorithm(self, context, feedback):
        database = self.getParameterValue(self.DATABASE)
        uri = QgsDataSourceUri(database)
        if uri.database() is '':
            if '|layerid' in database:
                database = database[:database.find('|layerid')]
            uri = QgsDataSourceUri('dbname=\'%s\'' % (database))
        db = spatialite.GeoDB(uri)

        overwrite = self.getParameterValue(self.OVERWRITE)
        createIndex = self.getParameterValue(self.CREATEINDEX)
        convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES)
        dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH)
        forceSinglePart = self.getParameterValue(self.FORCE_SINGLEPART)
        primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) or 'id'
        encoding = self.getParameterValue(self.ENCODING)

        layerUri = self.getParameterValue(self.INPUT)
        layer = QgsProcessingUtils.mapLayerFromString(layerUri, context)

        table = self.getParameterValue(self.TABLENAME)
        if table:
            table.strip()
        if not table or table == '':
            table = layer.name()
        table = table.replace(' ', '').lower()
        providerName = 'spatialite'

        geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN)
        if not geomColumn:
            geomColumn = 'the_geom'

        options = {}
        if overwrite:
            options['overwrite'] = True
        if convertLowerCase:
            options['lowercaseFieldNames'] = True
            geomColumn = geomColumn.lower()
        if dropStringLength:
            options['dropStringConstraints'] = True
        if forceSinglePart:
            options['forceSinglePartGeometryType'] = True

        # Clear geometry column for non-geometry tables
        if not layer.hasGeometryType():
            geomColumn = None

        uri = db.uri
        uri.setDataSource('', table, geomColumn, '', primaryKeyField)

        if encoding:
            layer.setProviderEncoding(encoding)

        (ret, errMsg) = QgsVectorLayerExporter.exportLayer(
            layer,
            uri.uri(),
            providerName,
            self.crs,
            False,
            options,
        )
        if ret != 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Error importing to Spatialite\n{0}').format(errMsg))

        if geomColumn and createIndex:
            db.create_spatial_index(table, geomColumn)
Пример #26
0
    def ogrConnectionStringAndFormat(uri, context):
        """Generates OGR connection string and format string from layer source
        Returned values are a tuple of the connection string and format string
        """
        ogrstr = None
        format = None

        layer = QgsProcessingUtils.mapLayerFromString(uri, context, False)
        if layer is None:
            path, ext = os.path.splitext(uri)
            format = QgsVectorFileWriter.driverForExtension(ext)
            return '"' + uri + '"', '"' + format + '"'

        provider = layer.dataProvider().name()
        if provider == 'spatialite':
            # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql=
            regex = re.compile("dbname='(.+)'")
            r = regex.search(str(layer.source()))
            ogrstr = r.groups()[0]
            format = 'SQLite'
        elif provider == 'postgres':
            # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999
            # user='******' password='******' sslmode=disable
            # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON
            # table="t4" (geom) sql=
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            conninfo = dsUri.connectionInfo()
            conn = None
            ok = False
            while not conn:
                try:
                    conn = psycopg2.connect(dsUri.connectionInfo())
                except psycopg2.OperationalError:
                    (ok, user, passwd) = QgsCredentials.instance().get(
                        conninfo, dsUri.username(), dsUri.password())
                    if not ok:
                        break

                    dsUri.setUsername(user)
                    dsUri.setPassword(passwd)

            if not conn:
                raise RuntimeError(
                    'Could not connect to PostgreSQL database - check connection info'
                )

            if ok:
                QgsCredentials.instance().put(conninfo, user, passwd)

            ogrstr = "PG:%s" % dsUri.connectionInfo()
            format = 'PostgreSQL'
        elif provider == "oracle":
            # OCI:user/password@host:port/service:table
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            ogrstr = "OCI:"
            if dsUri.username() != "":
                ogrstr += dsUri.username()
                if dsUri.password() != "":
                    ogrstr += "/" + dsUri.password()
                delim = "@"

            if dsUri.host() != "":
                ogrstr += delim + dsUri.host()
                delim = ""
                if dsUri.port() != "" and dsUri.port() != '1521':
                    ogrstr += ":" + dsUri.port()
                ogrstr += "/"
                if dsUri.database() != "":
                    ogrstr += dsUri.database()
            elif dsUri.database() != "":
                ogrstr += delim + dsUri.database()

            if ogrstr == "OCI:":
                raise RuntimeError(
                    'Invalid oracle data source - check connection info')

            ogrstr += ":"
            if dsUri.schema() != "":
                ogrstr += dsUri.schema() + "."

            ogrstr += dsUri.table()
            format = 'OCI'
        else:
            ogrstr = str(layer.source()).split("|")[0]
            path, ext = os.path.splitext(ogrstr)
            format = QgsVectorFileWriter.driverForExtension(ext)

        return '"' + ogrstr + '"', '"' + format + '"'
Пример #27
0
    def addWms(self, wms_name, url, layers, mime_type, epsg_code, protocol):
        """
            # Slot for exposing the same-name function to Javascript. #
            Adding the WMS to the QGis TOC.
            :param wms_name: The WMS name to add in TOC as group
            :type wms_name: str
            :param url: The WMS URL
            :type url: str
            :param layers: The list of the WMS layers to add
            :type layers: list of str
            :param mime_type: The image MIME TYPE (e.g. image/png)
            :type mime_type: str
            :param epsg_code: The EPSG code (e.g. the number 32632)
            :type epsg_code: int
            :param protocol: The protocol (i.e. should be 'ba' for applying basic authentication). Not yet managed.
            :type protocol: str
        """
        qgs_logger = QgsApplication.messageLog()
        qgs_logger.logMessage('addWms: wms_name = {}'.format(wms_name),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: url = {}'.format(url),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: layers = {}'.format(layers),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: mime_type = {}'.format(mime_type),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: epsg_code = {}'.format(epsg_code),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: protocol = {}'.format(protocol),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)

        # For storing the URI data
        uri = QgsDataSourceUri()

        # Split the host with the request data
        pieces = url.split("?")
        if len(pieces) == 1:
            qgs_logger.logMessage('len(pieces) == 1',
                                  tag=configuration.LOGGER_TAG,
                                  level=Qgis.Info)
        elif len(pieces) == 2:
            qgs_logger.logMessage('len(pieces) == 2',
                                  tag=configuration.LOGGER_TAG,
                                  level=Qgis.Info)
            # Overriding the URL
            url = "{}{}".format(pieces[0], "?")
            parameters_values = pieces[1].split("=")
            if len(parameters_values) == 2:
                qgs_logger.logMessage('len(parameters) == 2',
                                      tag=configuration.LOGGER_TAG,
                                      level=Qgis.Info)
                uri.setParam(parameters_values[0], parameters_values[1])
                qgs_logger.logMessage('uri.param({}): {}'.format(
                    parameters_values[0], uri.param(parameters_values[0])),
                                      tag=configuration.LOGGER_TAG,
                                      level=Qgis.Info)
            else:
                qgs_logger.logMessage('len(p) != 2',
                                      tag=configuration.LOGGER_TAG,
                                      level=Qgis.Info)
        else:
            qgs_logger.logMessage('len(pieces) > 2 Not yet managed!',
                                  tag=configuration.LOGGER_TAG,
                                  level=Qgis.Warning)

        # Setting the URL to the URI
        uri.setParam("url", url)

        # Process the layers accordingly if just an element or a list of elements
        layers_list = []
        if "," in layers:
            layers_list = layers.split(",")
        else:
            layers_list.append(layers)

        # Setting the parameter 'layers' in the URI
        for val in layers_list:
            uri.setParam("layers", val)

        # Setting the other parameters
        # Styles seems required: https://gis.stackexchange.com/questions/183485/load-wms-with-pyqgis
        uri.setParam("styles", "")
        uri.setParam("format", mime_type)
        uri.setParam("crs", "EPSG:{}".format(epsg_code))

        # https://docs.qgis.org/3.4/en/docs/pyqgis_developer_cookbook/loadlayer.html#raster-layers
        # Ignore GetCoverage URL advertised by GetCapabilities. May be necessary if a server is not configured properly.
        uri.setParam("IgnoreGetMapUrl", "1")

        # Adding the parameters for the basic authentication
        qgs_logger.logMessage('Applying Basic-Authentication',
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        uri.setParam("username", self.session_user)
        uri.setParam("password", self.session_password)

        # Logging the parameters for debugging
        qgs_logger.logMessage('uri.param(url): {}'.format(uri.param("url")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.param(layers): {}'.format(
            uri.param("layers")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.param(format): {}'.format(
            uri.param("format")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.param(crs): {}'.format(uri.param("crs")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.service(): {}'.format(uri.service()),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('encodedUri: {}'.format(str(uri.encodedUri())),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.uri(): {}'.format(uri.uri()),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)

        # Generating the WMS layer
        wms_layer = QgsRasterLayer(str(uri.encodedUri()), wms_name, 'wms')

        # If the WMS is correctly generated, add to the QGis TOC
        if wms_layer.isValid():
            QgsProject.instance().addMapLayer(wms_layer)
        else:
            qgs_logger.logMessage(
                'Impossibile aggiungere il WMS: {}'.format(wms_name),
                tag=configuration.LOGGER_TAG,
                level=Qgis.Warning)
            self.show_message(
                "Attenzione!",
                "Impossibile aggiungere il WMS " + wms_name + " al progetto")