I'm interested by the script Leaflet motion.
I tried to update the code to add a custom GeoJSON created from QGIS or any tool.
But the current error is :
leaflet.motion.min.js:9 Uncaught TypeError: Cannot read properties of null (reading 'traveledPath')
at i._motion (leaflet.motion.min.js:9:2842)
at i.motionStart (leaflet.motion.min.js:9:3960)
at i.motionStart (leaflet.motion.min.js:9:12135)
at test14.html:110:26
<!DOCTYPE html>
<html>
<head>
<title>Leaflet motion plugin</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="https://leaflet.github.io/Leaflet.draw/src/leaflet.draw.css"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"></script>
<script src="https://mappingforyou.eu/javascript/leaflet.ajax.min.js"></script>
<script src="../javascript/leaflet.motion.min.js"></script>
<style>
html, body, #map { width: 100%; height: 100%; margin: 0px; padding: 0px;}
.leaflet-div-icon {
background: transparent!important;
border: none!important;
color: white;
}
.red {
color: red!important;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map("map").setView([51, 1], 5);
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
}).addTo(map);
var options = {
draw: {
circle: false, // Turns off this drawing tool
rectangle: false,
marker: false,
circlemarker: false
}
};
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (e) {
var type = e.layerType,
layer = e.layer;
if (type === "polyline") {
var line = L.motion.polyline(layer.getLatLngs(), {
color: "orange"
}, {
auto: true,
easing: L.Motion.Ease.swing
}).motionSpeed(100000).addTo(map);
}
if (type === "polygon") {
L.motion.polygon(layer.getLatLngs(), {
color: "red",
fill: true,
fillOpacity: 0.4
},{
auto: true
}, {
removeOnEnd: true,
icon: L.divIcon({className:"red", html: "<i class='fa fa-superpowers fa-spin fa-2x' aria-hidden='true' motion-base='0'></i>", iconSize: L.point(24, 24), iconAnchor: L.point(5, 22)})
}).motionDuration(10000).addTo(map);
}
});
var geoJsonData ={"type":"FeatureCollection","features":[{"properties":{"name":""},"type":"Feature","geometry":{"type":"LineString","coordinates":[[-7.271833,51.09715],[0.15577,50.667658],[8.638181,48.79433],[12.703585,45.710102],[9.297436,43.090615],[0.749099,41.036735],[-4.393088,41.548214]]}}]};
var seqGroup = L.motion.seq([
L.motion.polyline(geoJsonData, {
color: "orangered"
}, {
easing: L.Motion.Ease.easeInOutQuad
}, {
removeOnEnd: false,
icon: L.divIcon({html: "<i class='fa fa-truck fa-2x fa-flip-horizontal' 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);
</script>
</body>
</html>
I'm looking for a way to create a simple line like the one of this json.parse.
Can you help?
Alternatively, I'd like to feed Leaflet Motion with an external geojson file, that would gave the same result.
Best Answer
All you have to do is extract line string coordinates from
geoJsonData
and store them in some array, let's saydataCoords
, and flip coordinates while doing that, since Leaflet expects[lat, lng]
coordinate order, while GeoJSON has[lng, lat]
order:Array
dataCoords
can then be used as input toL.motion.polyline
: