Reputation: 61
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);
Upvotes: 6
Views: 7212
Reputation: 33344
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: '© <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/[email protected]/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" crossorigin=""/>
<script src="https://unpkg.com/[email protected]/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
Upvotes: 5
Reputation: 53225
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: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script>
<div id="map" style="height: 200px"></div>
Upvotes: 3