Problem with Markers —> Goole Maps API Javascript

Issue

can you help me with this problem? My dashboard works like this: I have to locate a rover (flag icon) on the map, then I have to add markers on the map that simulate the waypoints that the rover must perform, when I press the START button I have to see the rover moving to each waypoint I created with the markers, to the last and stop there.

My problem is that the rover (flag icon) only moves to the last marker entered. I used a dynamic array to store the markers inside it, and in my solution idea, the rover, with a For loop and the setPosition() method should go to the first marker, wait 5s (setTimeout(5000)) and then move to the next, etc. what am I doing wrong?

this is the code JS:




/**
 * @license
 * Copyright 2019 Google LLC. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

//MAP---------------------------------

function initMap() {
//array arr1 which will contain the dynamically added markers      
  var arr1=[];

//myLatLng object with lat and lng attributes for position (europe)
  let myLatLng = { lat: 44.525961, lng: 15.255119  };

//constant map and assigned the map placed in the div id="map"
        const map = new google.maps.Map(document.getElementById("map"), {
          zoom: 4,
          //coordinates europe
          center: myLatLng,
        });
        
      //MARKER--------------------------------------
//marker object to put starting marker (rover)
        var markerRover = new google.maps.Marker({
          position: myLatLng,
          map: map,
          draggable: true,
          title: "ROVER",
          icon: "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png"
  
        });
  
//variables to write the rover coordinates in form input

        let latitudine= document.getElementById('latitudine').value= markerRover.position.lat();
        let longitudine= document.getElementById('longitudine').value= markerRover.position.lng();
  
//CLICK EVENT TO ADD MARKER by clicking on the map, calls the placeMarker function which places the marker on the map where the click occurred
        map.addListener("click", (e) => {
          placeMarker(e.latLng, map);
        });
      
        function placeMarker(latLng, map) {
          var mark= new google.maps.Marker({
            position: latLng,
            map: map,
          });
        
// dynamic array to store the markers placed by placeMarker
          arr1.push(mark);
  
//test print arr dynamic markers          
          console.log(arr1);
  
//event for START button
          var START = document.getElementById('start');
          START.addEventListener("click",  function spostaRover()
          {
//test print to see the length of the array
            console.log(arr1.length);
        
//for loop to set rover position on markers added dynamically  

              for(let i=0; i<arr1.length; i++)
                {
  
                  markerRover.setPosition(arr1[i].position);

//attempt to wait 5s and then move rover marker to new position
                    setTimeout(() =>  markerRover.setPosition(arr1[i].position),5000);
                    console.log('marcatore '+i+' fatto')
  
//in the Rover Coordinates input form, I add the new coordinates that the rover will have   
                      latitudine=document.getElementById('latitudine').value= markerRover.position.lat();
                      longitudine=document.getElementById('longitudine').value= markerRover.position.lng();
      
                }
  
          });
  
    /*
              //evento per tasto CONFIRM
              var CONFIRM = document.getElementById('confermaTappa');
              CONFIRM.addEventListener("click",  function addTappa(){
        
             
                
      
                // scrive in textArea le coordinate dell'ultimo marcatore creato
                let td1= document.getElementById("coordTry").textContent= "latitudine: "+mark.position.lat()+"\n" +"longitudine: " +mark.position.lng();
      
                //let td2= document.getElementById("coordTry").textContent=mark.position.lng();
            
              });
  
  
          //evento per tasto remove
          var REMOVE = document.getElementById('removeMarker');
          REMOVE.addEventListener("click", function removeMarker(){
        
            //leva da arr1 (array dei marcatori) ultimo marcatore da array
            arr1.pop(mark);
            //prova di stampa
            console.log(arr1);
            mark.setMap(null);
            //manca di togliere ultimo marcatore dalla mappa
          });
  */
      }//closing placemarker
     
      }
       
        window.initMap = initMap;

And this is the html:

<!DOCTYPE html>
<!--
 @license
 Copyright 2019 Google LLC. All Rights Reserved.
 SPDX-License-Identifier: Apache-2.0
-->
<html>
  <head>
    <title>geo-rover</title>
    
    <script src="script.js"></script>


    <link rel="stylesheet" href="style.css">

    <!-- jsFiddle will insert css and js -->
  </head>

<body>

<div class="container1">
  
  <h1>GEO-ROVER</h1>

      <div id="map">

      </div>

    
    <div class="containerPulsanti1">

      <div class="containerPulsanti2">

      <button class="pulsante" 
        id="removeMarker"
        type="button">
        REMOVE
      </button>
    
      <button class="pulsante"
        id="stop"
        type="button">
        STOP
      </button>

      <button class="pulsante"
        id="start"
        type="button"> 
        START
    </button>

    
    
      <button class="pulsante"
        id="confermaTappa"
        type="button">
        CONFIRM
      </button>

    </div>

      </div>
   
    <!-- Container 2 per coordinate attuali e tabella tappe*/  -->
    <div class="container2">

      <!-- Container 3 per gestire in flex contenuto container2 -->
      <div class="container3">
        
     <!-- Container per label coordinate-->
        <div class="containerCoordinate">

          <h2>Coordinate rover</h2>

            <div id="coordinate">

              <label for="coordinate" class="coordinateLat" > Latitudine</label>
              <input type="text" class="coordinateGeo" id="latitudine" name="latitudine" disabled >

              <label for="coordinate" class="coordinateLong"> Longitudine</label>
              <input type="text" class="coordinateGeo" id="longitudine" name="longitudine" disabled >

            </div>
     
        </div>

      <div class="containerTable">

        <h2>Coordinate tappe Rover</h2>

            <label for="coordTry"></label>
            <textarea id="coordTry" name="story" rows="10" cols="45" >
            </textarea>
    
    
        
      <!-- <table class="table">

      <thead>

      <tr>
      <th>TAPPE</th>
      <th>LATITUDINE</th>
      <th>LONGITUDINE</th>
      </tr>

      </thead>

      <tbody class="bodyTable">

      <tr>
      <th>1</th>
      <td id="tappa1lat">-</td>
      <td id="tappa1lng">-</td>
      </tr>

      <tr>
      <th>2</th>
      <td id="tappa2lat">--</td>
      <td id="tappa2lng">--</td>
      </tr>

      <tr>
      <th>3</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      </tr>

      <tr>
      <th>4</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      </tr>

      </tbody>          
      </table>

  
      </div>
       -->

    </div>
  </div>
</div>
    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    
<!--<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAFkjhEDLfud-pZFUtE_wdfspot2IWnuXI&callback=initMap&libraries=drawing&v=weekly" defer>   </script>
-->
 
<!--  ,geometry,places  ---non mio-->

  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=drawing&v=weekly" defer> </script>  

</body>

</html>


This is the CSS style:

  /* stile html e body*/
   
   @import url('https://fonts.googleapis.com/css?family=Coda');

   html,
   body {
     background: rgb(0,0,0);
   background: linear-gradient(180deg, rgba(0,0,0,1) 71%, rgba(168,167,0,1) 100%, rgba(204,209,0,1) 100%);
     margin: 0;
     padding: 0;
     height: 150vh;
     width: 100%
   }
   
   /*my rules*/
   
   /*TITOLI*/
   h1{
   
     font-family: Coda, cursive;
     font-style: italic;
       text-align: center;
       font-size: 35px;
       letter-spacing: 4px;
       word-spacing: 3px;
       color: rgb(247, 255, 0);
      
   }
   
   
   h2 {
    
     font-family: Coda, cursive;
     font-style: italic;
       text-align: center;
       
       letter-spacing: 4px;
       word-spacing: 3px;
       color: rgb(247, 255, 0);
   }

   
   /*container Principale che parte da sotto al titolo h1*/
   .container1 {
   
     display: flex;
     flex-direction: column;
     height: 100%;
   
   }
   /*mappa GOOGLE     div per contenere mappa*/
   #map  {
   
     flex: 6;
   }
   
   /*Container 2 per coordinate attuali e tabella tappe*/
   .container2 {
     
     flex: 3;
     padding-bottom: 1%;
     
   }
   /*container 3 per gestire in flexbox contenuto container 2*/
   .container3{
     display: flex;
     flex-direction: row;
     justify-content: space-around;
     
   }
   
   
   .containerPulsanti1{
   
     padding: 10px;
     flex:1;
   }
   .containerPulsanti2 {
     padding: 10px;
     margin: 10px;
     display: flex;
     flex-direction: row;
     justify-content: space-evenly;
     align-items: center;
   }
   .pulsante {
     
     cursor:pointer;
     color:#ffffff;
     font-family:Arial;
     font-size:17px ;
     padding:10px 25px;
     text-decoration:none;
   }
   
   .containerPulsanti2 {
     position:relative;
     top:1px;
   }
   #start{
     box-shadow: 0px 0px 5px 0px #3dc21b;
     background-color:#44c767;
     border-radius:28px;
     border:1px solid #18ab29;
   }
   
   #start:hover {
     background-color:#5cbf2a;
   }
   #start:active {
     background-color:#055509;
   }
   #stop{
     box-shadow: 0px 0px 5px 0px red;
     background-color:red;
     border-radius:28px;
     border:1px solid red;
   }
   #stop:hover {
     background-color: #f16161;
   }
   #stop:active {
     background-color:#890303;
   }
   #removeMarker{
     color: #000000;
     box-shadow: 0px 0px 5px 0px yellow;
     background-color:yellow;
     border-radius:28px;
     border:1px solid yellow;
   }
   
   #removeMarker:hover {
     background-color:#fcf288;
   }
   #removeMarker:active {
     background-color:#7b7100;
   }
   #confermaTappa{
     color: #000000;
     box-shadow: 0px 0px 5px 0px yellow;
     background-color:yellow;
     border-radius:28px;
     border:1px solid yellow;
   }
   #confermaTappa:hover {
     background-color:#fcf288;
   }
   
   #confermaTappa:active {
     background-color:#7b7100;
   }
   
   
   .coordinateGeo {
     padding: 5px;
     font-size: 16px;
     border-width: 2px;
     border-color: #fffb09;
     background-color: black;
     color: #ffffff;
     border-style: solid;
     border-radius: 10px;
     margin-top: 1vh;
     
   }
   /*.coordinateGeo:focus {
     outline:none;
   }*/
   #coordinate {
   
     display: flex;
     flex-direction: column;
   text-align: center;
   }
   .coordinateLong {
     margin-top: 2vh;
     font-family: verdana;
       text-align: center;
       font-size: 20px;
       color: rgb(255, 255, 255);
   
   }
   .coordinateLat {
    margin-top: 2vh;
     font-family: verdana;
       text-align: center;
       font-size: 20px;
       color: rgb(255, 255, 255);
   
   }
   #latitudine{
         text-align: center;
   
   }
   #longitudine{
         text-align: center;
   
   }
   

       
      
      
      
     
   

Solution

If my understanding is correct you simply want to move the beachflag/Rover marker from it’s initial position to each waypoint added by clicking on the map then perhaps the following simplified piece of code might help? The markers are moved with the timing function setInterval rather than setTimeout otherwise you would need some form of recursion to move to the next item in waypoints array.

If the aim is to simulate driving etc in pseudo realtime along a route calculated by Google’s Directions API then the following could be used as a basis but the codebase needed would be substantially more complicated.

<!doctype html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Google Maps: Follow the Rover til it's over!</title>
        <style>

            @import url('https://fonts.googleapis.com/css?family=Coda');
            html,
            body {
              background: rgb(0, 0, 0);
              background: linear-gradient(180deg, rgba(0, 0, 0, 1) 71%, rgba(168, 167, 0, 1) 100%, rgba(204, 209, 0, 1) 100%);
              margin: 0;
              padding: 0;
              height: 150vh;
              width: 100%
            }
            h1 {
              font-family: Coda, cursive;
              font-style: italic;
              text-align: center;
              font-size: 35px;
              letter-spacing: 4px;
              word-spacing: 3px;
              color: rgb(247, 255, 0);
            }
            h2 {
              font-family: Coda, cursive;
              font-style: italic;
              text-align: center;
              letter-spacing: 4px;
              word-spacing: 3px;
              color: rgb(247, 255, 0);
            }
            .container1 {
              display: flex;
              flex-direction: column;
              height: 100%;
            }
            #map {
              flex: 6;
            }
            .container2 {
              flex: 3;
              padding-bottom: 1%;
            }
            .container3 {
              display: flex;
              flex-direction: row;
              justify-content: space-around;
            }
            .containerPulsanti1 {
              padding: 10px;
              flex: 1;
            }
            .containerPulsanti2 {
              padding: 10px;
              margin: 10px;
              display: flex;
              flex-direction: row;
              justify-content: space-evenly;
              align-items: center;
            }
            .pulsante {
              cursor: pointer;
              color: #ffffff;
              font-family: Arial;
              font-size: 17px;
              padding: 10px 25px;
              text-decoration: none;
            }
            .containerPulsanti2 {
              position: relative;
              top: 1px;
            }
            #start {
              box-shadow: 0px 0px 5px 0px #3dc21b;
              background-color: #44c767;
              border-radius: 28px;
              border: 1px solid #18ab29;
            }
            #start:hover {
              background-color: #5cbf2a;
            }
            #start:active {
              background-color: #055509;
            }
            #stop {
              box-shadow: 0px 0px 5px 0px red;
              background-color: red;
              border-radius: 28px;
              border: 1px solid red;
            }
            #stop:hover {
              background-color: #f16161;
            }
            #stop:active {
              background-color: #890303;
            }
            #removeMarker {
              color: #000000;
              box-shadow: 0px 0px 5px 0px yellow;
              background-color: yellow;
              border-radius: 28px;
              border: 1px solid yellow;
            }
            #removeMarker:hover {
              background-color: #fcf288;
            }
            #removeMarker:active {
              background-color: #7b7100;
            }
            #confermaTappa {
              color: #000000;
              box-shadow: 0px 0px 5px 0px yellow;
              background-color: yellow;
              border-radius: 28px;
              border: 1px solid yellow;
            }
            #confermaTappa:hover {
              background-color: #fcf288;
            }
            #confermaTappa:active {
              background-color: #7b7100;
            }
            .coordinateGeo {
              padding: 5px;
              font-size: 16px;
              border-width: 2px;
              border-color: #fffb09;
              background-color: black;
              color: #ffffff;
              border-style: solid;
              border-radius: 10px;
              margin-top: 1vh;
            }
            #coordinate {
              display: flex;
              flex-direction: column;
              text-align: center;
            }
            .coordinateLong {
              margin-top: 2vh;
              font-family: verdana;
              text-align: center;
              font-size: 20px;
              color: rgb(255, 255, 255);
            }
            .coordinateLat {
              margin-top: 2vh;
              font-family: verdana;
              text-align: center;
              font-size: 20px;
              color: rgb(255, 255, 255);
            }
            #latitudine {
              text-align: center;
            }
            #longitudine {
              text-align: center;
            }
        </style>
        <script>
            const _DELAY=1;
            const $obj=(id)=>document.getElementById(id);
            
            function initMap() {
                var waypoints = [];
                let myLatLng = {
                    lat: 44.525961,
                    lng: 15.255119
                };
                const map = new google.maps.Map( $obj('map'), {
                    zoom: 4,
                    center: myLatLng
                });

                var markerRover = new google.maps.Marker({
                    position: myLatLng,
                    map: map,
                    draggable:true,
                    title:'ROVER',
                    icon:'//developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png'
                });


                let latitudine = $obj('latitudine').value = markerRover.position.lat();
                let longitudine = $obj('longitudine').value = markerRover.position.lng();

                

                const placeMarker=(e)=>{
                    waypoints.push( new google.maps.Marker({
                        position: e.latLng,
                        map: map
                    }));
                };

                const spostaRover=()=>{
                    console.groupCollapsed('Rover Activated')
                    let i=0;
                    
                    let tx=setInterval(()=>{
                        if( i >= waypoints.length ){
                            clearInterval( tx );
                            console.log('Finished');
                            console.groupEnd();
                            return true;
                        }
                        markerRover.setPosition( waypoints[i].position );
                        console.log( i, markerRover.getPosition() )
                        i++;
                    }, _DELAY * 1000 );
                };
                
                
                map.addListener('click', placeMarker );
                $obj('start').addEventListener('click',spostaRover);
            }
        </script>
    </head>
    <body>
        <div class='container1'>
            <h1>GEO-ROVER</h1>
            <div id='map'></div>


            <div class='containerPulsanti1'>
                <div class='containerPulsanti2'>
                    <button class='pulsante' id='removeMarker' type='button'>REMOVE</button>
                    <button class='pulsante' id='stop' type='button'>STOP</button>
                    <button class='pulsante' id='start' type='button'>START</button>
                    <button class='pulsante' id='confermaTappa' type='button'>CONFIRM</button>
                </div>
            </div>


            <div class='container2'>
                <div class='container3'>
                    <div class='containerCoordinate'>
                        <h2>Coordinate rover</h2>
                        <div id='coordinate'>
                            <label for='coordinate' class='coordinateLat'> Latitudine</label>
                            <input type='text' class='coordinateGeo' id='latitudine' name='latitudine' disabled>
                            <label for='coordinate' class='coordinateLong'> Longitudine</label>
                            <input type='text' class='coordinateGeo' id='longitudine' name='longitudine' disabled>
                        </div>
                    </div>
                    <div class='containerTable'>
                        <h2>Coordinate tappe Rover</h2>
                        <label for='coordTry'></label>
                        <textarea id='coordTry' name='story' rows='10' cols='45'></textarea>
                    </div>
                </div>
            </div>
        </div>
        <script async defer src='//maps.googleapis.com/maps/api/js?key=AIzaSy...........8.....Acp............E5G04tA&callback=initMap&libraries=drawing'></script>
    </body>
</html>

Proof of concept Fiddle

Answered By – Professor Abronsius

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published