0

First, to get some context, I asked this a few weeks ago.

I now have Leaflet parsing a folder of gpx files, and drawing all of them in one map instance, using the Omnivore plugin.

Now what I need is for those files to change dynamically. I have a slider that represents a time interval. Each time I use the slider, I narrow the interval in which I want the tracks to be shown.

Ex: My slider goes from 15th of January to the 15th of May. So, the map shows all tracks from that time. If I change the slider to show from the 1st of April to the 15th of May, the map should react accordingly and re-draw the corresponding files, erasing from the map the tracks from before the 1st of April.

The problem is that I can't seem to get it doing this, since I keep getting a

TypeError: Cannot read property 'addLayer' of undefined

When I make a console.log of the layer, in the line where the problem happens, it prints at exactly the same time, the layer and then an undefined. I don't know why this happens and it is very hard do debug.

My code is as follows:

setTimeout(function() {

          var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
          osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
          osm = L.tileLayer(osmUrl, {maxZoom: 18, attributionControl: false});
          var ggl = new L.Google();

          angular.element($elem[0]).append(angular.element('<div id="trackmap'+ trackmapCount +'" style="width: 100%; height: calc(100% - 25px); border: 1px solid #ccc"></div>'));
          trackmaps[trackmapCount] = new L.Map('trackmap'+ trackmapCount +'', {center: new L.LatLng(center[0], center[1]), zoom: 10});
          trackmaps[trackmapCount].addControl(new L.Control.Layers( {'Google':ggl,'OSM':osm}, {}));
          console.log('map'+ trackmapCount +'');
          var layer1 = osm.addTo(trackmaps[trackmapCount]);
          createTracks(jsonRes);

          $scope.$watch(function () {
            return $elem[0].parentNode.clientWidth;
          }, function ( w ) {
            if ( !w ) { return; }
            for(var i = 0; i < trackmapCount; i++) {
              trackmaps[i].invalidateSize();
            }
          });

          $scope.$watch(function () {
            return $elem[0].parentNode.clientHeight;
          }, function ( h ) {
            if ( !h ) { return; }
            for(var i = 0; i < trackmapCount; i++) {
              trackmaps[i].invalidateSize();
            }
          });

          $scope.$on('$destroy', function() {
            rootScopeBroadcast();
          });

          var rootScopeBroadcast = $rootScope.$on('rootScope:broadcast-timeline_slider', function (event, data) {
            for(var i = 0; i < trackmapCount; i++) {
              trackmaps[i].removeLayer(runLayer);
            }
              var new_tracks = sliderProcessing(data.min_time, data.max_time, jsonRes)
              createTracks(new_tracks); // THE PROBLEM IS HERE
          });


          function createTracks (track_list) {


              myStyle = {
                  "color": "#0033ff",
                  "weight": 5,
                  "opacity": 0.65,
                  "clickable": true
              };

              customLayer = L.geoJson(null, {
                  style: myStyle,
              });


              for (var i = 0; i < track_list.length; i += 1) {
                runLayer = omnivore.gpx(folderPath + track_list[i], null, customLayer) 
                  .on('ready', function() {
                      //runLayer.showExtremities('arrowM');
                  })
                  .addTo(trackmaps[trackmapCount])
//a console.log of trackmaps[trackmapCount] here shows both the layer and an undefined at the same time
                  .on('click', function(d) {
                      console.log(d);
                  });
              }

          }

          trackmapCount++;
          delay = 0;

          }, delay);

I'm probably missing some Leaflet re-draw function, or my control code is not correctly placed, but I've messed around with it and it stays the same.

1

I could not find the problem, but here are some various suggestions

  • Use debugger; statement in your browser, and inspect more closely at the data structures like trackmaps you have created. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger

  • I cannot tell from your code where the var runLayer is declared, or what else could be modifying it.

  • Design code first to basically work, in smaller modules, before you try to connect it with a UI element like a slider. The UI definitely adds more complexity for debugging.

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.