I have a vector layer of polygons. There are two important attributes (a1, and a2). a1 is a integer and is the unique user generated id of the polygon and a2 is a string. This string is a list of comma separated values (for example a string can be 1,2,3,4). These comma separated values are integers that refer to the user-generated id. So 1,2,3,4 are four polygons of the same layer.
For example if a1 is 10 and its corresponding a2 has comma separated values of 1,2,3,4. I would like that whenever user choose a1 = 10, polygons 1,2,3,4 are selected.
I am trying to do this with graphical modeler. So first user selects the vector layer (vector_layer), then vector_field a1 value, say 10 from the dropdown. Then when this model is run, the result should be 4 selected polygons (1,2,3,4) from the same vector layer.
As an example see image below: when I select 2083 (vector_field value), the model after processing should select all the polygons with id as shown in column autogis_ti.
I am not sure how to apprach this epscially unpacking the comma-separated values into a selection.
2 Answers 2
I think using actions is more comfortable for this usecase, so here is a solution for this:
- go to the layer properties and navigate to "actions"
- click on the small green "+" sign
- choose "Python" as type and give it a name
- add the following code; adjust the fieldnames if necessary
selection = [] # clear selection
layer = QgsProject.instance().mapLayer('[%@layer_id%]') # get the layer
value = '[%a1%]' # get the value (change field name here)
value = int(value) # convert value to integer
for f in layer.getFeatures():
values = f["a2"] # get the values (change field name here)
if values: # only if not empty
values = values.split(',') # convert string to a list
values = [int(val) for val in values] # convert all list elements to int
if value in values: # test if value is in list of values
selection.append(f.id()) # if so, add feature id to selection list
layer.selectByIds(selection) # select by feature ids
You can then use it by using the "action" feature enter image description here. The action in action:
Disclaimer: I assume there is a more elegant way to write that code...
-
Thank you @MrXsquared. I love this interactive solution. For this particular case, I am looking for non-interactive solution. I am accepting your second answer. But thank you for showing me this method.BKS– BKS2024年08月18日 08:55:59 +00:00Commented Aug 18, 2024 at 8:55
Here is a simple expression to use within "select by expression", just change the number (here 3) to what you want to select and eventually the fieldname "a2":
array_contains(array_foreach(string_to_array("a2",','),to_int(@element)),3)
-
In a model you could use something like
array_contains(array_foreach(string_to_array(eval(@field),','),to_int(@element)),to_int(eval(@select_number)))
, however, I am currently not able to make this work as a selection, only "Extract by Expression" works for me in a model... So this just as comment, not as an answer.MrXsquared– MrXsquared2024年08月17日 14:13:34 +00:00Commented Aug 17, 2024 at 14:13 -
Thank you @MrXsquared. I am going to accept your second answer as the results of this exerise go into the next step of model builder. please correct me if I am wrong. Your solution assumes that the parameter_value 3 in array_contains exists in the a2 string. I wonder how to go about, when user selects 2083 (in my image) , irrespective of whether 2083 exists or not in the a2 string, the row with 2083 in a1 is selected and all polygons with ids as in a2 string are selected. please advice.BKS– BKS2024年08月17日 20:32:22 +00:00Commented Aug 17, 2024 at 20:32
-
So you want to select all polygons having 2083 in a1 and all polygons having 2083 in a2 at once?MrXsquared– MrXsquared2024年08月18日 19:28:55 +00:00Commented Aug 18, 2024 at 19:28
-
values in a1 and a2 are in Layer1 (polygon). Values in a1 and a2 refer to polygon ids of Layer1. a1 is unique and always contain only one value in it (you could say it can be a proxy for featureid). a2 has a list. The algorithm goes feature by feature. for each feature it selects group of polygons (csv in a2). It is more like value in a1 is a service provider polygon and a2 are list of polygons serviced by a1 polygon. a2 may or maynot contain a1 value. 95% it will not contain a1.BKS– BKS2024年08月18日 19:36:07 +00:00Commented Aug 18, 2024 at 19:36