markerGroup: L.LayerGroup;
this.markerGroup.eachLayer(function (layer) {
this.markerGroup.removeLayer(layer);
});
this.markerGroup.clearLayers();
removeLayer() and clearLayers() are working as described in the leaflet documentation but I am wondering if there is a way to remove the layer/marker/instance from my markerGroup variable entirely. Even though the markers are cleared/removed, when my refresh button is called it still has the previous markers in the markerGroup variable and adds the same ones again thus duplicating them. This is a problem as I have shadows for these markers which duplicate over each other and eventually becoming 100% opaque. Has anybody got any suggestions or come across this problem before?
Edit: Thanks for the suggestion #Falke Design. map.removeLayer doesn't work for me unfortunately. Hopefully the information below is more helpful:
refreshButton() {
this.markerGroup = new L.LayerGroup;
clearInterval(this.refreshTimer);
this.dynamicLatLong = this.map.getCenter();
this.dynamicZoom = this.map.getZoom();
this.markerGroup.clearLayers();
this.polygonGroup.clearLayers();
this.map.removeLayer(this.markerGroup);
this.getCurrentAzure();
this.leafletMap();
}
getCurrentAzure() uses a for loop to get the data such as lat, lng, etc. of each instance and assigns it to a variable named marker. Each marker is added to markerGroup with this line:
marker.addTo(this.markerGroup);
leafletMap() creates the map and draws the markerGroup onto the map with this line:
this.markerGroup = L.layerGroup().addTo(this.map);
Related
I'm using this quite nice guide to add markers from a Google sheet to a basic leaflet.js map:
https://rdrn.me/leaflet-maps-google-sheets/
The problem is, using these code snippets here i get all the data logged and returned in the console, but none of the points appear on the map itself.
This is probably some really basic JavaScript issue that i'm not able to see. Sorry, still learning.
Here's a jfiddle, linking to a demo sheets with one marker point
https://jsfiddle.net/xfs19cz7/1/
with the map part:
function init() {
Tabletop.init({
key: '*url to gsheets here*',
callback: myFunction,
simpleSheet: true
})
}
window.addEventListener('DOMContentLoaded', init)
function myFunction(data, tabletop) {
console.log(data);
}
var map = L.map('map-div').setView([64.6220498,25.5689638], 5);
var basemap = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Basemap (c) OpenStreetMap',
minZoom: 5,
maxZoom: 18
});
basemap.addTo(map);
function addPoints(data, tabletop) {
for (var row in data) {
var marker = L.marker([
data[row].Latitude,
data[row].Longitude
]).addTo(map);
marker.bindPopup('<strong>' + data[row].Info + '</strong>');
}
}
This should add one point to a basic map. Now actually the map is not at all rendered, and no marker shows up. I can't find any issues in the code making the map show up blank, but there probably are some.
The marker from gsheets is however logged in the console, i suspect there is something missing in my code relating to really basic javascript functions / looping / sloppy syntax.
Also tried the init() and addPoints(data, tabletop) parts to a map i had where the map with the same basemap link, which rendereded OK. Adding this still left the map rendering, but no markers showed up. Again, the gsheets was loaded as an array of objects.
Could anyone point me to this, probably very basic, issue in the code?
edit:
callback: myFunction,
line above needs to be changed to
callback: addPoints,
also, init function needs to be called and position set to absolute. Thanks for the working fiddle in answer marked as correct below.
Fixes
Try setting map position absolute
calling the init() function
Working fiddle
My scenario is that the user would click on a marker that is part of a cluster and be redirected somewhere else. Then when they come back they need to return the the same bounds on the map where they were before at that marker, but the cluster in which the marker is found is no longer expanded/spiderfy'd, which I need to get done.
At this point I know which marker I'm looking for, but need to expand its cluster. What I've done so far:
Iterate through the markers in the initially populated L.markerClusterGroup() object:
layers = L.markerClusterGroup();
. . . populate 'layers' ...
$.each(layers, function (idx, layer) {
if(layer._tooltip._content === 'known marker tooltip') {
layer.__parent.spiderfy();
}
});
Although the spiderfy() function sort of works, it doesn't seem to be intended to be used on its own and breaks the cluster pretty bad.
Alternatively, I've tried calling fire('clusterclick') on the above layer object, as well as on layer.__parent, which I presume would represent the cluster, but can't get anything working.
I would need a solution in which I can properly trigger the clusterclick event that would handle everything, as if I had actually clicked the cluster myself.
My objective here is to remove all the markers added to leaflet using layer group for a paginated listing page.When navigated to other page i am able to remove layer group of previous page, but on adding new layer group of markers(markers of next page) i am getting this error in browser and markers are not added to the map
error is - Uncaught TypeError: layer.onAdd is not a function;
code is
var leaflet_factory = {
//initializing map container
initialize: function() {
var map = L.map('mapresults');
var googleLayer = new L.Google('ROADMAP');
map.addLayer(googleLayer);
},
//set view of mao
setview: function(lat, long, zoom) {
map.setView([lat, long], zoom);
},
//add list of markers to maps
addMarkersList: function(marker_array) {
var markerArray = [];
$.each(marker_array, function(key, data) {
var marker_pointer = L.marker([data.lat, data.long]).bindPopup('<strong>' + $(this).attr('data-vendor').capitalize() + '</strong><br>' + $(this).attr('data-location').capitalize());
markerArray.push(marker_pointer);
});
window.page_makers_layer = L.layerGroup(markerArray);
window.page_makers_layer.addTo(map);
},
//remove the current marker layer group
removeMarkerLayer: function() {
map.removeLayer(window.page_makers_layer);
}
}
The problem with the above code is when calling addMarkersList for first time after initializing the map container it works.
But when i call addMarkerList with new list of markers(lat long pair) after calling removeMarkerLayer to remove existing marker layer it gives me following error which i am trying to debug.
Uncaught TypeError: layer.onAdd is not a function
Please point where i am doing wrong.
You're doing a few things wrong. Not catastrophically wrong, just antipattern wrong, e.g.:
map.removeLayer(window.page_makers_layer);
Do NOT use window globals to store references to your data (unless you're really, really, really sure of what you're doing). If you're wrapping map creation in a factory or a module, store your data in that scope.
var leaflet_factory = {
Do not name something a factory if it doesn't follow the factory pattern. It's very confusing. Just name it differently, make it a CJS module instead, or skip it entirely.
Research into common programming patterns. Do you have something that appears only once in the webpage? Consider singletons.
gives me following error which I am trying to debug.
How are you trying to debug it? Learn to use your browser debugging capabilities, and provide a complete stack trace.
You should be able to easily keep track of the value of the problematic variable, and see if it is an instance of L.LayerGroup when the call is made.
I am working with the lealflet api, where user can draw shapes to
map(image)...
Initially the layer control(handling 1 layer) is added for base map
using imageoverlay......
I have added a button of id 'newLyer' to page where click event
handles the creation of new layer.....i.e user can create new layer
and update layer control(which is now handling 2 layers)....
I have used several methods to create the layers and adding to control
but failed....
Adding new layer to layerGroup
var layerGroup = new L.LayerGroup(),
imageOverlayUrl = 'aa.jpg',
// New imageoverlay added to the layergroup
imageOverlay = new L.ImageOverlay(imageOverlayUrl, bounds).addTo(layerGroup),
// New featuregroup added to the layergroup
featureGroup = new L.FeatureGroup().addTo(layerGroup);
LayerControl where i needed to add the control(if i am correct)
var layerControl = new L.control.layers({
'Main': layerGroup,
//here i need to add new layer control
}, null, { collapsed: false }).addTo(map);
OnClick function with so far static code, this will be executed on click
$('#newLayer').click(function addNewLayer() {
// Second layergroup not added to the map yet
var layerGroupNew = new L.LayerGroup(),
imageOverlayUrlNew = 'bb.png',
// New imageoverlay added to the second layergroup
imageOverlayNew = new L.imageOverlay(imageOverlayUrlNew, bounds).addTo(layerGroup2),
// New featuregroup added to the second layergroup
featureGroupNew = new L.FeatureGroup().addTo(layerGroupNew);
});
In Short
Initially, i have one layer with its control, now onclick function
creates the new layer which will be added to the map but how i can add
this layer into layerControl....
If someone has idea about how to do this sort of thing, please do help,,,, any kind of help or reference will be appreciated....
Thanks for your time
If you look at the documentation for L.Control.Layers:
http://leafletjs.com/reference.html#control-layers
You'll see that L.Control.Layers has a addBaseLayer method:
http://leafletjs.com/reference.html#control-layers-addbaselayer
Adds a base layer (radio button entry) with the given name to the control.
Thus you can do:
layerControl.addBaseLayer(newBaseLayer, 'My New BaseLayer');
And you're good to go. As you see, you could have spared yourself the trouble of posting this question if you would have taken a look at the reference. Leaflet is very well documented. I've personally learned most that i know about Leaflet by reading the docs completely once of twice. Good luck with your project, cheers!
I'd like to list all of the elements from a Mapbox gridLayer that are visible to a user in the viewport.
There is an excellent example on the Mapbox site called 'Listing markers in view'. It shows all the markers on the featureLayer that are in the view of the browser.
I'd like to create something similar, but using using a gridLayer instead. (the gridLayer was created in TileMill)
Here is an example fiddle of the data with a version of non-working 'in-bounds' code:
http://jsfiddle.net/bfab/uSLVw/1/
For reference, the gridLayer has a variable in it (passed from TileMill in the UTFGrid) called '{{{Magnitude}}}' I'd like to list each of the instances of earthquakes that appear to the user, and add it to a list on the bottom left of the example. The function I'm trying to use is gridLayer.getData(latlng,callback).
Here is the snippet of code that is not working:
map.on('move', function() {
// Construct an empty list to fill with gridLayer elements.
var inBounds = [],
// Get the map bounds - the top-left and bottom-right locations.
bounds = map.getBounds();
// For each part of the grid, consider whether
// it is currently visible by comparing with the current map bounds.
// This is what fails....
myGridLayer.getData(bounds,function(earthquake){
inBounds.push(earthquake.Magnitude);
});
// Display a list of markers.
document.getElementById('coordinates').innerHTML = inBounds.join('\n');
});
Apologies if I am making a simple error...
Actually you can't (not easily at least)
1/ You misunderstand the getData function on the gridlayer
first parm is not a boundary but a location latlng
when you use this in a callback (onclick for example) you will get data only if you click on one of your circles, if not you get undefined). The data is not a list of markers but the information of your earthquake (e.g. {DateTime: "2014-04-26T16:59:15.710+00:00", Magnitude: 3.9})
myGridLayer.getData(event.latlng, function(data) {
console.log(data);
// if clicked on a marker: data is defined
// e.g. Object {DateTime: "2014-04-26T16:59:15.710+00:00", Magnitude: 3.9}
});
http://jsfiddle.net/FranceImage/uSLVw/11/
2/ It is not easy to think in terms of markers when using gridlayer as the markers are already part of the image when you load tiles:
http://a.tiles.mapbox.com/v3/bfab.i4nm0adm/3/0/2.png
The interaction is described in some javascript loaded at the same time
http://a.tiles.mapbox.com/v3/bfab.i4nm0adm/3/0/2.grid.json