Значок SVG не отображается в OpenLayers, в то время как другой SVG работает правильно - PullRequest
0 голосов
/ 03 августа 2020

У меня проблема с отображением изображения SVG в виде значка в OL6. Я видел здесь все похожие проблемы, но это не помогло. Вот код рабочего изображения значка:

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/

Как видите, атрибуты ширины и высоты были добавлены как не работающие, но все еще безрезультатно. Может быть, вы знаете, в чем может быть проблема?

1 Ответ

1 голос
/ 03 августа 2020

Ваш "рабочий" стиль у меня тоже не работает (я вижу значок стиля по умолчанию). Вам нужно URL-адрес кодировать файл svg. Вы можете использовать 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
  })
});

доказательство концепции скрипта

image

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>

...