I received a shapefile from Arcmap. It has a column for label representation. Here's an example: 'PP3<FNT name ="SymbolMono BT" size ="11">g</FNT>gc2'. In Armap the codes are replaced and we have something like the following acronym "PP3ggc2",

enter image description here

with variation in font type and size.

How can I play this label in QGIS 3.8.3?

Is there any way? Else, how may you get around this situation?

Following is an example of the table. enter image description here

  • 1
    What does "codes are replaced" mean? I am not very familiar with ArcMap, so I might miss something here.
    – MrXsquared
    Sep 23 '19 at 17:44
  • The code ('PP3 <FNT name = "SymbolMono BT" size = "11"> g gc2') are acronyms for use in geology. The code above is displayed in Arcmap as label as "PP3ggc2". I edited the initial question.
    – Denilson
    Sep 23 '19 at 18:08
  • So you need to remove the part inside <> signs? e.g. "parttokeep<parttoberemoved>parttokeep" and additionally use the part inside <> signs as rule for fonttype, fontsize, etc.?
    – MrXsquared
    Sep 23 '19 at 18:13
  • I get it, but in the part to be removed I need the Greek symbol GAMA. And it would not be advisable for me to change the data because shapefile can be used by others.
    – Denilson
    Sep 23 '19 at 18:20
  • Ok I see. This can be done by expressions and data defined override. No need to change the original data. Will see if I can create a working one.
    – MrXsquared
    Sep 23 '19 at 18:24

Figured out a working expression. Hope this covers all your cases. Maybe there is also a more elegant solution. First use data defined override:

enter image description here

enter your individual expressions.

In "Font" it is:

substr(substr(regexp_substr( "label",'FNT name(.*?)size'),4),0,length(substr(regexp_substr( "label",'FNT name(.*?)size'),4))-2)

and in "size" it is:

substr(substr(regexp_substr( "label",'size(.*?)">'),4),0,length(substr(regexp_substr( "label",'FNT name(.*?)size'),4))-2)

Fill your "label with" field with this expression:

left("label",regexp_match( "label",'\\<')-1)  ||replace( right( left("label",regexp_match( "label",'\\</FNT>')-1) ,1),'g','​ɣ')  || right("label",regexp_match( "label",'\\<')-1)

if you have more special characters than gamma, you need to insert more replace() rules.

In my example the field containing the label is called "label". Replace it with "LEGENDA".

It is hard to explain these expressions in words, but what they basically do is search for key strings like "FNT name" and extract string parts right or left of them.


A more 'readable' expression to use in the 'data defined override' as suggested by @MrXsquared:

To get the fontname:

array_get(string_to_array( "legenda", '"'), 1)

To get the size:

array_get(string_to_array( "legenda", '"'), 3)

a little explanation:

  • you can devide the string in logical parts by string_to_array(), with the double qoutes (") as delimiter:

enter image description here

  • then call the different parts of the array by array_get(). The last number is the index, starting with 0 for the first part.

enter image description here

another approach:

QGIS gives the possibility to use unicode characters. Eg. char(611) gives you the gamma.

Here you can find a list of all unicodes: https://en.wikipedia.org/wiki/List_of_Unicode_characters. Look in the column 'decimal'.

So you can use following code to reproduce your legenda:

array_first(string_to_array("legenda", '<')) ||
when "legenda" like '%>a<%' then char(945)
when "legenda" like '%>b<%' then char(946)
when "legenda" like '%>c<%' then char(947)
when "legenda" like '%>d<%' then char(948)
||array_last(string_to_array("label", '>'))(string_to_array("legenda", '>'))
  • 2
    Great idea to use arrays here. A lot better to read and understand
    – MrXsquared
    Sep 24 '19 at 10:12
  • I used the expressions and was able to filter the items to be represented on the map. But I tried to specify different FONTS for each of the parts and it didn't work. Different font sizes I haven't tried yet.
    – Denilson
    Sep 24 '19 at 12:24
  • example to filter:
    – Denilson
    Sep 24 '19 at 12:25
  • Array_get(string_to_array( "legenda", '<FNT'), 0) || substr( Array_get(string_to_array( "legenda", '"'), 4),2,1) || Array_get(string_to_array( "legenda", '>'), 2)
    – Denilson
    Sep 24 '19 at 12:25
  • Example to change FONTs: CASE WHEN Array_get(string_to_array( "legenda", '<FNT'), 0) IS TRUE THEN 'calibri' WHEN substr( Array_get(string_to_array( "legenda", '"'), 4),2,1) IS TRUE THEN 'SymbolMono BT' WHEN Array_get(string_to_array( "legenda", '>'), 2) IS TRUE THEN 'calibri' END
    – Denilson
    Sep 24 '19 at 12:25

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.