Пример #1
0
    def test_joined_layers_conversion(self):
        v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory")
        self.assertEqual(v1.isValid(), True)
        v2 = QgsVectorLayer("Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory")
        self.assertEqual(v2.isValid(), True)
        v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory")
        self.assertEqual(v3.isValid(), True)
        QgsProject.instance().addMapLayers([v1, v2, v3])
        joinInfo = QgsVectorJoinInfo()
        joinInfo.targetFieldName = "b_id"
        joinInfo.joinLayerId = v2.id()
        joinInfo.joinFieldName = "id"
        #joinInfo.prefix = "B_";
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)

        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))

        # with a field subset
        v1.removeJoin(v2.id())
        joinInfo.setJoinFieldNamesSubset(["bname"])
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 5)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))
        joinInfo.setJoinFieldNamesSubset(None)

        # add a table prefix to the join
        v1.removeJoin(v2.id())
        joinInfo.prefix = "BB_"
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS BB_bname, j1.bfield AS BB_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))
        joinInfo.prefix = ""
        v1.removeJoin(v2.id())
        v1.addJoin(joinInfo)

        # add another join
        joinInfo2 = QgsVectorJoinInfo()
        joinInfo2.targetFieldName = "c_id"
        joinInfo2.joinLayerId = v3.id()
        joinInfo2.joinFieldName = "id"
        v1.addJoin(joinInfo2)
        self.assertEqual(len(v1.fields()), 7)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), ('SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield, j2.cname AS C_cname FROM {} AS t ' +
                                      'LEFT JOIN {} AS j1 ON t."b_id"=j1."id" ' +
                                      'LEFT JOIN {} AS j2 ON t."c_id"=j2."id"').format(v1.id(), v2.id(), v3.id()))

        QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id()])
Пример #2
0
    def test_JoinUsingExpression2(self):
        """ test joining a layer using a virtual field (the other way!) """
        joinLayer = QgsVectorLayer(
            "Point?field=x:string&field=y:integer&field=z:integer",
            "joinlayer", "memory")
        pr = joinLayer.dataProvider()
        f1 = QgsFeature()
        f1.setAttributes(["foo", 246, 321])
        f2 = QgsFeature()
        f2.setAttributes(["bar", 456, 654])
        self.assertTrue(pr.addFeatures([f1, f2]))
        joinLayer.addExpressionField('"y"/2', QgsField('exp1', QVariant.LongLong))

        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
                               "addfeat", "memory")
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes(["test", 123])
        self.assertTrue(pr.addFeatures([f]))

        QgsProject.instance().addMapLayers([layer, joinLayer])

        join = QgsVectorLayerJoinInfo()
        join.setTargetFieldName("fldint")
        join.setJoinLayer(joinLayer)
        join.setJoinFieldName("exp1")
        join.setUsingMemoryCache(True)
        layer.addJoin(join)

        f = QgsFeature()
        fi = layer.getFeatures()
        self.assertTrue(fi.nextFeature(f))
        attrs = f.attributes()
        self.assertEqual(attrs[0], "test")
        self.assertEqual(attrs[1], 123)
        self.assertEqual(attrs[2], "foo")
        self.assertEqual(attrs[3], 246)
        self.assertEqual(attrs[4], 321)
        self.assertFalse(fi.nextFeature(f))

        QgsProject.instance().removeMapLayers([layer.id(), joinLayer.id()])
Пример #3
0
    def test_JoinUsingFeatureRequestExpression(self):
        """ test requesting features using a filter expression which requires joined columns """
        joinLayer = QgsVectorLayer(
            "Point?field=x:string&field=y:integer&field=z:integer",
            "joinlayer", "memory")
        pr = joinLayer.dataProvider()
        f1 = QgsFeature()
        f1.setAttributes(["foo", 123, 321])
        f2 = QgsFeature()
        f2.setAttributes(["bar", 124, 654])
        self.assertTrue(pr.addFeatures([f1, f2]))

        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
                               "addfeat", "memory")
        pr = layer.dataProvider()
        f1 = QgsFeature()
        f1.setAttributes(["test", 123])
        f2 = QgsFeature()
        f2.setAttributes(["test", 124])
        self.assertTrue(pr.addFeatures([f1, f2]))

        QgsProject.instance().addMapLayers([layer, joinLayer])

        join = QgsVectorLayerJoinInfo()
        join.setTargetFieldName("fldint")
        join.setJoinLayer(joinLayer)
        join.setJoinFieldName("y")
        join.setUsingMemoryCache(True)
        layer.addJoin(join)

        f = QgsFeature()
        fi = layer.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.SubsetOfAttributes).setFilterExpression('joinlayer_z=654'))
        self.assertTrue(fi.nextFeature(f))
        self.assertEqual(f['fldint'], 124)
        self.assertEqual(f['joinlayer_z'], 654)

        QgsProject.instance().removeMapLayers([layer.id(), joinLayer.id()])
Пример #4
0
    def test_JoinUsingFeatureRequestExpression(self):
        """ test requesting features using a filter expression which requires joined columns """
        joinLayer = QgsVectorLayer(
            "Point?field=x:string&field=y:integer&field=z:integer",
            "joinlayer", "memory")
        pr = joinLayer.dataProvider()
        f1 = QgsFeature()
        f1.setAttributes(["foo", 123, 321])
        f2 = QgsFeature()
        f2.setAttributes(["bar", 124, 654])
        self.assertTrue(pr.addFeatures([f1, f2]))

        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
                               "addfeat", "memory")
        pr = layer.dataProvider()
        f1 = QgsFeature()
        f1.setAttributes(["test", 123])
        f2 = QgsFeature()
        f2.setAttributes(["test", 124])
        self.assertTrue(pr.addFeatures([f1, f2]))

        QgsProject.instance().addMapLayers([layer, joinLayer])

        join = QgsVectorLayerJoinInfo()
        join.setTargetFieldName("fldint")
        join.setJoinLayer(joinLayer)
        join.setJoinFieldName("y")
        join.setUsingMemoryCache(True)
        layer.addJoin(join)

        f = QgsFeature()
        fi = layer.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.SubsetOfAttributes).setFilterExpression('joinlayer_z=654'))
        self.assertTrue(fi.nextFeature(f))
        self.assertEqual(f['fldint'], 124)
        self.assertEqual(f['joinlayer_z'], 654)

        QgsProject.instance().removeMapLayers([layer.id(), joinLayer.id()])
Пример #5
0
    def test_value_exists_joins(self):
        """Test that unique values in fields from joined layers, see GH #36167"""

        p = QgsProject()
        main_layer = QgsVectorLayer("Point?field=fid:integer", "main_layer",
                                    "memory")
        self.assertTrue(main_layer.isValid())
        # Attr layer is joined with layer on fk ->
        attr_layer = QgsVectorLayer("Point?field=id:integer&field=fk:integer",
                                    "attr_layer", "memory")
        self.assertTrue(attr_layer.isValid())

        p.addMapLayers([main_layer, attr_layer])
        join_info = QgsVectorLayerJoinInfo()
        join_info.setJoinLayer(attr_layer)
        join_info.setJoinFieldName('fk')
        join_info.setTargetFieldName('fid')
        join_info.setUsingMemoryCache(True)
        main_layer.addJoin(join_info)
        main_layer.updateFields()
        join_buffer = main_layer.joinBuffer()
        self.assertTrue(join_buffer.containsJoins())
        self.assertEqual(main_layer.fields().names(), ['fid', 'attr_layer_id'])

        f = QgsFeature(main_layer.fields())
        f.setAttributes([1])
        main_layer.dataProvider().addFeatures([f])

        f = QgsFeature(attr_layer.fields())
        f.setAttributes([1, 1])
        attr_layer.dataProvider().addFeatures([f])

        self.assertTrue(QgsVectorLayerUtils.valueExists(main_layer, 0, 1))
        self.assertTrue(QgsVectorLayerUtils.valueExists(main_layer, 1, 1))
        self.assertFalse(QgsVectorLayerUtils.valueExists(main_layer, 0, 2))
        self.assertFalse(QgsVectorLayerUtils.valueExists(main_layer, 1, 2))
Пример #6
0
    def test_joined_layers_conversion(self):
        v1 = QgsVectorLayer(
            "Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string",
            "A", "memory")
        self.assertEqual(v1.isValid(), True)
        v2 = QgsVectorLayer(
            "Point?field=id:integer&field=bname:string&field=bfield:integer",
            "B", "memory")
        self.assertEqual(v2.isValid(), True)
        v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C",
                            "memory")
        self.assertEqual(v3.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayers([v1, v2, v3])
        joinInfo = QgsVectorJoinInfo()
        joinInfo.targetFieldName = "b_id"
        joinInfo.joinLayerId = v2.id()
        joinInfo.joinFieldName = "id"
        #joinInfo.prefix = "B_";
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)

        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))

        # with a field subset
        v1.removeJoin(v2.id())
        joinInfo.setJoinFieldNamesSubset(["bname"])
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 5)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))
        joinInfo.setJoinFieldNamesSubset(None)

        # add a table prefix to the join
        v1.removeJoin(v2.id())
        joinInfo.prefix = "BB_"
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS BB_bname, j1.bfield AS BB_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))
        joinInfo.prefix = ""
        v1.removeJoin(v2.id())
        v1.addJoin(joinInfo)

        # add another join
        joinInfo2 = QgsVectorJoinInfo()
        joinInfo2.targetFieldName = "c_id"
        joinInfo2.joinLayerId = v3.id()
        joinInfo2.joinFieldName = "id"
        v1.addJoin(joinInfo2)
        self.assertEqual(len(v1.fields()), 7)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), (
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield, j2.cname AS C_cname FROM {} AS t '
            + 'LEFT JOIN {} AS j1 ON t."b_id"=j1."id" ' +
            'LEFT JOIN {} AS j2 ON t."c_id"=j2."id"').format(
                v1.id(), v2.id(), v3.id()))

        QgsMapLayerRegistry.instance().removeMapLayers(
            [v1.id(), v2.id(), v3.id()])
Пример #7
0
    def test_joined_layers_conversion(self):
        v1 = QgsVectorLayer(
            "Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string",
            "A", "memory")
        self.assertEqual(v1.isValid(), True)
        v2 = QgsVectorLayer(
            "Point?field=id:integer&field=bname:string&field=bfield:integer",
            "B", "memory")
        self.assertEqual(v2.isValid(), True)
        v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C",
                            "memory")
        self.assertEqual(v3.isValid(), True)
        tl1 = QgsVectorLayer(
            "NoGeometry?field=id:integer&field=e_id:integer&field=0name:string",
            "D", "memory")
        self.assertEqual(tl1.isValid(), True)
        tl2 = QgsVectorLayer("NoGeometry?field=id:integer&field=ena me:string",
                             "E", "memory")
        self.assertEqual(tl2.isValid(), True)
        QgsProject.instance().addMapLayers([v1, v2, v3, tl1, tl2])
        joinInfo = QgsVectorLayerJoinInfo()
        joinInfo.setTargetFieldName("b_id")
        joinInfo.setJoinLayer(v2)
        joinInfo.setJoinFieldName("id")
        #joinInfo.setPrefix("B_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)

        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))

        # with a field subset
        v1.removeJoin(v2.id())
        joinInfo.setJoinFieldNamesSubset(["bname"])
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 5)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))
        joinInfo.setJoinFieldNamesSubset(None)

        # add a table prefix to the join
        v1.removeJoin(v2.id())
        joinInfo.setPrefix("BB_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "BB_bname", j1."bfield" AS "BB_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))
        joinInfo.setPrefix("")
        v1.removeJoin(v2.id())
        v1.addJoin(joinInfo)

        # add another join
        joinInfo2 = QgsVectorLayerJoinInfo()
        joinInfo2.setTargetFieldName("c_id")
        joinInfo2.setJoinLayer(v3)
        joinInfo2.setJoinFieldName("id")
        v1.addJoin(joinInfo2)
        self.assertEqual(len(v1.fields()), 7)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), (
            'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield", j2."cname" AS "C_cname" FROM "{}" AS t '
            + 'LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id" ' +
            'LEFT JOIN "{}" AS j2 ON t."c_id"=j2."id"').format(
                v1.id(), v2.id(), v3.id()))

        # test NoGeometry joined layers with field names starting with a digit or containing white spaces
        joinInfo3 = QgsVectorLayerJoinInfo()
        joinInfo3.setTargetFieldName("e_id")
        joinInfo3.setJoinLayer(tl2)
        joinInfo3.setJoinFieldName("id")
        tl1.addJoin(joinInfo3)
        self.assertEqual(len(tl1.fields()), 4)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(tl1)
        self.assertEqual(
            df.query(),
            'SELECT t.rowid AS uid, t."id", t."e_id", t."0name", j1."ena me" AS "E_ena me" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."e_id"=j1."id"'
            .format(tl1.id(), tl2.id()))

        QgsProject.instance().removeMapLayers(
            [v1.id(), v2.id(), v3.id(),
             tl1.id(), tl2.id()])
Пример #8
0
    def test_joined_layers_conversion(self):
        v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory")
        self.assertEqual(v1.isValid(), True)
        v2 = QgsVectorLayer("Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory")
        self.assertEqual(v2.isValid(), True)
        v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory")
        self.assertEqual(v3.isValid(), True)
        tl1 = QgsVectorLayer("NoGeometry?field=id:integer&field=e_id:integer&field=0name:string", "D", "memory")
        self.assertEqual(tl1.isValid(), True)
        tl2 = QgsVectorLayer("NoGeometry?field=id:integer&field=ena me:string", "E", "memory")
        self.assertEqual(tl2.isValid(), True)
        QgsProject.instance().addMapLayers([v1, v2, v3, tl1, tl2])
        joinInfo = QgsVectorLayerJoinInfo()
        joinInfo.setTargetFieldName("b_id")
        joinInfo.setJoinLayer(v2)
        joinInfo.setJoinFieldName("id")
        #joinInfo.setPrefix("B_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)

        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))

        # with a field subset
        v1.removeJoin(v2.id())
        joinInfo.setJoinFieldNamesSubset(["bname"])
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 5)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))
        joinInfo.setJoinFieldNamesSubset(None)

        # add a table prefix to the join
        v1.removeJoin(v2.id())
        joinInfo.setPrefix("BB_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "BB_bname", j1."bfield" AS "BB_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))
        joinInfo.setPrefix("")
        v1.removeJoin(v2.id())
        v1.addJoin(joinInfo)

        # add another join
        joinInfo2 = QgsVectorLayerJoinInfo()
        joinInfo2.setTargetFieldName("c_id")
        joinInfo2.setJoinLayer(v3)
        joinInfo2.setJoinFieldName("id")
        v1.addJoin(joinInfo2)
        self.assertEqual(len(v1.fields()), 7)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), ('SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield", j2."cname" AS "C_cname" FROM "{}" AS t '
                                      + 'LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id" '
                                      + 'LEFT JOIN "{}" AS j2 ON t."c_id"=j2."id"').format(v1.id(), v2.id(), v3.id()))

        # test NoGeometry joined layers with field names starting with a digit or containing white spaces
        joinInfo3 = QgsVectorLayerJoinInfo()
        joinInfo3.setTargetFieldName("e_id")
        joinInfo3.setJoinLayer(tl2)
        joinInfo3.setJoinFieldName("id")
        tl1.addJoin(joinInfo3)
        self.assertEqual(len(tl1.fields()), 4)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(tl1)
        self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t."id", t."e_id", t."0name", j1."ena me" AS "E_ena me" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."e_id"=j1."id"'.format(tl1.id(), tl2.id()))

        QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id(), tl1.id(), tl2.id()])
    def fusionnerJointure(self, cheminCompletParcelle, jointureChoisie):
        """ Selon les tables déja ouverte dans le projet : ouverture si necessaire des différents cas de délimiteurs
            Jointure par QGIS """
        # Vérification du projet ouverte
        monProjet = QgsProject.instance()
        if monProjet.fileName() == None or monProjet.fileName() == "":
            monPrint("Projet en cours de création", T_WAR)
        else:
            monPrint("Projet ouvert {}".format(monProjet.fileName()))

        root = monProjet.layerTreeRoot()
        # Création du groupe jointure_date
        dateMaintenant = datetime.now()
        nomGroupe = MonParcellaire_JOI + " du " + dateMaintenant.strftime(
            "%d %b à %Hh%M:%S")
        temporaireGroupe = QgsLayerTreeGroup(nomGroupe)
        # Positionner en haut de root
        root.addChildNode(temporaireGroupe)
        nouveauGroupe = temporaireGroupe.clone()
        root.insertChildNode(0, nouveauGroupe)
        root.removeChildNode(temporaireGroupe)

        # Ouverture du vecteur parcelle
        parcelle = QgsVectorLayer(
            cheminCompletParcelle,
            MonParcellaire_PAR + SEP_U + MonParcellaire_JOI, 'ogr')
        monProjet.addMapLayer(parcelle, False)
        nouveauGroupe.addLayer(parcelle)

        # Recherche delimiteur
        delimiteur, csv, nomCsv = self.rechercherDelimiteurJointure(
            jointureChoisie, "No Pandas")
        nomCourtJointure = os.path.basename(jointureChoisie)

        monPrint(
            "Délimiteur identifié {0} pour {1}".format(delimiteur,
                                                       nomCourtJointure), T_OK)
        monProjet.addMapLayer(csv, False)
        nouveauGroupe.addLayer(csv)

        # Jointure
        attributsSelectionnes = self.AttributsAJoindre_listWidget.selectedItems(
        )
        attributsAJoindre = []
        for positionAttribut in range(len(attributsSelectionnes)):
            attributsAJoindre.append(
                str(self.AttributsAJoindre_listWidget.selectedItems()
                    [positionAttribut].text()))
        #monPrint( "Attributs à joindre {}".format( attributsAJoindre))
        # Liste des champs dans csv
        nomColonnes, _ = self.lireAttributsJointure(jointureChoisie)
        attributsAJoindreOrdonne = []
        for col in nomColonnes:
            if col in attributsAJoindre:
                if col != MonParcellaireNomAttribut:
                    attributsAJoindreOrdonne.append(col)
        #monPrint( "Attributs à joindre ordonné {}".format( attributsAJoindreOrdonne))

        champVecteur = MonParcellaireNomAttribut
        maJointure = QgsVectorLayerJoinInfo()
        champCsv = self.AttributJointure_comboBox.currentText()
        maJointure.setJoinFieldName(champCsv)
        maJointure.setTargetFieldName(champVecteur)
        maJointure.setUsingMemoryCache(True)
        maJointure.setPrefix("")
        maJointure.setJoinLayer(csv)
        # Récupérer les champs de jointure
        maJointure.setJoinFieldNamesSubset(attributsAJoindreOrdonne)
        parcelle.addJoin(maJointure)
        return jointureChoisie, attributsAJoindreOrdonne
Пример #10
0
    def testJoinedFieldIsEditableRole(self):
        layer = QgsVectorLayer("Point?field=id_a:integer", "addfeat", "memory")
        layer2 = QgsVectorLayer("Point?field=id_b:integer&field=value_b",
                                "addfeat", "memory")
        QgsProject.instance().addMapLayers([layer, layer2])

        # editable join
        join_info = QgsVectorLayerJoinInfo()
        join_info.setTargetFieldName("id_a")
        join_info.setJoinLayer(layer2)
        join_info.setJoinFieldName("id_b")
        join_info.setPrefix("B_")
        join_info.setEditable(True)
        join_info.setUpsertOnEdit(True)
        layer.addJoin(join_info)

        m = QgsFieldModel()
        m.setLayer(layer)

        self.assertIsNone(
            m.data(m.indexFromName('id_a'),
                   QgsFieldModel.JoinedFieldIsEditable))
        self.assertTrue(
            m.data(m.indexFromName('B_value_b'),
                   QgsFieldModel.JoinedFieldIsEditable))
        self.assertIsNone(
            m.data(m.indexFromName('an expression'),
                   QgsFieldModel.JoinedFieldIsEditable))
        self.assertIsNone(
            m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))
        m.setAllowExpression(True)
        m.setExpression('an expression')
        self.assertIsNone(
            m.data(m.indexFromName('an expression'),
                   QgsFieldModel.JoinedFieldIsEditable))
        m.setAllowEmptyFieldName(True)
        self.assertIsNone(
            m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))

        proxy_m = QgsFieldProxyModel()
        proxy_m.setFilters(QgsFieldProxyModel.AllTypes
                           | QgsFieldProxyModel.HideReadOnly)
        proxy_m.sourceFieldModel().setLayer(layer)
        self.assertEqual(proxy_m.rowCount(), 2)
        self.assertEqual(proxy_m.data(proxy_m.index(0, 0)), 'id_a')
        self.assertEqual(proxy_m.data(proxy_m.index(1, 0)), 'B_value_b')

        # not editable join
        layer3 = QgsVectorLayer("Point?field=id_a:integer", "addfeat",
                                "memory")
        QgsProject.instance().addMapLayers([layer3])
        join_info = QgsVectorLayerJoinInfo()
        join_info.setTargetFieldName("id_a")
        join_info.setJoinLayer(layer2)
        join_info.setJoinFieldName("id_b")
        join_info.setPrefix("B_")
        join_info.setEditable(False)

        layer3.addJoin(join_info)
        m = QgsFieldModel()
        m.setLayer(layer3)

        self.assertIsNone(
            m.data(m.indexFromName('id_a'),
                   QgsFieldModel.JoinedFieldIsEditable))
        self.assertFalse(
            m.data(m.indexFromName('B_value_b'),
                   QgsFieldModel.JoinedFieldIsEditable))
        self.assertIsNone(
            m.data(m.indexFromName('an expression'),
                   QgsFieldModel.JoinedFieldIsEditable))
        self.assertIsNone(
            m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))
        m.setAllowExpression(True)
        m.setExpression('an expression')
        self.assertIsNone(
            m.data(m.indexFromName('an expression'),
                   QgsFieldModel.JoinedFieldIsEditable))
        m.setAllowEmptyFieldName(True)
        self.assertIsNone(
            m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))

        proxy_m = QgsFieldProxyModel()
        proxy_m.sourceFieldModel().setLayer(layer3)
        proxy_m.setFilters(QgsFieldProxyModel.AllTypes
                           | QgsFieldProxyModel.HideReadOnly)
        self.assertEqual(proxy_m.rowCount(), 1)
        self.assertEqual(proxy_m.data(proxy_m.index(0, 0)), 'id_a')
Пример #11
0
    def add_joined_layer(
            source_layer: Union[FeatureLayer, StandaloneTable],  # pylint: disable=too-many-branches
            input_file,
            base_layer: QgsVectorLayer,
            context: Context):
        """
        Adds joined layers
        """
        if not source_layer.join:
            return None

        if isinstance(source_layer.join, MemoryRelationshipClassName):
            if isinstance(source_layer.join.origin_name, RelQueryTableName):
                if context.unsupported_object_callback:
                    context.unsupported_object_callback(
                        '{}: Nested joins are not supported in QGIS'.format(
                            context.layer_name),
                        level=Context.CRITICAL)

                return None

            join_info = QgsVectorLayerJoinInfo()

            join_info.setJoinFieldName(source_layer.join.origin_primary_key)
            join_info.setTargetFieldName(source_layer.join.origin_foreign_key)

            base, _ = os.path.split(input_file)

            source_layer_props = DatasetNameConverter.convert(
                name=source_layer.join.destination_name,
                base=base,
                crs=QgsCoordinateReferenceSystem(),
                context=context)
            context.layer_type_hint = source_layer_props.wkb_type

            name = 'join'
            if hasattr(source_layer.join.destination_name, 'name'):
                name = source_layer.join.destination_name.name
                join_info.setPrefix(name + '.')

            if Qgis.QGIS_VERSION_INT >= 30800:
                opts = QgsVectorLayer.LayerOptions()
                if source_layer_props.wkb_type is not None:
                    opts.fallbackWkbType = source_layer_props.wkb_type

                vl = QgsVectorLayer(source_layer_props.uri, name,
                                    source_layer_props.provider, opts)
            else:
                vl = QgsVectorLayer(source_layer_props.uri, name,
                                    source_layer_props.provider)
            if not vl.isValid() and Qgis.QGIS_VERSION_INT < 30600:
                if source_layer_props.provider == 'ogr' and not os.path.exists(
                        source_layer_props.file_name
                ) and context.invalid_layer_resolver:
                    res = context.invalid_layer_resolver(
                        source_layer.join.name, source_layer_props.uri,
                        source_layer_props.wkb_type)
                    source_layer_props.uri = res.uri
                    source_layer_props.provider = res.providerKey

                vl = QgsVectorLayer(source_layer_props.uri, 'join',
                                    source_layer_props.provider)

            # todo layer name
            vl.setRenderer(QgsNullSymbolRenderer())

            try:
                vl.setFlags(vl.flags() | QgsMapLayer.Private)
            except AttributeError:
                pass

            join_info.setJoinLayer(vl)
            base_layer.addJoin(join_info)

            return vl

        else:
            if context.unsupported_object_callback:
                context.unsupported_object_callback(
                    '{}: Join layers of type {} are not yet supported'.format(
                        context.layer_name,
                        source_layer.join.__class__.__name__),
                    level=Context.CRITICAL)

            return None