Leaflet Plugins – Using Leaflet.motion Plugin on Geometry Returned by WFS Service

geojsonleafletleaflet-pluginswfs

I'm back with my Leaflet.motion service because I'd like to link it to an existing WFS service for easier and live updating.

The Javascript plugin for WFS and Leaflet motion are:

  <script src="https://iamtekson.github.io/leaflet-geoserver-request/src/L.Geoserver.js"></script>
 <script src="https://mappingforyou.eu/javascript/leaflet.motion.min.js"></script>

I have the error: "Uncaught TypeError: wfsLayer.features is undefined"

The code successfully loads the WFS onto the map:

var wfsLayer = L.Geoserver.wfs("https://mappingforyou.eu/geoserver/worldmap/ows", {
    layers: "worldmap:debra",
});
wfsLayer.addTo(map);
    

dataCoords = [];

wfsLayer.features[0].geometry.coordinates.forEach(function(coords) {   dataCoords.push([coords[1], coords[0]]); });

            var seqGroup = L.motion.seq([
                    L.motion.polyline(dataCoords, {
                    color: "MediumVioletRed",
                    
                    weight: 10,
                    
                    opacity: 0.8
                    
                    }, {
                        easing: L.Motion.Ease.easeInOutQuad
                    }, {
                        removeOnEnd: false,
                        icon: L.divIcon({html: "<i class='fa fa-male fa-2x' aria-hidden='true'></i>", iconSize: L.point(27.5, 24)})
                    }).motionDuration(8000)
                ]).addTo(map);


            seqGroup.on("click", function(){
                seqGroup.motionStart();
            });

            seqGroup.on("dblclick", function(e){
                seqGroup.motionToggle();
            });

            setTimeout(function () {
                seqGroup.motionStart();
            }, 1000);

But it's not showing the motion

the wfs service is
https://mappingforyou.eu/geoserver/worldmap/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=worldmap%3Adebra&maxFeatures=50&outputFormat=text%2Fjavascript

Any help please?

page is at https://mappingforyou.eu/italia/test1.html

Best Answer

L.Geoserver.wfs is async method, so any data in wfsLayer is accessible only after layer is loaded. L.Geoserver.wfs is extension of L.FeatureGroup which means it fires layeradd event after layer is loaded/added.

Since the above L.Geoserver.wfs call returns MultiLineString, this has to be checked when converting geometry to array of coordinates.

Taking all this into account, code could look something like this (tested):

var dataCoords = [];

function doMotion() {
  var seqGroup = L.motion.seq([
    L.motion.polyline(dataCoords, {
    color: "MediumVioletRed",
    weight: 10,
    opacity: 0.8
    }, {
      easing: L.Motion.Ease.easeInOutQuad
    }, {
      removeOnEnd: false,
      icon: L.divIcon({html: "<i class='fa fa-male fa-2x' aria-hidden='true'></i>", iconSize: L.point(27.5, 24)})
    }).motionDuration(8000)
  ]).addTo(map);
  seqGroup.on("click", function(){
    seqGroup.motionStart();
  });
  seqGroup.on("dblclick", function(e){
    seqGroup.motionToggle();
  });
  setTimeout(function () {
    seqGroup.motionStart();
  }, 1000);
}
  
var wfsLayer = L.Geoserver.wfs("https://mappingforyou.eu/geoserver/worldmap/ows", {
  layers: "worldmap:debra",
});
wfsLayer.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.push([coords[1], coords[0]]);
  });
  doMotion();
});

wfsLayer.addTo(map);