Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic SVG #199

Closed
3nids opened this issue Oct 19, 2020 · 5 comments
Closed

Dynamic SVG #199

3nids opened this issue Oct 19, 2020 · 5 comments

Comments

@3nids
Copy link
Member

3nids commented Oct 19, 2020

QGIS Enhancement: Dynamic SVG

Date 2020/10/10

Author Denis Rouzaud (@3nids)

Contact denis@opengis.ch

maintainer @3nids

Version QGIS 3.x

Summary

There is a common need to customize SVG images from the data.
For quite some time (about 10 years), QGIS supports the customization of fill color, stroke color and stroke width (https://blog.sourcepole.ch/2011/06/30/svg-symbols-in-qgis-with-modifiable-colors/).

We propose to extend this to allow the customization of any part of the SVGs.

This opens the door to having an unlimited number of editable colors, to draw custom paths, and even write data-defined texts.
For road signs, this means that the direction text could be dynamically written using a layer attribute.

image

Current SVG situation and issue

The current approach to customize the fill color, stroke color and stroke width is based on a proposal for SVG 2.0 dating from 2009 which actually was never integrated.
https://www.w3.org/TR/2009/WD-SVGParamPrimer-20090616/

This means that our approach is based on something unofficial.

Main drawback of this approach is that the SVG is not correctly rendered in an SVG editor, and the SVG parameters might be altered when saved.

The original proposal from 2009 has been adapted and is proposed for SVG 2.1
w3c/svgwg#128
https://tabatkins.github.io/specs/svg-params/

New approach sounds more powerful, but it is not backward compatible. It is a bit more obtrusive in the SVG code and more complex to write. Until this is officially accepted, it does not sound reasonable to integrate it in our code base.

Proposed approach

We propose to reuse the same approach, and dynamically replace any param(name) in the SVG code.

UX

A new table would be added to the SVG configuration to enter parameters as pairs of name (str) and expressions (str).

SVG Cache

QgsSvgCache::svgAsImage, cacheEntry, findExistingEntry methods need to be extended to receive an optional dictionary (string,string) of parameters.
QgsSvgCache::replaceElemParams needs to replace any param(__name__) with the corresponding value from the dictionary of parameters.
It also needs to change not only the style XML attributes (for color, width, …) but any part of the SVG code.

Performance implications

If we put apart the case of having tons of different huge SVGs for a same layer with as much parameters combination, we do not expect any performance decrease.

Further improvements

We could also introduce types of parameters to provide optimal widgets (color picker, spin box for numerical values,…)

A parsing of the given SVG could be made to automatically fill the table with the name of parameters. In case the SVG file is data-defined, the parsing could be done across the layer.

@nyalldawson
Copy link
Contributor

Nice proposal!

How would you propose the handle binding these parameters to data defined values?

@3nids
Copy link
Member Author

3nids commented Oct 19, 2020

How would you propose the handle binding these parameters to data defined values?

That's the UX part: a table where you enter the parameters and their values (can be expression). Further improvement proposes an auto fill of this table.

@andreasneumann
Copy link
Member

Unfortunately, W3C is not actively working on a parameterized SVG specification. I can ask and see if they could resuscitate the discussion ... but it will take time. Until there are any results there, I think your proposal is fine.

@cxcandid
Copy link

cxcandid commented Nov 20, 2020

@3nids Looks like creation of dynamic SVG symbols is already available, when we create inline-SVG-symbols using the expression string builder (see my example here: https://gis.stackexchange.com/questions/379437/use-text-diagram-for-labeling-in-qgis/379578#379578)
SVG caching/rendering needs to be tweaked a little bit.

@cxcandid
Copy link

cxcandid commented Dec 6, 2020

Even embedding images in SVGs is currently possible, when we base64 encode on-the-fly: https://gis.stackexchange.com/questions/380964/qgis-labels-with-html-formating/381241#381241

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants