如何在OpenLayers-3中将SVG图像用作地图标记?

时间:2015-03-19 18:33:57

标签: svg openlayers openlayers-3

我正在尝试创建地图" pin-drops" (即使用SVG图像在OpenLayers-3(OL3)中绘制地图标记。

目前,我正在使用PNG图像作为引用ol.style.Icon源(“src”)属性属性的pindrops。但是,这使用SVG图像失败。有没有其他方式以相同的方式使用SVG?也许通过使用ol.style.Icon之外的参考甚至? Open Layers中已经有很多内置的SVG,所以这个应该是可能的,但我还没有找到一种方法让它在OL3中运行。在OL3中还有其他一些方法可以考虑这个吗?

请注意:我们已尝试使用ol.Vector图层,但是当用户放大/缩小时,SVG图像的大小会增大/缩小,这是一种不适当的解决方法。


OL3(失败):

var createMapMarkerImage = function() {
    return function(feature, resolution) {
        var iconStyle = new ol.style.Style({
            image: new ol.style.Icon( ({
                src: 'img/map_pindrop.svg'   // OL3 doesn’t like this, but accepts a .PNG just fine
            }))
        });
        return [iconStyle];
    };
};

非常相似的功能,是我在网上找到的以下示例,如果不是因为该示例使用OpenLayers-2(OL2)功能调用openlayers.js库(而不是OL3的ol.js),这几乎是完美的。图书馆)。遗憾的是,交换这些javascript文件失败了。


OL2(有效 - 但是 OL库):

http://dev.openlayers.org/sandbox/camptocamp/tipi/examples/vector-symbols.html


在线搜索解决方案似乎只会产生其他困惑的人在寻找解决方案。

请帮忙,

FreeBeer

6 个答案:

答案 0 :(得分:9)

基于@ahocevar答案,您可以使用SVG的数据URI:

new ol.style.Style({
  image: new ol.style.Icon({
    anchor: [0, 0],
    src: 'data:image/svg+xml;utf8,<svg>/* SVG DATA */</svg>'
  })
});

答案 1 :(得分:3)

只要SVG图像文件的内容类型为image/svg+xml,SVG图标就可以正常工作。另请注意,SVG内部不支持外部引用。 OpenLayers 3只使用2d上下文的drawImage函数。您可以在此处找到有关SVG内容要求的更多详细信息:https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas

答案 2 :(得分:3)

将SVG转换为Base 64。这(Link)帮助了我。

复制了基础64并将其用作javascript中的字符串。

例如:var svg = "convertedBase64";

然后

var icon = new ol.style.Icon({
        src:'data:image/svg+xml;base64,'+svg ,
        other props
});

你已经完成了,可能比SVG多了几个Kbs,但这确实对我有用。

答案 3 :(得分:2)

我遇到了同样的问题,但是甚至没有提供适当的mime类型的图像。

归结为SVG没有正确定义宽度和高度。

我将widthheight属性添加到<svg>标记中,例如:

<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0.75 0 30 45" xml:space="preserve">

之后我就能像其他任何图像一样使用我的svg。

答案 4 :(得分:1)

我也有问题显示图标图像,ahocevar回答帮我 解决我的问题,但我还要为SVG搜索php标题 如果您或其他人看到此答案使用php生成SVG,您必须使用标头功能来识别内容类型

header('Content-type: image/svg+xml'); /* this line will do the magic */
echo '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
</svg>';

答案 5 :(得分:0)

在SoonDead的回答基础上,我必须想出一种方法来增加svg的宽度和高度,而不会接触到源。使用角度,这就是我所做的:

$http.get('path/to/image.svg').then(function (response) {
  // create element
  var svgEl = angular.element(response.data);

  // set width and height
  svgEl.attr('width', '50px');
  svgEl.attr('height', '50px');

  // base64 encode
  var base64Svg = btoa(unescape(encodeURIComponent(svgEl[0].outerHTML)));

  // create the style
  var style = new ol.style.Style({
    image: new ol.style.Icon({
      src: 'data:image/svg+xml;base64,'+base64Svg,
      imgSize: [50, 50],
      size: [50, 50],
    })
  });

 // apply the style
 feature.setStyle(style);
});

它有点冗长,但似乎可以胜任。