3

In QGIS 3.16: the "merge feature attributes" function (on the advanced digitizing toolbar) allows merging the attributes of selected features by either 1) selecting which feature to keep the attributes from, or 2) concatenating the values from all selected features. However, there is no 'concatenate unique' option here; equal values will be duplicated.

Is there a way to concatenate the attribute values without duplication? I am not looking to do this across the board for all features in a layer; just for features that I click and select. Thanks.

2
  • Maybe Aggregate could help, see: gis.stackexchange.com/a/395730/88814
    – Babel
    May 25 at 14:10
  • I considered it initially but didn't think it was the appropriate tool for this particular task, since I don't want to apply the same rule set to the whole layer, and I want to group many small batches of polygons somewhat subjectively, with different criteria each time. (I'd think that using Aggregate for that would probably be as much work as just concatenating the attribute values manually, since I would need to do it many times for my various selections.) But maybe I'm missing something...!
    – pete
    May 25 at 14:40
5

Nice use case for Layer Actions.

enter image description here

Just configure a new layer action like this:

enter image description here

Code for the layer action:

from qgis.core import QgsProject
from qgis.utils import iface

field_name = "etiqueta"  # CHANGE THIS TO YOUR OWN FIELD NAME

layer = QgsProject.instance().mapLayer("[% @layer_id %]")
idx = layer.fields().indexOf(field_name)

if layer.selectedFeatureCount():
    params = QgsAggregateCalculator.AggregateParameters()
    params.delimiter = ','

    value = layer.aggregate(
        QgsAggregateCalculator.StringConcatenateUnique,
        field_name, params, fids=layer.selectedFeatureIds())[0]
        
    for fid in layer.selectedFeatureIds():
        layer.changeAttributeValue(fid, idx, value)
            
    iface.messageBar().pushSuccess("Concatenate unique", "Done!")
else:
    iface.messageBar().pushInfo("Concatenate unique", "First select some features...")

Notes:

  • You just need to change the field_name variable to match your field name and you're done.
  • The layer action will be available in editing mode. It won't be saved until you click on Save Layer Edits.

Below the code for concatenating several fields at once:

from qgis.core import QgsProject
from qgis.utils import iface

field_names = ["my_field_1", "my_field_2"]  # CHANGE THIS TO YOUR OWN FIELD NAMES

layer = QgsProject.instance().mapLayer("[% @layer_id %]")
field_dict = {layer.fields().indexOf(fn): fn for fn in field_names}

if layer.selectedFeatureCount():
    params = QgsAggregateCalculator.AggregateParameters()
    params.delimiter = ','

    attr_map = dict()
    for idx, field_name in field_dict.items():
        value = layer.aggregate(
            QgsAggregateCalculator.StringConcatenateUnique,
            field_name, params, fids=layer.selectedFeatureIds())[0]
        attr_map[idx] = value
        
    for fid in layer.selectedFeatureIds():
        layer.changeAttributeValues(fid, attr_map)
            
    iface.messageBar().pushSuccess("Concatenate unique", "Done!")
else:
    iface.messageBar().pushInfo("Concatenate unique", "First select some features...")
11
  • Wow! it is again about the QgsAggregateCalculator
    – Taras
    May 26 at 5:10
  • Very cool @Germán Carrillo. Is it possible to tell it multiple fields, or all fields? I've tried various things such as field_name = "%" without success, and when I list more than one field_name, the code seems valid but the resulting action is only on the last field listed (if I list two field names, the concatenation will only happen for the second one). Thanks!
    – pete
    May 26 at 8:00
  • I will mark this question as answered, but if anybody knows how to accomplish this for all fields, please feel free to add a comment here for this Python beginner (and others). Thanks to all who have answered.
    – pete
    Jun 2 at 13:42
  • Just to get it right, you'll apply the same type of aggregate (QgsAggregateCalculator.StringConcatenateUnique) to several layers, right? Jun 2 at 14:48
  • What I had in mind was within one layer, i.e.: select features (from one layer), and 'concatenate unique' all fields for those features. (If there's a way to do that between layers that is also interesting, but probably a different question.)
    – pete
    Jun 2 at 15:18
2

You can run the Aggregate tool and check the box next to Selected features only. Set the Aggregate function to concatenate_unique.

enter image description here

2
  • So the reason I'd rather not use the Aggregate tool is because the output is an additional layer; I will be doing this operation many times and I'd rather the data consolidation happen within my working layer. Additionally there is the fact that I don't think that I can save my parameters for Aggregate Function, Delimiter, etc. (this is also true for "Merge feature attributes") and having to put them in each time for something like 50 fields gets tiring fast. (I assume there may be a way to generalize the parameters using SQL, but I'm not there yet!)
    – pete
    May 26 at 7:03
  • OK, that sounds reasonable!
    – Babel
    May 26 at 7:04

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.