3

Based on a layer with point geometry with the following fields:

res_1_name

res_1_perc

res_2_name

res_2_perc

res_3_name

res_3_perc

How could I automate that the 'res_name' field that has the highest value in the 'res_perc' field is labeled with the value of the 'res_name' field.

I add a screenshot with the structure and values of a table, pointing out the value that should be tagged.

In this case it would be necessary to detect that the highest value (on fields 'res_1_perc', 'res_2_perc', 'res_3_perc') is 41.5 ('res_1_perc') and to tag the value OPTION1 ('res_1_name').

Style label:

OPTION1

41.5 enter image description here

Seeking a more open and simplified solution

The function proposed by the user JGH is a good solution, however, in the case of my project, there is the problem that I have to handle 10x10 fields (res_1_perc, res_2_perc, res_3_perc..., res_10_perc, res_1_name, res_2_name, res_name_3_name..., res_10_name).

The function would be as follows:

case
 WHEN res_1_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_1_name
 WHEN res_2_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_2_name
 WHEN res_3_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_3_name
 WHEN res_4_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_4_name
 WHEN res_5_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_5_name
 WHEN res_6_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_6_name
 WHEN res_7_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_7_name   
 WHEN res_8_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_8_name
 WHEN res_9_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_9_nombre   
 ELSE res_10_name
END

I would like to ask for help to further refine the development of a function that simplifies the complexity of the previous function, as it could increase the number of fields in the attribute table.

My idea is to work with all the fields in the attribute table (no matter the number of fields), detecting the fields to process based on the field name suffix match.

I am working with the following function that tries to use the regexp_match function to solve this problem:

array_max(
    array_foreach(
        @layers ,
        array_length(
            if (
                regexp_match ("perc",'')),
                array()
))))

But this expression has now different problems (syntax, include field to tag res_*_name). Is it possible to use this approach from a correction of this expression?

1
  • 1
    Open expression editor for labels and try to describe this logic in expression. It can be besome nested if() functions or CASE blocks.
    – RainForest
    Commented Jul 27, 2023 at 13:44

2 Answers 2

4

Here is a completely generic solution. You can have as many fields as you like, but there should be no gaps in the given steps. Note that if there is more than one maxima, it will only pick the first one ordered by numeric fieldnames.

with_variable('vals',generate_series(1,3,1),
with_variable('percs',array_foreach(@vals,eval(concat('res_',@element,'_perc'))),
with_variable('names',array_foreach(@vals,eval(concat('res_',@element,'_name'))),

array_get(@names,array_find(@percs,array_max(@percs)))

)))

just change the values in generate_series(from,to,step) and the names of the fields if required.

Example result:

enter image description here

1
  • Exactly what my project requires. An absolutely out of the box solution that can be reused in many other projects Commented Jul 28, 2023 at 14:32
4

Click on the little epsilon icon beside the label and enter the following expression:

case
 WHEN res_1_perc >= res_2_perc AND res_1_perc >= res_3_perc 
   THEN res_1_name
 WHEN res_2_perc >= res_1_perc AND res_2_perc >= res_3_perc 
   THEN res_2_name
 ELSE res_3_name
END

enter image description here

4
  • Seeking a more open and simplified solution. The function proposed by the user JGH is a good solution, however, in the case of my project, there is the problem that I have to handle 10x10 fields (res_1_perc, res_2_perc, res_3_perc..., res_10_perc) and (res_1_name, res_2_name, name_3_name.., res_10_name) fields. I open a new request in the above answer: Commented Jul 28, 2023 at 8:12
  • 2
    I think you have an obligation to accept the answer that responds to your question, not any general case or what you meant to ask. Commented Jul 28, 2023 at 10:29
  • In my opinion, both answers (MrXsquared user and JGH user) are valid because they both achieve the goal. However, I am inclined to prioritize MrXsquared user solution because, in my opinion, it is more optimized and more efficient (it requires less code). I would like to accept both answers but it seems that the platform does not have this option. Is it correct as I have done it? Commented Jul 28, 2023 at 17:21
  • 2
    @IngridIngravida No big deal, but that's why it is important not to change the question midway...
    – JGH
    Commented Jul 28, 2023 at 17:58

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.