Consider this code:
L.marker({lat: 30.267222, lon: -97.743056})
.addTo(mymap)
.bindPopup("hello world!")
.on('popupopen', function(e) { alert('this far'); });
When I run it the alert() runs before the popup actually appears. Is there a way to make it so that some javascript code runs after the popup appears?
I ask because I'm trying to run some javascript after the popup appears that'd do stuff to the visible elements. If the popup isn't open when the popupopen event handler runs then that javascript clearly won't work.
Any ideas?
JS Fiddle: https://jsfiddle.net/7qn2dksb/
Thanks!
What about using a short delay using setTimeout?
L.marker({
lat: 30.267222,
lon: -97.743056
})
.addTo(mymap)
.bindPopup("hello world!")
.on('popupopen', function(e) {
setTimeout(() => {
alert('this far');
}, 100)
});
<!DOCTYPE html>
<html>
<head>
<title>Quick Start - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
</head>
<body>
<div id="mapid" style="width: 100%; height: 100vh"></div>
<script>
var mymap = L.map('mapid').setView({
lat: 30.267222,
lon: -97.743056
}, 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1
}).addTo(mymap);
L.marker({
lat: 30.267222,
lon: -97.743056
})
.addTo(mymap)
.bindPopup("hello world!")
.on('popupopen', function(e) {
setTimeout(() => {
alert('this far');
}, 100)
});
</script>
</body>
</html>
Related
I am trying to display open radioactivity data from the German Agency for Protection of Radiation (https://www.imis.bfs.de/geoportal/).
They have a nice GeoJson API.
I can display the individual markers (points of radioactivity sensors), but cannot display the value feature.properties.value in a popup.
I tried onEachFeature but somehow it did not work. I searched for quite a bit, but could not find a solution
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Radioaktivität</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="map"></div>
<script src="script.js"></script>
</body>
</html>
JavaScript:
let config = {
minZoom: 2,
maxZoom: 18,
};
const zoom = 7;
const lat = 51.7036;
const lng = 10.2166;
const map = L.map("map", config).setView([lat, lng], zoom);
let url = 'https://www.imis.bfs.de/ogc/opendata/ows?service=WFS&version=1.1.0&request=GetFeature&typeName=opendata:odlinfo_odl_1h_latest&outputFormat=application/json';
const response = fetch(url)
.then(response => response.json())
.then(response => {
L.geoJson(response, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.value);
}
}).addTo(map);
});
I'm just trying to do a simple map using the Leaflet.js libraries directly instead of the python wrappers(ipyleaflet, folium) but I can't any map to display regardless of what I do. the map area is drawn the correct size with the zoom controls, as are the tile attributions, and a marker in the right location. I have tried multiple browsers and also in QWebEngineView as well as different tile sets. I've also tried both the hosted js and css scripts as well as local copies The results are the same. Everything with the same v1.7.1 release though.
Here is the html code:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="leaflet.css" />
<script src="leaflet.js"></script>
<!-- <link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
-->
<style>
#map {
width: 900px;
height: 400px;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var layer = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox/satellite-v9',
tileSize: 512,
zoomOffset: -1,
accessToken: 'your.mapbox.access.token'
});
var mymap = L.map('map', { preferCanvas: true, center: [43.08695, -73.75792], layers: [layer], zoom: 10 });
var mymarker = L.marker([43.08695, -73.75792], { draggable: true }).addTo(mymap)
</script>
</body>
</html
Here's a screenshot
Anybody got any ideas? This ought to be something really simple...
I'm trying to make the map move inside it, dragging the map to the side, so I can get around the map.
But this is only being possible onmousedown on map1, when choosing map2 the map does not move, it is not possible to drag it.
When clicking on the map1 button the map appears and it is possible to move within it, but after I click on the map2 button it is no longer possible to move within the map.
Follow the code of what is happening.
How could this be fixed?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Map</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"></script>
</head>
<body>
<div style="margin: 10px">
<button onclick="maps(['New York', 40.6971494, -74.2598757])">Map 1</button>
</div>
<div style="margin: 10px">
<button onclick="maps(['London', 51.528308, -0.3817849])">Map 2</button>
</div>
<div id="mapid" style="width: 200px; height: 200px; margin: 10px"></div>
<script>
function maps(location) {
var container = L.DomUtil.get('mapid');
if(container != null){
container._leaflet_id = null;
}
var map = L.map( 'mapid', {
center: [location[1], location[2]],
minZoom: 2,
zoom: 13
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var m = L.marker([location[1], location[2]]).addTo(map).bindPopup(location[0])
}
</script>
</body>
</html>
I found the problem, I needed to change the way the map was initialized, follow the code below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Map</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"></script>
</head>
<body>
<div style="margin: 10px">
<button onclick="maps(['New York', 40.6971494, -74.2598757])">Map 1</button>
</div>
<div style="margin: 10px">
<button onclick="maps(['London', 51.528308, -0.3817849])">Map 2</button>
</div>
<div id="mapid" style="width: 200px; height: 200px; margin: 10px"></div>
<script>
var map = null; //added
function maps(location) {
//var container = L.DomUtil.get('mapid'); //removed
//if(container != null){ //removed
// container._leaflet_id = null; //removed
//}
if (map !== undefined && map !== null) { map.remove(); }//added
map = L.map( 'mapid', { //alterated
center: [location[1], location[2]],
minZoom: 2,
zoom: 13
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var m = L.marker([location[1], location[2]]).addTo(map).bindPopup(location[0])
}
</script>
</body>
</html>
I'm using Mapbox for maps, and the access token is public where people visit the website can easily copy. Is there a way to hide this access token or limit access to only my website? It seems other people are using my access code to do Python Requests for geocodes.
<!DOCTYPE html>
<html>
<head>
<title>Quick Start - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
</head>
<body>
<div id="mapid" style="width: 600px; height: 400px;"></div>
<script>
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox.streets'
}).addTo(mymap);
L.marker([40.7127837, -74.0059413]).addTo(mymap)
.bindPopup("<b>Hello world!</b><br />I am a popup.").openPopup();
var popup = L.popup();
function onMapClick(e) {
L.marker([e.latlng.lat, e.latlng.lng]).addTo(mymap)
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
</script>
</body>
</html>
You could add URL restrictions to your access token:
https://docs.mapbox.com/help/account/tokens/#domain-restrictions
Or you could hide your token with a method like this:
https://www.quora.com/How-do-you-hide-your-API-customer-key-token-when-youre-pushing-code-to-Github
I hope that's helpful!
I am new to leaflet and mapbox. I built a map with with mapbox with my own tiled layers that I made with tilemill exported as mbtiles and extracted with mb-util. Tested from my localhost everything is fine, but when I built the map from my webserver, the layer contents are repeating on each tile when zooming the map. Below is my code. I don't understand this different behaviour and how to avoid this. Can anybody help me, please??
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Layers Control</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox.js/v1.6.2/mapbox.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox.js/v1.6.2/mapbox.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script type="text/javascript">
var map = L.map('map').setView([50.11, 8.86], 13);
map.setMaxBounds([[50.09, 8.797], [50.134, 8.889]]);
L.control.layers({
'Base Map': L.mapbox.tileLayer('examples.map-9ijuk24y', { noWrap: true }).addTo(map),
'OSM': L.tileLayer('http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png', {
attribution: '© ' + 'OpenStreetMap' + ' Contributors', noWrap: true
})
}, {
'NEG Dietesheimer Steinbrüche': L.tileLayer('tiles/leafNegGrenz/{z}/{x}/{y}.png', { maxZoom: 19, minZoom: 0, noWrap: true }).addTo(map),
'NEG Ausstattung': L.tileLayer('tiles/leafNegAus/{z}/{x}/{y}.png', { maxZoom: 19, minZoom: 0, noWrap: true })
}).addTo(map);
Something is wrong with your server, or the export you created: tiles redirect to each other. For instance, open
http://geo-information.de/tiles/leafNegGrenz/15/17190/11098.png
In a browser, and it redirects to
http://geo-information.de/tiles/leafNegGrenz/15/17190/11096.png
This is why tiles are repeating.