Ejemplo n.º 1
0
 def testPktMapInsert(self):
     vl = QgsVectorLayer('{} table="qgis_test"."{}" key="obj_id" sql='.format(self.dbconn, 'oid_serial_table'), "oid_serial", "postgres")
     self.assertTrue(vl.isValid())
     f = QgsFeature(vl.fields())
     f['obj_id'] = vl.dataProvider().defaultValueClause(0)
     f['name'] = 'Test'
     r, f = vl.dataProvider().addFeatures([f])
     self.assertTrue(r)
     self.assertNotEqual(f[0]['obj_id'], NULL, f[0].attributes())
     vl.deleteFeatures([f[0].id()])
Ejemplo n.º 2
0
 def testPktIntInsert(self):
     vl = QgsVectorLayer('{} table="qgis_test"."{}" key="pk" sql='.format(self.dbconn, 'bikes_view'), "bikes_view", "postgres")
     self.assertTrue(vl.isValid())
     f = QgsFeature(vl.fields())
     f['pk'] = NULL
     f['name'] = 'Cilo'
     r, f = vl.dataProvider().addFeatures([f])
     self.assertTrue(r)
     self.assertNotEqual(f[0]['pk'], NULL, f[0].attributes())
     vl.deleteFeatures([f[0].id()])
Ejemplo n.º 3
0
 def testPktIntInsert(self):
     vl = QgsVectorLayer('{} table="qgis_test"."{}" key="pk" sql='.format(self.dbconn, 'bikes_view'), "bikes_view", "postgres")
     self.assertTrue(vl.isValid())
     f = QgsFeature(vl.fields())
     f['pk'] = NULL
     f['name'] = 'Cilo'
     r, f = vl.dataProvider().addFeatures([f])
     self.assertTrue(r)
     self.assertNotEqual(f[0]['pk'], NULL, f[0].attributes())
     vl.deleteFeatures([f[0].id()])
Ejemplo n.º 4
0
 def testPktMapInsert(self):
     vl = QgsVectorLayer('{} table="qgis_test"."{}" key="obj_id" sql='.format(self.dbconn, 'oid_serial_table'), "oid_serial", "postgres")
     self.assertTrue(vl.isValid())
     f = QgsFeature(vl.fields())
     f['obj_id'] = vl.dataProvider().defaultValueClause(0)
     f['name'] = 'Test'
     r, f = vl.dataProvider().addFeatures([f])
     self.assertTrue(r)
     self.assertNotEqual(f[0]['obj_id'], NULL, f[0].attributes())
     vl.deleteFeatures([f[0].id()])
Ejemplo n.º 5
0
    def testStringArray(self):
        vl = QgsVectorLayer('%s table="qgis_test"."string_array" sql=' % (self.dbconn), "teststringarray", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName('value')).type(), QVariant.StringList)
        self.assertEqual(fields.at(fields.indexFromName('value')).subType(), QVariant.String)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField('value')
        self.assertIsInstance(f.attributes()[value_idx], list)
        self.assertEqual(f.attributes()[value_idx], ['a', 'b', 'c'])

        new_f = QgsFeature(vl.fields())
        new_f['pk'] = NULL
        new_f['value'] = ['simple', '"doubleQuote"', "'quote'", 'back\\slash']
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]['pk']
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back['pk'], new_pk)
            self.assertEqual(read_back['value'], new_f['value'])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Ejemplo n.º 6
0
    def testStringArray(self):
        vl = QgsVectorLayer('%s table="qgis_test"."string_array" sql=' % (self.dbconn), "teststringarray", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName('value')).type(), QVariant.StringList)
        self.assertEqual(fields.at(fields.indexFromName('value')).subType(), QVariant.String)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField('value')
        self.assertIsInstance(f.attributes()[value_idx], list)
        self.assertEqual(f.attributes()[value_idx], ['a', 'b', 'c'])

        new_f = QgsFeature(vl.fields())
        new_f['pk'] = NULL
        new_f['value'] = ['simple', '"doubleQuote"', "'quote'", 'back\\slash']
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]['pk']
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back['pk'], new_pk)
            self.assertEqual(read_back['value'], new_f['value'])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Ejemplo n.º 7
0
    def testHstore(self):
        vl = QgsVectorLayer('%s table="qgis_test"."dict" sql=' % (self.dbconn), "testhstore", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName('value')).type(), QVariant.Map)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField('value')
        self.assertIsInstance(f.attributes()[value_idx], dict)
        self.assertEqual(f.attributes()[value_idx], {'a': 'b', '1': '2'})

        new_f = QgsFeature(vl.fields())
        new_f['pk'] = NULL
        new_f['value'] = {'simple': '1', 'doubleQuote': '"y"', 'quote': "'q'", 'backslash': '\\'}
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]['pk']
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back['pk'], new_pk)
            self.assertEqual(read_back['value'], new_f['value'])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Ejemplo n.º 8
0
    def testHstore(self):
        vl = QgsVectorLayer('%s table="qgis_test"."dict" sql=' % (self.dbconn), "testhstore", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName('value')).type(), QVariant.Map)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField('value')
        self.assertIsInstance(f.attributes()[value_idx], dict)
        self.assertEqual(f.attributes()[value_idx], {'a': 'b', '1': '2'})

        new_f = QgsFeature(vl.fields())
        new_f['pk'] = NULL
        new_f['value'] = {'simple': '1', 'doubleQuote': '"y"', 'quote': "'q'", 'backslash': '\\'}
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]['pk']
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back['pk'], new_pk)
            self.assertEqual(read_back['value'], new_f['value'])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Ejemplo n.º 9
0
    def testHstore(self):
        vl = QgsVectorLayer('%s table="qgis_test"."dict" sql=' % (self.dbconn), "testhstore", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName("value")).type(), QVariant.Map)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField("value")
        self.assertIsInstance(f.attributes()[value_idx], dict)
        self.assertEqual(f.attributes()[value_idx], {"a": "b", "1": "2"})

        new_f = QgsFeature(vl.fields())
        new_f["pk"] = NULL
        new_f["value"] = {"simple": "1", "doubleQuote": '"y"', "quote": "'q'", "backslash": "\\"}
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]["pk"]
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back["pk"], new_pk)
            self.assertEqual(read_back["value"], new_f["value"])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Ejemplo n.º 10
0
class StartDuplic:
    def __init__(self, iface, layer):

        self.iface = iface

        self.layer = layer
        self.tableSchema = 'edgv'
        self.geometryColumn = 'geom'
        self.keyColumn = 'id'

    def run(self, fid=0):

        ##################################
        ###### PEGA A LAYER ATIVA ########
        ##################################

        parametros = self.layer.source().split(
            " "
        )  # recebe todos os parametros em uma lista ( senha, porta, password etc..)

        ####################################
        ###### INICIANDO CONEXÃO DB ########
        ####################################

        # Outra opção para isso, seria usar ex: self.dbname.. self.host.. etc.. direto dentro do laço for.
        dbname = ""
        host = ""
        port = 0
        user = ""
        password = ""

        for i in parametros:
            part = i.split("=")

            # Recebe os parametros guardados na própria Layer

            if "dbname" in part[0]:
                dbname = part[1].replace("'", "")

            elif "host" in part[0]:
                host = part[1].replace("'", "")

            elif "port" in part[0]:
                port = int(part[1].replace("'", ""))

            elif "user" in part[0]:
                user = part[1].replace("'", "")

            elif "password" in part[0]:
                password = part[1].split("|")[0].replace("'", "")

        print dbname, host, port, user, password

        # Testa se os parametros receberam os valores pretendidos, caso não, apresenta a mensagem informando..
        if len(dbname) == 0 or len(host) == 0 or port == 0 or len(
                user) == 0 or len(password) == 0:
            self.iface.messageBar().pushMessage(
                "Erro",
                u'Um dos parametros não foram devidamente recebidos!',
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

    ####################################
    #### SETA VALORES DE CONEXÃO DB ####
    ####################################

        connection = QSqlDatabase.addDatabase('QPSQL')
        connection.setHostName(host)
        connection.setPort(port)
        connection.setUserName(user)
        connection.setPassword(password)
        connection.setDatabaseName(dbname)

        if not connection.isOpen(
        ):  # Testa se a conexão esta recebendo os parametros adequadamente.
            if not connection.open():
                print 'Error connecting to database!'
                self.iface.messageBar().pushMessage(
                    "Erro",
                    u'Error connecting to database!',
                    level=QgsMessageBar.CRITICAL,
                    duration=4)
                print connection.lastError().text()
                return

    ####################################
    ###### CRIAÇÃO DE MEMORY LAYER #####
    ####################################

        layerCrs = self.layer.crs().authid()  # Passa o formato (epsg: numeros)

        flagsLayerName = self.layer.name() + "_flags"
        flagsLayerExists = False

        for l in QgsMapLayerRegistry.instance().mapLayers().values(
        ):  # Recebe todas as camadas que estão abertas
            if l.name() == flagsLayerName:  # ao encontrar o nome pretendido..
                self.flagsLayer = l  # flagslayer vai receber o nome..
                self.flagsLayerProvider = l.dataProvider()
                flagsLayerExists = True  # se encontrado os parametros buscados, recebe True.
                break

        if flagsLayerExists == False:  # se não encontrado os parametros buscados, recebe False.
            tempString = "Point?crs="
            tempString += str(layerCrs)

            self.flagsLayer = QgsVectorLayer(tempString, flagsLayerName,
                                             "memory")
            self.flagsLayerProvider = self.flagsLayer.dataProvider()
            self.flagsLayerProvider.addAttributes([
                QgsField("flagId", QVariant.String),
                QgsField("geomId", QVariant.String),
                QgsField("motivo", QVariant.String)
            ])
            self.flagsLayer.updateFields()

        if fid == 0:  # Se tiver iniciando limpa, caso não, mantém.
            self.flagsLayer.startEditing()
            ids = [feat.id() for feat in self.flagsLayer.getFeatures()]
            self.flagsLayer.deleteFeatures(ids)
            self.flagsLayer.commitChanges()

        lista_fid = []  # Iniciando lista.
        for f in self.layer.getFeatures():
            lista_fid.append(
                str(f.id())
            )  # Guarda na lista. A lista de Feature ids passa tipo "int", foi convertido e guardado como "str".

        source = self.layer.source().split(" ")
        self.tableName = ""  # Inicia vazio.
        layerExistsInDB = False

        for i in source:

            if "table=" in i or "layername=" in i:  # Se encontrar os atributos pretendidos dentre todos do for
                self.tableName = source[source.index(i)].split(".")[
                    1]  # Faz split em ponto e pega a segunda parte.
                self.tableName = self.tableName.replace('"', '')
                layerExistsInDB = True
                break

        if layerExistsInDB == False:
            self.iface.messageBar().pushMessage(
                "Erro",
                u"Provedor da camada corrente não provem do banco de dados!",
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

        # Busca através do SQL
        sql = '''select * from (
        SELECT "{3}",
        ROW_NUMBER() OVER(PARTITION BY "{2}" ORDER BY "{3}" asc) AS Row,
        ST_AsText(geom) FROM ONLY "{0}"."{1}" 
        where {3} in ({4})
        ) dups 
        where dups.Row > 1'''.format(self.tableSchema, self.tableName,
                                     self.geometryColumn, self.keyColumn,
                                     ",".join(lista_fid))

        query = QSqlQuery(sql)

        self.flagsLayer.startEditing()
        flagCount = fid  # iniciando contador que será referência para os IDs da camada de memória.

        listaFeatures = []
        while query.next():

            id = query.value(0)
            ord = query.value(1)
            local = query.value(2)

            flagId = str(flagCount)

            flagFeat = QgsFeature()
            flagFeat.setFields(self.flagsLayer.fields()
                               )  # passa quais atributos serão usados.
            flagGeom = QgsGeometry.fromWkt(
                local)  # passa o local onde foi localizado o erro.
            flagFeat.setGeometry(flagGeom)
            flagFeat.setAttribute(
                0, flagId
            )  # insere o id definido para a coluna 0 da layer de memória.
            flagFeat.setAttribute(
                1, id
            )  # insere o id da geometria para a coluna 1 da layer de memória.
            flagFeat.setAttribute(2, u'Duplic-Geom')
            listaFeatures.append(flagFeat)

            flagCount += 1  # incrementando o contador a cada iteração.

        self.flagsLayerProvider.addFeatures(listaFeatures)
        self.flagsLayer.commitChanges()  # Aplica as alterações à camada.

        QgsMapLayerRegistry.instance().addMapLayer(
            self.flagsLayer)  # Adicione a camada no mapa.

        return flagCount
class StartOutofBoundsAngles:
    def __init__(self, iface):

        self.iface = iface

        self.tableSchema = 'edgv'
        self.geometryColumn = 'geom'
        self.keyColumn = 'id'
        self.angle = 10

    def initGui(self):
        # cria uma ação que iniciará a configuração do plugin
        pai = self.iface.mainWindow()
        icon_path = ':/plugins/StartOutofBoundsAngles/icon.png'
        self.action = QAction(
            QIcon(icon_path),
            u"Acessa banco de dados para encontrar anglos fechados.", pai)
        self.action.setObjectName("Start database")
        self.action.setStatusTip(None)
        self.action.setWhatsThis(None)
        self.action.triggered.connect(self.run)
        # Adicionar o botão icone
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        # remove o item de ícone do QGIS GUI.
        self.iface.removeToolBarIcon(self.action)

    def run(self):

        ##################################
        ###### PEGA A LAYER ATIVA ########
        ##################################

        layer = self.iface.activeLayer()

        if not layer:
            self.iface.messageBar().pushMessage("Erro",
                                                u"Esperando uma Active Layer!",
                                                level=QgsMessageBar.CRITICAL,
                                                duration=4)
            return
        if layer.featureCount() == 0:
            self.iface.messageBar().pushMessage(
                "Erro",
                u"a camada não possui feições!",
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

        parametros = layer.source().split(
            " "
        )  # recebe todos os parametros em uma lista ( senha, porta, password etc..)

        ####################################
        ###### INICIANDO CONEXÃO DB ########
        ####################################

        # Outra opção para isso, seria usar ex: self.dbname.. self.host.. etc.. direto dentro do laço for.
        dbname = ""
        host = ""
        port = 0
        user = ""
        password = ""

        for i in parametros:
            part = i.split("=")

            # Recebe os parametros guardados na própria Layer

            if "dbname" in part[0]:
                dbname = part[1].replace("'", "")

            elif "host" in part[0]:
                host = part[1].replace("'", "")

            elif "port" in part[0]:
                port = int(part[1].replace("'", ""))

            elif "user" in part[0]:
                user = part[1].replace("'", "")

            elif "password" in part[0]:
                password = part[1].split("|")[0].replace("'", "")

        print dbname, host, port, user, password

        # Testa se os parametros receberam os valores pretendidos, caso não, apresenta a mensagem informando..
        if len(dbname) == 0 or len(host) == 0 or port == 0 or len(
                user) == 0 or len(password) == 0:
            self.iface.messageBar().pushMessage(
                "Erro",
                u'Um dos parametros não foram devidamente recebidos!',
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

    ####################################
    #### SETA VALORES DE CONEXÃO DB ####
    ####################################

        connection = QSqlDatabase.addDatabase('QPSQL')
        connection.setHostName(host)
        connection.setPort(port)
        connection.setUserName(user)
        connection.setPassword(password)
        connection.setDatabaseName(dbname)

        if not connection.isOpen(
        ):  # Testa se a conexão esta recebendo os parametros adequadamente.
            if not connection.open():
                print 'Error connecting to database!'
                self.iface.messageBar().pushMessage(
                    "Erro",
                    u'Error connecting to database!',
                    level=QgsMessageBar.CRITICAL,
                    duration=4)
                print connection.lastError().text()
                return

    ####################################
    ###### CRIAÇÃO DE MEMORY LAYER #####
    ####################################

        layerCrs = layer.crs().authid()  # Passa o formato (epsg: numeros)

        flagsLayerName = layer.name() + "_flags"
        flagsLayerExists = False

        for l in QgsMapLayerRegistry.instance().mapLayers().values(
        ):  # Recebe todas as camadas que estão abertas
            if l.name() == flagsLayerName:  # ao encontrar o nome pretendido..
                self.flagsLayer = l  # flagslayer vai receber o nome..
                self.flagsLayerProvider = l.dataProvider()
                flagsLayerExists = True  # se encontrado os parametros buscados, recebe True.
                break

        if flagsLayerExists == False:  # se não encontrado os parametros buscados, recebe False.
            tempString = "Point?crs="
            tempString += str(layerCrs)

            self.flagsLayer = QgsVectorLayer(tempString, flagsLayerName,
                                             "memory")
            self.flagsLayerProvider = self.flagsLayer.dataProvider()
            self.flagsLayerProvider.addAttributes([
                QgsField("flagId", QVariant.Int),
                QgsField("geomId", QVariant.String),
                QgsField("motivo", QVariant.String)
            ])
            self.flagsLayer.updateFields()

        self.flagsLayer.startEditing()
        ids = [feat.id() for feat in self.flagsLayer.getFeatures()]
        self.flagsLayer.deleteFeatures(ids)
        self.flagsLayer.commitChanges()

        lista_fid = []  # Iniciando lista
        for f in layer.getFeatures():
            lista_fid.append(
                str(f.id())
            )  # Guarda na lista. A lista de Feature ids passa tipo "int", foi convertido e guardado como "str".

        source = layer.source().split(" ")
        self.tableName = ""  # Inicia vazio
        layerExistsInDB = False

        for i in source:

            if "table=" in i or "layername=" in i:  # Se encontrar os atributos pretendidos dentre todos do for
                self.tableName = source[source.index(i)].split(".")[
                    1]  # Faz split em ponto e pega a segunda parte.
                self.tableName = self.tableName.replace('"', '')
                layerExistsInDB = True
                break

        if layerExistsInDB == False:
            self.iface.messageBar().pushMessage(
                "Erro",
                u"Provedor da camada corrente não provem do banco de dados!",
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

        geomType = layer.geometryType()

        if geomType == QGis.Line:

            # Busca através do SQL
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-2)) as pt1, 
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")-1)) as anchor,
                              ST_PointN("{3}", generate_series(3, ST_NPoints("{3}"))) as pt2,
                              linestrings."{4}" as "{4}" 
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump("{3}")).geom as "{3}"
                               FROM only "{0}"."{1}"
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format(
                self.tableSchema, self.tableName, self.angle,
                self.geometryColumn, self.keyColumn, ",".join(lista_fid))

        elif geomType == QGis.Polygon:
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1)) as pt1,
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1) %  (ST_NPoints("{3}")-1)+1) as anchor,
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")) %  (ST_NPoints("{3}")-1)+1) as pt2,
                              linestrings."{4}" as "{4}"
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump(ST_Boundary(ST_ForceRHR((ST_Dump("{3}")).geom)))).geom as "{3}"
                               FROM only "{0}"."{1}" 
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format(
                self.tableSchema, self.tableName, self.angle,
                self.geometryColumn, self.keyColumn, ",".join(lista_fid))
        query = QSqlQuery(sql)

        self.flagsLayer.startEditing()
        flagCount = 0  # iniciando contador que será referência para os IDs da camada de memória.

        listaFeatures = []
        while query.next():
            id = query.value(0)
            local = query.value(1)
            angulo = query.value(2)
            flagId = flagCount

            print id, local, angulo

            flagFeat = QgsFeature()
            flagGeom = QgsGeometry.fromWkt(
                local)  # passa o local onde foi localizado o erro.
            flagFeat.setGeometry(flagGeom)
            flagFeat.initAttributes(3)
            flagFeat.setAttribute(
                0, flagId
            )  # insere o id definido para a coluna 0 da layer de memória.
            flagFeat.setAttribute(
                1, id
            )  # insere o id da geometria  para a coluna 1 da layer de memória.
            flagFeat.setAttribute(
                2, u"Ângulo para os vértices adjacentes inferior à tolerância")

            # TypeError: fromWkt(QString): argument 1 has unexpected type 'long'
            #     Traceback (most recent call last):
            #     File "/home/piangers/.qgis2/python/plugins/StartDuplic/StartDuplic.py", line 177, in run
            #     flagGeom = QgsGeometry.fromWkt(local) # passa o local onde foi localizado o erro.

            listaFeatures.append(flagFeat)

            flagCount += 1  # incrementando o contador a cada iteração

        self.flagsLayerProvider.addFeatures(listaFeatures)
        self.flagsLayer.commitChanges()  # Aplica as alterações à camada.

        QgsMapLayerRegistry.instance().addMapLayer(
            self.flagsLayer)  # Adicione a camada no mapa

        if flagCount == 0:

            QgsMapLayerRegistry.instance().removeMapLayer(self.flagsLayer.id())
            self.iface.messageBar().pushMessage(
                "Aviso",
                u"Não foi encontrado Flags em \"" + layer.name() + "\" !",
                level=QgsMessageBar.CRITICAL,
                duration=4)

            return
        if len(query.lastError().text()) == 1:
            self.iface.messageBar().pushMessage(
                "Aviso",
                "foram geradas " + str(flagCount) + " flags para a camada \"" +
                layer.name() + "\" !",
                level=QgsMessageBar.INFO,
                duration=4)
        else:
            self.iface.messageBar().pushMessage("Erro",
                                                u"a geração de flags falhou!",
                                                level=QgsMessageBar.CRITICAL,
                                                duration=4)
            print query.lastError().text()
class StartOutofBoundsAngles:

    def __init__(self, iface, layer):
        
        self.iface = iface

        self.layer = layer
        self.tableSchema = 'edgv'
        self.geometryColumn = 'geom'
        self.keyColumn = 'id'
        self.angle = 10

        
    def run(self, fid = 0):

    ##################################
    ###### PEGA A LAYER ATIVA ########
    ##################################

        parametros = self.layer.source().split(" ") # recebe todos os parametros em uma lista ( senha, porta, password etc..)

    ####################################
    ###### INICIANDO CONEXÃO DB ########
    ####################################

        # Outra opção para isso, seria usar ex: self.dbname.. self.host.. etc.. direto dentro do laço for.
        dbname = "" 
        host = ""
        port = 0
        user = ""
        password = ""

        for i in parametros:
            part = i.split("=")
            
        # Recebe os parametros guardados na própria Layer

            if "dbname" in part[0]:
                dbname = part[1].replace("'", "")

            elif "host" in part[0]:
                host = part[1].replace("'", "")

            elif "port" in part[0]:
                port = int(part[1].replace("'", ""))

            elif "user" in part[0]:
                user = part[1].replace("'", "")

            elif "password" in part[0]:
                password = part[1].split("|")[0].replace("'", "")

        print dbname, host, port, user, password


        # Testa se os parametros receberam os valores pretendidos, caso não, apresenta a mensagem informando..
        if len(dbname) == 0 or len(host) == 0 or port == 0 or len(user) == 0 or len(password) == 0:
            self.iface.messageBar().pushMessage("Erro", u'Um dos parametros não foram devidamente recebidos!', level=QgsMessageBar.CRITICAL, duration=4)
            return

    ####################################
    #### SETA VALORES DE CONEXÃO DB ####
    ####################################

        connection = QSqlDatabase.addDatabase('QPSQL')
        connection.setHostName(host)
        connection.setPort(port)
        connection.setUserName(user)
        connection.setPassword(password)
        connection.setDatabaseName(dbname)

        if not connection.isOpen(): # Testa se a conexão esta recebendo os parametros adequadamente.
            if not connection.open():
                print 'Error connecting to database!'
                self.iface.messageBar().pushMessage("Erro", u'Error connecting to database!', level=QgsMessageBar.CRITICAL, duration=4)
                print connection.lastError().text()
                return

    ####################################
    ###### CRIAÇÃO DE MEMORY LAYER #####
    ####################################
        
        layerCrs = self.layer.crs().authid() # Passa o formato (epsg: numeros)

        flagsLayerName = self.layer.name() + "_flags"
        flagsLayerExists = False

        for l in QgsMapLayerRegistry.instance().mapLayers().values(): # Recebe todas as camadas que estão abertas
            if l.name() == flagsLayerName: # ao encontrar o nome pretendido..
                self.flagsLayer = l # flagslayer vai receber o nome..
                self.flagsLayerProvider = l.dataProvider()
                flagsLayerExists = True # se encontrado os parametros buscados, recebe True.
                break
        
        if flagsLayerExists == False: # se não encontrado os parametros buscados, recebe False.
            tempString = "Point?crs="
            tempString += str(layerCrs)

            self.flagsLayer = QgsVectorLayer(tempString, flagsLayerName, "memory")
            self.flagsLayerProvider = self.flagsLayer.dataProvider()
            self.flagsLayerProvider.addAttributes([QgsField("flagId", QVariant.String), QgsField("geomId", QVariant.String), QgsField("motivo", QVariant.String)])
            self.flagsLayer.updateFields()

        if fid == 0: # Se for 0 então está iniciando e limpa, caso contrário não.
            self.flagsLayer.startEditing()
            ids = [feat.id() for feat in self.flagsLayer.getFeatures()]
            self.flagsLayer.deleteFeatures(ids)
            self.flagsLayer.commitChanges()
        
        
        lista_fid = [] # Iniciando lista
        for f in self.layer.getFeatures():
            lista_fid.append(str(f.id())) # Guarda na lista. A lista de Feature ids passa tipo "int", foi convertido e guardado como "str".

        source = self.layer.source().split(" ")
        self.tableName = "" # Inicia vazio
        layerExistsInDB = False
        
        for i in source:
                
            if "table=" in i or "layername=" in i: # Se encontrar os atributos pretendidos dentre todos do for
                self.tableName = source[source.index(i)].split(".")[1] # Faz split em ponto e pega a segunda parte.
                self.tableName = self.tableName.replace('"', '')
                layerExistsInDB = True
                break
             
        if layerExistsInDB == False:
            self.iface.messageBar().pushMessage("Erro", u"Provedor da camada corrente não provem do banco de dados!", level=QgsMessageBar.CRITICAL, duration=4)
            return

        
        geomType = self.layer.geometryType()

        if geomType == QGis.Line:
            
        # Busca através do SQL 
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-2)) as pt1, 
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")-1)) as anchor,
                              ST_PointN("{3}", generate_series(3, ST_NPoints("{3}"))) as pt2,
                              linestrings."{4}" as "{4}" 
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump("{3}")).geom as "{3}"
                               FROM only "{0}"."{1}"
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format( self.tableSchema, self.tableName, self.angle, self.geometryColumn, self.keyColumn,",".join(lista_fid))
        
        elif geomType == QGis.Polygon:
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1)) as pt1,
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1) %  (ST_NPoints("{3}")-1)+1) as anchor,
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")) %  (ST_NPoints("{3}")-1)+1) as pt2,
                              linestrings."{4}" as "{4}"
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump(ST_Boundary(ST_ForceRHR((ST_Dump("{3}")).geom)))).geom as "{3}"
                               FROM only "{0}"."{1}" 
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format( self.tableSchema, self.tableName, self.angle, self.geometryColumn, self.keyColumn,",".join(lista_fid) )
        query = QSqlQuery(sql)
        
        self.flagsLayer.startEditing()
        flagCount = fid # iniciando contador que será referência para os IDs da camada de memória.

        listaFeatures = []
        while query.next():
            id = query.value(0)
            local = query.value(1)
            angulo = query.value(2)
            flagId = str(flagCount)

            flagFeat = QgsFeature()
            flagFeat.setFields(self.flagsLayer.fields()) # passa quais atributos serão usados.           
            flagGeom = QgsGeometry.fromWkt(local) # passa o local onde foi localizado o erro.
            flagFeat.setGeometry(flagGeom)
            flagFeat.initAttributes(3)
            flagFeat.setAttribute(0,flagId) # insere o id definido para a coluna 0 da layer de memória.
            flagFeat.setAttribute(1, id) # insere o id da geometria  para a coluna 1 da layer de memória.
            flagFeat.setAttribute(2, u"Ângle-ExcededBound")
        
            listaFeatures.append(flagFeat)    

            flagCount += 1 # incrementando o contador a cada iteração.

        self.flagsLayerProvider.addFeatures(listaFeatures)
        self.flagsLayer.commitChanges() # Aplica as alterações à camada.
        
        QgsMapLayerRegistry.instance().addMapLayer(self.flagsLayer) # Adicione a camada no mapa.

        return flagCount
        
Ejemplo n.º 13
0
    def launchR2P(self):
        """Ridge to Point conversion"""
        layers = self.iface.legendInterface().layers()
        # Get index of combo box
        selected_line = self.lineComboBox.currentIndex()
        selected_dem_layer = self.DEMComboBox.currentIndex()
        # Get layer that fit with the combo box index
        self.lines_layer = layers[self.list_vect_ind[selected_line]]
        self.dem_layer = layers[self.list_rast_ind[selected_dem_layer]]
        self.min_dist = self.minLengthBox.value()
        self.id_line = self.idLineComboBox.currentText()
        self.output_path = self.outputEdit.text()
        l_done = []
        time = Timer()
        time.start()
        tmp_path = os.path.dirname(self.lines_layer.source())

        # Extract all points of interest (start of line, end of line, peak, pass) from polyline layer
        pointPassage, crs, self.dem_layer = passPointSeek(
            self.lines_layer, self.id_line, self.dem_layer, tmp_path)

        output_filename = os.path.join(os.path.dirname(self.output_path),
                                       r'temp.shp')
        QgsVectorFileWriter.writeAsVectorFormat(pointPassage, output_filename,
                                                "utf-8", crs, "ESRI Shapefile")
        pointPassage = None
        pointPassage = QgsVectorLayer(output_filename, 'pointpassage', "ogr")

        print 'R2P: Remove small ridge part'
        ids_rem = []
        orphans = []
        for pt in pointPassage.getFeatures():
            pt_id = pt.id()
            pt_geom = pt.geometry().asPoint()
            pt_x, pt_y = pt_geom
            bounding_box_buff = QgsRectangle(pt_x - self.min_dist,
                                             pt_y - self.min_dist,
                                             pt_x + self.min_dist,
                                             pt_y + self.min_dist)
            pts_near_it = pointPassage.getFeatures(
                QgsFeatureRequest().setFilterRect(bounding_box_buff))
            for pt_near in pts_near_it:
                pt_near_id = pt_near.id()
                if pt_near_id != pt_id:
                    dist = math.sqrt(
                        pt_geom.sqrDist(pt_near.geometry().asPoint()))
                    if dist != 0 and dist < self.min_dist:
                        pt_Tid = pt.attribute('T_id')
                        res = pt_Tid.split('p')
                        l_id1 = res[0]
                        pt_near_Tid = pt_near.attribute('T_id')
                        res = pt_near_Tid.split('p')
                        l_id2 = res[0]
                        if l_id1 == l_id2 and (
                            (pt_Tid[-1] == 's' and pt_near_Tid[-1] == 'e') or
                            (pt_Tid[-1] == 'e' and pt_near_Tid[-1] == 's')):
                            if pt_id not in ids_rem:
                                ids_rem.append(pt_id)
                            if pt_near_id not in ids_rem:
                                ids_rem.append(pt_near_id)
                            # if pt_Tid in orphans:
                            # orphans.remove(pt_Tid)
                            # if pt_near_Tid in orphans:
                            # orphans.remove(pt_near_Tid)
                            BB1 = pt.geometry().buffer(3, 4).boundingBox()
                            BB2 = pt_near.geometry().buffer(3, 4).boundingBox()
                            for feat1 in pointPassage.getFeatures(
                                    QgsFeatureRequest(
                                        QgsExpression(
                                            "nature='start' or nature='end'")).
                                    setFilterRect(BB1)):
                                tid1 = feat1.attribute("T_id")
                                if feat1.id(
                                ) not in ids_rem and tid1 not in orphans:
                                    orphans.append(tid1)
                            for feat2 in pointPassage.getFeatures(
                                    QgsFeatureRequest(
                                        QgsExpression(
                                            "nature='start' or nature='end'")).
                                    setFilterRect(BB2)):
                                tid2 = feat2.attribute("T_id")
                                if feat2.id(
                                ) not in ids_rem and tid2 not in orphans:
                                    orphans.append(tid2)

        pointPassage.startEditing()
        pointPassage.dataProvider().deleteFeatures(ids_rem)
        pointPassage.commitChanges()

        # Find link point between seperate line
        print 'R2P: Find link point between seperate line'
        already_done = []
        geom_to_change = []
        for pt in pointPassage.getFeatures():
            if pt.attribute('T_id') in orphans:
                pt_id = pt.id()
                pt_nat = pt.attribute('nature')
                if pt_nat == 'end':
                    pt_nat_opp = 'start'
                else:
                    pt_nat_opp = 'end'
                pt_opp_it = None
                pt_opp_it = pointPassage.getFeatures(
                    QgsFeatureRequest(
                        QgsExpression("L_id = '%s' and nature='%s'" %
                                      (pt.attribute('L_id'), pt_nat_opp))))
                pt_opp = next(pt_opp_it)
                pt_opp_geom = pt_opp.geometry().asPoint()
                pt_opp_buff = pt_opp.geometry().buffer(1, 4).boundingBox()
                pt_opp_near_it = pointPassage.getFeatures(
                    QgsFeatureRequest(
                        QgsExpression("L_id != '%s'" %
                                      (pt_opp.attribute('L_id')))))
                list_opp = [
                    pt_opp_near.attribute('T_id')
                    for pt_opp_near in pt_opp_near_it
                ]
                list_opp.append(pt_opp.attribute('T_id'))
                pt_geom = pt.geometry().asPoint()
                pt_x, pt_y = pt_geom
                bounding_box_buff = QgsRectangle(pt_x - self.min_dist * 2,
                                                 pt_y - self.min_dist * 2,
                                                 pt_x + self.min_dist * 2,
                                                 pt_y + self.min_dist * 2)
                pts_near_it = pointPassage.getFeatures(
                    QgsFeatureRequest().setFilterRect(bounding_box_buff))
                list_id = []
                w0 = 0
                id0 = pt_id
                act_dist = None
                list_line = []
                for pt_near in pts_near_it:
                    pt_near_id = pt_near.id()
                    pt_near_Tid = pt_near.attribute('T_id')
                    pt_near_geom = pt_near.geometry().asPoint()
                    if pt_near_id != pt_id and pt_near_Tid in orphans and pt_near_geom != pt_opp_geom:
                        dist = math.sqrt(pt_geom.sqrDist(pt_near_geom))
                        if dist != 0 and dist < self.min_dist * 2:
                            pt_Tid = pt.attribute('T_id')
                            res = pt_Tid.split('p')
                            l_id1 = res[0]
                            res = pt_near_Tid.split('p')
                            l_id2 = res[0]
                            if pt_id not in already_done and l_id1 != l_id2 and l_id2 not in list_line and pt_Tid[
                                    -1] in ['s', 'e'] and pt_near_Tid[-1] in [
                                        's', 'e'
                                    ]:
                                list_id.append(pt_near_id)
                                list_line.append(l_id2)
                                w0 += dist
                already_done.append(pt_id)
                for id in list_id:
                    point1 = next(
                        pointPassage.getFeatures(
                            QgsFeatureRequest().setFilterFid(id)))
                    point1_geom = point1.geometry().asPoint()
                    pt1_x, pt1_y = point1_geom
                    bounding_box_buff1 = QgsRectangle(pt_x - self.min_dist * 2,
                                                      pt_y - self.min_dist * 2,
                                                      pt_x + self.min_dist * 2,
                                                      pt_y + self.min_dist * 2)
                    pts1_near_it = pointPassage.getFeatures(
                        QgsFeatureRequest().setFilterRect(bounding_box_buff1))
                    w = 0
                    for opoint in pts1_near_it:
                        if id != opoint.id() and opoint.attribute(
                                'T_id') in orphans:
                            opoint_geom = opoint.geometry().asPoint()
                            p = math.sqrt(point1_geom.sqrDist(opoint_geom))
                            w += p
                    if w < w0:
                        w0 = w
                        id0 = opoint.id()
                    already_done.append(id)
                list_id.append(pt_id)
                try:
                    list_id.remove(id0)
                except ValueError:
                    continue
                change = [id0, list_id]
                geom_to_change.append(change)

        for change in geom_to_change:
            id_fix = change[0]
            req = QgsFeatureRequest().setFilterFid(id_fix)
            point_fix_it = pointPassage.getFeatures(req)
            try:
                for point_fix in point_fix_it:
                    geom_fix = point_fix.geometry()
                    # try:
                    # orphans.remove(point_fix.attribute("T_id"))
                    # except ValueError:
                    # continue
                ids_change = change[1]
                for id_change in ids_change:
                    req = QgsFeatureRequest().setFilterFid(id_change)
                    point_change_it = pointPassage.getFeatures(req)
                    point_change = next(point_change_it)
                    # try:
                    # orphans.remove(point_change.attribute("T_id"))
                    # except ValueError:
                    # continue
                    pointPassage.startEditing()
                    pointPassage.dataProvider().changeGeometryValues(
                        {id_change: geom_fix})
                    pointPassage.commitChanges()
                    pointPassage.updateExtents()
            except StopIteration:
                pass

        print 'R2P: Find link point between seperate line'
        already_done = []
        geom_to_change = []
        for pt in pointPassage.getFeatures():
            pt_id = pt.id()
            pt_geom = pt.geometry().asPoint()
            pt_x, pt_y = pt_geom
            bounding_box_buff = QgsRectangle(pt_x - self.min_dist,
                                             pt_y - self.min_dist,
                                             pt_x + self.min_dist,
                                             pt_y + self.min_dist)
            pts_near_it = pointPassage.getFeatures(
                QgsFeatureRequest().setFilterRect(bounding_box_buff))
            list_id = []
            w0 = 0
            id0 = pt_id
            for pt_near in pts_near_it:
                pt_near_id = pt_near.id()
                pt_near_Tid = pt_near.attribute('T_id')
                if pt_near_id != pt_id:
                    dist = math.sqrt(
                        pt_geom.sqrDist(pt_near.geometry().asPoint()))
                    if dist != 0 and dist < self.min_dist:
                        pt_Tid = pt.attribute('T_id')
                        res = pt_Tid.split('p')
                        l_id1 = res[0]
                        res = pt_near_Tid.split('p')
                        l_id2 = res[0]
                        if pt_id not in already_done and l_id1 != l_id2 and pt_Tid[
                                -1] in ['s', 'e'
                                        ] and pt_near_Tid[-1] in ['s', 'e']:
                            list_id.append(pt_near_id)
                            w0 += dist
            already_done.append(pt_id)
            for id in list_id:
                point1 = next(
                    pointPassage.getFeatures(
                        QgsFeatureRequest().setFilterFid(id)))
                point1_geom = point1.geometry().asPoint()
                pt1_x, pt1_y = point1_geom
                bounding_box_buff1 = QgsRectangle(pt_x - self.min_dist,
                                                  pt_y - self.min_dist,
                                                  pt_x + self.min_dist,
                                                  pt_y + self.min_dist)
                pts1_near_it = pointPassage.getFeatures(
                    QgsFeatureRequest().setFilterRect(bounding_box_buff1))
                w = 0
                for opoint in pts1_near_it:
                    if id != opoint.id():
                        opoint_geom = opoint.geometry().asPoint()
                        p = math.sqrt(point1_geom.sqrDist(opoint_geom))
                        w += p
                if w < w0:
                    w0 = w
                    id0 = opoint.id()
                already_done.append(id)
            list_id.append(pt_id)
            try:
                list_id.remove(id0)
            except ValueError:
                continue
            change = [id0, list_id]
            geom_to_change.append(change)

        for change in geom_to_change:
            id_fix = change[0]
            req = QgsFeatureRequest().setFilterFid(id_fix)
            point_fix_it = pointPassage.getFeatures(req)
            try:
                for point_fix in point_fix_it:
                    geom_fix = point_fix.geometry()
                ids_change = change[1]
                for id_change in ids_change:
                    pointPassage.startEditing()
                    pointPassage.dataProvider().changeGeometryValues(
                        {id_change: geom_fix})
                    pointPassage.commitChanges()
                    pointPassage.updateExtents()
            except StopIteration:
                pass

        # Remove small ridge part at the end/start of a line
        print 'R2P: Remove small ridge part at the end/start of a line'
        geom_to_change = []
        list_id = []
        for pt in pointPassage.getFeatures():
            pt_id = pt.id()
            pt_geom = pt.geometry().asPoint()
            pt_x, pt_y = pt_geom
            bounding_box_buff = QgsRectangle(pt_x - self.min_dist,
                                             pt_y - self.min_dist,
                                             pt_x + self.min_dist,
                                             pt_y + self.min_dist)
            pts_near_it = pointPassage.getFeatures(
                QgsFeatureRequest().setFilterRect(bounding_box_buff))
            for pt_near in pts_near_it:
                pt_near_id = pt_near.id()
                if pt_near_id != pt_id:
                    dist = math.sqrt(
                        pt_geom.sqrDist(pt_near.geometry().asPoint()))
                    if dist != 0 and dist < self.min_dist:
                        pt_Tid = pt.attribute('T_id')
                        res = pt_Tid.split('p')
                        l_id1 = res[0]
                        pt_near_Tid = pt_near.attribute('T_id')
                        res = pt_near_Tid.split('p')
                        l_id2 = res[0]
                        if l_id1 == l_id2 and pt_Tid[-1] in [
                                's', 'e'
                        ] and pt_near_Tid[-1] not in [
                                's', 'e'
                        ] and pt_near_Tid not in list_id:
                            change = [pt_id, pt_near_id]
                            list_id.append(pt_near_Tid)
                            geom_to_change.append(change)
        id_rm = []
        print 'R2P: geom_to_change: %s' % geom_to_change

        for change in geom_to_change:
            id_fix = change[0]
            req = QgsFeatureRequest().setFilterFid(id_fix)
            point_fix_it = pointPassage.getFeatures(req)
            point_fix = next(point_fix_it)
            try:
                id_change = change[1]
                req = QgsFeatureRequest().setFilterFid(id_change)
                point_ch_it = pointPassage.getFeatures(req)
                for point_ch in point_ch_it:
                    if point_fix.attribute('T_id')[-1] == 'e':
                        if int(point_ch.attribute('P_id')) < int(
                                point_fix.attribute('P_id')):
                            pointPassage.startEditing()
                            pointPassage.changeAttributeValue(
                                id_fix, 2, point_ch.attribute('P_id'))
                            pointPassage.commitChanges()
                    else:
                        pointPassage.startEditing()
                        pointPassage.changeAttributeValue(
                            id_fix, 2, point_ch.attribute('P_id'))
                        pointPassage.commitChanges()
                id_rm.append(id_change)
            except StopIteration:
                pass
        pointPassage.startEditing()
        pointPassage.deleteFeatures(id_rm)
        pointPassage.commitChanges()
        pointPassage.updateExtents()

        # First attempt
        print 'R2P: First attempt'
        already_done = []
        geom_to_change = []
        for pt in pointPassage.getFeatures():
            pt_id = pt.id()
            pt_geom = pt.geometry().asPoint()
            pt_x, pt_y = pt_geom
            bounding_box_buff = QgsRectangle(pt_x - self.min_dist,
                                             pt_y - self.min_dist,
                                             pt_x + self.min_dist,
                                             pt_y + self.min_dist)
            pts_near_it = pointPassage.getFeatures(
                QgsFeatureRequest().setFilterRect(bounding_box_buff))
            list_id = []
            w0 = 0
            id0 = pt_id
            for pt_near in pts_near_it:
                pt_near_id = pt_near.id()
                if pt_near_id != pt_id:
                    dist = math.sqrt(
                        pt_geom.sqrDist(pt_near.geometry().asPoint()))
                    if dist != 0 and dist < self.min_dist:
                        pt_Tid = pt.attribute('T_id')
                        res = pt_Tid.split('p')
                        l_id1 = res[0]
                        pt_near_Tid = pt_near.attribute('T_id')
                        res = pt_near_Tid.split('p')
                        l_id2 = res[0]
                        if pt_id not in already_done and pt_near_id not in already_done and l_id1 == l_id2:
                            pt1_elev = self.dem_layer.dataProvider().identify(
                                pt_geom, QgsRaster.IdentifyFormatValue)
                            pt2_elev = self.dem_layer.dataProvider().identify(
                                pt_near.geometry().asPoint(),
                                QgsRaster.IdentifyFormatValue)
                            already_done.append(pt_id)
                            already_done.append(pt_near_id)
                            if pt.attribute(
                                    'T_id')[-1] == 'd' and pt_near.attribute(
                                        'T_id') == 'd':
                                if pt1_elev > pt2_elev:
                                    change = pt_Tid
                                else:
                                    change = pt_near_Tid
                            else:
                                if pt1_elev < pt2_elev:
                                    change = pt_Tid
                                else:
                                    change = pt_near_Tid
                            geom_to_change.append(change)

        print 'R2P: geom_to_change: %s' % geom_to_change
        for change in geom_to_change:
            print 'R2P: change: %s' % change
            id_fix = change
            req = QgsFeatureRequest().setFilterExpression("T_id = '%s'" %
                                                          (id_fix))
            point_rm_it = pointPassage.getFeatures(req)
            point_rm = point_rm_it.next()
            id_rm = point_rm.id()
            line_id = point_rm.attribute('L_id')
            point_pid = int(point_rm.attribute('P_id'))
            nat = point_rm.attribute('nature')
            fin = 0
            count = 1
            found = False
            if nat == 'end':
                fin = 1
            else:
                pointPassage.startEditing()
                while True:
                    if found:
                        point_pid += 1
                    req = QgsFeatureRequest().setFilterExpression(
                        "L_id ='%s' and P_id = '%s'" %
                        (line_id, str(point_pid + count)))
                    point_nxt_it = pointPassage.getFeatures(req)
                    found = False
                    point_nxt = None
                    try:
                        point_nxt = next(point_nxt_it)
                    except StopIteration:
                        point_nxt = None
                        continue
                    if point_nxt != None:
                        pointPassage.changeAttributeValue(
                            point_nxt.id(), 2, str(point_pid))
                        current_id = point_nxt.attribute('T_id')
                        if current_id[-1] == 'e':
                            break
                        print 'R2P: current_id: %s' % current_id
                        found = True
                        count = 1
                    else:
                        count += 1
                        found = False
                pointPassage.deleteFeatures([id_rm])
                pointPassage.commitChanges()
        pointPassage.updateExtents()

        time.stop()
        print 'R2P: Processing Time:'
        time.show()
        error = QgsVectorFileWriter.writeAsVectorFormat(
            pointPassage, self.output_path, "utf-8", crs, "ESRI Shapefile")
        if error == QgsVectorFileWriter.NoError:
            print "R2P: Success!"
        out_layer = self.iface.addVectorLayer(self.output_path, "", "ogr")
        if not out_layer:
            print "R2P: Layer failed to load!"
Ejemplo n.º 14
0
    def testPktCompositeFloat(self):
        """
        Check that tables with PKs composed of many fields of different types are correctly read and written to
        """
        vl = QgsVectorLayer(
            '{} type=POINT key=\'"pk1","pk2","pk3"\' table="qgis_test"."tb_test_composite_float_pk" (geom)'
            .format(self.dbconn), "test_composite_float", "mssql")
        self.assertTrue(vl.isValid())

        fields = vl.fields()

        f = next(
            vl.getFeatures(
                QgsFeatureRequest().setFilterExpression('pk3 = 3.14159274')))
        # first of all: we must be able to fetch a valid feature
        self.assertTrue(f.isValid())
        self.assertEqual(f['pk1'], 1)
        self.assertEqual(f['pk2'], 2)

        self.assertEqual(round(f['pk3'], 6), round(3.14159274, 6))
        self.assertEqual(f['value'], 'test 2')

        # can we edit a field?
        vl.startEditing()
        vl.changeAttributeValue(f.id(), fields.indexOf('value'),
                                'Edited Test 2')
        self.assertTrue(vl.commitChanges())

        # Did we get it right? Let's create a new QgsVectorLayer and try to read back our changes:
        vl2 = QgsVectorLayer(
            '{} sslmode=disable srid=4326 key=\'"pk1","pk2","pk3"\' table="qgis_test"."tb_test_composite_float_pk" (geom)'
            .format(self.dbconn), "test_composite_float2", "mssql")
        self.assertTrue(vl2.isValid())
        f2 = next(
            vl.getFeatures(
                QgsFeatureRequest().setFilterExpression('pk3 = 3.14159274')))
        self.assertTrue(f2.isValid())

        # just making sure we have the correct feature
        # Only 6 decimals for PostgreSQL 11.
        self.assertEqual(round(f2['pk3'], 6), round(3.14159274, 6))

        # Then, making sure we really did change our value.
        self.assertEqual(f2['value'], 'Edited Test 2')

        # How about inserting a new field?
        f3 = QgsFeature(vl2.fields())
        f3['pk1'] = 4
        f3['pk2'] = -9223372036854775800
        f3['pk3'] = 7.29154
        f3['value'] = 'other test'
        vl.startEditing()
        res, f3 = vl.dataProvider().addFeatures([f3])
        self.assertTrue(res)
        self.assertTrue(vl.commitChanges())

        # can we catch it on another layer?
        f4 = next(
            vl2.getFeatures(QgsFeatureRequest().setFilterExpression(
                'pk2 = -9223372036854775800')))

        self.assertTrue(f4.isValid())
        expected_attrs = [4, -9223372036854775800, 7.29154, 'other test']
        gotten_attrs = [f4['pk1'], f4['pk2'], round(f4['pk3'], 5), f4['value']]
        self.assertEqual(gotten_attrs, expected_attrs)

        # Finally, let's delete one of the features.
        f5 = next(
            vl2.getFeatures(
                QgsFeatureRequest().setFilterExpression('pk3 = 7.29154')))
        vl2.startEditing()
        vl2.deleteFeatures([f5.id()])
        self.assertTrue(vl2.commitChanges())

        # did we really delete?
        f_iterator = vl.getFeatures(
            QgsFeatureRequest().setFilterExpression('pk3 = 7.29154'))
        got_feature = True

        try:
            f6 = next(f_iterator)
            got_feature = f6.isValid()
        except StopIteration:
            got_feature = False

        self.assertFalse(got_feature)
Ejemplo n.º 15
0
class ReorderProcess():
    """Along line point reordering

    according to given destination"""
    def __init__(self, exutoire, point_reseau):
        """Set all informations needed to order the network"""

        self.exutoire_layer = exutoire
        self.point_reseau_layer = point_reseau
        self.crs = QgsCoordinateReferenceSystem(
            self.point_reseau_layer.crs().authid())

        # Create ouput
        self.output = QgsVectorLayer("Point", "point", "memory")
        self.output.setCrs(self.crs)

        # Add fields
        name_T_id = "T_id"
        name_L_id = "L_id"
        name_P_id = "P_id"
        name_nat = "nature"
        provider = self.output.dataProvider()
        caps = provider.capabilities()
        if caps & QgsVectorDataProvider.AddAttributes:
            res = provider.addAttributes([
                QgsField(name_T_id, QVariant.String),
                QgsField(name_L_id, QVariant.String),
                QgsField(name_P_id, QVariant.String),
                QgsField(name_nat, QVariant.String)
            ])
            self.output.updateFields()
        # Save field index
        self.index_nat = self.point_reseau_layer.fieldNameIndex('nature')
        self.index_pid = self.point_reseau_layer.fieldNameIndex('P_id')
        self.index_order = self.point_reseau_layer.fieldNameIndex('order')
        self.l_done = []

    def reorder(self, pt, count_order):

        feat = QgsFeature(self.output.pendingFields())
        pt_geom = pt.geometry()
        feat.setGeometry(pt_geom)

        tid = pt.attribute("T_id")
        lid = pt.attribute("L_id")
        ppid = pt.attribute("P_id")
        nat = pt.attribute("nature")

        if nat == 'start':
            self.output.startEditing()
            feat.setAttributes([tid, str(count_order), ppid, nat])
            print 'reorder: %s' % ([tid, lid, ppid, nat, str(count_order)])
            self.output.dataProvider().addFeatures([feat])
            self.output.commitChanges()
            self.output.updateExtents()
            while nat != 'end':
                expr = QgsExpression('L_id = %s and P_id = %s' %
                                     (lid, str(int(ppid) + 1)))
                req = QgsFeatureRequest(expr)
                n_pt_it = self.point_reseau_layer.getFeatures(req)
                n_pt = n_pt_it.next()
                n_pt_it = None

                feat = QgsFeature(self.output.pendingFields())
                n_pt_geom = n_pt.geometry()
                feat.setGeometry(n_pt_geom)

                tid = n_pt.attribute("T_id")
                lid = n_pt.attribute("L_id")
                ppid = n_pt.attribute("P_id")
                nat = n_pt.attribute("nature")

                self.output.startEditing()
                feat.setAttributes([tid, str(count_order), ppid, nat])
                print[tid, lid, ppid, nat, str(count_order)]
                self.output.dataProvider().addFeatures([feat])
                self.output.commitChanges()
                self.output.updateExtents()
        else:
            pid = 0
            self.output.startEditing()
            feat.setAttributes([tid, str(count_order), str(pid), 'start'])
            print[tid, lid, str(pid), 'start', str(count_order)]
            self.output.dataProvider().addFeatures([feat])
            self.output.commitChanges()
            self.output.updateExtents()
            nat = None
            feat = None
            while nat != 'start':
                ppid = str(int(ppid) - 1)
                expr = QgsExpression('L_id = %s and P_id = %s' % (lid, ppid))
                req = QgsFeatureRequest(expr)
                n_pt_it = self.point_reseau_layer.getFeatures(req)
                n_pt = n_pt_it.next()
                n_pt_it = None

                feat = QgsFeature(self.output.pendingFields())
                n_pt_geom = n_pt.geometry()
                feat.setGeometry(n_pt_geom)

                tid = n_pt.attribute("T_id")
                nat = n_pt.attribute("nature")
                if nat != 'start':
                    pid += 1
                    self.output.startEditing()
                    feat.setAttributes([tid, str(count_order), str(pid), nat])
                    print[tid, lid, str(pid), nat, str(count_order)]
                    self.output.dataProvider().addFeatures([feat])
                    self.output.commitChanges()
                    self.output.updateExtents()
                    feat = None
                else:
                    pid += 1
                    self.output.startEditing()
                    feat.setAttributes(
                        [tid, str(count_order),
                         str(pid), 'end'])
                    print[tid, lid, str(pid), 'end', str(count_order)]
                    self.output.dataProvider().addFeatures([feat])
                    self.output.commitChanges()
                    self.output.updateExtents()
                    feat = None

    def executeReorder(self):

        count_order = 0
        # loop over exutoire features to process several network
        for exutoire in self.exutoire_layer.getFeatures():
            exutoire_geom = exutoire.geometry().buffer(1, 4).boundingBox()
            # Select the start point that intersects the outlet
            req = QgsFeatureRequest().setFilterRect(exutoire_geom)
            pts_reseau_sortie = self.point_reseau_layer.getFeatures(req)
            for pt_sortie in pts_reseau_sortie:
                count_order += 1
                L_id = pt_sortie.attribute("L_id")
                # Reorder the points of the first line of the network
                self.reorder(pt_sortie, count_order)
                nat = 'end'
                string = "L_id = %s AND nature = '%s'" % (count_order, nat)
                print string
                expr = QgsExpression(string)
                reque = QgsFeatureRequest(expr)
                # Select the last point of the first line
                pt_end_it = self.output.getFeatures(reque)
                pt_end = pt_end_it.next()
                pt_end_it = None
                # Make a buffer around the point to define a boundingBox
                pt_end_geom = pt_end.geometry().buffer(1, 4).boundingBox()
                req = QgsFeatureRequest(
                    QgsExpression("L_id != %s" %
                                  (str(L_id)))).setFilterRect(pt_end_geom)
                # Select the next points
                next_ls = self.point_reseau_layer.getFeatures(req)
                self.l_done.append(L_id)
                list_next = []
                # Fill next_ls list with the next features
                for next_l in next_ls:
                    list_next.append(next_l)
                # While there is features in list_next, reorder process continues
                while len(list_next) != 0:
                    current_list = list_next
                    list_next = []
                    # Loop over the next features
                    for next_pt in current_list:
                        # Get line id
                        L_id = next_pt.attribute("L_id")
                        print L_id
                        # if the line has not been already reorder
                        if L_id not in self.l_done:
                            count_order += 1
                            #then reorder
                            self.reorder(next_pt, count_order)
                            string = "L_id = %s AND nature='%s'" % (
                                count_order, nat)
                            print string
                            expr = QgsExpression(string)
                            req = QgsFeatureRequest(QgsExpression(expr))
                            pt_end_it = self.output.getFeatures(req)
                            pt_end = pt_end_it.next()
                            pt_end_it = None
                            pt_end_geom = pt_end.geometry().buffer(
                                1, 4).boundingBox()
                            # Find the next feature
                            reque = QgsFeatureRequest(
                                QgsExpression(
                                    "L_id != %s" %
                                    (L_id))).setFilterRect(pt_end_geom)
                            next_ls = self.point_reseau_layer.getFeatures(
                                reque)
                            self.l_done.append(L_id)
                            # Fill next_ls list again and loop
                            for next_l in next_ls:
                                list_next.append(next_l)
                    print len(list_next)

        expr = QgsExpression("nature = 'end'")
        req = QgsFeatureRequest(expr)
        end_pts = self.output.getFeatures(req)
        change_dict = {}
        change_list = []
        rm_ids = []
        #clean lines that aren't a cross border anymore because a small part has been removed
        for end_pt in end_pts:
            end_pt_geom = end_pt.geometry().buffer(1, 4).boundingBox()
            end_pt_id = end_pt.id()
            end_lid = end_pt.attribute("L_id")
            end_pid = end_pt.attribute("P_id")
            expr = QgsExpression("L_id != '%s'" % (end_lid))
            req = QgsFeatureRequest(expr).setFilterRect(end_pt_geom)
            int_pts = []
            for int_pt in self.output.getFeatures(req):
                lid_int_pt = int_pt.attribute("L_id")
                int_pts.append(int_pt)
            if len(int_pts) == 1:
                rm_ids.append(end_pt_id)
                if int(end_lid) in change_dict:
                    change_dict[int(lid_int_pt)] = change_dict[int(end_lid)]
                else:
                    change_dict[int(lid_int_pt)] = int(end_lid)
        print change_dict
        change_dict = sorted(change_dict.items(), key=lambda t: t[0])
        for ch_tuple in change_dict:
            print ch_tuple[0]
            end_lid = str(ch_tuple[1])
            end_pid = None
            for end_pt in self.output.getFeatures(
                    QgsFeatureRequest(
                        QgsExpression("L_id = '%s' and nature = '%s'" %
                                      (end_lid, "end")))):
                if end_pid is None:
                    end_pid = end_pt.attribute("P_id")
                elif int(end_pid) < int(end_pt.attribute("P_id")):
                    end_pid = end_pt.attribute("P_id")
            expr = QgsExpression("L_id = '%s'" % (str(ch_tuple[0])))
            req = QgsFeatureRequest(expr)
            for ch_pt in self.output.getFeatures(req):
                ch_pt_id = ch_pt.id()
                if ch_pt.attribute("nature") == "start":
                    rm_ids.append(ch_pt_id)
                else:
                    ch_tid = ch_pt.attribute("T_id")
                    ch_nature = ch_pt.attribute("nature")
                    self.output.startEditing()
                    self.output.changeAttributeValue(ch_pt_id, 1, end_lid)
                    self.output.changeAttributeValue(ch_pt_id, 2, end_pid)
                    self.output.commitChanges()
                    end_pid = int(end_pid) + 1
        self.output.startEditing()
        self.output.deleteFeatures(rm_ids)
        self.output.commitChanges()

        return self.output, self.crs
Ejemplo n.º 16
0
class StartNotSimple:

    def __init__(self, iface):
        
        self.iface = iface

        self.tableSchema = 'edgv'
        self.geometryColumn = 'geom'
        self.keyColumn = 'id'

    def initGui(self): 
        # cria uma ação que iniciará a configuração do plugin 
        pai = self.iface.mainWindow()
        icon_path = ':/plugins/StartNotSimple/icon.png'
        self.action = QAction (QIcon (icon_path),u"Acessa banco de dados para revisão de Geometria Simples", pai)
        self.action.setObjectName ("Stard database")
        self.action.setStatusTip(None)
        self.action.setWhatsThis(None)
        self.action.triggered.connect(self.run)
        # Adicionar o botão icone
        self.iface.addToolBarIcon (self.action) 
        #Cria uma nova toolbar
        #self.toolbar = self.iface.addToolBar(u'Validation Tool')
        #self.toolbar.addAction(self.action)
    def unload(self):
        # remove o item de ícone do QGIS GUI.
        self.iface.removeToolBarIcon (self.action)
        
        
    def run(self):

    ##################################
    ###### PEGA A LAYER ATIVA ########
    ##################################

        layer = self.iface.activeLayer() 

        if not layer:
            self.iface.messageBar().pushMessage("Erro", u"Esperando uma Active Layer!", level=QgsMessageBar.CRITICAL, duration=4)
            return
        if layer.featureCount() == 0:
            self.iface.messageBar().pushMessage("Erro", u"a camada não possui feições!", level=QgsMessageBar.CRITICAL, duration=4)
            return

        parametros = layer.source().split(" ") # recebe todos os parametros em uma lista ( senha, porta, password etc..)

    ####################################
    ###### INICIANDO CONEXÃO DB ########
    ####################################

        # Outra opção para isso, seria usar ex: self.dbname.. self.host.. etc.. direto dentro do laço for.
        dbname = "" 
        host = ""
        port = 0
        user = ""
        password = ""

        for i in parametros:
            part = i.split("=")
            
        # Recebe os parametros guardados na própria Layer

            if "dbname" in part[0]:
                dbname = part[1].replace("'", "")

            elif "host" in part[0]:
                host = part[1].replace("'", "")

            elif "port" in part[0]:
                port = int(part[1].replace("'", ""))

            elif "user" in part[0]:
                user = part[1].replace("'", "")

            elif "password" in part[0]:
                password = part[1].split("|")[0].replace("'", "")

        print dbname, host, port, user, password

        # Testa se os parametros receberam os valores pretendidos, caso não, apresenta a mensagem informando..
        if len(dbname) == 0 or len(host) == 0 or port == 0 or len(user) == 0 or len(password) == 0:
            self.iface.messageBar().pushMessage("Erro", u'Um dos parametros não foram devidamente recebidos!', level=QgsMessageBar.CRITICAL, duration=4)
            return

    ####################################
    #### SETA VALORES DE CONEXÃO DB ####
    ####################################

        connection = QSqlDatabase.addDatabase('QPSQL')
        connection.setHostName(host)
        connection.setPort(port)
        connection.setUserName(user)
        connection.setPassword(password)
        connection.setDatabaseName(dbname)

        if not connection.isOpen(): # Testa se a conexão esta recebendo os parametros adequadamente.
            if not connection.open():
                print 'Error connecting to database!'
                self.iface.messageBar().pushMessage("Erro", u'Error connecting to database!', level=QgsMessageBar.CRITICAL, duration=4)
                print connection.lastError().text()
                return

    ####################################
    ###### CRIAÇÃO DE MEMORY LAYER #####
    ####################################
        

        layerCrs = layer.crs().authid() # Passa o formato (epsg: numeros)

        flagsLayerName = layer.name() + "_flags"
        flagsLayerExists = False

        for l in QgsMapLayerRegistry.instance().mapLayers().values(): # Recebe todas as camadas que estão abertas
            if l.name() == flagsLayerName: # ao encontrar o nome pretendido..
                self.flagsLayer = l # flagslayer vai receber o nome..
                self.flagsLayerProvider = l.dataProvider()
                flagsLayerExists = True # se encontrado os parametros buscados, recebe True.
                break
        
        if flagsLayerExists == False: # se não encontrado os parametros buscados, recebe False.
            tempString = "Point?crs="
            tempString += str(layerCrs)

            self.flagsLayer = QgsVectorLayer(tempString, flagsLayerName, "memory")
            self.flagsLayerProvider = self.flagsLayer.dataProvider()
            self.flagsLayerProvider.addAttributes([QgsField("id", QVariant.Int), QgsField("geomId", QVariant.String), QgsField("motivo", QVariant.String)])
            self.flagsLayer.updateFields()

        self.flagsLayer.startEditing()
        ids = [feat.id() for feat in self.flagsLayer.getFeatures()]
        self.flagsLayer.deleteFeatures(ids)
        self.flagsLayer.commitChanges()
        
        lista_fid = [] # Iniciando lista
        for f in layer.getFeatures():
            lista_fid.append(str(f.id())) # Guarda na lista. A lista de Feature ids passa tipo "int", foi convertido e guardado como "str".

        source = layer.source().split(" ")
        self.tableName = " " # Inicia vazio
        layerExistsInDB = False
        
        for i in source:
                
            if "table=" in i or "layername=" in i: # Se encontrar os atributos pretendidos dentre todos do for
                self.tableName = source[source.index(i)].split(".")[1] # Faz split em ponto e pega a segunda parte.
                self.tableName = self.tableName.replace('"', '')
                layerExistsInDB = True
                break
             
        if layerExistsInDB == False:
            self.iface.messageBar().pushMessage("Erro", u"Provedor da camada corrente não provem do banco de dados!", level=QgsMessageBar.CRITICAL, duration=4)
            return

        ##############################
        #### Busca através do SQL ####
        ##############################


        sql = """select foo."{3}" as "{3}", ST_AsText(ST_MULTI(st_startpoint(foo."{2}"))) as "{2}" from (
        select "{3}" as "{3}", (ST_Dump(ST_Node(ST_SetSRID(ST_MakeValid("{2}"),ST_SRID("{2}"))))).geom as "{2}" from "{0}"."{1}"  
        where ST_IsSimple("{2}") = 'f' and {3} in ({4})) as foo where st_equals(st_startpoint(foo."{2}"),st_endpoint(foo."{2}"))""".format(self.tableSchema, self.tableName, self.geometryColumn, self.keyColumn, ",".join(lista_fid))
            
        query = QSqlQuery(sql)

        self.flagsLayer.startEditing()
        flagCount = 0 # iniciando contador que será referência para os IDs da camada de memória.

        listaFeatures = []
        while query.next():

            
            id = query.value(0) # recebendo valores buscados no sql
            local = query.value(1) # recebendo valores buscados no sql
            motivo = query.value(2)
            print local, id, motivo
           
            flagId = flagCount

            flagFeat = QgsFeature()
	    flagFeat.setFields(self.flagsLayer.fields()) # passa quais atributos serão usados.
            flagGeom = QgsGeometry.fromWkt(local) # passa o local onde foi localizado o erro.
            flagFeat.setGeometry(flagGeom)
            flagFeat.setAttribute(0, flagId) # insere o id definido para a coluna 0 da layer de memória.
            flagFeat.setAttribute(1, id) # insere o id da geometria para a coluna 1 da layer de memória.
            flagFeat.setAttribute(2,  u"A geometria não é simples.")
            listaFeatures.append(flagFeat)    

            flagCount += 1 # incrementando o contador a cada iteração

        self.flagsLayerProvider.addFeatures(listaFeatures)
        self.flagsLayer.commitChanges() # Aplica as alterações à camada.
        
        QgsMapLayerRegistry.instance().addMapLayer(self.flagsLayer) # Adicione a camada no mapa
       
        if flagCount == 0: 
            
            QgsMapLayerRegistry.instance().removeMapLayer(self.flagsLayer.id())
            self.iface.messageBar().pushMessage("Aviso", u"Não foi encontrado Flags em \"" + layer.name() + "\" !", level=QgsMessageBar.CRITICAL, duration=4)

            return
        if len(query.lastError().text()) == 1:
            self.iface.messageBar().pushMessage("Aviso", "foram geradas " + str(flagCount) + " flags para a camada \"" + layer.name() + "\" !", level=QgsMessageBar.INFO, duration=4)
        else:
            self.iface.messageBar().pushMessage("Erro", u"a geração de flags falhou!", level=QgsMessageBar.CRITICAL, duration=4)
            print query.lastError().text()
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        source_distance = self.parameterAsDouble(parameters,
                                                 self.INPUT_DISTANCE, context)
        source_dem = self.parameterAsRasterLayer(parameters, self.INPUT_DEM,
                                                 context)
        source_points = self.parameterAsVectorLayer(parameters,
                                                    self.INPUT_POINTS, context)
        source_field = self.parameterAsFields(parameters, self.INPUT_FIELD,
                                              context)
        output_summit = self.parameterAsOutputLayer(parameters,
                                                    self.OUTPUT_SUMMIT,
                                                    context)
        output_folder = self.parameterAsString(parameters, self.OUTPUT_FOLDER,
                                               context)

        results = {}
        outputs = {}
        #feedback = QgsProcessingMultiStepFeedback(3, feedback)
        feedback.pushInfo('Hello World')
        if not os.path.exists(
                output_folder):  #If the folder indicated is not existing
            os.makedirs(output_folder)  #Creating the folder
        url_buffer_1 = output_folder + '/buffer.shp'
        url_buffer_2 = output_folder + '/buffer_overlaping.shp'
        url_buffer_3 = output_folder + '/buffer_overlaping_summit.shp'
        url_buffer_4 = output_folder + '/buffer_AUTO.shp'
        url_buffer_5 = output_folder + '/points_incremented.shp'
        url_buffer_6 = output_folder + '/summit_process_all.gpkg'
        liste_url = [
            url_buffer_1, url_buffer_2, url_buffer_3, url_buffer_4,
            url_buffer_5, url_buffer_6
        ]
        for url_buffer in liste_url:
            if os.path.isfile(url_buffer):  #If one of these url already exist
                os.remove(url_buffer)  #Removing the file at this url
                feedback.pushInfo("Removing: " + url_buffer)

        if source_field == []:
            feedback.pushInfo(
                "Adding auto-incremental field to the point layer")
            # Add autoincremental field
            alg_params = {
                'FIELD_NAME': 'ID_Point',
                'GROUP_FIELDS': None,
                'INPUT': source_points,
                'SORT_ASCENDING': True,
                'SORT_EXPRESSION': '',
                'SORT_NULLS_FIRST': False,
                'START': 0,
                'OUTPUT': url_buffer_5
            }
            outputs['AddAutoincrementalField_start'] = processing.run(
                'native:addautoincrementalfield',
                alg_params,
                context=context,
                feedback=feedback)
            source_field = ['ID_Point']
            source_points = outputs['AddAutoincrementalField_start']['OUTPUT']

        # Buffer
        #Buffer polygons have the same attributes as the points
        alg_params = {
            'DISSOLVE': False,
            'DISTANCE': source_distance,
            'END_CAP_STYLE': 0,
            'INPUT': source_points,
            'JOIN_STYLE': 0,
            'MITER_LIMIT': 2,
            'SEGMENTS': 5,
            'OUTPUT': url_buffer_1
        }
        outputs['Buffer'] = processing.run('native:buffer',
                                           alg_params,
                                           context=context,
                                           feedback=feedback)

        # Summit process
        alg_params = {
            'INPUT_AREA': outputs['Buffer']['OUTPUT'],
            'INPUT_DEM': source_dem,
            'INPUT_FIELD': source_field[0],
            'OUTPUT_SUMMIT': url_buffer_6,
            'OUTPUT_FOLDER': output_folder + '/Summit_computing_all'
        }
        outputs['SummitProcess'] = processing.run('script:summitprocess_2',
                                                  alg_params,
                                                  context=context,
                                                  feedback=feedback)

        # Extract by location: buffers overlaping between themselves
        alg_params = {
            'INPUT': outputs['Buffer']['OUTPUT'],
            'INTERSECT': outputs['Buffer']['OUTPUT'],
            'PREDICATE': 5,
            'OUTPUT': url_buffer_2
        }
        outputs['ExtractByLocation_1'] = processing.run(
            'native:extractbylocation',
            alg_params,
            context=context,
            feedback=feedback)

        if feedback.isCanceled():
            return None

        # Extract by location: summits which are in a buffer intersecting another buffer polygon
        alg_params = {
            'INPUT': outputs['SummitProcess']['OUTPUT_SUMMIT'],
            'INTERSECT': outputs['ExtractByLocation_1']['OUTPUT'],
            'PREDICATE': 0,
            'OUTPUT': url_buffer_3
        }
        outputs['ExtractByLocation_2'] = processing.run(
            'native:extractbylocation',
            alg_params,
            context=context,
            feedback=feedback)

        if feedback.isCanceled():
            return None

        ###Deletion from the overall summit layer, of summits which are in a buffer intersecting another buffer polygon
        layer_all_summit = QgsVectorLayer(
            outputs['SummitProcess']['OUTPUT_SUMMIT'], "layer_all_summit",
            "ogr"
        )  #Create as a vector layer, a layer gathering all the summits
        layer_1 = QgsVectorLayer(
            outputs['ExtractByLocation_2']['OUTPUT'], "layer_1", "ogr"
        )  #Create as a vector layer, a layer of the summits which may intersect multiples buffers
        features_all_summit = layer_all_summit.getFeatures(
        )  #Getting the features
        features_1 = layer_1.getFeatures()  #Getting the features
        liste_suppress = [
        ]  #Initializing a list which will keep in memory the summits whiwh will be deleted
        fid_max = layer_all_summit.featureCount(
        )  #Get the number of summit. This value will be used to set the next summits id
        for index_all_summit, summit_all in enumerate(
                features_all_summit):  #Iterating over all summits
            layer_summit_buffer_chevauche = QgsVectorLayer(
                outputs['ExtractByLocation_2']['OUTPUT'],
                "layer_summit_buffer_chevauche",
                "ogr")  #Create as a vector layer, a layer
            features_summit_buffer_chevauche = layer_summit_buffer_chevauche.getFeatures(
            )  #Getting the features
            for index_summit_buffer_chevauche, summit_buffer_chevauche in enumerate(
                    features_summit_buffer_chevauche
            ):  #Iterating over summits which are in a contentious buffer
                if summit_all.attributes(
                ) == summit_buffer_chevauche.attributes(
                ):  #if the contentious summit is in the overall summit layer
                    liste_suppress.append(
                        summit_all.id())  #Add the summit to the suppress list
        feedback.pushInfo(
            "Deletion of summits which intersect at least two buffers")
        layer_all_summit.startEditing()  #Enabling edition
        layer_all_summit.deleteFeatures(
            liste_suppress
        )  #Deleting contentious summits of the overall summit layer
        layer_all_summit.commitChanges()  #Commiting the changes
        feedback.pushInfo(str(layer_all_summit.commitErrors(
        )))  #Displaying a message about the state of the commit

        total = 100 / layer_1.featureCount()  #Initializing the progress bar
        for index_1, summit_1 in enumerate(
                features_1):  #Iterating over contentious summits
            feedback.setProgress(int(index_1 *
                                     total))  #Update the progress bar
            layer_2 = QgsVectorLayer(
                outputs['ExtractByLocation_2']['OUTPUT'], "layer_2",
                "ogr")  #Create as a vector layer, the contentious summits
            features_2 = layer_2.getFeatures()  #Getting features
            for index_2, summit_2 in enumerate(
                    features_2
            ):  #Iterating over contentious summits. These two loops allows to compare summits in the same layer
                summit_1_geometry = summit_1.geometry().asPoint(
                )  #Getting the geometry of the summit number 1
                summit_2_geometry = summit_2.geometry().asPoint(
                )  #Getting the geometry of the summit number 2
                if summit_1_geometry.toString() == summit_2_geometry.toString(
                ):  #If they have the same geometry (may be optimised by using the function equals())
                    ID_point_summit_1 = summit_1.attribute(
                        source_field[0]
                    )  #Getting the ID of the buffer polygon of the summit number 1
                    ID_point_summit_2 = summit_2.attribute(
                        source_field[0]
                    )  #Getting the ID of the buffer polygon of the summit number 2
                    if ID_point_summit_1 != ID_point_summit_2:  #If the two points don't come from the same buffer polygon
                        features_source_points = source_points.getFeatures()
                        for indx, points_source in enumerate(
                                features_source_points
                        ):  #Searching in the point layer given by the user, the two current points
                            if points_source.attribute(
                                    source_field[0]) == ID_point_summit_1:
                                point_summit_1 = points_source  #Getting the point which was be used to create the buffer polygon of the summit number 1
                            if points_source.attribute(
                                    source_field[0]) == ID_point_summit_2:
                                point_summit_2 = points_source  #Getting the point which was be used to create the buffer polygon of the summit number 2

                        #Calculating the minimal distance between the two original points and the summit
                        distance_min = m.sqrt(
                            m.pow(
                                point_summit_1.geometry().asPoint().x() -
                                summit_1_geometry.x(), 2) + m.pow(
                                    point_summit_1.geometry().asPoint().y() -
                                    summit_1_geometry.y(), 2))
                        distance = m.sqrt(
                            m.pow(
                                point_summit_2.geometry().asPoint().x() -
                                summit_1_geometry.x(), 2) + m.pow(
                                    point_summit_2.geometry().asPoint().y() -
                                    summit_1_geometry.y(), 2))
                        if distance < distance_min:
                            distance_min = distance

                        layer_2_copy = QgsVectorLayer(
                            outputs['ExtractByLocation_2']['OUTPUT'],
                            "layer_2", "ogr"
                        )  #Create as a layer, the contentious summits in order to update the ID
                        features_2_copy = layer_2_copy.getFeatures(
                        )  #Getting features
                        for index_2_copy, summit_2_copy in enumerate(
                                features_2_copy
                        ):  #Iterating over the contentious summits
                            if str(summit_2_copy.attributes()) == str(
                                    summit_1.attributes()
                            ):  #Retrieving the summit number 1 in this layer in order to have the right ID
                                summit_1_in_layer_2 = summit_2_copy
                        feedback.pushInfo("Minimal distance: " +
                                          str(distance_min))
                        feedback.pushInfo("Deleting: " + str(
                            layer_2.getFeature(
                                summit_2.id()).attributes()) + " and " + str(
                                    layer_2.getFeature(summit_1_in_layer_2.id(
                                    )).attributes()))
                        layer_2.startEditing()  #Enabling edition mode
                        layer_2.deleteFeatures(
                            [summit_2.id(),
                             summit_1_in_layer_2.id()]
                        )  #Deleting the two summits which have the same geometry
                        layer_2.commitChanges()  #Commiting changes
                        feedback.pushInfo(str(layer_2.commitErrors(
                        )))  #Displaying a message about the commit state

                        #Creating a temporary layer
                        liste_fields = [
                        ]  #Initializing a field list in order to create the summit fields list
                        for i in range(
                                summit_1.fields().size()):  #For each fields
                            field_i = summit_1.fields().field(i)
                            liste_fields.append([
                                field_i.name(),
                                field_i.typeName()
                            ])  #[Name of the field, Type of the field]
                        new_layer = _create_layer(
                            "Point", "32616", liste_fields,
                            "layer_2_points")  #Create a new point layer
                        new_layer.startEditing()  #Enabling edition mode
                        point_summit_1.setAttributes(
                            [1] + point_summit_1.attributes()
                        )  #Setting the attributes in order to match to a new field "fid" added when the temporary layer was created
                        point_summit_2.setAttributes(
                            [2] + point_summit_2.attributes()
                        )  #Setting the attributes in order to match to a new field "fid" added when the temporary layer was created
                        new_layer.dataProvider().addFeatures(
                            [point_summit_1, point_summit_2]
                        )  #Adding the two summits which have the same geometry
                        new_layer.commitChanges()  #Commiting changes

                        #Setting a new folder to save intermediate files for each time when two summits have the same geometry
                        new_folder_string = output_folder + '/Summit_computing_buffer_' + str(
                            ID_point_summit_1) + "_" + str(ID_point_summit_2)
                        if not os.path.exists(
                                new_folder_string
                        ):  #If the folder indicated is not existing
                            os.makedirs(
                                new_folder_string)  #Creating the folder
                        url_buffer_7 = new_folder_string + '/buffer_2_points.shp'
                        url_buffer_8 = new_folder_string + '/buffer_2_points_without_fid.shp'
                        liste_url = [url_buffer_7, url_buffer_8]
                        for url_buffer in liste_url:
                            if os.path.isfile(
                                    url_buffer
                            ):  #If one of these url already exist
                                os.remove(
                                    url_buffer)  #Removing the file at this url

                        #Creating new buffer around the two original points which have their summits identical, but this time with a smaller distance
                        # Buffer
                        alg_params = {
                            'DISSOLVE': False,
                            'DISTANCE': distance_min,
                            'END_CAP_STYLE': 0,
                            'INPUT': new_layer,
                            'JOIN_STYLE': 0,
                            'MITER_LIMIT': 2,
                            'SEGMENTS': 5,
                            'OUTPUT':
                            new_folder_string + '/buffer_2_points.shp'
                        }
                        outputs['Buffer_2_points'] = processing.run(
                            'native:buffer',
                            alg_params,
                            context=context,
                            feedback=feedback)

                        #The "fid" field must be removed
                        # Drop field(s)
                        alg_params = {
                            'COLUMN':
                            "fid",
                            'INPUT':
                            outputs['Buffer_2_points']['OUTPUT'],
                            'OUTPUT':
                            new_folder_string +
                            '/buffer_2_points_without_fid.shp'
                        }
                        outputs['DropFields'] = processing.run(
                            'qgis:deletecolumn',
                            alg_params,
                            context=context,
                            feedback=feedback,
                            is_child_algorithm=True)

                        if feedback.isCanceled():
                            return None

                        #Calculating summits in this new area
                        # Summit process
                        alg_params = {
                            'INPUT_AREA': outputs['DropFields']['OUTPUT'],
                            'INPUT_DEM': source_dem,
                            'INPUT_FIELD': source_field[0],
                            'OUTPUT_SUMMIT':
                            new_folder_string + '/layer_2_points.gpkg',
                            'OUTPUT_FOLDER': new_folder_string
                        }
                        outputs['SummitProcess_2_points'] = processing.run(
                            'script:summitprocess_2',
                            alg_params,
                            context=context,
                            feedback=feedback)

                        if feedback.isCanceled():
                            return None

                        layer_2_points = QgsVectorLayer(
                            outputs['SummitProcess_2_points']['OUTPUT_SUMMIT'],
                            "layer_2_points", "ogr"
                        )  #Create as a vector layer, the new summits which they were identical
                        features_2_points = layer_2_points.getFeatures(
                        )  #Getting features
                        for indx, new_summit in enumerate(
                                features_2_points):  #For each new summit
                            layer_1.startEditing()  #Enabling edition mode
                            layer_1.dataProvider().addFeatures(
                                [new_summit]
                            )  #Add the new summit to the contentious summit layer
                            layer_1.commitChanges()  #Commiting changes

        layer_output_summit = QgsVectorLayer(
            url_buffer_6, "layer_output_summit",
            "ogr")  #Create as a vector layer, the output layer
        features_2 = layer_2.getFeatures(
        )  #Getting former contentious summits features
        for indx, summit_2 in enumerate(
                features_2):  #For each former contentious summits
            layer_output_summit.startEditing()  #Enabling edition mode
            summit_2.setAttributes(
                [fid_max + indx] + summit_2.attributes()[1:]
            )  #Setting the attributes in order to give a fid value than isn't already exist
            layer_output_summit.dataProvider().addFeatures([
                summit_2
            ])  #Add the former contentious summit to the output summit layer
            layer_output_summit.commitChanges()  #Commiting changes
            feedback.pushInfo("Point added to the output layer " +
                              str(summit_2.attributes()))
        layer_output_summit.endEditCommand()
        writer = QgsVectorFileWriter.writeAsVectorFormat(
            layer_output_summit, output_summit, "utf-8"
        )  #Saving the output layer in a vector layer at the path given by the user

        results['OUTPUT_SUMMIT'] = output_summit

        return results
Ejemplo n.º 18
0
    def testPktComposite(self):
        """
        Check that tables with PKs composed of many fields of different types are correctly read and written to
        """
        vl = QgsVectorLayer(
            '{} type=POINT estimatedmetadata=true key=\'"pk1","pk2"\' table="qgis_test"."tb_test_compound_pk" (geom)'
            .format(self.dbconn), "test_compound", "mssql")
        self.assertTrue(vl.isValid())

        fields = vl.fields()

        f = next(
            vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                'pk1 = 1 AND pk2 = 2')))
        # first of all: we must be able to fetch a valid feature
        self.assertTrue(f.isValid())
        self.assertEqual(f['pk1'], 1)
        self.assertEqual(f['pk2'], 2)
        self.assertEqual(f['value'], 'test 2')

        # can we edit a field?
        vl.startEditing()
        vl.changeAttributeValue(f.id(), fields.indexOf('value'),
                                'Edited Test 2')
        self.assertTrue(vl.commitChanges())

        # Did we get it right? Let's create a new QgsVectorLayer and try to read back our changes:
        vl2 = QgsVectorLayer(
            '{} type=POINT estimatedmetadata=true table="qgis_test"."tb_test_compound_pk" (geom) key=\'"pk1","pk2"\' '
            .format(self.dbconn), "test_compound2", "mssql")
        self.assertTrue(vl2.isValid())
        f2 = next(
            vl2.getFeatures(QgsFeatureRequest().setFilterExpression(
                'pk1 = 1 AND pk2 = 2')))
        self.assertTrue(f2.isValid())

        # Then, making sure we really did change our value.
        self.assertEqual(f2['value'], 'Edited Test 2')

        # How about inserting a new field?
        f3 = QgsFeature(vl2.fields())
        f3['pk1'] = 4
        f3['pk2'] = -9223372036854775800
        f3['value'] = 'other test'
        vl.startEditing()
        res, f3 = vl.dataProvider().addFeatures([f3])
        self.assertTrue(res)
        self.assertTrue(vl.commitChanges())

        # can we catch it on another layer?
        f4 = next(
            vl2.getFeatures(QgsFeatureRequest().setFilterExpression(
                'pk2 = -9223372036854775800')))

        self.assertTrue(f4.isValid())
        expected_attrs = [4, -9223372036854775800, 'other test']
        self.assertEqual(f4.attributes(), expected_attrs)

        # Finally, let's delete one of the features.
        f5 = next(
            vl2.getFeatures(QgsFeatureRequest().setFilterExpression(
                'pk1 = 2 AND pk2 = 1')))
        vl2.startEditing()
        vl2.deleteFeatures([f5.id()])
        self.assertTrue(vl2.commitChanges())

        # did we really delete? Let's try to get the deleted feature from the first layer.
        f_iterator = vl.getFeatures(
            QgsFeatureRequest().setFilterExpression('pk1 = 2 AND pk2 = 1'))
        got_feature = True

        try:
            f6 = next(f_iterator)
            got_feature = f6.isValid()
        except StopIteration:
            got_feature = False

        self.assertFalse(got_feature)
Ejemplo n.º 19
0
class StartData:

    def __init__(self, iface):
        
        self.iface = iface

        self.tableSchema = 'edgv'
        self.geometryColumn = 'geom'
        self.keyColumn = 'id'

    def initGui(self): 
        # cria uma ação que iniciará a configuração do plugin 
        pai = self.iface.mainWindow()
        icon_path = ':/plugins/StartData/icon.png'
        self.action = QAction (QIcon (icon_path),u"Acessa banco de dados para revisão", pai)
        self.action.setObjectName ("Stard database")
        self.action.setStatusTip(None)
        self.action.setWhatsThis(None)
        self.action.triggered.connect(self.run)
        # Adicionar o botão icone
        self.iface.addToolBarIcon (self.action) 

    def unload(self):
        # remove o item de ícone do QGIS GUI.
        self.iface.removeToolBarIcon (self.action)
        
        
    def run(self):

    ##################################
    ###### PEGA A LAYER ATIVA ########
    ##################################

        layer = self.iface.activeLayer() 

        if not layer:
            self.iface.messageBar().pushMessage("Erro", u"Esperando uma Active Layer!", level=QgsMessageBar.CRITICAL, duration=4)
            return
        if layer.featureCount() == 0:
            self.iface.messageBar().pushMessage("Erro", u"a camada não possui feições!", level=QgsMessageBar.CRITICAL, duration=4)
            return

        parametros = layer.source().split(" ") # recebe todos os parametros em uma lista ( senha, porta, password etc..)

    ####################################
    ###### INICIANDO CONEXÃO DB ########
    ####################################

        # Outra opção para isso, seria usar ex: self.dbname.. self.host.. etc.. direto dentro do laço for.
        dbname = "" 
        host = ""
        port = 0
        user = ""
        password = ""

        for i in parametros:
            part = i.split("=")
            
        # Recebe os parametros guardados na própria Layer

            if "dbname" in part[0]:
                dbname = part[1].replace("'", "")

            elif "host" in part[0]:
                host = part[1].replace("'", "")

            elif "port" in part[0]:
                port = int(part[1].replace("'", ""))

            elif "user" in part[0]:
                user = part[1].replace("'", "")

            elif "password" in part[0]:
                password = part[1].split("|")[0].replace("'", "")

        #print dbname, host, port, user, password

        # Testa se os parametros receberam os valores pretendidos, caso não, apresenta a mensagem informando..
        if len(dbname) == 0 or len(host) == 0 or port == 0 or len(user) == 0 or len(password) == 0:
            self.iface.messageBar().pushMessage("Erro", u'Um dos parametros não foram devidamente recebidos!', level=QgsMessageBar.CRITICAL, duration=4)
            return

    ####################################
    #### SETA VALORES DE CONEXÃO DB ####
    ####################################

        connection = QSqlDatabase.addDatabase('QPSQL')
        connection.setHostName(host)
        connection.setPort(port)
        connection.setUserName(user)
        connection.setPassword(password)
        connection.setDatabaseName(dbname)

        if not connection.isOpen(): # Testa se a conexão esta recebendo os parametros adequadamente.
            if not connection.open():
                print 'Error connecting to database!'
                self.iface.messageBar().pushMessage("Erro", u'Error connecting to database!', level=QgsMessageBar.CRITICAL, duration=4)
                print connection.lastError().text()
                return

    ####################################
    ###### CRIAÇÃO DE MEMORY LAYER #####
    ####################################
        

        layerCrs = layer.crs().authid() # Passa o formato (epsg: numeros)

        flagsLayerName = layer.name() + "_flags"
        flagsLayerExists = False

        for l in QgsMapLayerRegistry.instance().mapLayers().values(): # Recebe todas as camadas que estão abertas
            if l.name() == flagsLayerName: # ao encontrar o nome pretendido..
                self.flagsLayer = l # flagslayer vai receber o nome..
                self.flagsLayerProvider = l.dataProvider()
                flagsLayerExists = True # se encontrado os parametros buscados, recebe True.
                break
        
        if flagsLayerExists == False: # se não encontrado os parametros buscados, recebe False.
            tempString = "Point?crs="
            tempString += str(layerCrs)

            self.flagsLayer = QgsVectorLayer(tempString, flagsLayerName, "memory")
            self.flagsLayerProvider = self.flagsLayer.dataProvider()
            self.flagsLayerProvider.addAttributes([QgsField("id", QVariant.Int), QgsField("motivo", QVariant.String)])
            self.flagsLayer.updateFields()

        self.flagsLayer.startEditing()
        ids = [feat.id() for feat in self.flagsLayer.getFeatures()]
        self.flagsLayer.deleteFeatures(ids)
        self.flagsLayer.commitChanges()
        
        lista_fid = [] # Iniciando lista
        for f in layer.getFeatures():
            lista_fid.append(str(f.id())) # Guarda na lista. A lista de Feature ids passa tipo "int", foi convertido e guardado como "str".

        source = layer.source().split(" ")
        self.tableName = "" # Inicia vazio
        layerExistsInDB = False
        
        for i in source:
                
            if "table=" in i or "layername=" in i: # Se encontrar os atributos pretendidos dentre todos do for
                self.tableName = source[source.index(i)].split(".")[1] # Faz split em ponto e pega a segunda parte.
                self.tableName = self.tableName.replace('"', '')
                layerExistsInDB = True
                break
             
        if layerExistsInDB == False:
            self.iface.messageBar().pushMessage("Erro", u"Provedor da camada corrente não provem do banco de dados!", level=QgsMessageBar.CRITICAL, duration=4)
            return
        
        # Busca através do SQL 
        query_string  = '''select distinct (reason(ST_IsValidDetail(f."{2}",0))) AS motivo, '''
        query_string += '''ST_AsText(ST_Multi(ST_SetSrid(location(ST_IsValidDetail(f."{2}",0)), ST_Srid(f.{2})))) as local from '''
        query_string += '''(select "{3}", "{2}" from only "{0}"."{1}"  where ST_IsValid("{2}") = 'f' and {3} in ({4})) as f''' 
        query_string  = query_string.format(self.tableSchema, self.tableName, self.geometryColumn, self.keyColumn, ",".join(lista_fid))
        
        query = QSqlQuery(query_string)
        
        self.flagsLayer.startEditing()
        flagCount = 0 # iniciando contador que será referência para os IDs da camada de memória.

        listaFeatures = []
        while query.next():
            motivo = query.value(0)
            local = query.value(1)
            flagId = flagCount

            flagFeat = QgsFeature()
            flagGeom = QgsGeometry.fromWkt(local) # passa o local onde foi localizado o erro.
            flagFeat.setGeometry(flagGeom)
            flagFeat.initAttributes(2)
            flagFeat.setAttribute(0,flagId) # insere o id definido para a coluna 0 da layer de memória.
            flagFeat.setAttribute(1, motivo) # insere o motivo/razão pré-definida para a coluna 1 da layer de memória.

            listaFeatures.append(flagFeat)    

            flagCount += 1 # incrementando o contador a cada iteração

        self.flagsLayerProvider.addFeatures(listaFeatures)
        self.flagsLayer.commitChanges() # Aplica as alterações à camada.
        
        QgsMapLayerRegistry.instance().addMapLayer(self.flagsLayer) # Adicione a camada no mapa
        
        
        ##################################
        ##### TROCA MARCADOR DA LAYER ####
        ##################################
        
        # # AQUI PRETENDO PERSONALIZAR O MARCADOR DA MEMORY LAYER, POREM A PRINCIPIO SÓ ESTA ALTERANDO A LAYER ORIGINAL.
        # for lay in QgsMapLayerRegistry.instance().mapLayers().values():
            
        #     if lay == flagsLayerName and not layer.name():

        #         # Estilo base.    
        #         line = QgsLineSymbolV2()    

        #         # Crie uma linha de marcadores.
        #         marker_line = QgsMarkerLineSymbolLayerV2()
        #         marker_line.setInterval(10)

        #         # Configure o marcador.
        #         simple_marker = QgsSimpleMarkerSymbolLayerV2()
        #         simple_marker.setShape(QgsSimpleMarkerSymbolLayerBase.HalfSquare) # Formato
        #         simple_marker.setSize(3)
        #         simple_marker.setAngle(180)
        #         simple_marker.setColor(QColor('red')) # cor
        #         simple_marker.setOutlineColor(QColor('red')) # cor

        #         # O marcador tem sua própria camada de símbolo.
        #         marker = QgsMarkerSymbolV2()
        #         marker.changeSymbolLayer(0, simple_marker)

        #         # Adicione a camada à camada do marcador.
        #         marker_line.setSubSymbol(marker)

        #         # Finalmente, substitua a camada de símbolo no estilo base.
        #         line.changeSymbolLayer(0, marker_line)

        #         # Adicione o estilo à camada de linha.        
        #         renderer = QgsSingleSymbolRendererV2(line)
        #         layer.setRendererV2(renderer)
        
        if flagCount == 0: 
            
            QgsMapLayerRegistry.instance().removeMapLayer(self.flagsLayer.id())
            self.iface.messageBar().pushMessage("Aviso", u"Não foi encontrado Flags em \"" + layer.name() + "\" !", level=QgsMessageBar.CRITICAL, duration=4)

            return
        if len(query.lastError().text()) == 1:
            self.iface.messageBar().pushMessage("Aviso", "foram geradas " + str(flagCount) + " flags para a camada \"" + layer.name() + "\" !", level=QgsMessageBar.INFO, duration=4)
        else:
            self.iface.messageBar().pushMessage("Erro", u"a geração de flags falhou!", level=QgsMessageBar.CRITICAL, duration=4)
            print query.lastError().text()