1

I have 7 GPX files that I successfully loaded into a Leaflet map. My problem is that I would like to show/hide each of them using some link on the web page. Let say that links have the following code:

<a href="#" id="GPX1">Link show/hide GPX1</a>
<a href="#" id="GPX2">Link show/hide GPX2</a>
<a href="#" id="GPX3">Link show/hide GPX3</a>
<a href="#" id="GPX4">Link show/hide GPX4</a>
<a href="#" id="GPX5">Link show/hide GPX5</a>
<a href="#" id="GPX6">Link show/hide GPX6</a>
<a href="#" id="GPX7">Link show/hide GPX7</a>

and the JS script I am using is the following

var mbAttr = 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
            'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'


// replace this with your own mapbox token!
var token = 'my_token_here';
var mapboxUrl = 'https://api.mapbox.com/styles/v1/mapbox/streets-v10/tiles/{z}/{x}/{y}@2x?access_token=' + token;

var OpenStreetMap_Mapnick=L.tileLayer(mapboxUrl, {id: 'mapbox/light-v9', attribution: mbAttr})

var map = L.map('mapid', {
        center: [45.43538, 12.33297],
        zoom: 14,
    layers: [OpenStreetMap_Mapnick]
});

var control = L.control.layers(null, null).addTo(map);

for (let i = 1; i <= 7; i++) {
  new L.GPX('gpx/MuVe_7D/MuVe_7D_T'+i+'.gpx', {
    async: true,
    marker_options: {
      startIconUrl: 'assets/pins/Pin_ATG.png',
      endIconUrl: 'assets/pins/Pin_CUR.png',
      shadowUrl: 'assets/pins/Pin_shadow.png'
    }
  }).on('loaded', function(e) {
    var gpx = e.target;
    control.addOverlay(gpx, 'gpr_GPX'+i);
  }).addTo(map);
}


$("#GPX1").click(function(event) {
    event.preventDefault();
    if(map.hasLayer(gpr_GPX1)) {
        $(this).removeClass('selected');
        map.removeLayer(gpr_GPX1);
    } else {
        map.addLayer(gpr_GPX1);
        $(this).addClass('selected');
   }
});

now, when I click on the GPX1 link I get the following error

Uncaught ReferenceError: gpr_GPX1 is not defined

How can I solve it?

I am using this snippet of code to show/hide layers but it doesn't work. The curious fact about it is that if I plot a POI the show/hide functionality from the link works, it seems I am doing something wrong defining the layers.

1 Answer 1

2

Leaflet method map.hasLayer requires layer as argument, you are giving it nonexistent gpr_GPX1 variable/object.

When creating GPX layers, they can be stored in an array and later referenced by index coming from link HTML element id.

Assuming all your GPX layers being treated equal, code could then look something like this, covering all 7 GPX layers:

var gpxLayers = [];

for (let i = 1; i <= 7; i++) {
  gpxLayers[i] = new L.GPX('gpx/MuVe_7D/MuVe_7D_T'+i+'.gpx', {
    async: true,
    marker_options: {
      startIconUrl: 'assets/pins/Pin_ATG.png',
      endIconUrl: 'assets/pins/Pin_CUR.png',
      shadowUrl: 'assets/pins/Pin_shadow.png'
    }
  }).on('loaded', function(e) {
    var gpx = e.target;
    control.addOverlay(gpx, 'gpr_GPX'+i);
  }).addTo(map);
}

$("*[id^='GPX']").click(function(evt) {
  evt.preventDefault();
  var i = parseInt(evt.target.id.substr(-1));
  var gpxLayer = gpxLayers[i];
  if(map.hasLayer(gpxLayer)) {
    $(this).removeClass('selected');
    map.removeLayer(gpxLayer);
  } else {
    map.addLayer(gpxLayer);
    $(this).addClass('selected');
 }
});
3
  • Sorry but I can't make it work with this code, so I made a minimum example in JSFiddle with only two GPX. Can you please check it out? jsfiddle.net/nicolaesse/f1uvkopm/10
    – Nicolaesse
    Jul 16 at 12:12
  • Your JSFiddle can't work since your forgot to include/link JQuery library and loading GPX data has CORS error and you forgot control definition. Putting that aside, it should be gpxLayers[i] = new L.GPX( ....
    – TomazicM
    Jul 16 at 15:33
  • Thanks for your support, I corrected my code with your advice and now it works!
    – Nicolaesse
    Jul 18 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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