6

I have an OpenLayers3 map on my local filesystem, and I want a point layer to use SVG icons. This seems to fail silently:

var style = new ol.style.Style({
    image: new ol.style.Icon({
        size: [95, 95],
        src: "styles/transport_aerodrome.svg"
    })
});

Is this because the SVG, since it is a local file, does not have content-type, but OL3 needs SVGs to have content-type: image/svg+xml? Or is there another reason this fails, and a way to fix it?

8

I am not sure whether this is a file location problem or if it is a problem of the svg you use. As long as it is within the root folder of your app I can not see why is not working. Dont you have any firebug errors? try to use the following snip to check if it is working. I have tried it works fine.

var style = new ol.style.Style({
    image: new ol.style.Icon({
        src: 'http://www.williambuck.com/portals/0/Skins/WilliamBuck2014/images/location-icon.svg'
    })
});

Also consider removing the size you provide within your code snip. So call it like that

var style = new ol.style.Style({
image: new ol.style.Icon({
    src: "styles/transport_aerodrome.svg"
})
});

UPDATE if you can get the xml out of your svg file. try the following:

var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">'+    
'<path fill="#156BB1" d="M22.906,10.438c0,4.367-6.281,14.312-7.906,17.031c-1.719-2.75-7.906-12.665-7.906-17.031S10.634,2.531,15,2.531S22.906,6.071,22.906,10.438z"/>'+
'<circle fill="#FFFFFF" cx="15" cy="10.677" r="3.291"/></svg>';

var mysvg = new Image();
mysvg.src = 'data:image/svg+xml,' + encodeURIComponent(svg);

//and then declare your style with img and imgSize
var style = new ol.style.Style({
image: new ol.style.Icon({
    img: mysvg,
    imgSize:[30,30]
})
});
9
  • I've tried without the size, with no change. And your first example doesn't help me because the SVG is not a local file. Try to put together a minimal example and browse to it as a local file. That's what seems to be the problem for me. Nov 28 '15 at 20:56
  • I have updated with one more option working locally for me. If you need it just for testing is fine but on production deployed apps you should have no problem getting it from url.
    – pavlos
    Nov 29 '15 at 0:10
  • I'd seen mention of writing out the inline XML. Not keen, but if it's the only way possible, I'll have to consider it. I'd still like authoritative confirmation of what causes this issue, though. Nov 30 '15 at 12:22
  • Maybe this is not an ol problem. Did you try to use the svg file to dispaly for example as a background image of your html page. If it works then it is an ol3 problem .If not you know the way to find out the reason. On the other hand having a local file on the file system is not the proper way to run an app, so this case would not cause you problems on a deployed app
    – pavlos
    Nov 30 '15 at 12:35
  • 2
    Just wanted to say, I used the above code today and it still works great. More proper to use encodeURIComponent() than escape() though. Apr 28 '20 at 11:01
3

It works if you just put in the svg in the src element ol.style.Icon, but if you scale it, the svg will become unsharp. In my case I use the same svg for multiple Zoom Levels and wanted a different size each zoom Level.

The way i got the scaling problem work is:

function getVectorImage(src, size) {
    var canvas = document.createElement('canvas');
    canvas.setAttribute("width", size);
    canvas.setAttribute("height", size);
    var ctx = canvas.getContext("2d");
    var img = new Image();
    img.onload = function() {
        ctx.drawImage(img, 0, 0, size, size);
    }
    img.src = src;
    return canvas;
}

//example: size = 25  and  imgSrc = "test.svg"
function getWfsStyle(size, imgSrc) {
    var img = getVectorImage(imgSrc, size);
    var style = new ol.style.Style({
        image : new ol.style.Icon({
            img : img,
            imgSize : [size, size]
        }),
        zIndex : 4
    });
    return style;
}
1

It turns out that SVGs in IE11 need the value imgSize setting to the SVG's native dimensions. That seems to have been the problem. However, it seems not to work with size, so I now need to find out how I can resize them client-side.

0

One thing that was missing for me was the width="Xpx" height="Ypx" attributes in the svg.

3
  • 2
    Pls explain how to set this attributes...
    – wittich
    Jun 21 '16 at 18:39
  • @wittich you can use anchor attributes for that and specify where the icon should appear and also it's size Jun 28 '16 at 13:14
  • as legenwsait said, my svg was missing the width="Xpx" height="Ypx" attributes. when added it works finally
    – Victor V
    Mar 30 '17 at 17:47

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.