6

When I embed an SVG symbol in QGIS 3.x, the symbol is stored in the layer definition. If I have another layer and like to use the symbol again, I have to embed it a second time.

How can I embed an SVG symbol globally and use it in multiple layers?

2
  • 1
    "The symbol is stored in the layer definition" : what do you mean ?
    – Snaileater
    Sep 16, 2020 at 9:29
  • Ok, better call it symbol definition of the layer. You find it in your project .qgs file.
    – christoph
    Sep 16, 2020 at 10:19

3 Answers 3

10

Found the answer to my problem: We can store the base64 encoded SVG string in a project variable and link to this variable (i.e. 'mySymbol').

base64:PHN2ZyBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1NzkuOTk3IDU3OS45OTciIGhlaWdodD0iNTc5Ljk5NyIgdmlld0JveD0iMCAwIDU3OS45OTcgNTc5Ljk5NyIgd2lkdGg9IjU3OS45OTciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Im0yODkuOTk3IDMzLjMxbC0yMjQuNjEgNTEzLjc2NSAyMjAuNDk5LTE0My45NDYgMjI4LjYzMiAxNDMuNzM2eiIgZmlsbD0icGFyYW0oZmlsbCkiIGZpbGwtb3BhY2l0eT0icGFyYW0oZmlsbC1vcGFjaXR5KSIgc3Ryb2tlPSJwYXJhbShvdXRsaW5lKSIgc3Ryb2tlLW9wYWNpdHk9InBhcmFtKG91dGxpbmUtb3BhY2l0eSkiIHN0cm9rZS13aWR0aD0icGFyYW0ob3V0bGluZS13aWR0aCkiLz4KPC9zdmc+Cg==

enter image description here

3
  • 2
    Great idea -- a very elegant solution!
    – ndawson
    Sep 16, 2020 at 22:36
  • 2
    Unfortunately, this only works with simple symbols, because project variables are limited to a length < 6000 characters. But fortunately, we can use Expression functions as well to retrieve complex symbols (i.e. base64 encoded SVGs with base64 encoded images embedded) from somewhere else.
    – christoph
    Sep 17, 2020 at 16:25
  • 3
    A better solution: storing symbol names and base64 strings in a Geopackage table "svg" and using expression functions to select the symbols -- [ attribute( get_feature( 'svg','name','mySymbol'),'symbol') ]
    – christoph
    Sep 17, 2020 at 18:01
4

While playing around with Data URIs, I managed to store SVG images inline without base64 encoding. Only have to put 'data:image/svg+xml;utf8,' in front. Depending on the SVG content, the inline SVG data strings are much smaller without encoding.

'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve" height="100px" width="100px"><path fill="param(fill) #000000" d="M50,2.5c-19.2,0-34.8,15-34.8,33.4C15.2,61.3,50,97.5,50,97.5s34.8-36.2,34.8-61.6  C84.8,17.5,69.2,2.5,50,2.5z M50,48.2c-7.1,0-12.9-5.8-12.9-12.9c0-7.1,5.8-12.9,12.9-12.9c7.1,0,12.9,5.8,12.9,12.9  C62.9,42.4,57.1,48.2,50,48.2z"/></svg>'
1

Following @christoph's advice, the data:image format is working for me, but with the svg as xml-encoded, like this:

<prop v="data:image/svg+xml;utf8,&lt;svg enable-background=&quot;new 0 0 580 580&quot; height=&quot;580&quot; viewBox=&quot;0 0 580 580&quot; width=&quot;580&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;&lt;path d=&quot;m504.911 519.52l.713-.006-10.927-19.284-190.172-360.682 35.603-67.259-23.227-12.295-27.214 51.412-28.368-53.804-23.246 12.257 36.007 68.292c-15.495 32.074-121.491 230.255-192.826 362.816l-10.441 19.403 94.237-.156 23.41.181.115-.22 202.599-.336.291.556 91.769-.708 21.747-.036zm-214.949-233.661c21.655 72.987 67.317 167.251 87.688 207.723l-175.523.29c20.298-40.308 66.127-134.848 87.835-208.013z&quot; fill=&quot;param(fill)&quot; fill-opacity=&quot;param(fill-opacity)&quot; stroke=&quot;param(outline)&quot; stroke-opacity=&quot;param(outline-opacity)&quot; stroke-width=&quot;param(outline-width)&quot;/&gt;&lt;/svg&gt;" k="name"/>

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.