Leaflet WFS – How to Use Leaflet.Motion Sequence Capabilities with Two Consecutive WFS Layers

leafletwfs

The following code is my attempt to use the consecutive lines of the Leaflet motion plugin, as used in the source code of this page example https://igor-vladyka.github.io/leaflet.motion/ : a car, then a boat, then a plane, and so on.

I'm using Leaflet Motion (https://github.com/Igor-Vladyka/leaflet.motion) for animation, Fontawesome for the markers and leaflet-geoserver-request https://github.com/iamtekson/leaflet-geoserver-request that calls the WFS services.

The code, based on Using Leaflet.motion plugin on geometry returned by WFS service?, works great, but I can't load another WFS service to make the second track (a boat trip, in Italian traghetto, that would follow the walking trip identified by debra, that worked). This is my attempt: I need the coords of both WFS services to be loaded into memory before the doMotion_debra starts. I have been delaying the doMotion_debra trigger with the second WFS loading with no success.

var dataCoords_debra = [];
var dataCoords_traghetto = [];

function doMotion_debra() {
  var seqGroup = L.motion.seq([
    L.motion.polyline(dataCoords_debra, {
    color: "MediumVioletRed",
    weight: 10,
    opacity: 0.8
    }, {
      easing: L.Motion.Ease.easeInOutQuad
    }, {
      removeOnEnd: false,
      icon: L.divIcon({html: "<i class='fa fa-hiking fa-2x' aria-hidden='true' motion-base='-43'></i>", iconSize: L.point(27.5, 24)})
    }).motionDuration(48000),

 L.motion.polyline(dataCoords_traghetto, {
    color: "cyan",
    weight: 10,
    opacity: 0.8
    }, {
      easing: L.Motion.Ease.easeInOutQuad
    }, {
      removeOnEnd: false,
      icon: L.divIcon({html: "<i class='fa fa-ship fa-2x' aria-hidden='true' motion-base='-43'></i>", iconSize: L.point(27.5, 24)})
    }).motionDuration(4000),

  ]).addTo(map);
  seqGroup.on("click", function(){
    seqGroup.motionStart();
  });
  seqGroup.on("dblclick", function(e){
    seqGroup.motionToggle();
  });
  setTimeout(function () {
    seqGroup.motionStart();
  }, 1000);
};

var wfsLayer_debra = L.Geoserver.wfs("https://mappingforyou.eu/geoserver/worldmap/ows", {
 layers: "worldmap:tracks.debra.done",
});

var wfsLayer_traghetto = L.Geoserver.wfs("https://mappingforyou.eu/geoserver/worldmap/ows", {
 layers: "worldmap:tracks.debra.traghetto",
});


wfsLayer_debra.on('layeradd', function(evt) {
  var coords;
  var geometry = evt.layer.feature.geometry;

  if (geometry.type = 'MultiLineString')
    coords = geometry.coordinates[0];
  else if (geometry.type = 'LineString')
    coords = geometry.coordinates;
  else {
    return;
  }
  coords.forEach(function(coords) {
     dataCoords_debra.push([coords[1], coords[0]]);
  });
 // doMotion_debra();
});

 wfsLayer_traghetto.on('layeradd', function(evt) {
  var coords;
  var geometry = evt.layer.feature.geometry;
  if (geometry.type = 'MultiLineString')
    coords = geometry.coordinates[0];
  else if (geometry.type = 'LineString')
    coords = geometry.coordinates;
  else {
    return;
  }
  coords.forEach(function(coords) {
     dataCoords_traghetto.push([coords[1], coords[0]]);
  });
  doMotion_debra();
});

Best Answer

All you have to do is to make sure that coordinates from both layers are loaded before calling doMotion_debra(). Simplest way to do is to have some layers loaded counter that is incremented upon layer being loaded. Then you can check the value of the counter and if it equals 2, you can call doMotion_debra().

Relevant part of the code could then look something like this:

var overlayCount = 0;

wfsLayer_debra.on('layeradd', function(evt) {
  var coords;
  var geometry = evt.layer.feature.geometry;

  if (geometry.type = 'MultiLineString')
    coords = geometry.coordinates[0];
  else if (geometry.type = 'LineString')
    coords = geometry.coordinates;
  else {
    return;
  }
  coords.forEach(function(coords) {
     dataCoords_debra.push([coords[1], coords[0]]);
  });
  overlayCount++;
  if (overlayCount == 2) doMotion_debra();
});

wfsLayer_traghetto.on('layeradd', function(evt) {
  var coords;
  var geometry = evt.layer.feature.geometry;
  if (geometry.type = 'MultiLineString')
    coords = geometry.coordinates[0];
  else if (geometry.type = 'LineString')
    coords = geometry.coordinates;
  else {
    return;
  }
  coords.forEach(function(coords) {
     dataCoords_traghetto.push([coords[1], coords[0]]);
  });
  overlayCount++;
  if (overlayCount == 2) doMotion_debra();
});