How to place group of markers with transition effect?

400 views Asked by At

I have to show vehicle movements in google map, so on click of of group i make ajax call it gets lat lng and some info of all vehicles then I place a marker on map. Here if vehicle moves for the next ajax call I get diff lat lng at that time I show transition effect to marker. this is giving me problem ,

Here is my callback function of Ajax,

function callBackFunction(http_request) {
  if (http_request.readyState == 4) {
    if (http_request.status == 200) {


        var rs = http_request.responseText;
       //here rs is as follow in servlet  fstring=fstring+lat+","+lng+"$"+vn+"@notsame@"+busImg+"@"+drvcdr+"#";
       var SlNo=0;
       var position="";
       var busImg="";
       clear_Icon();  
       while(rs.length)
       {
           lat=rs.substring(0,rs.indexOf(","));
           lng=rs.substring(rs.indexOf(",")+1,rs.indexOf("$"));
           vn=rs.substring(rs.indexOf("$")+1,rs.indexOf("@"));
           rs=rs.substring(rs.indexOf("@")+1);
           position=rs.substring(0,rs.indexOf("@"));
           rs=rs.substring(rs.indexOf("@")+1);

           busImg=rs.substring(0,rs.indexOf("@"));
           rs=rs.substring(rs.indexOf("@")+1);
           drvcdr=rs.substring(0,rs.indexOf("#")); 
           add_icon(lat,lng,SlNo,vn,position,busImg,drvcdr);

           rs=rs.substring(rs.indexOf("#")+1);
           SlNo++;
       }

    } else {
        alert('ERR OR: AJAX request status = ' + http_request.status);
    }
}
}

placing marker and transition effect,

function add_icon(lt, ln,n,vn,position,busImg,drvcdr)  {

        var point = new google.maps.LatLng( lt, ln);
        //alert("Icon: "+busImg);

        marker= createMarker(point,n,vn,position,busImg,drvcdr);
        alert("After Marker placed:"+point.lat()+"  "+point.lng());
        transitionnn(point);
      }

  var gmarkers = [];

  function createMarker(point, number,vn,position,busImg,drvcdr) {

            var angleDegrees = 150;
               var marker = new google.maps.Marker({
                  position: point,
                  map: map,
                  raiseOnDrag: true,
                  icon:busImg,

                 // animation: google.maps.Animation.DROP,
                  draggable: false,
                  zIndex: number,
                  id:vn,
                  drvcddr:drvcdr


              });             

      var html = number;

      var infowindow = new google.maps.InfoWindow({
          content: 'Latitude: ' + point.lat() +
          '<br>Longitude: ' + point.lng()  + '<br>BusNo : '+ marker.get("id")+ '<br>DrivrConductor : '+ marker.get("drvcddr"), 
          maxwidth: 1000
      });

      google.maps.event.addListener(marker, 'click', function() {
        //map.setZoom(15);
        map.setCenter(marker.getPosition());
          infowindow.open(map,marker);
          });

      gmarkers.push(marker);
      return marker;
    };

    function transitionnn(point)
    {
      var result = [point.lat(), point.lng()];
      transition(result);
    }

    var numDeltas = 100;
    var delay = 100; //milliseconds
    var i = 0;
    var deltaLat;
    var deltaLng;


    function transition(result){

        i = 0;
        deltaLat = (result[0] - position[0])/numDeltas;
        deltaLng = (result[1] - position[1])/numDeltas;
        moveMarker();
    }

    function moveMarker(){
        position[0] += deltaLat;
        position[1] += deltaLng;
        var latlng = new google.maps.LatLng(position[0], position[1]);
        marker.setPosition(latlng);
        if(i!=numDeltas){
            i++;
            setTimeout(moveMarker, delay);
        }
    }

The problem is , in map I get markers but not in exact position and transition effect also not showing currectly. I dont know where I am going wrong can anyone help me to solve this . THank you.

1

There are 1 answers

2
Emmanuel Delay On

I think this is basically the effect you want.

What I do: 4 cars start from Brussels; each time you click on the button, you get the next points. Each marker transitions to its new spot.

The data should come from some DB (or so); I just use 3 sets of location (for each car)

Notice: you don't use jQuery. So I made (kind of) a minimal version of $.ajax with raw javascript

ajax_json.php

<?php
$locations = json_decode(
  '[
    [{"lat": 50.8454638, "lng": 4.33719938}, {"lat": 50.8555429, "lng": 4.35711210}, {"lat": 50.8454638, "lng": 4.369300}, {"lat": 50.8331057, "lng": 4.35711210}],
    [{"lat": 51.0540382, "lng": 3.72185772}, {"lat": 51.2199126, "lng": 4.40142220}, {"lat": 50.96458043, "lng": 5.493295848}, {"lat": 50.45450295, "lng": 3.95242041}],
    [{"lat": 51.20249156, "lng": 3.22428649}, {"lat": 51.92036145, "lng": 4.4799894}, {"lat": 50.936165, "lng": 6.96152633}, {"lat": 49.258189, "lng": 4.03229659}]
]');

$t = isset($_GET['t']) ? (int) $_GET['t'] : 0;
echo json_encode(array('locations'=> $locations[$t], 'get'=> print_r($_GET, 1) ));
?>

index.php

<style>
  #map_canvas {
    width: 700px;
    height: 500px;
  }
</style>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<link rel="stylesheet" href="css/style.css" type="text/css">
<script>
  // a few globals
  var t = 0;
  var markers = [];  // let's keep this global, so we can easily access it everywhere
  var map;
  // settings (100 steps, each step is 20ms apart)
  var interval = 20;
  var steps = 100;

  // this function makes an Ajax call, to get the locations of the car.
  function getNextLocations() {
    ajax({
      success: receiveNextLocations,
      url: 'ajax_json.php?t=' + t,
      dataType: 'json'
    });
    t++;
  }
  // callback for the ajax call.  Gets triggerd when the next locations are received from the server
  function receiveNextLocations(data) {
    for (var i=0; i<data.locations.length; i++) {
      if (markers[i]) {
        // update marker position, we use transition
        markerTransition(markers[i], markers[i].getPosition(), new google.maps.LatLng(data.locations[i].lat, data.locations[i].lng), 0);
      }
      else {
        // new marker
        var marker = new google.maps.Marker({
          position: new google.maps.LatLng(data.locations[i].lat, data.locations[i].lng),
          map: map
        });
        // we store the markers in an array
        markers.push(marker);
      }
    }
  }
  // recursive function.  Takes a marker and moves it to a destination, in many steps
  function markerTransition(marker, oldPosition, newPosition, i) {
    // we calculate the temporary position
    var tempPosition = new google.maps.LatLng(
      oldPosition.lat() + i * (newPosition.lat() - oldPosition.lat()) / steps,
      oldPosition.lng() + i * (newPosition.lng() - oldPosition.lng()) / steps    
    );
    marker.setPosition(tempPosition);
    if(i<steps) {
      setTimeout(function() {
          markerTransition(marker, oldPosition, newPosition, i+1);
        },
        interval
      );
    }
  }

  // initialize Google Maps
  function initialize() {
    var mapCanvas = document.getElementById('map_canvas');
    var mapOptions = {
      center: new google.maps.LatLng(50.8, 4.7),
      zoom: 6,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map = new google.maps.Map(mapCanvas, mapOptions);
  }
  google.maps.event.addDomListener(window, 'load', initialize);
</script>
<script>
  // ajax function that looks a bit like jQuery $.ajax
  // minimal code for what I need; not dummy proof, no error handling ...
  // feel free to extend this
  var http_request = new XMLHttpRequest();
  function ajax(options) {
    http_request.open(options.type || 'GET', options.url, true);
    http_request.send(options.data || null);
    http_request.onreadystatechange = function() {
      if (http_request.readyState == 4) {
        if (http_request.status == 200) {
          var type = options.dataType || '';
          switch (type.toLowerCase()) {
            default: 
              options.success(http_request.responseText);
              break;
            case 'json': 
              options.success(JSON.parse(http_request.responseText));
              break;
          }
        }
      }
    }
  }
</script>
<p id="map_canvas" ></p>
<input type="button" value="Next locations" onclick="getNextLocations()"><br><br>
<div id="messages"></div>