首页 > 解决方案 > SVG 图标在 OpenLayers 中不可见,而其他 SVG 工作正常

问题描述

我在 OL6 中将 SVG 图像显示为图标时遇到问题。我在这里看到了所有类似的问题,但没有帮助。这是工作图标图像的代码:

const workingIconFeature = new ol.Feature({
  geometry: new ol.geom.Point([0, 0])
});

const workingSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="30" height="91.19" style="fill: #fff"> <g> <g> <path d="M15,0A49,49,0,0,0,0,35L.2,70H29.8L30,35A49,49,0,0,0,15,0Z"/> <rect y="71.19" width="30" height="20"/> </g> </g> </svg>`;

const workingStyle = new ol.style.Style({
  image: new ol.style.Icon({
    opacity: 1,
    src: 'data:image/svg+xml;utf8,' + workingSvg,
    scale: 0.3
  })
});

workingIconFeature.setStyle(workingStyle);

这是我无法显示的图标:

const notWorkingIconFeature = new ol.Feature({
  geometry: new ol.geom.Point([20, 20])
});

const notWorkingSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="45" height="110" viewBox="0 0 40 102">
          <defs>
              <style>
                  .a{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:2px;}.a,.b{opacity:0.7;}.b{fill:#fff;}.c{fill:#031120;}
              </style>
          </defs>
          <line class="a" x1="20" y1="12" x2="20" y2="62" />
          <circle class="b" cx="20" cy="6" r="6" />
          <circle class="c" cx="20" cy="6" r="5" />
          <circle class="b" cx="20" cy="82" r="20" />
          <circle class="c" cx="20" cy="82" r="15" />
      </svg>`;

const notWorkingStyle = new ol.style.Style({
  image: new ol.style.Icon({
    opacity: 1,
    src: 'data:image/svg+xml;utf8,' + notWorkingSvg,
    scale: 0.3
  })
});

workingIconFeature.setStyle(notWorkingStyle);

http://jsfiddle.net/8afskcL2/2/

正如你所看到的,宽度和高度属性被添加到不起作用但仍然没有效果。也许你知道什么可能是一个问题?

标签: javascriptopenlayersopenlayers-6

解决方案


您的“工作”风格也不适合我(我看到了默认样式的图标)。您需要对 svg 进行 URL 编码。您可以使用escape.

带有 SVG 图标的工作示例

const workingStyle = new ol.style.Style({
  image: new ol.style.Icon({
    opacity: 1,
    src: 'data:image/svg+xml;utf8,' + escape(workingSvg),
    scale: 0.3
  })
});
const notWorkingStyle = new ol.style.Style({
  image: new ol.style.Icon({
    opacity: 1,
    src: 'data:image/svg+xml;utf8,' + escape(notWorkingSvg),
    scale: 0.3
  })
});

概念证明小提琴

地图截图

代码片段:

const workingIconFeature = new ol.Feature({
  geometry: new ol.geom.Point([-1000, -1000])
});

const workingSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="30" height="91.19" style="fill: #0f0"> <g> <g> <path d="M15,0A49,49,0,0,0,0,35L.2,70H29.8L30,35A49,49,0,0,0,15,0Z"/> <rect y="71.19" width="30" height="20"/> </g> </g> </svg>`;

const workingStyle = new ol.style.Style({
  image: new ol.style.Icon({
    opacity: 1,
    src: 'data:image/svg+xml;utf8,' + escape(workingSvg),
    scale: 0.3
  })
});

workingIconFeature.setStyle(workingStyle);

const notWorkingIconFeature = new ol.Feature({
  geometry: new ol.geom.Point([1000, 1000])
});

const notWorkingSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="45" height="110" viewBox="0 0 40 102">
          <defs>
              <style>
                  .a{fill:none;stroke:#f00;stroke-miterlimit:10;stroke-width:2px;}.a,.b{opacity:0.7;}.b{fill:#f00;}.c{fill:#031120;}
              </style>
          </defs>
          <line class="a" x1="20" y1="12" x2="20" y2="62" />
          <circle class="b" cx="20" cy="6" r="6" />
          <circle class="c" cx="20" cy="6" r="5" />
          <circle class="b" cx="20" cy="82" r="20" />
          <circle class="c" cx="20" cy="82" r="15" />
      </svg>`;

const notWorkingStyle = new ol.style.Style({
  image: new ol.style.Icon({
    opacity: 1,
    src: 'data:image/svg+xml;utf8,' + escape(notWorkingSvg),
    scale: 0.3
  })
});

notWorkingIconFeature.setStyle(notWorkingStyle);

const vectorSource = new ol.source.Vector({
  features: [workingIconFeature, notWorkingIconFeature]
});

const vectorLayer = new ol.layer.Vector({
  source: vectorSource
});

const rasterLayer = new ol.layer.Tile({
  source: new ol.source.OSM()
});

const map = new ol.Map({
  layers: [rasterLayer, vectorLayer],
  target: document.getElementById('map'),
  view: new ol.View({
    center: [0, 0],
    zoom: 12
  })
});
html,
body {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
}

.map {
  height: 100%;
  width: 100%;
}
<html lang="en">

<head>
  <link rel="stylesheet" href="https://openlayers.org/en/v6.4.2/css/ol.css" type="text/css">
  <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.2/build/ol.js"></script>
  <title>OpenLayers example</title>
</head>

<body>
  <div id="map" class="map"></div>
</body>

</html>


推荐阅读