6

I would like to use the "create categorized renderer from style" Plugin in QGIS 3.14.15 but I didn't have any .XML-file for this.

I tried to create one for a vector layer but in the options to export my style I didn't find an XML extension. I exported the style to XLSX and converted it to XML. Then, I tried to import this with "create categorized renderer from style" and I set the input layer and the column for matching the data from the XML and set the style database (.XML-file) and ran it. However, I have been getting an error message:

Incorrect root tag in style: workbook.

How could I export an XML file to be used to "create categorized renderer from style" Plugin? I have to use this plugin for an assignment.

1 Answer 1

7

The qml file style file you get when exporting layer styles is different from the one you get in the "Style manager" when you export. The second format is the accepted one in "Create categorized renderer from style"

What is missing is a script to get "Style manager" compatible file from an existing layer style. I've made a script to make a "bridge" between both (limited as I've tested it only using Style Manager Fill symbols)

Script to bridge QML style and Style Manager XML

import xml.etree.ElementTree as ET
import copy

layer =iface.activeLayer()
outpath_layer_style = '/tmp/qml_style.qml'
out_style_manager = '/tmp/out_style_manager.xml'

# Export layer style to QML
layer.saveNamedStyle(outpath_layer_style)
# Read layer style QML
tree_qml = ET.parse(outpath_layer_style)
root_qml = tree_qml.getroot()

# Style Manager output style template
tree_template = ET.fromstring('''
<!DOCTYPE qgis_style>
<qgis_style version="2">
  <symbols>
  </symbols>
  <colorramps/>
  <textformats/>
  <labelsettings/>
  <legendpatchshapes/>
  <symbols3d/>
</qgis_style>''')

# Need to fill name in each symbol with it categories name
symbols_root = tree_template.find('symbols')
symbols = root_qml.findall('.//symbols/symbol')
categories = { category.attrib['symbol']: category.attrib['value'] for category in root_qml.findall('.//categories/category')}

# Make update to symbol name and add symbol modified to template
for symbol in symbols:
    s = copy.deepcopy(symbol)
    s.attrib['name'] = categories[symbol.attrib['name']]
    symbols_root.append(s)

with open(out_style_manager, 'w') as outfile:
    outfile.write(ET.tostring(tree_template, encoding='unicode'))

How to export from Style Manager

To get the XML style manager file you need to provide to the "Create categorized renderer from style" you can use the following recipe.

You need to go to the menu "Settings" > "Style Manager"

At the bottom of the window, you can export your selected styles to the XML (see below screenshot)

Your selected styles names should match the categories in the layer (I used "List unique values" before in the Processing Toolbox to name them)

Style Manager export window

Then, you can apply the style

Standalone use case to completely try "Create categorized renderer from style"

To test, you can set a vector layer with source /vsicurl/https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_admin_0_countries.geojson

Then, you can use the Processing Toolbox "Create categorized renderer from style" using column region_un and use the following style "un_region.xml" (download link, generated from the Style manager XML export)

See the following configuration

"Create categorized renderer from style" window

You will get the following output

Output result

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.