[GIS] Leaflet JS calling animatedMarker.stop() from event listener

animatedmarkerjavascriptleafletweb-mapping

I'm using the animated marker plug-in for Leaflet JS and would like to stop the marker from animating when it reaches a certain lat lon position.

Currently I'm using Leaflet's 'move' event listener to detect when the marker reaches the specified lat lon. This part is working as I can console.log a message when the desired position is reached, however the stop method is not actually stopping the marker from animating.

a live demo to my code can be found here

My code is as follows:

<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width">             
        <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
        <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
        <script src="http://rawgithub.com/clhenrick/Major-Studio-Two/gh-pages/map-story/html/js/pct-trail-partial.js"></script>
        <script src="http://rawgithub.com/openplans/Leaflet.AnimatedMarker/master/src/AnimatedMarker.js"></script>
        <script type="text/javascript" src="http://maps.stamen.com/js/tile.stamen.js?v1.2.4"></script>  
        <style type="text/css">
                html, body {
                    margin: 0 auto;
                    padding: 0px;
                    width: 500px;
                    height: 500px;
                }
                #map {
                    width: 500px;
                    height: 500px;
                }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <script type="text/javascript">
            // init the map with Stamen Terrain tiles
            var map = L.map('map').setView([40.3025, -121.2347], 15);
            var layer = new L.StamenTileLayer("terrain");
            map.addLayer(layer);

            // create geojson layer
            var geojson = new L.geoJson(pct);
            geojson.addTo(map);

            // temporary array to store geojson lat, lon
            var temp = [];

            var eachLayer = geojson.eachLayer(function(layer){

                var coordinates = layer.feature.geometry.coordinates,
                    len = coordinates.length,
                    i = 0;
                for (i; i<len; i++){
                    var lat = coordinates[i][1],
                        lon = coordinates[i][0];
                    // reverse order of lon, lat for L.polyline
                    temp.push([lat, lon]);
                }
            });

            var line = new L.polyline(temp),
                animatedMarker = L.animatedMarker(line.getLatLngs(), {
                    autoStart: false,
                    distance: 500,
                    interval: 1000
                });

            map.addLayer(animatedMarker);

            // pan the map to follow the marker
            setInterval(function(){
                map.panTo({lon: animatedMarker['_latlng'].lng, lat: animatedMarker['_latlng'].lat});
            }, 100);

            // delay start so that data has time to load
            setTimeout(function(){
                animatedMarker.start();
            }, 3000);

            // function to track animatedMarker's position
            // and stop it at given lat lon values
            var checkLatLon = function(e) {
                // lat lon values to check for
                var lat = 32.608639206779,
                    lon = -116.49114320162762;

                if (e.latlng.lng === lon && e.latlng.lat === lat){
                    alert("whoa!"); // shows the test works
                    console.log("lat lon check worked!"); // ""
                    animatedMarker.stop(); // doesn't seem to work?
                }
            }

            // event listener to check animatedMarker's position
            animatedMarker.on('move', checkLatLon);

        </script>   
    </body>
</html>

Best Answer

I've made some changes to your code, to make it work as you wish. Here's only the code between the body tags:

<body>
    <div id="map"></div>
    <script type="text/javascript">
        // init the map with Stamen Terrain tiles
        var map = L.map('map').setView([40.3025, -121.2347], 15);
        var layer = new L.StamenTileLayer("terrain");
        var animatedMarker;
        map.addLayer(layer);

        // create geojson layer
        var geojson = new L.geoJson(pct);
        geojson.addTo(map);

        // temporary array to store geojson lat, lon
        var temp = [];

        var eachLayer = geojson.eachLayer(function(layer){

            var coordinates = layer.feature.geometry.coordinates,
                len = coordinates.length,
                i = 0;
            for (i; i<len; i++){
                var lat = coordinates[i][1],
                    lon = coordinates[i][0];
                // reverse order of lon, lat for L.polyline
                temp.push([lat, lon]);
            }
        });

        var line = new L.polyline(temp),
            animatedMarker = L.animatedMarker(line.getLatLngs(), {
                autoStart: false,
                distance: 500,
                interval: 1000
            });

        map.addLayer(animatedMarker);

        var flag = 0; // the variable used to signalise the animation stop

        function pan_map(){
            map.panTo({lon: animatedMarker['_latlng'].lng, lat: animatedMarker['_latlng'].lat});;
        }
        pan_map(); // pan the map to the marker start position

        // set the interval timer
        var vInterval = setInterval(function(){
            if (flag == 1){
                animatedMarker.stop();
                clearInterval(vInterval); // stops the interval timing, also
            }
            pan_map(); // pan the map to follow the marker
        }, 100);

        // delay start so that data has time to load
        Timeout = setTimeout(function(){
            animatedMarker.start();
        }, 3000);

        // function to track animatedMarker's position
        // and stop it at given lat lon values
        var checkLatLon = function(e) {
            var lat = 32.608639206779,
                lon = -116.49114320162762;
            if (e.latlng.lng === lon && e.latlng.lat === lat){
                flag = 1; // signals the animation can be stopped
            }
        }

        // event listener to check animatedMarker's position
        animatedMarker.on('move', checkLatLon);
    </script>   
</body>