Reputation: 43
Am teaching myself JavaScript using Leaflet to create some simple web maps. This step is to add layer control to the map. I'm testing control for both the base layers and the overlay.
I'm getting a JS type error. I've used some debugging but can't find what I'm doing wrong.
The error is occurring when the "layers" option for the Map API is used. If I remove that option, the error doesn't occur (obviously the map doesn't work, so just done for debugging).
Using debugger in Firefox, the content of the overlay layer groups looks OK. I would appreciate another set of eyes on this.
// Creates a variable to hold the attribution including OSM, Creative Commons license,and Mapbox imagery; this is done via variable because two tileLayers will each need attribution
var mbAttr = 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
mbUrl = 'https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png';
var grayscale = L.tileLayer(mbUrl, {id: 'examples.map-20v6611k', attribution: mbAttr}),
streets = L.tileLayer(mbUrl, {id: 'examples.map-i875mjb7', attribution: mbAttr});
// var myURL = jQuery( 'script[src$="kcdfp.js"]' ).attr( 'src' ).replace( 'kcdfp.js', '' ); // Gets the URL and removes the file name, which will be replaced in the icon API; can't get it to work
var myURL = 'http://www.myspatialhome.org/'; // Sets the url for icon images
// Criteria for overlay layers
// In Active -1=YES, 0 = NO
// Create new layerGroups for overlay
var active = new L.layerGroup();
var inactive = new L.layerGroup();
// Create Marker icons
var myIcon = L.icon({
iconUrl: myURL + 'images/pin24.png',
iconRetinaUrl: myURL + 'images/pin48.png',
iconSize: [29, 24],
iconAnchor: [9, 21],
popupAnchor: [0, -14]
});
// Loop through the entire JSON file
for ( var i=0; i < kcdfp.length; ++i )
{
if (kcdfp[i].In_Active == 0){ // Inactive=no, i.e. Active
L.marker( [kcdfp[i].Lat, kcdfp[i].Lon], {icon: myIcon} )
.bindPopup( '<a href="ATL_map_service_test_leaflet_url.htm" target="_blank">' + kcdfp[i].Last_Name + '</a>' )
.addTo( active ); // Add to active layer group
}
else { // Otherwise show a Inactive
L.marker( [kcdfp[i].Lat, kcdfp[i].Lon], {icon: myIcon} )
.bindPopup( '<a href="ATL_map_service_test_leaflet_url.htm" target="_blank">' + kcdfp[i].Last_Name + '</a>' )
.addTo( inactive ); // Add to inactive layer group
}
}
// Create the map
var map = L.map( 'map', {
center: [47.5, -121.95],
minZoom: 10,
zoom: 10,
layers: [streets, active, inactive] // ERROR
});
// Set variables for layer control
var baseLayers = {
"Grayscale": grayscale,
"Streets": streets
};
var overlays = {
"Active": active,
"Inactive": inactive
}; // Sets the other variable for layer control
L.control.layers(baseLayers, overlays).addTo(map); // Adds a layer control to the map
Edit: Further testing leads me to think the way I'm creating the layerGroups is wrong. I changed the Map to only include the street tileLayer and added the layerGroups with an .addTo(map) clause.
An error appears to happen when the layerGroups are added to the map.
It appears layerGroups wants an array. I changed the Marker with an .addLayer clause. Does layerGroup see that as an array element?
// Loop through the entire JSON file
for ( var i=0; i < kcdfp.length; ++i )
{
if (kcdfp[i].In_Active == 0){ // Inactive=no, i.e. Active
L.marker( [kcdfp[i].Lat, kcdfp[i].Lon], {icon: myIcon} )
.bindPopup( '<a href="ATL_map_service_test_leaflet_url.htm" target="_blank">' + kcdfp[i].Last_Name + '</a>' )
.addLayer( active ); // Add to active layer group
}
else { // Otherwise show a Inactive
L.marker( [kcdfp[i].Lat, kcdfp[i].Lon], {icon: myIcon} )
.bindPopup( '<a href="ATL_map_service_test_leaflet_url.htm" target="_blank">' + kcdfp[i].Last_Name + '</a>' )
.addLayer( inactive ); // Add to inactive layer group
}
}
Upvotes: 1
Views: 1055
Reputation: 43
The root problem turned out to be data errors (i.e. lat/lon NULL). The testing included both the original JS and that modified based on the proposed answer that adds "var newMarker" to the L.marker APIs. The original JS was based on Leaflet tutorial 6.
I'm curious if there are advantages to picking one approach over the other.
Thanks for answers. It helps my JS/Leaflet learning.
Upvotes: 0
Reputation: 2991
Your add layer flow is a bit reversed.
They should look like
var newMarker = L.marker( [kcdfp[i].Lat, kcdfp[i].Lon], {icon: myIcon} ).bindPopup( '<a href="ATL_map_service_test_leaflet_url.htm" target="_blank">' + kcdfp[i].Last_Name + '</a>' )
active.addLayer(newMarker); // Add to active layer group
Upvotes: 0