xyz
xyz copied to clipboard
SVG templates for icons
In order to not create multiple pins for each and every colour required we have introduced SVG templates.
https://codepen.io/dbauszus-glx/pen/NWwPJOx
The svg_symbols template util assigns feature properties to parameters defined in the icon's style configuration.
export function template(icon, feature) {
const params = Object.assign({}, icon.params, feature.getProperties())
let template = icon.template
for (const entry of Object.entries(params)) {
template = template.replaceAll(entry[0], entry[1]);
}
return `data:image/svg+xml,${encodeURIComponent(template)}`
}
With the style icon configured like so:
"icon": {
"type": "template",
"template": "<svg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path fill='#f00' d='M 10 1.238 C 5.51 1.238 2.144 4.83 2.144 9.32 C 2.144 10.667 2.593 12.463 3.716 14.483 C 5.961 18.3 10 23.238 10 23.238 C 10 23.238 14.491 18.3 16.736 14.483 C 17.859 12.463 18.1 11.116 18.1 9.32 C 18.1 4.83 14.49 1.238 10 1.238 Z'/><circle cx='10.226' cy='8.871' r='5.612' fill='#fffa'/><circle cx='10.226' cy='8.871' r='2.806' fill='#baa'/></svg>",
"src": "https://geolytix.github.io/MapIcons/f00baa_pin.svg",
"params": {
"f00": "blue"
},
"scale": 2,
"anchor": [0.5, 1]
}
To allow for optional properties it is recommend to use real values as properties to be substituted. It should be possible to render the SVG without any property being substituted.
It should also be possible to fetch an icon template string from a src url. However, vectortile layer features do not have a setStyle function and Openlayers layer style function cannot be async, hence it is not possibke to fetch a ressource prior to substituting properties in the template string.
A plugin could be written to fetch all svg defined as src in any of the layer styles in a locale.
SVG templates should be cached for a locale.