Add a custom html to leaflet map - leaflet

I have a html template. I want to add on map the template to left position. Firstly I added map containter. Here the problem is when zoom is changed the custom template is disappearing. How can I use different way?
HTML
<div id="map" class="active"></div>
<ul>
<li><button onclick="fullSc();"><span>Full sc</span></button></li>
<li><button onclick="findMe();"><span>Find</span></button></li>
</ul>
JS
var map = L.map('map', {
zoomControl: true,
maxZoom: 18,
minZoom: 0
}).setView([41.00650212603, 28.8530806151128], 13);
L.tileLayer('https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
}).addTo(map);
var marker = L.marker(map.getCenter(), {
draggable: true,
icon: L.icon({
iconUrl: '/assets/img/pin-4ldpi.png',
iconSize: [30, 35],
iconAnchor: [30 / 2, 35],
})
}).addTo(map);

Related

changing the color of polylines and marker icon's when the layer changes?

Let's say I'm a purple polyline and am using a purple icon for markers with one layer but wanted to use orange polylines and orange marker icon's for another layer. How would I do that? Is there an onlayerchange event? But even if there were how could I change all the icon's for all the markers? Alternatively, maybe I could delete all the markers and then replace them, albeit with a different icon, but idk how to delete markers, en masse or otherwise.
Any ideas?
I am not sure if I understood correctly but here is what you can do.
If you want to toggle between markers with polylines and assign different color you can use this plugin and return icon markers by passing the color.
const icon = (color) => L.icon({
iconSize: [25, 41],
iconAnchor: [10, 41],
popupAnchor: [2, -40],
iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-${color}.png`,
shadowUrl: "https://unpkg.com/leaflet#1.6/dist/images/marker-shadow.png"
});
and then you have the latlngs and assing to the markers an icon with the prefered color
var places1 = [
{ latlng: [39.61, -105.02], popup: 'This is Littleton, CO.'},
{ latlng: [39.74, -104.99], popup: 'This is Denver, CO.'},
{latlng: [39.73, -104.8], popup: 'This is Aurora, CO.'}
];
places1.forEach(place => L.marker(place.latlng, {
icon: icon('violet')
}).bindPopup(place.popup).addTo(cities1))
and here define the polyline color
L.polyline(places1.map(({latlng}) => latlng), {
color: 'purple'
}).addTo(cities1);
Similarly you can follow the same steps for any other overlay
<!DOCTYPE html>
<html>
<head>
<title>Layers Control Tutorial - 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>
<style>
html,
body {
height: 100%;
margin: 0;
}
#map {
width: 600px;
height: 400px;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
var cities1 = L.layerGroup();
var cities2 = L.layerGroup();
var map = L.map('map', {
center: [39.73, -104.99],
zoom: 10,
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
const icon = (color) => L.icon({
iconSize: [25, 41],
iconAnchor: [10, 41],
popupAnchor: [2, -40],
iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-${color}.png`,
shadowUrl: "https://unpkg.com/leaflet#1.6/dist/images/marker-shadow.png"
});
var places1 = [{
latlng: [39.61, -105.02],
popup: 'This is Littleton, CO.'
},
{
latlng: [39.74, -104.99],
popup: 'This is Denver, CO.'
},
{
latlng: [39.73, -104.8],
popup: 'This is Aurora, CO.'
}
];
places1.forEach(place => L.marker(place.latlng, {
icon: icon('violet')
}).bindPopup(place.popup).addTo(cities1))
var places2 = [{
latlng: [39.77, -105.23],
popup: 'This is Golden, CO.'
},
{
latlng: [39.75, -105.16],
popup: 'This is Applewood, CO.'
}
];
places2.forEach(place => L.marker(place.latlng, {
icon: icon('orange')
}).bindPopup(place.popup).addTo(cities2))
L.polyline(places1.map(({
latlng
}) => latlng), {
color: 'purple'
}).addTo(cities1);
L.polyline(places2.map(({
latlng
}) => latlng), {
color: 'orange'
}).addTo(cities2);
var overlays = {
"cities1": cities1.addTo(map),
"cities2": cities2
};
L.control.layers(null, overlays).addTo(map);
</script>
</body>
</html>
For the scenario you want to change the color upon baselayer change:
you can still reuse icon() function and use now the follow chunk to change the color dynamically when the layer is changed by listening to map's baselayerchange event
function addMarkersAndPolyline(color) {
places.forEach(place => L.marker(place.latlng, {
icon: icon(color)
}).bindPopup(place.popup).addTo(cities))
L.polyline(places.map(({
latlng
}) => latlng), {
color
}).addTo(cities);
}
<!DOCTYPE html>
<html>
<head>
<title>Layers Control Tutorial - 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>
<style>
html,
body {
height: 100%;
margin: 0;
}
#map {
width: 600px;
height: 400px;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
var cities = L.layerGroup();
var map = L.map('map', {
center: [39.73, -104.99],
zoom: 10,
});
var mbAttr = 'Map data © OpenStreetMap contributors, ' +
'Imagery © Mapbox',
mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var grayscale = L.tileLayer(mbUrl, {
id: 'mapbox/light-v9',
tileSize: 512,
zoomOffset: -1,
attribution: mbAttr
}),
streets = L.tileLayer(mbUrl, {
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
attribution: mbAttr
});
var baseLayers = {
"Grayscale": grayscale.addTo(map),
"Streets": streets
};
const icon = (color) => L.icon({
iconSize: [25, 41],
iconAnchor: [10, 41],
popupAnchor: [2, -40],
iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-${color}.png`,
shadowUrl: "https://unpkg.com/leaflet#1.6/dist/images/marker-shadow.png"
});
var places = [{
latlng: [39.61, -105.02],
popup: 'This is Littleton, CO.'
},
{
latlng: [39.74, -104.99],
popup: 'This is Denver, CO.'
},
{
latlng: [39.73, -104.8],
popup: 'This is Aurora, CO.'
}
];
function addMarkersAndPolyline(color) {
places.forEach(place => L.marker(place.latlng, {
icon: icon(color)
}).bindPopup(place.popup).addTo(cities))
L.polyline(places.map(({
latlng
}) => latlng), {
color
}).addTo(cities);
}
addMarkersAndPolyline('violet')
map.on('baselayerchange', function(e) {
cities.clearLayers();
if (e.name === 'Streets') {
addMarkersAndPolyline('orange');
return
}
addMarkersAndPolyline('violet');
});
var overlays = {
"cities1": cities.addTo(map),
};
L.control.layers(baseLayers, overlays).addTo(map);
</script>
</body>
</html>

Shift between WMS Tiles in Leaflet

I use Leaflet to show a WMS Layer via a proxy.php (for authentication). That is working on most WMS Layers. But I have some WMS Sources, which are having a small shift in the tiles. See Overlay Map in the example.
var map1 = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 30,
maxNativeZoom: 18
});
var map4 = new L.tileLayer.wms("https://entwicklung.firetab.ch/maptest/proxy.php?url=http://geoshop.kommunalportal.ch/SWMS?", {
layers: 'lk_wms_wasser',
format: 'image/png',
transparent: true,
maxZoom:30
});
var map = L.map('mapid').setView([47.549904, 9.152927], 18);
var baseMaps = {
"map1": map1
};
var overlayMaps = {
"map4": map4
};
L.control.layers(baseMaps, overlayMaps).addTo(map);
map1.addTo(map);
map4.addTo(map);
<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>
<div id="mapid" style="width: 100%; height: 800px;"></div>

Trying to make a custom marker show up on my exact location when I allow tracking of my location

I want to use the pic userPosition.png on my location when I accept the prompt of asking for location, right now it doesn't work.
<!DOCTYPE html>
<html lang="en">
<head>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin=""
/>
<script
src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
crossorigin=""
></script>
<script src="./leaflet/leaflet.js"></script>
<style></style>
</head>
<body>
<h2 style="text-align: center;">My interactive map</h2>
<div id="mapid" style="width: 100%;height: 500px;"></div>
<script>
var mymap;
mymap = L.map("mapid").setView([55.70584, 13.19021], 12);
L.tileLayer(
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFkc2pvaGFuc2VuIiwiYSI6ImNrNWkxZnA3bzA5NnIza3M2cGczNnprMHcifQ.Z2h9R1lODB6zPZ2Ex92BrA",
{
attribution:
'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: "mapbox/streets-v11",
accessToken: "your.mapbox.access.token"
}
).addTo(mymap);
function onLocationFound(e) {
var radius = e.accuracy / 2;
L.marker(e.latlng)
.addTo(map)
.bindPopup("You are within " + radius + " meters from this point")
.openPopup();
}
function onLocationError(e) {
alert(e.message);
}
map.on("locationfound", onLocationFound);
map.on("locationerror", onLocationError);
map.locate({
setView: true,
maxZoom: 16
});
var popup = L.popup();
var marker = L.marker();
var circle = L.circle();
var newMarkerIcon = L.Icon.extend({
options: {
iconSize: [38, 95],
shadowSize: [50, 64],
iconAnchor: [22, 94],
shadowAnchor: [4, 62],
popupAnchor: [-3, -76]
}
});
var blackMarker = new newMarkerIcon({ iconUrl: "userPosition.png" });
function onMapClick(e) {
L.marker(e.latlng, "Insert postition PNG pic here")
.addTo(mymap)
.bindPopup("You clicked the map at " + e.latlng.toString());
}
mymap.on("click", onMapClick);
</script>
</body>
</html>
Use this :
L.marker([e.latlng], { icon: YourIconHere })
.bindPopup("You are within " + radius + " meters from this point")
.openPopup()
.addTo(map);
You can also add circle like that:
L.circle([e.latlng], radius,
{ weight: 1, color: 'blue', fillColor: '#cacaca', fillOpacity: 0.2 })
.addTo(map);

How to use leaflet.js heat with pane?

I want to show/hide Leaflet.heat(https://github.com/Leaflet/Leaflet.heat) layer, and new pane should somehow do this.
But is there any support for panes on Leaflet.heat?
This code does not work.
var heatPane = map.createPane("heat");
var heat = L.heatLayer([], {
radius: 10,
maxZoom: 6,
pane: "heat"
}).addTo(map);
heat.addLatLng([44,7])
heat.addLatLng([44,7])
UPD: I can use heat._heat._canvas.style.display = "none" to hide heat layer, but I don't think it is a good practice.
Thanks.
Is seems current release version of leaflet-heat.js does not support using pane option. You can use beta/development version if you want and you can achieve your requirements by just setting style on the pane.
Check out the code below:
document.onreadystatechange = function(e){
if(document.readyState != 'complete') return;
var map = L.map('map').setView([44, 7], 12);
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {}).addTo(map);
var heatPane = map.createPane("heat");
var heat = L.heatLayer([[44, 7], [44, 7], [44, 7], [44, 7]], {
radius: 10,
maxZoom: 6,
pane: "heat"
}).addTo(map);
document.getElementById("btnShow").onclick = function(){
heatPane.style.display = 'block';
};
document.getElementById("btnHide").onclick = function(){
heatPane.style.display = 'none';
};
};
#map {
width: 400px;
height: 400px;
}
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v1.3.4/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v1.3.4/leaflet.js"></script>
<!-- <script src="http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script> -->
<script src="http://leaflet.github.io/Leaflet.heat/src/HeatLayer.js"></script>
<script src="http://mourner.github.io/simpleheat/simpleheat.js"></script>
<div>
<button id="btnHide">Hide</button>
<button id="btnShow">Show</button>
</div>
<div id="map"></div>
P.S: You can uncomment the code and use release version of the script but it will not work because current release version of leaflet-heat draws canvas on default map layer.

Show popup at the center of screen

Currently, after an event I show the user a popup. However I do it as shown in the tutorial, by putting in the coordinates where the popup should show:
var greenIcon = L.icon({
iconUrl: 'leaf-green.png',
shadowUrl: 'leaf-shadow.png',
iconSize: [38, 95], // size of the icon
shadowSize: [50, 64], // size of the shadow
popupAnchor: [-3, -76] // point from which the popup should open relative to the iconAnchor
});
L.marker([51.5, -0.09], {icon: greenIcon}).addTo(map);
The problem with this is that I have to fly the user to a predetermined place (incase they not in view of where the marker will be put) so they can see the popup.
What if I just want the popup to show in the center of the user viewport?
Simply retrieve the lat/lng position of the current map view center, using map.getCenter():
Returns the geographical center of the map view
Example:
var map = L.map('map').setView([48.86, 2.35], 11);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
setTimeout(function() {
var currentViewCenter = map.getCenter();
L.marker(currentViewCenter).addTo(map);
}, 1000);
<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-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<div id="map" style="height: 200px"></div>