4

I'm trying to add a Layer Control (for streets and towns) in Leaflet but can't get it to work - not sure where I've gone wrong. My code is made up of two functions. One gets data using AJAX (JSON), and the other plots the data. I wont post all the code, just the parts relating to the layers:

function getJSON () {

  var map = L.map('map', {
  center: [57.73, -98.99],
  zoom: 10,
  layers: [streets, towns]
  });

  var baseMaps = {
  "Streets": streets
  };

  var overlayMaps = {
  "Towns": towns
  };

  var streets = L.tileLayer('https://api.mapbox.com/styles/v1/mapbox/streets-v10/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {id: 'mapbox.streets',   
      attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © CloudMade'})

function plotData {

  var townMarkers = L.markerClusterGroup();

  var towns = L.layerGroup([marker]);

  for (var i = 0; i < townData.length; i++) {

  var townLocation = new L.LatLng(townData[i].lat, townData[i].lon);

  var marker = new L.Marker(townLocation);

  marker.bindPopup("<div class=townInfo><h1>" +
  townData[i].name)

  townMarkers.addLayer(marker);
  }
  map.addLayer(townMarkers);
  L.control.layers(baseMaps, overlayMaps).addTo(map);
  }
  }

I think I have one or two of the variables in the wrong location, but have tried them inside the for-loop and inside the plotData function.

Can anyone see where I have gone wrong?

1
  • 2
    I would make sure you do not use variables which are not declared yet e.g.: layers: [streets, towns], setting baseMaps with streets variable which is declared a few lines later etc.
    – Jihlavanka
    May 1, 2017 at 21:39

1 Answer 1

1

Ok, so here's the order you need to do things in (code is untested - throw up a GIST if you want me to edit your code):

var map = L.map('map', {
  center: [57.73, -98.99],
  zoom: 10
});

var streetsUrl = 'https://api.mapbox.com/styles/v1/mapbox/streets-v10/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'
var streets = L.tileLayer(
  streetsUrl, 
  {
    id: 'mapbox.streets', 
    attribution: 'Map data © OpenStreetMap contributors, 
    CC-BY-SA, Imagery © CloudMade'}
).addTo(map)

var towns = L.markerClusterGroup();

for (var i = 0; i < townData.length; i++) {
  var townLocation = new L.LatLng(townData[i].lat, townData[i].lon);
  var marker = new L.Marker(townLocation);
  marker.bindPopup("<div class=townInfo><h1>" +
  townData[i].name)
  towns.addLayer(marker);
}

map.addLayer(towns);
var baseMaps = {
  "Streets": streets
};

var overlayMaps = {
  "Towns": towns
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

If you're getting your townData with AJAX, you need to wrap it in a function, but you should be able to wrap just the for loop in a function that is called when your AJAX request finishes.

IMPORTANT NOTE: JavaScript is asynchronous, so code that is in sequence may not run in sequence, i.e., AJAX is something that your code doesn't wait for.

Having said that, you do need to do regular things, like declaring variables, in order. You can't add a variable to an array and declare it later. You also can't declare a variable inside a function and expect it to just work in a different function.

3
  • I have the AJAX in a function within the getJSON function. I tried your code with var map and var streets in the getJSON function and the rest in the plotData function although it didn't work. I think a L.layerGroup class is needed, as shown in this tutorial leafletjs.com/examples/layers-control
    – Steven
    May 2, 2017 at 8:27
  • As I am trying to add a layer which uses L.markerClusterGroup, I am thinking i may need this? github.com/ghybs/Leaflet.FeatureGroup.SubGroup
    – Steven
    May 2, 2017 at 8:49
  • Make the change then, @Steven. If you want more help, set it up as a JSFiddle. jsfiddle.net
    – Alex Leith
    May 2, 2017 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.