Search code examples
javascriptangulartypescriptopenlayers

OpenLayers for SVG Images


For my webpage I want an image that I can navigate with drag-Events and scroll-Events similar to Google-Maps. Instead of implementing it myself, I tried to achieve this with OpenLayers, where I want to use this image instead of a map. I've read about the other examples in stackoverflow, but I am still struggling to understand how to pass the image as first layer. Currently I try to do the following:

testOL(content: string) {
// content is the svg as string
this.map = new Map({
  target: 'imageArea',
  layers: [
    new Image({
      source: new ImageStatic({
        src: content,
      })
    })
  ] ,view : new View({
    center: [0,0],
    zoom: 1
  }) 
})
}

The target is simply a div without any content.

I've already tried it by passing an url to a svg as source of the image and I already tried to add a Projection and a view in the map, which all did not work. I would be happy, if anybody could help me with the issue


Solution

  • src is not the correct option name, it should be url, and its value should be a data url. ImageStatic also requires the imageExtent to be specified in projection coordinates.

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8"/>
        <link rel="stylesheet" href="https://openlayers.org/en/v6.4.3/css/ol.css" type="text/css">
        <script src="https://openlayers.org/en/v6.4.3/build/ol.js"></script>
        <style>
          html, body, .map {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
          }
        </style>
    </head>
    <body>
    <div id="imageArea" class="map"></div> 
    <script>
    
    const content =
    '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
    '<svg' +
    '   xmlns:dc="http://purl.org/dc/elements/1.1/"' +
    '   xmlns:cc="http://creativecommons.org/ns#"' +
    '   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"' +
    '   xmlns:svg="http://www.w3.org/2000/svg"' +
    '   xmlns="http://www.w3.org/2000/svg"' +
    '   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"' +
    '   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"' +
    '   width="20"' +
    '   height="20"' +
    '   version="1.1"' +
    '   id="svg6"' +
    '   sodipodi:docname="dot.svg"' +
    '   inkscape:version="0.92.3 (2405546, 2018-03-11)">' +
    '  <metadata' +
    '     id="metadata12">' +
    '    <rdf:RDF>' +
    '      <cc:Work' +
    '         rdf:about="">' +
    '        <dc:format>image/svg+xml</dc:format>' +
    '        <dc:type' +
    '           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />' +
    '        <dc:title></dc:title>' +
    '      </cc:Work>' +
    '    </rdf:RDF>' +
    '  </metadata>' +
    '  <defs' +
    '     id="defs10" />' +
    '  <sodipodi:namedview' +
    '     pagecolor="#ffffff"' +
    '     bordercolor="#666666"' +
    '     borderopacity="1"' +
    '     objecttolerance="10"' +
    '     gridtolerance="10"' +
    '     guidetolerance="10"' +
    '     inkscape:pageopacity="0"' +
    '     inkscape:pageshadow="2"' +
    '     inkscape:window-width="1533"' +
    '     inkscape:window-height="845"' +
    '     id="namedview8"' +
    '     showgrid="false"' +
    '     inkscape:zoom="11.8"' +
    '     inkscape:cx="-35.042373"' +
    '     inkscape:cy="11.5"' +
    '     inkscape:window-x="67"' +
    '     inkscape:window-y="102"' +
    '     inkscape:window-maximized="1"' +
    '     inkscape:current-layer="g4"' +
    '     fit-margin-top="0"' +
    '     fit-margin-left="0"' +
    '     fit-margin-right="0"' +
    '     fit-margin-bottom="0" />' +
    
    '  <g' +
    '     id="g4"' +
    '     transform="translate(1.5,-1.5)">' +
    '    <circle' +
    '       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"' +
    '       id="path822"' +
    '       cx="8.5"' +
    '       cy="11.5"' +
    '       r="8.5"' +
    '       inkscape:export-xdpi="400"' +
    '       inkscape:export-ydpi="400" />' +
    '  </g>' +
    '</svg>'
    
    const map = new ol.Map({
      target: 'imageArea',
      layers: [
        new ol.layer.Image({
          source: new ol.source.ImageStatic({
            url: 'data:image/svg+xml,' + encodeURIComponent(content),
            imageExtent: [0, 0, 5e6, 5e6],
          })
        })
      ] ,view : new ol.View({
        center: [0, 0],
        zoom: 1,
      }) 
    });
    
       </script>
    </body>
    </html>