How can I use a SVG image as layer on OpenLayers-3
Asked Answered
H

3

20

How can I use a SVG image as a Layer (so not as a map marker) with OpenLayers-3

I was unable to get any output of my SVG image when using any of the ol.source.Vector and ol.format.Feature instances.

Small example:

var mapLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
        url: 'image.svg',
        format: new ol.format.Feature() // http://openlayers.org/en/v3.12.1/apidoc/ol.format.Feature.html
    }),
}); 

I was able to get output when using the ImageStatic layer, but this uses/generates(?) a static image so the advantages of SVG are gone.

Example:

// Not sure if I need this for SVG, but is is required for an image
var extent = [0, 0, 1000, 1000]; // random image size
var projection = new ol.proj.Projection({
    code: 'test',
    units: 'pixels',
    extent: extent
});

var mapLayer = new ol.layer.Image({
    source: new ol.source.ImageStatic({
        url: 'image.svg',
        projection: projection,
        imageExtent: extent
    })
});

I already tried the trick with setting the Content-type: to image/svg+xml but this did not help me at all.

So, again: How can I (if possible) use a SVG image a a layer with OpenLayers-3?

Hounding answered 22/12, 2015 at 12:55 Comment(5)
I'm curious, how would you want to use the advantages of SVG, other than as a static image?Curet
Well, to my ideas (and please correct me if I'm wrong) I should be able to add a "zoomable" SVG layer so even when you zoom in the image won't get pixelated and stays sharp. We tend to use it for floorplans so SVG (or perhaps an other vector format) would be great. A static image is still possible of course but this will always get blurry when you zoom in.Hounding
Still getting up-to-speed with OL3 myself, and have been wondering about SVG. I also need CAD-like vector drawing over base layers, and from comments I've read maybe SVG is not supported yet? But you can definitely use Point, LineString and Polygon types to make a zoomable layer. I'm going to try ogr2ogr to translate DXF to GeoJSON.Curet
Yes, that is my question. I don't know if it is supported (I don't see any info about it on the website so my guess is no). It's just that SVG it such a commonly used format I thought I'm just missing something. Perhaps I'll need to ask this question on the GitHub page as it does not seem to be answered here. And thx for your link I'll look into that as well.Hounding
Oh and btw I noticed that SVG icons are possible so perhaps we can just use a giant icon :) #29152905Hounding
C
14

You can not use the ol.source.Vector with svg files, but OL3 can display svg files as images.

The image stays sharp when zoomed.

I modified the official static image example, and replaced the png file with a svg file. See the runnable example below.

var extent = [0, 0, 512, 512];
var projection = new ol.proj.Projection({
  code: 'static-image',
  units: 'pixels',
  extent: extent
});

var map = new ol.Map({
  layers: [
    new ol.layer.Image({
      source: new ol.source.ImageStatic({
        url: 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg',
        projection: projection,
        imageExtent: extent
      })
    })
  ],
  target: 'map',
  view: new ol.View({
    projection: projection,
    center: ol.extent.getCenter(extent),
    zoom: 0
  })
});
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div>
Collett answered 23/3, 2016 at 16:33 Comment(1)
Thanks for this answer. Do you know how to apply styles from the SVG itself (style attribute) and also let's say onmousehover events? e.g. <svg style="..." onmouseover="..."></svg>Echelon
B
10

Nowadays, 2018, a example for Open Layers 4:

var svgComment = '<svg width="160" height="160" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" viewPort="0 0 160 160" class="svgClass">'
    + '<circle cx="30" cy="30" r="10" stroke="rgb(0, 191, 255)" stroke-width="1" fill="none" opacity="0.8">'
    + '<animate attributeType="CSS" attributeName="stroke-width" from="1" to="30" dur="0.5s" begin="0s" repeatCount="indefinite" />'
    + '<animate attributeType="CSS" attributeName="opacity" from="0.8" to="0.2" dur="0.5s" begin="0s" repeatCount="indefinite" />'
    + '</circle>'
    + '<circle cx="30" cy="30" r="10" fill="rgba(0,0,0,0.8)">'
    + '</circle>'
    + '</svg>';


//Test SVG
//var img = document.createElement('img');
//img.src=src;
//document.body.append(img);

 var commentStyle =  new ol.style.Style({
    image: new ol.style.Icon({
      src: 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgComment)
    })
  });

var vectorSource = new ol.source.Vector({
  features: [
      new ol.Feature({
        geometry: new ol.geom.Point([0, 0])
      }) 
  ]
});

var vectorLayer = new ol.layer.Vector({
  name: 'Comments',
  style: commentStyle,
  source: vectorSource
});

//display the map
var rasterLayer = new ol.layer.Tile({
  source: new ol.source.TileJSON({
    url: 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json?secure',
    crossOrigin: ''
  })
});

var map = new ol.Map({
  layers: [rasterLayer, vectorLayer],
  target: document.getElementById('map'),
  view: new ol.View({
    center: [0, 0],
    zoom: 3
  })
});
<script src="https://openlayers.org/en/v4.6.4/build/ol.js"></script>
<div id="map" class="map"></div>

see original post:

https://mcmap.net/q/663496/-how-can-i-use-a-svg-image-as-layer-on-openlayers-4

Benzoate answered 12/1, 2018 at 21:26 Comment(0)
C
4

@Alvin Lindstam's answers is almost there but doesn't show the full image on Chrome (or any on IE). Because the SVG doesn't have a fixed size the width and height need to be set in an imageLoadFunction

var extent = [0, 0, 512, 512];
var projection = new ol.proj.Projection({
  code: 'static-image',
  units: 'pixels',
  extent: extent
});

var map = new ol.Map({
  layers: [
    new ol.layer.Image({
      source: new ol.source.ImageStatic({
        url: 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg',
        projection: projection,
        imageExtent: extent,
        imageLoadFunction: function (image, src) {
           image.getImage().src = src;
           image.getImage().width = ol.extent.getWidth(extent);
           image.getImage().height = ol.extent.getHeight(extent);
        }
      })
    })
  ],
  target: 'map',
  view: new ol.View({
    projection: projection,
    center: ol.extent.getCenter(extent),
    zoom: 0
  })
});
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div>
Collbaith answered 29/5, 2019 at 16:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.