7

Value Maps can be added to attributes via the loading of a CSV file, as described in the docs:

https://docs.qgis.org/3.28/en/docs/user_manual/working_with_vector/vector_properties.html#edit-widgets

enter image description here

It is possible to add a CSV (or any format) Value Map to an attribute of a layer using PyQGIS?

I have tried to find documentation on this, but it appears to be fairly sparse, and I can't tell if this is even the right class to be looking at:

https://qgis.org/pyqgis/3.28/core/QgsValueMapFieldFormatter.html

1 Answer 1

12

To set a value map widget with values loaded manually, you can just do something like:

#QgsVectorLayer object
vl = iface.activeLayer()

# Get field index
fld_idx = vl.fields().lookupField('fuzzylinefeaturetype')

# define value map
v_map = {'map': [{'Beach': '2'}, {'DuneLike': '3'}, {'GeneralLocality': '5'}, {'RangeLike': '13'}, {'ValleyLike': '18'}]}

# Set editor widget setup to layer, passing in field index & widget setup
vl.setEditorWidgetSetup(fld_idx, QgsEditorWidgetSetup('ValueMap', v_map))

To load the values from a csv, I think the easiest solution is just to write a simple function like below:

import csv

path = '/path/to/your/field_map.csv'

def loadValueMapFromCsv(fpath):
    v_map = {}
    entries = []
    with open(fpath, newline='') as mapfile:
        reader = csv.reader(mapfile, delimiter=',')
        for row in reader:
            entries.append({row[1]: row[0]})
    v_map['map'] = entries
    
    return v_map
    
#print(loadValueMapFromCsv(path))

vl = iface.activeLayer()

fld_idx = vl.fields().lookupField('fuzzylinefeaturetype')

v_map = loadValueMapFromCsv(path)

vl.setEditorWidgetSetup(fld_idx, QgsEditorWidgetSetup('ValueMap', v_map))

Results on a test layer:

Example of csv file:

enter image description here

Attribute form dialog after running code in Python console:

enter image description here

The method in the source code which parses a csv file is: QgsValueMapConfigDlg::loadMapFromCSV

There are also useful references in the Python test for QgsAttributeForm.

By the way, to find the correct structure/syntax for the value map, I set it up manually then ran:

vl = iface.activeLayer()

fld_idx = vl.fields().lookupField('Name')

print(vl.editorWidgetSetup(fld_idx).config())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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