How to add Layer stored as variable to mapbox map - mapbox

I am working with mapbox.js and I am trying to reset a layer that I removed, but stored in a variable. I have created a map object and attached it to a div and stored it as the variable map. I initialize the layers like so
var myLayer = L.mapbox.featureLayer().addTo(map);
var secondLayer = L.mapbox.featureLayer().addTo(map);
Then I store them in a json object
var geoJsons = {"myLayer": myLayer,
"secondLayer": secondLayer
};
in a function below, I have an onclick function which draws on the data attribute of the object clicked to point to the specific layer in the json object.
var layer = $(this).data('layer');
map.removeLayer(geoJsons[layer]);
I then try to re-add it on the click of a different button
geoJsons[layer] = L.mapbox.featureLayer().addTo(map);
This last bit does not work. My question is, is there a way to re-add the layer to the map by calling it from within this json object?

geoJsons[layer] = L.mapbox.featureLayer().addTo(map);
What you are doing here is overwriting the layerobject stored with a new instance of L.mapbox.featureLayer. The stored layer is accessible via geoJsons[layer] (Assuming the layer variable holds the string myLayer or secondLayer) you can add it by simply calling it's addTo method like so:
geoJsons[layer].addTo(map);
//or
map.addLayer(geoJsons[layer]);

Related

How can I add a class to leaflet layer groups?

I am making a game map with different layer groups. Everything works fine, but is it possible to add a class to the Layer groups as shown below?
The reason why is because I would like for example to place the second layer group on top of the first layer group. I know it is possible to add a class and then changing the z-index, but I have no idea how to do this.
This is how I have set up the Layer groups currently.
// Layer Groups
var lg_locat = L.layerGroup([locat_001, locat_002, locat_003,
locat_004]).addTo(map);
var lg_quests = L.layerGroup([quest_001, quest_002, quest_003,
quest_004, quest_005, quest_006, quest_007]).addTo(map);
var lg_noticeboards = L.layerGroup([noticeboard_001,
noticeboard_002, noticeboard_003]).addTo(map);
var lg_treasures = L.layerGroup([treasure_001, treasure_002,
treasure_003, treasure_004, treasure_005]).addTo(map);
Example of the map: http://www.droogjeproductions.nl/leaflet-map-test/index.html
You can call the setZIndex() method on the layer groupe which is setting the z-index of each layer of the layer group
For exemple if lg_noticeboards are above quests which are above treasures which are above locat :
var lg_locat = L.layerGroup([locat_001, locat_002, locat_003,
locat_004]).addTo(map).setZIndex(1);
var lg_quests = L.layerGroup([quest_001, quest_002, quest_003,
quest_004, quest_005, quest_006, quest_007]).addTo(map).setZIndex(3);
var lg_noticeboards = L.layerGroup([noticeboard_001,
noticeboard_002, noticeboard_003]).addTo(map).setZIndex(4);
var lg_treasures = L.layerGroup([treasure_001, treasure_002,
treasure_003, treasure_004, treasure_005]).addTo(map).setZIndex(2);
Something like that may work I think, if it doesn't try this:
lg_locat.setZIndex(1);
lg_quests.setZIndex(3);
lg_noticeboards.setZIndex(4);
lg_treasures.setZIndex(2);

leaflet L.Control Overlay

As a newcomer to javascript and the use of leaflet I'm unsure which subject this should be.
Using the Layer Groups and Layers Control example as a model I wish to assign the Control text to the overlays from a variable.
Inserting the variable name simply uses that as text.
Code I've used follows.
var cities_title_0="cities(N-S)"
var cities_title_1="cities(E-W)"
var overlays = {cities_title_0: cities_layer[0],cities_title_1: cities_layer[1] };
L.control.layers(null,overlays).addTo(map);
How can I get the value of the variable in the control and not it's name please?
Previously (<= ES5) you would have to proceed in 2 steps:
Initialize the object var overlays = {}
Assign your computed key: overlays[cities_title_0] = cities_layer[0]
One way is to put the variable name in [] - eg
var cities_title_0="cities(N-S)"
var cities_title_1="cities(E-W)"
var overlays = {[cities_title_0]: cities_layer[0], [cities_title_1]: cities_layer[1] };
L.control.layers(null,overlays).addTo(map);

Get leaflet marker from a layer

I'm new to leaflet and am trying to implement a set of markers with different CSS-styles.
So, I am aware that after adding a marker to a map I can access different CSS-attributes by calling getElement() on my marker for example:
marker.addTo(map);
marker.getElement().style.borderColor = '#000';
This works just fine, but when adding a marker to a layer, this can no longer be used since a TypeError occurs (getElement() is undefined). Here is the example code where the error occurs:
myLayer.addLayer(marker);
marker.getElement().style.borderColor = '#000';
Am I overlooking a simpler way to set CSS-Attributes for markers and divicons that are added to layers or is there a similar way to access layer-added markers and divicons in JavaScript?
So I found a solution that is working for me.
The idea is to extend the function that is used to create the icon.
Last answer here github.com/Leaflet/Leaflet/issues/5231 helped a lot.
var borderSize = ...;
L.DivIcon.Custom = L.DivIcon.extend({
createIcon: function(oldIcon) {
var icon = L.DivIcon.prototype.createIcon.call(this, oldIcon);
icon.style.borderSize = borderSize;
...
return icon;
}
})
var icon = new L.DivIcon.Custom({
...
});
var ll = L.latLng(entry.Longitude, entry.Latitude);
var marker = L.marker(ll, {
icon: icon
})
this.myLayer.addLayer(marker);
Welcome to SO!
When not added onto a map (since your parent myLayer may not be added to the map itself), a marker does not have any element.
If you do not need to change too many styles individually and dynamically, you might rather use the className option of your Icon / DivIcon.

Unable to add marker to Angular Leaflet directive

I'm trying to add a marker to the Leaflet directive but somehow it doesn't accept markers created with the default L.marker() method.
The directive is used as follows:
<leaflet markers="markers" center="center" layers="layers" defaults="defaults"></leaflet>
I'm extending my $scope in the controller as prescribed:
angular.extend($scope, {
markers: {},
//markers: { { someName: {lat:52.163815,lng:5.365131} } //this does work
});
Adding a marker afterwards doesn't work somehow. First the .markers object is not an array, so I can't just add any elements using push(). But even adding an element as associative array doesn't work:
var marker = L.marker(L.latLng(52.163815, 5.365131));
$scope.markers[0] = marker;
The error is:
[AngularJS - Leaflet] The marker definition is not valid.
[AngularJS - Leaflet] Received invalid data on the marker 0.
I'm overlooking something very simple but I've got no idea what... Any lead would be greatly appreciated.
$scope.markers is expecting to get an object with marker properties, not the marker itself. What would work in your example is just a LatLng object, before wrapping it as Marker.
$scope.markers[0] = L.latLng(52.163815, 5.365131);
Or, if you get Markers from the outside, you can get it back from the inside:
$scope.markers[0] = marker.getLatLng();
Obviously, that doesn't convey another markers' properties, just coordinates.

Find out if a leaflet control has already been added to the map

I wrote a custom Leaflet control. It's some kind of legend that may be added for each layer. The control itself has a close button to remove it from the map (like a popup).
The control can be added by clicking a button.
My problem is that the user may add the same control to the map several times. So what I need is to test if this specific control has already been added to the map and, if so, don't add it again.
I create a control for each layer, passing some options
var control = L.control.customControl(mylayer);
and add it to my map on button click
control.addTo(map);
Now imagine the control has a close button and may be closed. Now if the user clicks the button again, I only want to add the control if it's not already on the map - something like this (hasControl is pseudocode, there is afaik no such function)
if(!(map.hasControl(control))) {
control.addTo(map);
}
For simplicity I made an example where I create a zoom control and add it twice here.
Easiest way is to check for the existence of the _map property on your control instance:
var customControl = new L.Control.Custom();
console.log(customControl._map); // undefined
map.addControl(customControl);
console.log(customControl._map); // returns map instance
But please keep in mind, when using the _map property, that the _ prefix of the property implies that it's a private property, which you are normally not supposed to use. It could be changed or removed in future versions of Leaflet. You're not going to encounter that if you use the follow approach:
Attaching a reference of your custom control to your L.Map instance:
L.Control.Custom = L.Control.extend({
options: {
position: 'bottomleft'
},
onAdd: function (map) {
// Add reference to map
map.customControl = this;
return L.DomUtil.create('div', 'my-custom-control');
},
onRemove: function (map) {
// Remove reference from map
delete map.customControl;
}
});
Now you can check for the reference on your map instance like so:
if (map.customControl) { ... }
Or create a method and include it in L.Map:
L.Map.include({
hasCustomControl: function () {
return (this.customControl) ? true : false;
}
});
That would work like this:
var customControl = new L.Control.Custom();
map.addControl(customControl);
map.hasCustomControl(); // returns true
map.removeControl(customControl);
map.hasCustomControl(); // returns false
Here's a demo of the concept on Plunker: http://plnkr.co/edit/nH8pZzkB1TzuTk1rnrF0?p=preview