【问题标题】:How can I use an SVG image as a map marker in OpenLayers-3?如何在 OpenLayers-3 中使用 SVG 图像作为地图标记?
【发布时间】:2015-03-19 18:33:56
【问题描述】:

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

目前,我使用 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.js 库的 OpenLayers-2 (OL2) 功能(而不是 OL3 的 ol.js图书馆)。遗憾的是,交换这些 javascript 文件失败了。


OL2(工作 - 但是 OL 库):

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


在网上搜索解决方案似乎只会让其他困惑的人寻找解决方案。

请帮忙,

免费啤酒

【问题讨论】:

  • 仅供参考,SVG 在 OpenLayers 2 中是受支持的渲染器,但在 OpenLayers 3 中不受支持。ol3 中支持的渲染器是:DOM、Canvas 和 WebGL。

标签: svg openlayers openlayers-3


【解决方案1】:

根据@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>'
  })
});

【讨论】:

  • 很棒的解决方案,比 base64 更好,因为您甚至可以轻松更改原始 SVG 内容(更改填充和描边颜色)。要缩放 SVG,可以直接通过 Icon 样式的 "scale" (0-1 = 0%-100%) 属性来实现
【解决方案2】:

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

复制 base 64 并将其用作 javascript 中的字符串。

例如:var svg = "convertedBase64";

然后

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

你已经完成了,可能比 SVG 多几个 Kbs,但这对我来说确实很完美。

【讨论】:

    【解决方案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

    【讨论】:

    • 这是否意味着本地文件系统 OL3 地图不能使用 SVG 图标?我当然不能让它工作。
    【解决方案4】:

    我遇到了同样的问题,但使用正确的 mime 类型提供图像也没有帮助。

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

    我在&lt;svg&gt; 标签中添加了widthheight 属性,例如:

    <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。

    【讨论】:

    • 这对我有用,只要我记得在宽度和高度值中添加“px”。花了一个小时调试...
    【解决方案5】:

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

    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>';
    

    【讨论】:

      【解决方案6】:

      基于 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);
      });
      

      这有点冗长,但似乎可以完成这项工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-15
        • 2018-06-28
        相关资源
        最近更新 更多