Search code examples
javascriptgoogle-mapsgoogle-polyline

How can I set the speed of a symbol moving on a polyline


I'm creating a project for my internship, and I have some planes moving on a polyline in google maps. I want to create my project on the simple way because I have almost no experience, and maybe i'm making this the wrong way and that´s why i´m asking for help. You can see what i'm talking about here

I Have 4 planes in the moment so I had to create one function to each one because if i don´´t the Plane to Spain arrives at the same time than the plane to Brasil, and they both took off at the same time.

This is what I have in the moment, so I created the costum path symbol and then the polylines.

function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 3,
        center: {lat: 12.1336018, lng: -15.1832411},
        mapTypeId: 'terrain'
    });
    //Define the custom symbols. All symbols are defined via SVG path notation.
    // They have varying stroke color, fill color, stroke weight,
    // opacity and rotation properties.

    var planeSymbol = {path: 'M 8.1326447,0.80527736 C 8.5471666,0.063577346 9.742752,0.030177346 10.052431,0.82497736 C 10.093464,3.0114774 10.134497,5.1980774 10.17553,7.3845774 C 12.760407,8.9653774 15.345284,10.546179 17.930161,12.127079 C 17.930161,12.881779 17.930161,13.636479 17.930161,14.391179 C 15.373077,13.579479 12.815993,12.767779 10.258908,11.956179 C 10.27281,13.280479 10.286713,14.604879 10.300615,15.929279 C 10.8565,16.555879 11.412385,17.182479 11.96827,17.809079 C 12.25527,18.269479 12.437605,19.641079 11.59784,19.085079 C 10.804104,18.802179 10.010367,18.519179 9.21663,18.236279 C 8.3133108,18.620779 7.4099916,19.005279 6.5066724,19.389779 C 6.3952441,18.705879 6.2272708,17.857479 6.8519879,17.359679 C 7.2927717,16.882879 7.7335555,16.406079 8.1743393,15.929279 C 8.1465467,14.604879 8.1187541,13.280479 8.0909615,11.956179 C 5.5894706,12.824879 3.0879797,13.693479 0.58648883,14.562179 C 0.54479393,13.821679 0.50309893,13.081079 0.46140403,12.340579 C 3.0184842,10.717079 5.5755645,9.0935778 8.1326447,7.4700774 C 8.1326447,5.2484774 8.1326447,3.0268774 8.1326447,0.80527736 z',
        scale: 1,
        strokeOpacity: 1,
        strokecolor: 'black',
        strokeWeight: 1,
        anchor: new google.maps.Point(9, 9)
    };


    var GRU = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: -23.6276104, lng: -46.6568016}], //Lis - GRU
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    animatePlane(GRU);

    var LAD = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: -8.8648774, lng: 13.2249472}], //Lis - LAD
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    animatePlane1(LAD);

    var MIA = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: 25.8027373, lng: -80.2892127}], //Lis - MIA
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    animatePlane2(MIA);

    var MAD = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: 40.4690627, lng: -3.5599042}], //Lis - MAD
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    animatePlane3(MAD);
    
    
    

    function animatePlane(line) {
        var count = 0;
        var listener = window.setInterval(function() {
            count = (count + 1) % 200;

            var icons = line.get('icons');
            icons[0].offset = (count / 2) + '%';
            line.set('icons', icons);
            if (count >= 199)
                clearInterval(listener);
        }, 2000);
    }

    function animatePlane1(line) {
        var count = 0;
        var listener = window.setInterval(function() {
            count = (count + 1) % 200;

            var icons = line.get('icons');
            icons[0].offset = (count / 2) + '%';
            line.set('icons', icons);
            if (count >= 199)
                clearInterval(listener);
        }, 2000);
    }
    
        function animatePlane2(line) {
        var count = 0;
        var listener = window.setInterval(function() {
            count = (count + 1) % 200;

            var icons = line.get('icons');
            icons[0].offset = (count / 2) + '%';
            line.set('icons', icons);
            if (count >= 199)
                clearInterval(listener);
        }, 2000);
    }

    function animatePlane3(line) {
        var count = 0;
        var listener = window.setInterval(function() {
            count = (count + 1) % 200;

            var icons = line.get('icons');
            icons[0].offset = (count / 2) + '%';
            line.set('icons', icons);
            if (count >= 199)
                clearInterval(listener);
        }, 2000);
    }

}
#map {
    width: 900px;
    height: 684px;

}
<html>
    <body>     
<div id="map"></div>  
        
      
      <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCUYsLGs_ek6Ids4TN1ZZeJvv6X-r4j5N4&callback=initMap"></script>
                    
    </body>
</html>

So this is just a sample but my real question is can I simulate the real speed of the plane or can i set how many time(in hours) it takes to a plane to reach the end of a polyline?

Pls don´t report my question, just help me learning! if i'm off topic just tell me how to improve my questions :D


Solution

  • Okay, first let's get rid of those four functions. One function can handle all.

    Since it's a generic function now, we need parameters to specify what we're handling.

    As parameters I chose steps (= number of steps), and stepTime ( number of milliseconds between steps). I could have chosen different parameters, like speed and totalTime, but that's just simple calculations.

    Anyway, as an example I set 20 steps to Madrid, stepTime 2 seconds, so you get there in 40 seconds.

    Can you handle the calculations? Or do you need anything specific? Search the distance, guestimate the ideal step time, ... Deepak's answer gives you a distance calculator, and a way of thinking about it...

    Anyway, let me know

    <script>
    // http://stackoverflow.com/questions/42225019/how-can-i-set-the-speed-of-a-symbol-moving-on-a-polyline#42225019
    function initMap() {
    
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 3,
        center: {lat: 12.1336018, lng: -15.1832411},
        mapTypeId: 'terrain'
    });
    //Define the custom symbols. All symbols are defined via SVG path notation.
    // They have varying stroke color, fill color, stroke weight,
    // opacity and rotation properties.
    var planeSymbol = {path: 'M 8.1326447,0.80527736 C 8.5471666,0.063577346 9.742752,0.030177346 10.052431,0.82497736 C 10.093464,3.0114774 10.134497,5.1980774 10.17553,7.3845774 C 12.760407,8.9653774 15.345284,10.546179 17.930161,12.127079 C 17.930161,12.881779 17.930161,13.636479 17.930161,14.391179 C 15.373077,13.579479 12.815993,12.767779 10.258908,11.956179 C 10.27281,13.280479 10.286713,14.604879 10.300615,15.929279 C 10.8565,16.555879 11.412385,17.182479 11.96827,17.809079 C 12.25527,18.269479 12.437605,19.641079 11.59784,19.085079 C 10.804104,18.802179 10.010367,18.519179 9.21663,18.236279 C 8.3133108,18.620779 7.4099916,19.005279 6.5066724,19.389779 C 6.3952441,18.705879 6.2272708,17.857479 6.8519879,17.359679 C 7.2927717,16.882879 7.7335555,16.406079 8.1743393,15.929279 C 8.1465467,14.604879 8.1187541,13.280479 8.0909615,11.956179 C 5.5894706,12.824879 3.0879797,13.693479 0.58648883,14.562179 C 0.54479393,13.821679 0.50309893,13.081079 0.46140403,12.340579 C 3.0184842,10.717079 5.5755645,9.0935778 8.1326447,7.4700774 C 8.1326447,5.2484774 8.1326447,3.0268774 8.1326447,0.80527736 z',
        scale: 1,
        strokeOpacity: 1,
        strokecolor: 'black',
        strokeWeight: 1,
        anchor: new google.maps.Point(9, 9)
    };
    
    var GRU = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: -23.6276104, lng: -46.6568016}], //Lis - GRU
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    var LAD = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: -8.8648774, lng: 13.2249472}], //Lis - LAD
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    var MIA = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: 25.8027373, lng: -80.2892127}], //Lis - MIA
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    var MAD = new google.maps.Polyline({
        path: [{lat: 38.771183, lng: -9.131135}, {lat: 40.4690627, lng: -3.5599042}], //Lis - MAD
        strokeOpacity: 0.1,
        icons: [{
                icon: planeSymbol,
                offset: '0'
            }],
        map: map});
    // call the function for all flight paths
    animatePlaneLine(GRU, 100, 200);  // 100 steps at an interval of 0.2 seconds 
    animatePlaneLine(LAD, 200, 2000);
    animatePlaneLine(MIA, 200, 2000);
    animatePlaneLine(MAD, 20, 2000);   // 20 steps, at an interval of 2 seconds 
    
    // One function to rule them all      
    function animatePlaneLine(line, steps, stepTime) {
      var count = 0;  // it counts from 0 to (parameter) steps, then cycles.
      var listener = window.setInterval(function() {
        count = (count + 1) % steps;
        var icons = line.get('icons');
        icons[0].offset = (100 * count / steps) + '%';
        line.set('icons', icons);
      }, stepTime);
      // you don't need this return, but you could use it for extra control, like if you have buttons to pause/stop/start the animation.
      return listener;  
    }
    }
    </script>