5

I have one point layer and one table inside a GeoPackage. Let's say within the layer attribute table I have 4 columns (A, B, C and D) and in the table I have also 4 columns (E, F, G and H). The possible values of A are the same with the E, the B with the F and the C with the G.

What I want is that, depending on the values I introduce in A, B or C the row D is automatically updated looking at the table when A=E and B=F and C=G then take the H corresponding with this row and paste it into D.

enter image description here

4
  • So, you want to create a link based on three fields?
    – Erik
    Jan 14 at 12:40
  • 1
    You may create a new field in each table that concatenate the field A, B, C and E, F, G then join your data based on these new field
    – J.R
    Jan 14 at 13:13
  • Are there other rows in table.csv or only four rows?
    – Emma
    Jan 14 at 21:39
  • More rows, like 70 or so! The 4 rows I did it as an example
    – Serggg182
    Jan 15 at 13:56
6

You can use the following script after adding point layer and table to QGIS.

table = QgsProject.instance().mapLayersByName("table_layer_name")[0]
layer = QgsProject.instance().mapLayersByName("point_layer_name")[0]

layer.startEditing()

# add new column named D. if it exists in the layer, delete the line below
layer.addAttribute(QgsField("D", QVariant.String, len=20))

for f in layer.getFeatures():
    filtre = f"E={f['A']} and F={f['B']} and G={f['C']}"
    
    try: 
        # Assuming one row matching the filter
        color = [r["H"] for r in table.getFeatures(filtre)][0]
    
    # if no matching row, the line below throws IndexError.
    # in this case, we should continue to the next feature
    except IndexError: 
        continue
    
    f["D"] = color
    layer.updateFeature(f) 

layer.commitChanges()

enter image description here

4

On attribut form, you can use Case expression as this on field D

case 
 when "A" = '1' and "B" = '6' and "C" = '7' then 'Orange' 
 when "A" = '1' and "B" = '1' and "C" = '1' then 'GREEN'
 when "A" = '6' and "B" = '3' and "C" = '1' then 'RED'
end

enter image description here

5
  • 2
    or, shorter: case when A || B || C = 111 then 'green' when A || B || C = 123 then 'blue' when A || B || C = 367 then 'orange' when A || B || C = 631 then 'red' end
    – Babel
    Jan 14 at 20:01
  • 2
    Or : map_get (map('111','green','123','blue','367','orange','631','red'),A||B||C)
    – Babel
    Jan 14 at 20:08
  • 2
    what if there are many records in table.csv?
    – Emma
    Jan 14 at 21:38
  • Which is the case. But I could take a bit of coffee and some music and try to write it all. Or is there any maximum number or coding rows I can write inside this expresion calculator?
    – Serggg182
    Jan 15 at 14:07
  • Adding to this, I have to say that, using this approach I wouldnt need the CSV table inside the project. Right? Do you guys know if doing it like this will also populate the result when using QField?
    – Serggg182
    Jan 15 at 14:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.