50

I want to create some svg symbols for QGIS using Inkscape, those symbols must have attributes as described in the question. For the last two days, I have been experimenting as instructed by Sourcepole and mimicked some symbols came bundled with qgis that have desired attributes without any success.

Finally, I experimented with the simplest form of symbol: I created an svg that contains only a circle in Inkscape and tried to modify it.

The original file (circle.svg) have this line:

<path
   sodipodi:type="arc"
   style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.01988637;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
   

I modified it into:

<path
   sodipodi:type="arc"
   style="fill:param(fill) #ffffff;fill-opacity:1;stroke:param(outline) #000000;stroke-width:param(stroke-width) 1.01988637;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"

Saved as circle_modified.svg and selected it as point symbol, but Qgis couldn't change all three parameters at the same time.

What did I do wrong or should do differently?

My system: QGIS 1.8.0 on Ubuntu 12.04 64 bit, Inkscape 0.48, Gedit 3.4.1 text editor.

0

8 Answers 8

60

To create SVG symbols with modifiable fill color, stroke color and stroke width in QGIS, you should replace the style attribute from the path element with these 3 attributes:

  • fill="param(fill) #FFF"
  • stroke="param(outline) #000"
  • stroke-width="param(outline-width) 1"

If you are using InkScape, after writing the new SVG file, edit the file and replace the entire line beggining with style:

style="fill:#00a000;fill-opacity:1;stroke:#000000;stroke-width:1;(...)"

with the following line:

fill="param(fill) #FFF" stroke="param(outline) #000" stroke-width="param(outline-width) 1"
0
10

It seems worth providing a simple answer about the basics of SVGs to go alongside the details provided here about specifics around software...

An SVG file is just a text file. The file ending will be .svg but it can be opened in a text editor the same as a file with the ending .txt

A simple svg file looks something like this:

<svg width="580" height="400" xmlns="http://www.w3.org/2000/svg">
<!-- This is a comment -->

<g id="group1">
<title>My group</title>
<rect id="rectangle1" height="29" width="27" y="50" x="57" stroke-width="1.5" stroke="#000" fill="#ff0"/>
<ellipse ry="17" rx="16" id="circle1" cy="64" cx="113.5" stroke-width="1.5" stroke="#999" fill="#aaa"/>
<path id="path1" d="m56.5,97l51.5,1l5,25l-29,-5l-27.5,-21z" stroke-width="1.5" stroke="#f00" fill="#fff"/>
</g>
</svg>

In this you can see that the colours are defined by the parameters (where the dots are replaced with characters between 0-9 or A-F):

stroke=#...
fill=#...

And the stroke width is defined by

stroke-width="..."

The following can be added, using the text editor, to replace whatever defined values you choose in the SVG... making it possible for the values to be set by QGIS. QGIS understands a value for 'param(fill)' - and the other 'param(...)' values - as these are set by QGIS itself.

Fill colour: fill="param(fill) #FFF"

Outline / line colour: stroke="param(outline) #000"

Outline / line width: stroke-width="param(outline-width) 1"

Fill opacity: fill-opacity="param(fill-opacity)"

Outline / line opacity: stroke-opacity="param(outline-opacity)"

Take note that there's nothing to stop you using the 'param(...)' values in slightly odd places - so for instance you could use the 'param(fill-opacity)' value to define a fill colour in one bit of the SVG file, but a stroke/line colour in another bit of the SVG.

In the QGIS composer or style symbol dialogue the settings for the SVG colours are fairly obvious. The fill and stroke/line opacity is set as part of the colour settings. The stroke/line width setting is obvious.

Lastly two points

First, note that while in an SVG it is valid to define the colours as a collection of attributes like so:

style="fill:none;fill-opacity:1;stroke:#000000;"

This appears not to work properly if you are including parameters as described here.

Second, when using software like Illustrator or Inkscape lots of additional attributes can be added to the SVG text by this software. If you know what you're doing and understand the basics of an SVG as above it may make life simpler if you get rid of this additional text. In particular you may find that colours are set through the definition of styles rather than item by item.

5

I've also wanted to do this since coming across Seeking SVG symbol library for QGIS, but they were all black.

I also found this page which confirms the answer: SVG SYMBOLS IN QGIS WITH MODIFIABLE COLORS

To have the possibility to change the colors of the marker, we have to add the placeholders ‘param(fill)’ for fill color, ‘param(outline)’ for outline color and ‘param(outline-width)’ for stroke width. These placeholders can optionally be followed by a default value:

<svg width="100%" height="100%">
  <rect fill="param(fill) #ff0000" stroke="param(outline) #00ff00" stroke-width="param(stroke-width) 10" width="100" height="100">
  </rect>
</svg>`
0
3

I also had the same problem but after some attempts it finally worked.

I created a simple spiral in inkscape and saved it as svg. Then I opened it in a text editor (e.g. Notepad++) and the entry "style" occured twice in my svg code. First in this chunk:

<linearGradient
   id="linearGradient6172"
   osb:paint="solid">
  <stop
     style="stop-color:#000000;stop-opacity:1;"
     offset="0"
     id="stop6174" />
</linearGradient>

And then here:

<path
   sodipodi:type="spiral"
   style="fill:none;fill-rule:nonzero;opacity:1;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:35;stroke-miterlimit:4;stroke-dasharray:none;stroke-linecap:round;stroke-linejoin:round"
   id="path4686" />

To make the code work in order to have an editable svg spiral in qgis I completely removed the first "style" entry from the first code chunk:

<linearGradient
   id="linearGradient6172"
   osb:paint="solid">
</linearGradient>

And substitute the second "style" entry in the second code chunk as follows:

<path
   sodipodi:type="spiral"
   fill="param(fill) #000" stroke="param(outline) #FFF" stroke-  width="param(outline-width) 1"
   id="path4686" />

"#000" and "#FFF" are two default colours for the fill and the outline while "1" is the default outline width if not differently specified. After saving these changes you can store the svg in the correct path, the one specified by QGis (depending on the version it can be found in Settings -> Options -> SVG paths). Finally your new svg object will appear among the other default objects and it will be editable.

2

I am going to expand on this because it took me a while to get it working. Make your symbol and save it as an Inkscape SVG and open in text editor. In the bottom code block you will see; style="fill:#00a000;fill-opacity:1;stroke:#000000;stroke-width:1;(...)" Replace this line with; fill="param(fill) #FFF" stroke="param(outline) #000" stroke-width="param(outline-width) 1" In my SVG files the style line appears for every entity or shape in the svg and replacing those lines didn't work for me; but doing it at the bottom on an Inkscape SVG worked. I tried my solution and the directions here on Optimized and Plain SVG formats but it didn't work, hope this helps. Inkscape 0.48, QGIS 2.12.0, NotePad++

2

It seems to be a problem, if we use an exact value. Every time we open the options, an individual value for color or stroke is reset to the ones in the SVG. This can be fixed by setting a value in the advanced options. My tests showed me, it would be better to use fill="param(fill)" instead of fill="param(fill) #FFF" and so on in the SVG.

Another interesting workaround: If you have an SVG with foreground and background color, you can use the stroke color as your fill background color. Notice, then you can't use a separate outline color for the whole SVG.

1

There are some great tips here and they pointed me in the right direction but none addressed my specific issue so I'll add what I figured out to the pot. Since there doesn't seem to be one right answer for every case, I'd like to first offer a suggestion for testing your results as quickly as possible.

Fast Edit Testing

  • Temporarily move all of your svg icons out of the QGIS svg folder.
  • Make a copy of the svg file you wish to work on read only so you don't overwrite it and put an editable version of it in the QGIS svg folder.
  • Open QGIS, load a point layer to work with, open the layer properties and select "SVG marker".
  • You may additionally wish to right-click on an svg file and temporarily set the default "Open with" program to Notepad so you can just double-click on them to edit them in Notepad.

With this setup you can immediately see how QGIS responds to your edits. Leave the svg file open in Notepad and the properties pane open in QGIS. To test the results of an edit, just hit Ctrl+S to save it in Notepad and switch over to QGIS. To reload the svg, change the symbol layer type to anything else, then change it back to SVG marker. There's also only one in there so you have no trouble finding it. I tested dozens of edits very quickly like this. If you have any trouble getting the svg back to source form after an edit you can just delete it and make another copy.

Making SVG Icon Editable

The problem I had was that the specific icon I was working on didn't have the words "style" or "fill" anywhere so I had trouble figuring out where to put the parameter line. The Inkscape trick described by Martina solved this problem but I have a bunch of them to do and I didn't want to open and save each in Inkscape so I decided to attempt trial and error. Looking at the code I could see that the version info and metadata was at the top and the shape instructions were at the bottom enclosed in quotation marks that were bounded at the beginning by <g><path d= (some have <g><g><path d=) and at the end by /></g></svg>. After a little experimenting I figured out that putting the parameter line between path and d= worked but the icon was invisible in the selector pane and the icon in the preview pane at the top was entirely filled in black. The invisible icon issue seems to have been a bug. I fixed it by adding an opacity parameter that I will describe below. It turned out that the black fill was just because the icon was only 4mm and it was filled by just the outline. To fix this I bumped the icon size up to 10mm (in QGIS) and bumped the outline down to 0.1 (in Notepad).

Summary

If your icon doesn't have the words "style" or "fill" anywhere, but it does have this line <g><path d= (or <g><g><path d=) right before the shape instructions you should be able to add the edit parameters by replacing the above line with <g><path fill="param(fill) #FFF" stroke="param(outline) #000" stroke-width="param(outline-width) 1" d=

If the border is too thick, you can shrink it by changing the last number to a fraction e.g. <g><path fill="param(fill) #FFF" stroke="param(outline) #000" stroke-width="param(outline-width) 0.5" d=

If you wish to make your icon semitransparent you can do so by changing the above line to this one <g><path style="opacity:0.5;fill:param(fill) #FFF" stroke="param(outline) #000" stroke-width="param(outline-width) 1" d=. The opacity value can be from 1 (fully opaque) to 0 (fully transparent) and you can use hundredths or even thousandths for additional precision (e.g. 0.01). The same rule goes for border thickness.

If you have a lot of them to edit, you can find batch files here on StackExchange to automate the search and replace process.

0

In my case none of the previous answers worked: I'm working with OCHA icons that come with a defs parameter. I had to get rid of it (in Notepad++). Example (not including path!) using the mobile clinic icon:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 30"> <defs> <style>.cls-1,.cls-2{fill:#418fde;}.cls-1{fill-rule:evenodd;}</style> </defs> <title>Asset 882</title> <g id="Layer_2" data-name="Layer 2"> <g id="Icons"> <path [...] /> </g> </g> </svg>

becomes

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 30"> <g fill="param(fill)" stroke="param(outline) #000" stroke-width="param(outline-width) 0" id="Layer_2" data-name="Layer 2"> <g id="Icons"> <path [...] /> </g> </g> </svg>

to be able to modify color, outline color and outline thickness in QGIS.

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.