简体   繁体   中英

How to make svg paths clickable in leaflet and get path ID by clicking

I am new to leaflet programming, I have a .svg file and I want to make that clickable on super imposing on open street map.

I have tried making it as an overlay on an open street map by Image-overlay option but svg is not clickable.

Basically I want to get the ID of clicked svg path or element (what ever you call) in leaflet. The map is getting zoom when I clicked.

var imageUrl = 'test2.svg', 
                imageBounds = [(image bounds)]; 
L.imageOverlay(imageUrl, imageBounds).addTo(map);

Loading the SVG file

You can load your file through an imageOverlay but you won't get events on individual paths/groups/shapes, you are limited to events on the overlay.

To get events on the components of the SVG, you have to embed it into your DOM nodes, either by inlining it or by loading it and creating the required nodes. Something like this 1 :

 var url = 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg'; var req = new XMLHttpRequest(); req.onload = function(resp) { var xml = this.responseXML; var importedNode = document.importNode(xml.documentElement, true); var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.appendChild(importedNode); g.setAttribute('class', 'svglayer'); var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.appendChild(g); svg.addEventListener('click', function(e) { console.log(e.target.id) }) document.body.appendChild(svg); }; req.open("GET", url, true); req.send(); 

This snippet will load a SVG file, append it to the DOM et and setup a click event that will log the id of the target element.

Embedding SVG into a map

Armed with this knowledge, you can append the SVG node to a map pane instead of the document.body . Here's a simple example that directly modifies the overlay pane :

map.getPane('overlayPane').appendChild(svg);

An important point to note is that Leaflet disables clicking on individual path elements by setting the CSS property pointer-events to none . You have to alter this to get events on the path nodes, hence the added CSS property:

.leaflet-pane > svg .svglayer path {
    pointer-events: auto ;
}

And a demo

 var map = L.map(document.getElementById('map'),{ renderer: L.canvas() }).setView([48.8583736, 2.2922926], 15); L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }).addTo(map); var url = 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg'; var req = new XMLHttpRequest(); req.onload = function(resp) { var xml = this.responseXML; var importedNode = document.importNode(xml.documentElement, true); var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.appendChild(importedNode); g.setAttribute('class', 'svglayer'); var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.appendChild(g); svg.addEventListener('click', function(e) { console.log(e.target.id, e.target.tagName) }) map.getPane('overlayPane').appendChild(svg); }; req.open("GET", url, true); req.send(); 
 html, body {padding:0; margin:0; height: 100%} #map {height: 180px} .leaflet-pane > svg .svglayer path { pointer-events: auto ; } 
 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" crossorigin=""/> <script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js" integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log==" crossorigin=""></script> <div id='map'> </div> 

1 Image by Ghostscript authors (GPL Ghostscript SVN: tiger.eps) [GPL ( http://www.gnu.org/licenses/gpl.html)] , via Wikimedia Commons

You need to explicitly specify the interactive option on your Image Overlay:

If true , the image overlay will emit mouse events when clicked or hovered.

 var map = L.map("map").setView([48.85, 2.35], 12); var imageBounds = [ [48.8, 2.3], [48.9, 2.4] ]; var imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/9/9c/Map_of_country_subdivisions_%28states%29.svg'; var imageOverlay = L.imageOverlay(imageUrl, imageBounds, { interactive: true, attribution: '<a href="https://commons.wikimedia.org/wiki/File:Map_of_country_subdivisions_(states).svg">CC-BY-SA 4.0 Wikimedia contributor</a>' }).addTo(map); imageOverlay.on('click', function(event) { alert('clicked on SVG image'); }); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }).addTo(map); 
 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"> <script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet-src.js"></script> <div id="map" style="height: 200px"></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM