Leaflet hide markers in zoom levels - leaflet

Is it possible to hide a marker on leaflet map in some specific zoom level?
I tried:map.on('zoomend', onZoomend);
function onZoomend(){if(map.getZoom()>11){map.removeLayer(markername);}
BUT it is not working although it is the case for geometries.
I am not refering to marker cluster.

This code shows markers in zoom number equal and greater than 14 and for lesser hides marker from the map
var mymap = L.map('mapid').setView([35.75, 51.375], 8);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar'}).addTo(mymap);
var marker = L.marker([35.75, 51.375],{
draggable:true,
title : 'title',
});/
mymap.on('zoomend' , function (e) {
var geo = mymap.getCenter();
console.log(mymap.getZoom());
if (mymap.getZoom()>14)
{
marker.setLatLng(geo);
marker.addTo(mymap);
}else {
marker.remove();
}
});
https://jsfiddle.net/sajjadgol/6qprq9z9/3/

Related

How do I remove a Leaflet polyline using marker coords?

I've placed my markers and drawn the polylines between them and it's working great.
I've also given the user the ability to remove a marker using the following function
function hide(marker) {
map.closePopup();
map.removeLayer(marker);
}
Now, when a marker is removed I'd also like to remove the polyline. I've been doing a lot of searching but haven't come across my specific issue: I'm using pixel coordinates and need to remove the polyline between two markers.
markers
var marker1 = L.marker(map.unproject([8706, 7789], map.getMaxZoom()));
var marker2 = L.marker(map.unproject([8302, 5273], map.getMaxZoom()));
var marker3 = L.marker(map.unproject([9303, 7251], map.getMaxZoom()));
polylines
polyline = L.polyline([
map.unproject([8706, 7789], map.getMaxZoom()),
map.unproject([8302, 5273], map.getMaxZoom()),
map.unproject([9303, 7251], map.getMaxZoom())
]);
So when a user removes marker1, the polyline disappears between marker1 and marker2, but remains between marker2 and marker3, and so on down the line...
How is this accomplished?
You can add the polylines to the markers. And if the marker is removed you can read out the lines and remove them too.
marker1 = L.marker([51.498912, -0.122223],{connectedLines: []}).addTo(mymap);
marker2 = L.marker([51.496988, -0.056305],{connectedLines: []}).addTo(mymap);
poly1 = L.polyline([marker1.getLatLng(),marker2.getLatLng()]).addTo(mymap);
marker1.options.connectedLines.push(poly1);
marker2.options.connectedLines.push(poly1);
function removeMarkerLine(e){
var marker = this;
if(marker.options && marker.options.connectedLines){
var lines = marker.options.connectedLines;
lines.forEach(function(line){
mymap.removeLayer(line);
});
}
mymap.removeLayer(marker);
};
https://jsfiddle.net/falkedesign/3aukgm7t/
Simplest way, keep track of which polylines belongs to which two markers, and if one is removed you also remove that one.
Can be easily accomplished using layer groups.

Getting the bounds of loaded tile of leaflet

Using leaflet is there any way I can get the bounds (NorthEast, SouthWest) of a loaded tile? I want to request the server to load the markers only for a particular tile which is loaded, so that when user is panning/dragging the map he can easily see the new markers on new area.
What you really want to do is a subclass of L.GridLayer. This will allow fine control over loaded/unloaded tiles, and is the best way to use the private L.GridLayer._tileCoordsToBounds() method.
With some basic handling of loaded markers, it should look like:
L.GridLayer.MarkerLoader = L.GridLayer.extend({
onAdd: function(map){
// Add a LayerGroup to the map, to hold the markers
this._markerGroup = L.layerGroup().addTo(map);
L.GridLayer.prototype.onAdd.call(this, map);
// Create a tilekey index of markers
this._markerIndex = {};
},
onRemove: function(map){
this._markergroup.removeFrom(map);
L.GridLayer.prototype.onRemove.call(this, map);
};
createTile: function(coords, done) {
var tileBounds = this._tileCoordsToBounds(coords);
var tileKey = this._tileCoordsToKey(coords);
var url = ...; // Compute right url using tileBounds & coords.z
fetch(url).then(function(res){
if (!key in this._markerIndex) { this._markerIndex[key] = []; }
// unpack marker data from result, instantiate markers
// Loop as appropiate
this._markerGroup.addLayer(marker);
this._markerIndex[key] = marker;
done(); // Signal that the tile has been loaded successfully
});
},
_removeTile: function (key) {
for (var i in this._markerIndex[key]) {
this._markerGroup.remove(this._markerIndex[key][i]);
}
L.GridLayer.prototype._removeTile.call(this, key);
}
});
Please note that zooming might be a source of bugs and graphical glitches (markers being removed because a tile unloads, before the markers at the new zoom level are loaded). Beware of that.

Leaflet several featuregroups order changes when toggled

I am using Leaflet.js to create a map. The data displayed on the map depends on user selection so I instantiate two empty feature groups on map load, one for the values, and one for a color marker behind the value ( color depends on the value ).
if( dHMT.dataColorLayer===undefined ){
dHMT.dataColorLayer = new L.featureGroup({}).addTo(dHMT.map);
}
if( dHMT.dataValueLayer===undefined ){
dHMT.dataValueLayer = new L.featureGroup({}).addTo(dHMT.map);
}
I then add the empty layers to the layer switcher.
dHMT.overlayMapsLS = {
"Bassins ": dHMT.bassinLayer,
"Couleurs ": dHMT.dataColorLayer,
"Données ": dHMT.dataValueLayer
};
Once the user selects data, the featureGroups are filled with the relevant values/markers.
var iconColor = L.divIcon({className: 'dataSpans',html:"<div style='text-align: center;border-radius: 50%;height:40px;width:40px;padding-top:9px;background:"+dHMT.siteinfo[x].color+"'></div>"});
var iconColorDiv = L.marker([dHMT.ecartArray[x].lat, dHMT.ecartArray[x].lon], {icon: iconColor})
.bindPopup(
'Nom : '+dHMT.siteinfo[x].name+'<br>'+
'Numéro : '+dHMT.siteinfo[x].stnm+'<br>'+
'Stid : '+dHMT.siteinfo[x].stid+'<br>'+
'LatLon : '+dHMT.siteinfo[x].lat+','+dHMT.ecartArray[x].lon+'<br>'+
'Valeur : '+dHMT.ecartArray[x].ecart+'<br>'
).on('mouseover', function (e) {
this.openPopup();
}).on('mouseout', function (e) {
this.closePopup();
});
var iconValue = L.divIcon({className: 'dataSpans',html:"<div style='text-align: center;height:40px;width:40px;padding-top:9px;'>"+value+"</div>"});
var iconValueDiv = L.marker([dHMT.ecartArray[x].lat, dHMT.ecartArray[x].lon], {icon: iconValue});
dataColorFeatures.push(iconColorDiv);
dataValueFeatures.push(iconValueDiv);
L.featureGroup(dataColorFeatures).addTo(dHMT.dataColorLayer);
L.featureGroup(dataValueFeatures).addTo(dHMT.dataValueLayer);
Both layers are fine, I have a nice map with a marker layer with colored circles with another layer displaying values over the marker. The goal being to deactivate the colors or the values using the layer switcher.
The problem is that if, for example, I toggle the color layer off, and turn it on again, the colored circles reappear over the values. The desired behavior would be to have them reappear in the original order, behind the values.
You can listen to the overlayadd event on your L.Map instance:
Fired when an overlay is selected through the layer control.
http://leafletjs.com/reference.html#map-overlayadd
When fired you can use the bringToFront method of L.FeatureLayer:
Brings the layer group to the top of all other layers.
http://leafletjs.com/reference.html#featuregroup-bringtofront
map.on('overlayadd', function () {
dHMT.dataValueLayer.bringToFront();
});

Leaflet: Removing markers from map

I load some lat / lon info, then use it to build a polyline.
I then want to add a marker at each of the polyline vertices that will show when the polyline is clicked.
The vertices should disappear if a different (or the same) polyline is clicked.
The code below creates the polyline and the vertex markers.
But the vertex markers do not ever disappear.
I've tried to do this several ways with the same result. I've tried storing the vertex markers in an array and adding them directly to the map, then map.removeLayer'ing them. That doesn't work either. Nor does it work if I use an L.featureGroup instead of a layerGroup.
Clearly I've missed the point somewhere as to how markers can be removed. Could someone point me at the error in my methodology?
// trackMarkersVisible is a global L.layerGroup
// success is a callback from an ajax that fetches trackData, an array f lat/lon pairs
success: function (trackData) {
// build an array of latLng's
points = buildTrackPointSet(trackData, marker.deviceID);
var newTrack = L.polyline(
points, {
color: colors[colorIndex],
weight: 6,
clickable: true
}
);
$(newTrack).on("click", function () {
trackMarkersVisible.clearLayers();
$.each(points, function(idx, val) {
var tm = new L.Marker(val);
trackMarkersVisible.addLayer(tm);
});
map.addLayer(trackMarkersVisible);
});
}
Without a JSFiddle or Plunker it's hard to say because i'm not sure what behaviour your getting but using the clearLayers() method of L.LayerGroup should remove all layers from that group. I would check in the onclick handler if the group already has layers: group.getLayers().length === 0 If the group is empty, add the markers, if the group has layers use clearLayers. Example in code:
polyline.on('click', function (e) {
if (group.getLayers().length === 0) {
e.target._latlngs.forEach(function (latlng) {
group.addLayer(L.marker(latlng));
});
} else {
group.clearLayers();
}
});
This works for me, see the example on Plunker: http://plnkr.co/edit/7IPHrO?p=preview
FYI: an instance of L.Polyline is always clickable by default so you can leave out the clickable: true

style a geojson point like a POI with leaflet/mapbox

I am using mapbox.js to render a mapbox map. I am trying to load geojson from my server that contain either a country polygon or a city coordinates (lon,lat).
I have been able to style the country polygons but not the city points/markers.
I am not able to modify the geojson to use mapbox simplestyle
Here is the code executed when the page loads (I changed the mapbox map ID):
var southWest = L.latLng(-90, -360), northEast = L.latLng(90, 360);
var bounds = L.latLngBounds(southWest, northEast);
var map = L.mapbox.map('map', 'MapboxMapID', { zoomControl: false, infoControl: true, detectRetina: true, maxBounds: bounds, minZoom: 2, legendControl: {position: 'topright'}});
new L.Control.Zoom({ position: 'bottomright' }).addTo(map);
map.fitBounds(bounds);
var locationsGroup = L.featureGroup().addTo(map);
and then when the user selects a country or city with a selectbox:
$("#select2-search-up").on("change", function (e) {
if (e.added) {
var location = L.mapbox.featureLayer().loadURL('/citiesCountriesID/' + e.added.id).on('ready', function(featLayer) {
this.eachLayer(function(polygon) {
polygon.setStyle({
stroke:false, fillColor:'red', fillOpacity:0.2
});
});
});
locationsGroup.addLayer(location);
} else {
locationsGroup.eachLayer(function (layer) {
if (layer._geojson[0]._id == e.removed.id) {
locationsGroup.removeLayer(layer);
}
});
}
});
Ideally I would like to display a different icon that the standard marker, but I could do with a small red square
Thank you for your inputs
In this example I did some circle markers but I'm pretty sure you can do other basic svg shps or your own .png pretty easy. http://bl.ocks.org/mpmckenna8/db2eef40314fe24e9177
This example from Mapbox also shows how to use a icon from their icon Library which has a lot of choices also. https://www.mapbox.com/mapbox.js/example/v1.0.0/l-mapbox-marker/
It might also help to see some of your geojson structure to see why it can't use simplestyle
In my bl.ocks example I loaded each of the geojson datasets separately
var begin = L.geoJson(start,{
pointToLayer:function(feature, latlng){
return L.circleMarker(latlng,{
radius:9,
fillColor: "orange",
fillOpacity:.7
})
}
})
Is how I set up my circles and I set a different L.geoJson to the other data which I left as the default markers.