def test_isValid(self): referencedLayer = createReferencedLayer() referencingLayer = createReferencingLayer() QgsMapLayerRegistry.instance().addMapLayers( [referencedLayer, referencingLayer]) rel = QgsRelation() assert not rel.isValid() rel.setRelationId('rel1') assert not rel.isValid() rel.setRelationName('Relation Number One') assert not rel.isValid() rel.setReferencingLayer(referencingLayer.id()) assert not rel.isValid() rel.setReferencedLayer(referencedLayer.id()) assert not rel.isValid() rel.addFieldPair('foreignkey', 'y') assert rel.isValid() QgsMapLayerRegistry.instance().removeAllMapLayers()
def test_fieldPairs(self): rel = QgsRelation() rel.setRelationId('rel1') rel.setRelationName('Relation Number One') rel.setReferencingLayer(self.referencingLayer.id()) rel.setReferencedLayer(self.referencedLayer.id()) rel.addFieldPair('foreignkey', 'y') assert (rel.fieldPairs() == {'foreignkey': 'y'})
def test_fieldPairs(self): rel = QgsRelation() rel.setRelationId("rel1") rel.setRelationName("Relation Number One") rel.setReferencingLayer(self.referencingLayer.id()) rel.setReferencedLayer(self.referencedLayer.id()) rel.addFieldPair("foreignkey", "y") assert rel.fieldPairs() == {"foreignkey": "y"}
def test_getReferencedFeature(self): rel = QgsRelation() rel.setRelationId('rel1') rel.setRelationName('Relation Number One') rel.setReferencingLayer(self.referencingLayer.id()) rel.setReferencedLayer(self.referencedLayer.id()) rel.addFieldPair('foreignkey', 'y') feat = self.referencingLayer.getFeatures().next() f = rel.getReferencedFeature(feat) assert f.isValid() assert f[0] == 'foo'
def test_getRelatedFeatures(self): rel = QgsRelation() rel.setRelationId('rel1') rel.setRelationName('Relation Number One') rel.setReferencingLayer(self.referencingLayer.id()) rel.setReferencedLayer(self.referencedLayer.id()) rel.addFieldPair('foreignkey', 'y') feat = self.referencedLayer.getFeatures().next() it = rel.getRelatedFeatures(feat) assert [a.attributes() for a in it] == [[u'test1', 123], [u'test2', 123]]
def test_getReferencedFeature(self): rel = QgsRelation() rel.setRelationId('rel1') rel.setRelationName('Relation Number One') rel.setReferencingLayer(self.referencingLayer.id()) rel.setReferencedLayer(self.referencedLayer.id()) rel.addFieldPair('foreignkey', 'y') feat = next(self.referencingLayer.getFeatures()) f = rel.getReferencedFeature(feat) assert f.isValid() assert f[0] == 'foo'
def test_getReferencedFeature(self): rel = QgsRelation() rel.setRelationId("rel1") rel.setRelationName("Relation Number One") rel.setReferencingLayer(self.referencingLayer.id()) rel.setReferencedLayer(self.referencedLayer.id()) rel.addFieldPair("foreignkey", "y") feat = next(self.referencingLayer.getFeatures()) f = rel.getReferencedFeature(feat) assert f.isValid() assert f[0] == "foo"
def test_getRelatedFeatures(self): rel = QgsRelation() rel.setRelationId("rel1") rel.setRelationName("Relation Number One") rel.setReferencingLayer(self.referencingLayer.id()) rel.setReferencedLayer(self.referencedLayer.id()) rel.addFieldPair("foreignkey", "y") feat = next(self.referencedLayer.getFeatures()) self.assertEqual(rel.getRelatedFeaturesFilter(feat), '"foreignkey" = 123') it = rel.getRelatedFeatures(feat) assert [a.attributes() for a in it] == [["test1", 123], ["test2", 123]]
def test_fieldPairs(self): referencedLayer = createReferencedLayer() referencingLayer = createReferencingLayer() QgsMapLayerRegistry.instance().addMapLayers([referencedLayer,referencingLayer]) rel = QgsRelation() rel.setRelationId( 'rel1' ) rel.setRelationName( 'Relation Number One' ) rel.setReferencingLayer( referencingLayer.id() ) rel.setReferencedLayer( referencedLayer.id() ) rel.addFieldPair( 'foreignkey', 'y' ) assert( rel.fieldPairs() == { 'foreignkey': 'y'} ) QgsMapLayerRegistry.instance().removeAllMapLayers()
def test_isValid(self): rel = QgsRelation() assert not rel.isValid() rel.setRelationId('rel1') assert not rel.isValid() rel.setRelationName('Relation Number One') assert not rel.isValid() rel.setReferencingLayer(self.referencingLayer.id()) assert not rel.isValid() rel.setReferencedLayer(self.referencedLayer.id()) assert not rel.isValid() rel.addFieldPair('foreignkey', 'y') assert rel.isValid()
def test_isValid(self): rel = QgsRelation() assert not rel.isValid() rel.setRelationId("rel1") assert not rel.isValid() rel.setRelationName("Relation Number One") assert not rel.isValid() rel.setReferencingLayer(self.referencingLayer.id()) assert not rel.isValid() rel.setReferencedLayer(self.referencedLayer.id()) assert not rel.isValid() rel.addFieldPair("foreignkey", "y") assert rel.isValid()
def test_getRelatedFeatures(self): referencedLayer = createReferencedLayer() referencingLayer = createReferencingLayer() QgsMapLayerRegistry.instance().addMapLayers([referencedLayer,referencingLayer]) rel = QgsRelation() rel.setRelationId( 'rel1' ) rel.setRelationName( 'Relation Number One' ) rel.setReferencingLayer( referencingLayer.id() ) rel.setReferencedLayer( referencedLayer.id() ) rel.addFieldPair( 'foreignkey', 'y' ) feat = referencedLayer.getFeatures().next() it = rel.getRelatedFeatures( feat ) [ a.attributes() for a in it ] == [[u'test1', 123], [u'test2', 123]] QgsMapLayerRegistry.instance().removeAllMapLayers()
def test_getRelatedFeatures(self): referencedLayer = createReferencedLayer() referencingLayer = createReferencingLayer() QgsMapLayerRegistry.instance().addMapLayers( [referencedLayer, referencingLayer]) rel = QgsRelation() rel.setRelationId('rel1') rel.setRelationName('Relation Number One') rel.setReferencingLayer(referencingLayer.id()) rel.setReferencedLayer(referencedLayer.id()) rel.addFieldPair('foreignkey', 'y') feat = referencedLayer.getFeatures().next() it = rel.getRelatedFeatures(feat) [a.attributes() for a in it] == [[u'test1', 123], [u'test2', 123]] QgsMapLayerRegistry.instance().removeAllMapLayers()
def applyRelations(self): searchEPRelation = QgsProject.instance().relationManager().relation("EA_lines_on_polygons") if not searchEPRelation.isValid(): EPRelation = QgsRelation() EPRelation.setReferencingLayer(self.EPlLayer.id()) EPRelation.setReferencedLayer(self.EPpLayer.id()) EPRelation.addFieldPair("ID_EP", "ID") EPRelation.setRelationId("EP_lines_on_polygons") EPRelation.setRelationName("EP lines on polygons") QgsProject.instance().relationManager().addRelation(EPRelation) searchEPRelation = QgsProject.instance().relationManager().relation("WDS_on_EP") if not searchEPRelation.isValid(): EPRelation = QgsRelation() EPRelation.setReferencingLayer(self.WDSLayer.id()) EPRelation.setReferencedLayer(self.EPpLayer.id()) EPRelation.addFieldPair("ID_EP", "ID") EPRelation.setRelationId("WDS_on_EP") EPRelation.setRelationName("WDS on EP") QgsProject.instance().relationManager().addRelation(EPRelation) searchEPRelation = QgsProject.instance().relationManager().relation("WDS_on_EA") if not searchEPRelation.isValid(): EPRelation = QgsRelation() EPRelation.setReferencingLayer(self.WDSLayer.id()) EPRelation.setReferencedLayer(self.EPpLayer.id()) EPRelation.addFieldPair("ID_EA", "ID") EPRelation.setRelationId("WDS_on_EA") EPRelation.setRelationName("WDS on EA") QgsProject.instance().relationManager().addRelation(EPRelation) searchEPRelation = QgsProject.instance().relationManager().relation("WDS_on_WR") if not searchEPRelation.isValid(): EPRelation = QgsRelation() EPRelation.setReferencingLayer(self.WDSLayer.id()) EPRelation.setReferencedLayer(self.EPpLayer.id()) EPRelation.addFieldPair("ID_WR", "ID") EPRelation.setRelationId("WDS_on_WR") EPRelation.setRelationName("WDS on WR") QgsProject.instance().relationManager().addRelation(EPRelation)
def testExportFeatureRelations(self): """ Test exporting a feature with relations """ #parent layer parent = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=foreignkey:integer", "parent", "memory") pr = parent.dataProvider() pf1 = QgsFeature() pf1.setFields(parent.fields()) pf1.setAttributes(["test1", 67, 123]) pf2 = QgsFeature() pf2.setFields(parent.fields()) pf2.setAttributes(["test2", 68, 124]) assert pr.addFeatures([pf1, pf2]) #child layer child = QgsVectorLayer( "Point?field=x:string&field=y:integer&field=z:integer", "referencedlayer", "memory") pr = child.dataProvider() f1 = QgsFeature() f1.setFields(child.fields()) f1.setAttributes(["foo", 123, 321]) f2 = QgsFeature() f2.setFields(child.fields()) f2.setAttributes(["bar", 123, 654]) f3 = QgsFeature() f3.setFields(child.fields()) f3.setAttributes(["foobar", 124, 554]) assert pr.addFeatures([f1, f2, f3]) QgsProject.instance().addMapLayers([child, parent]) rel = QgsRelation() rel.setRelationId('rel1') rel.setRelationName('relation one') rel.setReferencingLayer(child.id()) rel.setReferencedLayer(parent.id()) rel.addFieldPair('y', 'foreignkey') QgsProject.instance().relationManager().addRelation(rel) exporter = QgsJSONExporter() exporter.setVectorLayer(parent) self.assertEqual(exporter.vectorLayer(), parent) exporter.setIncludeRelated(True) self.assertEqual(exporter.includeRelated(), True) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test1", "fldint":67, "foreignkey":123, "relation one":[{"x":"foo", "y":123, "z":321}, {"x":"bar", "y":123, "z":654}] } }""" self.assertEqual(exporter.exportFeature(pf1), expected) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test2", "fldint":68, "foreignkey":124, "relation one":[{"x":"foobar", "y":124, "z":554}] } }""" self.assertEqual(exporter.exportFeature(pf2), expected) # test excluding related attributes exporter.setIncludeRelated(False) self.assertEqual(exporter.includeRelated(), False) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test2", "fldint":68, "foreignkey":124 } }""" self.assertEqual(exporter.exportFeature(pf2), expected) # test without vector layer set exporter.setIncludeRelated(True) exporter.setVectorLayer(None) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test2", "fldint":68, "foreignkey":124 } }""" self.assertEqual(exporter.exportFeature(pf2), expected)
def open_db(self): edb_filename = self.open_db_lineedit.text() edb_name, ext = os.path.splitext(os.path.basename(str(edb_filename))) QgsMessageLog.logMessage( "Loading edb %s" % edb_filename, 'AirviroOfflineEdb', QgsMessageLog.INFO ) self.db_uri.setDatabase(edb_filename) self.con, self.cur = connect(str(self.db_uri.database())) self.epsg = get_epsg(self.con) root = QgsProject.instance().layerTreeRoot() edb_increment = 1 while root.findGroup(edb_name) is not None: edb_name = edb_name + unicode(edb_increment) edb_increment += 1 QgsMessageLog.logMessage( "Adding edb layers in %s" % edb_name, 'AirviroOfflineEdb', QgsMessageLog.INFO ) edb_group = root.addGroup(edb_name) point_group = edb_group.addGroup('Point sources') area_group = edb_group.addGroup('Area sources') grid_group = edb_group.addGroup('Grid sources') road_group = edb_group.addGroup('Road sources') subtable_group = edb_group.addGroup('Subtables') company_group = edb_group.addGroup('Companies') facility_group = edb_group.addGroup('Facilities') emis_group = edb_group.addGroup('Emissions') point_support_group = point_group.addGroup('Support tables') area_support_group = area_group.addGroup('Support tables') grid_support_group = grid_group.addGroup('Support tables') road_support_group = road_group.addGroup('Support tables') facility_support_group = facility_group.addGroup('Support tables') company_support_group = company_group.addGroup('Support tables') unit_group = subtable_group.addGroup('Units') road_vehicle_group = subtable_group.addGroup('Road vehicles') road_vehicle_support_group = road_vehicle_group.addGroup( 'Support tables' ) roadtype_group = subtable_group.addGroup('Roadtypes') emis_func_group = subtable_group.addGroup('Emission functions') searchkey_group = subtable_group.addGroup('Searchkeys') timevar_group = subtable_group.addGroup('Time variations') subgrp_group = subtable_group.addGroup('Substance groups') self.layers = {} schema = '' geom_table_column_dict = dict(GEOMETRY_TABLES_COLUMNS) for table in TABLES: if not table_in_db(self.cur, table): iface.messageBar().pushMessage( "Warning", "Table %s not found in edb" % table, level=QgsMessageBar.WARNING, duration=3 ) continue geom_col = geom_table_column_dict.get(table, None) self.db_uri.setDataSource( schema, table, geom_col or '' ) layer_uri = self.db_uri.uri() # + "&crs=EPSG:4326" layer = QgsVectorLayer(layer_uri, table, 'spatialite') layer.setCrs(QgsCoordinateReferenceSystem( self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) ) if not layer.isValid(): raise ValueError(edb_filename) map_layer = QgsMapLayerRegistry.instance().addMapLayer( layer, False ) if 'timevar' in table: group = timevar_group elif 'emission_function' in table: group = emis_func_group elif 'searchkey' in table: group = searchkey_group elif 'unit' in table: group = unit_group elif 'subgrp' in table: group = subgrp_group elif table == 'substances': group = subtable_group elif table.endswith('_emis'): group = emis_group elif table == 'points': group = point_group elif 'point_' in table: group = point_support_group elif table == 'areas': group = area_group elif 'area_' in table: group = area_support_group elif table == 'roads': group = road_group elif table in ('road_vehicle_link', 'road_alobs'): group = road_support_group elif 'road_' in table: group = road_vehicle_group elif 'roadtype' in table: group = roadtype_group elif table == 'facilties': group = facility_group elif 'facility' in table: group = facility_support_group elif 'companies' == table: group = company_group elif 'company' in table: group = company_support_group elif 'traffic_situation' in table: group = road_vehicle_support_group group.setVisible(False) group.setExpanded(False) group.addLayer(map_layer) self.layers[table] = map_layer.id() for table in TABLES: foreign_keys = get_foreign_keys(self.con, table) referencing_layer = self.layers[table] for row in foreign_keys: referenced_layer = self.layers[row['table']] from_column = row['from'] to_column = row['to'] rel = QgsRelation() rel.setReferencingLayer(referencing_layer) rel.setReferencedLayer(referenced_layer) rel.addFieldPair(from_column, to_column) rel_name = 'fk_%s_%s-%s_%s' % ( table, from_column, row['table'], to_column ) rel.setRelationId(rel_name) rel.setRelationName( 'fk_%s_%s-%s_%s' % ( table, from_column, row['table'], to_column) ) if not rel.isValid(): raise ValueError( 'Reference %s is invalid' % rel_name ) QgsProject.instance().relationManager().addRelation(rel)
def applyJoin(self): self.dlg.show() selectedFields = self.getSelFieldList() or [] if self.dlg.targetLayerCombo.currentText()[:6] != 'Select' and self.dlg.joinLayerCombo.currentText()[:6] != 'Select' and self.dlg.spatialTypeCombo.currentText()[:6] != 'Select': targetLayer = self.layerSet[self.dlg.targetLayerCombo.currentText()] joinLayer = self.layerSet[self.dlg.joinLayerCombo.currentText()] joinLayerFields = [field.name() for field in joinLayer.pendingFields()] #targetLayerFields = [field.name() for field in targetLayer.pendingFields()] targetLayerFields = [] for field in targetLayer.pendingFields(): if field.name()[0:7] == 'spjoin_': idx = targetLayer.pendingFields().fieldNameIndex(field.name()) self.tra.ce("removing:"+field.name()+str(idx)) targetLayer.dataProvider().deleteAttributes([idx]) targetLayer.removeExpressionField(idx) else: targetLayerFields.append(field.name()) self.tra.ce(targetLayerFields) targetLayer.updateFields() joinField = 'spjoin_rif' exp = "geom"+self.dlg.spatialTypeCombo.currentText()+"('"+joinLayer.name()+"','$id')" self.tra.ce( exp) #add a rif field if build relation requested if self.dlg.checkBuildRelation.checkState() == Qt.Checked: #joinLayer.addExpressionField('$id', QgsField('spjoin_rif', QVariant.Int)) joinLayer.dataProvider().addAttributes([QgsField(joinField, QVariant.Int)]) #joinLayer.updateFields() idx = joinLayer.dataProvider().fields().fieldNameIndex(joinField) expObj = QgsExpression('$id') changes = {} for feature in joinLayer.getFeatures(): value = expObj.evaluate(feature) #joinLayer.dataProvider().changeAttributeValues({feature.id():{idx:value}}) changes[feature.id()] = {idx:value} joinLayer.dataProvider().changeAttributeValues(changes) if self.dlg.checkDynamicJoin.checkState() == Qt.Checked: targetLayer.addExpressionField(exp, QgsField(joinField, QVariant.Int)) else: #Create static rif field targetLayer.dataProvider().addAttributes([QgsField(joinField, QVariant.Int)]) #targetLayer.updateFields() F = [field.name() for field in targetLayer.dataProvider().fields()] self.tra.ce(F) #Compile spatial expression to get feature rifs expObj = QgsExpression(exp) expObj.prepare(targetLayer.pendingFields()) idx = targetLayer.dataProvider().fields().fieldNameIndex(joinField) self.tra.ce( "new " + joinField + str(idx)) changes = {} #init progress bar self.dlg.progressBar.setMinimum(0) self.dlg.progressBar.setMaximum(targetLayer.featureCount()) #cicle into feature to build mod vector for count, feature in enumerate(targetLayer.getFeatures()): self.dlg.progressBar.setValue(count) value = expObj.evaluate(feature) changes[feature.id()] = {idx:value} self.tra.ce(changes) #apply mod vector targetLayer.dataProvider().changeAttributeValues(changes) targetLayer.updateFields() #build expression fields to connect to join field rif for f in selectedFields: fieldType = joinLayer.pendingFields().field(f).type() exp = """dbvaluebyid('%s','%s',"%s")""" %(joinLayer.name(),f,joinField) self.tra.ce(exp) targetLayer.addExpressionField(exp, QgsField('spjoin_'+f, fieldType)) targetLayer.updateFields() if self.dlg.checkBuildRelation.checkState() == Qt.Checked: jRel = QgsRelation() jRel.setRelationId(targetLayer.name()+"_"+str(uuid.uuid1())) jRel.setRelationName("%s_%s-rif_%s" % (targetLayer.name(),self.dlg.spatialTypeCombo.currentText(),joinLayer.name())) jRel.setReferencedLayer(joinLayer.id()) jRel.setReferencingLayer(targetLayer.id()) jRel.addFieldPair('spjoin_rif','spjoin_rif') QgsProject.instance().relationManager().addRelation(jRel) self.dlg.hide()
def open_db(self): edb_filename = self.open_db_lineedit.text() edb_name, ext = os.path.splitext(os.path.basename(str(edb_filename))) QgsMessageLog.logMessage("Loading edb %s" % edb_filename, 'AirviroOfflineEdb', QgsMessageLog.INFO) self.db_uri.setDatabase(edb_filename) self.con, self.cur = connect(str(self.db_uri.database())) self.epsg = get_epsg(self.con) root = QgsProject.instance().layerTreeRoot() edb_increment = 1 while root.findGroup(edb_name) is not None: edb_name = edb_name + unicode(edb_increment) edb_increment += 1 QgsMessageLog.logMessage("Adding edb layers in %s" % edb_name, 'AirviroOfflineEdb', QgsMessageLog.INFO) edb_group = root.addGroup(edb_name) point_group = edb_group.addGroup('Point sources') area_group = edb_group.addGroup('Area sources') grid_group = edb_group.addGroup('Grid sources') road_group = edb_group.addGroup('Road sources') subtable_group = edb_group.addGroup('Subtables') company_group = edb_group.addGroup('Companies') facility_group = edb_group.addGroup('Facilities') emis_group = edb_group.addGroup('Emissions') point_support_group = point_group.addGroup('Support tables') area_support_group = area_group.addGroup('Support tables') grid_support_group = grid_group.addGroup('Support tables') road_support_group = road_group.addGroup('Support tables') facility_support_group = facility_group.addGroup('Support tables') company_support_group = company_group.addGroup('Support tables') unit_group = subtable_group.addGroup('Units') road_vehicle_group = subtable_group.addGroup('Road vehicles') road_vehicle_support_group = road_vehicle_group.addGroup( 'Support tables') roadtype_group = subtable_group.addGroup('Roadtypes') emis_func_group = subtable_group.addGroup('Emission functions') searchkey_group = subtable_group.addGroup('Searchkeys') timevar_group = subtable_group.addGroup('Time variations') subgrp_group = subtable_group.addGroup('Substance groups') self.layers = {} schema = '' geom_table_column_dict = dict(GEOMETRY_TABLES_COLUMNS) for table in TABLES: if not table_in_db(self.cur, table): iface.messageBar().pushMessage("Warning", "Table %s not found in edb" % table, level=QgsMessageBar.WARNING, duration=3) continue geom_col = geom_table_column_dict.get(table, None) self.db_uri.setDataSource(schema, table, geom_col or '') layer_uri = self.db_uri.uri() # + "&crs=EPSG:4326" layer = QgsVectorLayer(layer_uri, table, 'spatialite') layer.setCrs( QgsCoordinateReferenceSystem( self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)) if not layer.isValid(): raise ValueError(edb_filename) map_layer = QgsMapLayerRegistry.instance().addMapLayer( layer, False) if 'timevar' in table: group = timevar_group elif 'emission_function' in table: group = emis_func_group elif 'searchkey' in table: group = searchkey_group elif 'unit' in table: group = unit_group elif 'subgrp' in table: group = subgrp_group elif table == 'substances': group = subtable_group elif table.endswith('_emis'): group = emis_group elif table == 'points': group = point_group elif 'point_' in table: group = point_support_group elif table == 'areas': group = area_group elif 'area_' in table: group = area_support_group elif table == 'roads': group = road_group elif table in ('road_vehicle_link', 'road_alobs'): group = road_support_group elif 'road_' in table: group = road_vehicle_group elif 'roadtype' in table: group = roadtype_group elif table == 'facilties': group = facility_group elif 'facility' in table: group = facility_support_group elif 'companies' == table: group = company_group elif 'company' in table: group = company_support_group elif 'traffic_situation' in table: group = road_vehicle_support_group group.setVisible(False) group.setExpanded(False) group.addLayer(map_layer) self.layers[table] = map_layer.id() for table in TABLES: foreign_keys = get_foreign_keys(self.con, table) referencing_layer = self.layers[table] for row in foreign_keys: referenced_layer = self.layers[row['table']] from_column = row['from'] to_column = row['to'] rel = QgsRelation() rel.setReferencingLayer(referencing_layer) rel.setReferencedLayer(referenced_layer) rel.addFieldPair(from_column, to_column) rel_name = 'fk_%s_%s-%s_%s' % (table, from_column, row['table'], to_column) rel.setRelationId(rel_name) rel.setRelationName( 'fk_%s_%s-%s_%s' % (table, from_column, row['table'], to_column)) if not rel.isValid(): raise ValueError('Reference %s is invalid' % rel_name) QgsProject.instance().relationManager().addRelation(rel)
def test_RelationReference_representValue(self): first_layer = QgsVectorLayer("none?field=foreign_key:integer", "first_layer", "memory") assert first_layer.isValid() second_layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string", "second_layer", "memory") assert second_layer.isValid() QgsMapLayerRegistry.instance().addMapLayers([first_layer, second_layer]) f = QgsFeature() f.setAttributes([123]) assert first_layer.dataProvider().addFeatures([f]) f = QgsFeature() f.setAttributes([123, 'decoded_val']) assert second_layer.dataProvider().addFeatures([f]) relMgr = QgsProject.instance().relationManager() reg = QgsEditorWidgetRegistry.instance() factory = reg.factory("RelationReference") self.assertIsNotNone(factory) rel = QgsRelation() rel.setRelationId('rel1') rel.setRelationName('Relation Number One') rel.setReferencingLayer(first_layer.id()) rel.setReferencedLayer(second_layer.id()) rel.addFieldPair('foreign_key', 'pkid') assert(rel.isValid()) relMgr.addRelation(rel) # Everything valid config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), 'decoded_val') # Code not find match in foreign layer config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual(factory.representValue(first_layer, 0, config, None, '456'), '456') # Invalid relation id config = {'Relation': 'invalid'} second_layer.setDisplayExpression('decoded') self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123') # No display expression config = {'Relation': rel.id()} second_layer.setDisplayExpression(None) self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123') # Invalid display expression config = {'Relation': rel.id()} second_layer.setDisplayExpression('invalid +') self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123') # Missing relation config = {} second_layer.setDisplayExpression('decoded') self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123') # Inconsistent layer provided to representValue() config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual(factory.representValue(second_layer, 0, config, None, '123'), '123') # Inconsistent idx provided to representValue() config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual(factory.representValue(first_layer, 1, config, None, '123'), '123') # Invalid relation rel = QgsRelation() rel.setRelationId('rel2') rel.setRelationName('Relation Number Two') rel.setReferencingLayer(first_layer.id()) rel.addFieldPair('foreign_key', 'pkid') self.assertFalse(rel.isValid()) relMgr.addRelation(rel) config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123') QgsMapLayerRegistry.instance().removeAllMapLayers()
def applyJoin(self): self.dlg.show() selectedFields = self.getSelFieldList() or [] if self.dlg.targetLayerCombo.currentText( )[:6] != 'Select' and self.dlg.joinLayerCombo.currentText( )[:6] != 'Select' and self.dlg.spatialTypeCombo.currentText( )[:6] != 'Select': targetLayer = self.layerSet[ self.dlg.targetLayerCombo.currentText()] joinLayer = self.layerSet[self.dlg.joinLayerCombo.currentText()] joinLayerFields = [ field.name() for field in joinLayer.pendingFields() ] #targetLayerFields = [field.name() for field in targetLayer.pendingFields()] targetLayerFields = [] for field in targetLayer.pendingFields(): if field.name()[0:7] == 'spjoin_': idx = targetLayer.pendingFields().fieldNameIndex( field.name()) self.tra.ce("removing:" + field.name() + str(idx)) targetLayer.dataProvider().deleteAttributes([idx]) targetLayer.removeExpressionField(idx) else: targetLayerFields.append(field.name()) self.tra.ce(targetLayerFields) targetLayer.updateFields() joinField = 'spjoin_rif' exp = "geom" + self.dlg.spatialTypeCombo.currentText( ) + "('" + joinLayer.name() + "','$id')" self.tra.ce(exp) #add a rif field if build relation requested if self.dlg.checkBuildRelation.checkState() == Qt.Checked: #joinLayer.addExpressionField('$id', QgsField('spjoin_rif', QVariant.Int)) joinLayer.dataProvider().addAttributes( [QgsField(joinField, QVariant.Int)]) #joinLayer.updateFields() idx = joinLayer.dataProvider().fields().fieldNameIndex( joinField) expObj = QgsExpression('$id') changes = {} for feature in joinLayer.getFeatures(): value = expObj.evaluate(feature) #joinLayer.dataProvider().changeAttributeValues({feature.id():{idx:value}}) changes[feature.id()] = {idx: value} joinLayer.dataProvider().changeAttributeValues(changes) if self.dlg.checkDynamicJoin.checkState() == Qt.Checked: targetLayer.addExpressionField( exp, QgsField(joinField, QVariant.Int)) else: #Create static rif field targetLayer.dataProvider().addAttributes( [QgsField(joinField, QVariant.Int)]) #targetLayer.updateFields() F = [ field.name() for field in targetLayer.dataProvider().fields() ] self.tra.ce(F) #Compile spatial expression to get feature rifs expObj = QgsExpression(exp) expObj.prepare(targetLayer.pendingFields()) idx = targetLayer.dataProvider().fields().fieldNameIndex( joinField) self.tra.ce("new " + joinField + str(idx)) changes = {} #init progress bar self.dlg.progressBar.setMinimum(0) self.dlg.progressBar.setMaximum(targetLayer.featureCount()) #cicle into feature to build mod vector for count, feature in enumerate(targetLayer.getFeatures()): self.dlg.progressBar.setValue(count) value = expObj.evaluate(feature) changes[feature.id()] = {idx: value} self.tra.ce(changes) #apply mod vector targetLayer.dataProvider().changeAttributeValues(changes) targetLayer.updateFields() #build expression fields to connect to join field rif for f in selectedFields: fieldType = joinLayer.pendingFields().field(f).type() exp = """dbvaluebyid('%s','%s',"%s")""" % (joinLayer.name(), f, joinField) self.tra.ce(exp) targetLayer.addExpressionField( exp, QgsField('spjoin_' + f, fieldType)) targetLayer.updateFields() if self.dlg.checkBuildRelation.checkState() == Qt.Checked: jRel = QgsRelation() jRel.setRelationId(targetLayer.name() + "_" + str(uuid.uuid1())) jRel.setRelationName("%s_%s-rif_%s" % (targetLayer.name(), self.dlg.spatialTypeCombo.currentText(), joinLayer.name())) jRel.setReferencedLayer(joinLayer.id()) jRel.setReferencingLayer(targetLayer.id()) jRel.addFieldPair('spjoin_rif', 'spjoin_rif') QgsProject.instance().relationManager().addRelation(jRel) self.dlg.hide()