Relative path to the plugin folder for SVG file in QGIS3 .SLD file

When you use relative path in SLD file, that path is relative to the current working directory (CWD), not relative to SLD file. If you change CWD into your plugin folder, relative path in SLD file works.

Sample plugin folder structure:

enter image description here

SLD File:

<se:OnlineResource xlink:href="./SVG/FILENAME.SVG" xlink:type="simple"/>

In your plugin file plugin_main.py, add below codes to related lines:

import os
.
os.chdir(os.path.dirname(__file__))
.
layer.loadSldStyle("./Styles.sld")
layer.triggerRepaint()

But If you change CWD into another folder later, you get '?' again.

In my QGIS Python console, os.getcwd() returns 'C:\\OSGEO4~1\\bin' and in this case QGIS searchs a file with relative path within that folder.


Well the solution was to add the folder to the SVG paths

Option to add the svg folder in QGIS

And then use .qml files to store the layer in instead of .sld files and in the .qml file specify the path relative to plugin_folder.

prop v="SVG_folder/SVG_name.svg" k="name"/>

I tried to make it relative to ..QGIS3\profiles\default/svg/ which is added by default, with ../python/plugins/plugin_name/image_folder/svg_name.svg in the .qml file. Which worked locally, hence in the .qgs was the absolute path stored..


In QGIS2.18 I could specify the path to the svg marker as: :/PLUGIN_NAME/IMAGE_FOLDER/FILENAME.svg

Paths that start with :/ (and qrc:///) are paths to Qt resources. I assume there is a .qrc file which has been compiled/packaged to a resources.py file. The file from QGIS 2 is not compatible with QGIS 3 and you need to recreate the file to be able to continue to use resources (and therefore also paths that start with :/)

Alternatively you can also specify the full path to the svg file (as you post yourself as an answer).

This can also be automated, the following snippet can be used to determine the plugin path:

import os 
plugin_path = os.path.dirname(os.path.realpath(__file__)) # Potentially fix subdirectories

Then check if this path is already configured and add it if missing

svg_paths = QgsSettings().value('svg/searchPathsForSVG')
if plugin_path not in svg_paths:
    QgsSettings().setValue('svg/searchPathsForSVG', svg_paths + [plugin_path])