Skip to main content

Automatic Web Symbology

The three flavours of the Riverscapes viewer each require symbology files in different formats (see the table below). Generating all three by hand is a lot of work! In September 2026 we introduced a new system that automatically converts QGIS .qml symbology files into the JSON format used by the Riverscapes Viewer for the web. This page explains how that automation works so you know what to expect when you add or change QML files.

Riverscapes ViewerSymbology File Type
Riverscapes Viewer for QGIS*.qml files
Riverscapes Viewer for ArcGIS Pro*.lyrx files
Riverscapes Viewer for the WebJSON files

This saves symbology authors time: you focus on QGIS and let the automation produce a first pass at the web symbology. You should review each automatically generated web symbology, and you can always override it — either by editing what the automation produced or by uploading your own.

Note that ArcPro symbology regrettably uses the proprietary *.lyrx format and must always be generated by hand.

Directory Layout

The table below illustrates where you put your QGIS QML files and then where the automation outputs the web symbology JSON files.

DirectoryContentsWho writes it
Symbology/qgis/<Context>/Your .qml files, organized by program/context (e.g. BRAT/, Anthro/, Hydro/)You (humans)
Symbology/web/<Context>/Generated .json files, one per QML, mirroring the QGIS folder structureThe GitHub Action (bot)

For example, a file named Symbology/qgis/BRAT/barrier_density.qml produces Symbology/web/BRAT/barrier_density.json. The generated JSON is also served publicly, so the viewer and external consumers read it from URLs like:

https://xml.riverscapes.xyz/Symbology/web/BRAT/barrier_density.json

When It Runs

The GitHub Action (.github/workflows/symbology_sync.yml) runs on every push to master that changes anything under Symbology/qgis/**. Importantly, the automation only creates missing web symbology JSON files — it never updates existing ones.

What the Automation Supports

The automation handles the common QGIS style features:

  • Renderer types: graduated, single symbol, categorized, and rule-based renderers
  • Geometry types: points/circles, lines, and fills (polygons)
  • QML dialects: both <Option>-style (QGIS 2) and <prop>-style (QGIS 3) attributes
  • Colours: solid and translucent (alpha) colours, converted to rgb()/rgba()/hsla() strings
  • Labels: range labels (e.g. "1 - 2", "> 10") and category labels end up in the JSON legend so the viewer can render a legend automatically

The output JSON contains a $schema reference plus a legend (list of [colour, label] pairs) and layerStyles (renderer paint/line/circle settings).

What is Not Created or Updated

The automation only creates missing JSON files. It never overwrites or regenerates existing ones (see Updating Existing Symbology for the workaround).

Specifically:

  • Existing JSON files are left untouched. If you edit a QML whose JSON already exists, the action skips it and reports it as "skipped".
  • Raster symbology is not produced. .qml files with a raster renderer are skipped (raster symbology is handled outside this converter).
  1. Put your .qml file in the folder that matches your program, e.g. Symbology/qgis/MyProject/.
    • The folder name becomes part of the output path and the URL, so choose it carefully.
    • Each .qml file gets its own JSON; a single QML containing several layers is also fine — the converter maps them into the JSON layerStyles.
  2. Commit and push to master. The push must include changes under Symbology/qgis/ for the action to run.
  3. Within a couple of minutes the action finishes and adds the new JSON to Symbology/web/ in a follow-up commit from the automation bot.
  4. Reference the JSON in the viewer, e.g. https://xml.riverscapes.xyz/Symbology/web/MyProject/my_style.json.

Updating Existing Symbology

Because the action never overwrites existing JSON, updating a style requires one extra step compared to adding new symbology:

  1. Edit or replace the .qml file in Symbology/qgis/.
  2. Delete the corresponding .json in Symbology/web/.
  3. Commit both the QML change and the JSON deletion together, then push to master. (Deleting only the JSON won't trigger the action — the trigger watches Symbology/qgis/, not Symbology/web/.)
  4. The action detects the missing JSON and regenerates it from your updated QML.

Alternatively, regenerate locally and push the result yourself:

cd python
uv run python QML2WebSymbology.py --dir MyProject --force