如何使原点标记(GM API DirectionService)缓慢移动到更新位置?

时间:2016-04-01 16:49:51

标签: javascript jquery google-maps-api-3

我有一个RoR项目,我可以获得两个对象的JSON坐标,任务卡车

我使用这些坐标通过Google Maps API DirectionService在它们之间绘制路线。

虽然任务的坐标是静态的,卡车的却不是,所以使用AJAX,我每隔10秒就会请求它们。

Atm,卡车的标记“跳”到新位置,造成难看的效果。

我想要完成的是,每次卡车的坐标更新时,卡车的标记应该慢慢滑动到新的位置。

关于如何做到这一点的任何想法,都会非常感激!

这是我的js文件:

$(document).on('page:change', function() {
  //gets new truck position every 10 seconds
  var intervalId = setInterval(getNewTruckPosition, 10000);

  // initial truck coordinates
  newTruckLatLng = {lat: 41.85, lng: -87.65};

  // mission coordinates(directionService destination -> static)
  missionLatLng = {lat: 40.771, lng: -73.974};
  drawMapData();

  function getNewTruckPosition() {
    $.ajax({
      ....
      success: function(data) {

        //gets new coordinates for truck
        newTruckLat = "new-value-from-json";
        newTruckLong = "new-value-from-json";
        newTruckLatLng = {lat: newTruckLat, lng: newTruckLong};

        //calculates and draws new route every time truck coordinates are updated
        drawMapData();
      }
    });
  }
  initMap();
});
function drawMapData() {

 ##########ISSUE I'M TRYING TO SOLVE#############

  //draws a new marker for the truck, deleting the last one ---> 
  //this results in a truck marker jumping effect
  //what I would like to achieve is the truck marker 
  //sliding to its new position, not jumping

  if (typeof newTruckLat != 'undefined') {
    function makeMarker() {
      if (typeof newMarker != 'undefined') {
        newMarker.setMap(null);
      }
      newMarker = new google.maps.Marker({
        //value received from JSON
        position: newTruckLatLng,
        map: map,
        title: "Truck's Position"
      });
    }
  }


  //***********ROUTING****************//

  directionsService = new google.maps.DirectionsService;
  directionsDisplay = new google.maps.DirectionsRenderer();

  directionsDisplay.setOptions(
  {
    suppressInfoWindow: true,
    suppressMarkers: true,
    polylineOptions: {
      strokeColor: "#1A239A",
      strokeOpacity: 0.9 ,
      strokeWeight: 5
     }
   });

  directionsDisplay.setMap(map);

  calculateAndDisplayRoute(directionsService, directionsDisplay);

  function calculateAndDisplayRoute(directionsService, directionsDisplay) {
    directionsService.route({

      //value received from JSON

      origin: newTruckLatLng,
      destination: missionLatLng,
      travelMode: google.maps.TravelMode.DRIVING
    }, function(response, status) {
      if (status === google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
        makeMarker();
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    });
  }
//***********Finished ROUTING****************//

}

function initMap() {

  isDraggable = $(document).width() > 480 ? true : false;

  if (typeof truckLat != 'undefined') {
    map = new google.maps.Map(document.getElementById('map'), {
      zoom: 12,
      draggable: isDraggable,
      scrollwheel: false,
      disableDefaultUI: true
    });
  }

  marker = new google.maps.Marker({
    position: missionLatLng,
    map: map,
    title: "Mission's Position"
  });

  newMarker = new google.maps.Marker({

    //initial value {newTruckLatLng = {lat: 41.85, lng: -87.65}}
    position: newTruckLatLng,
    map: map,
    title: "Truck's Position"
  });

  markers = [marker, newMarker];
  bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < markers.length; i++) {
   bounds.extend(markers[i].getPosition());
  }
  map.fitBounds(bounds);
}

1 个答案:

答案 0 :(得分:0)

管理解决我的问题。

HTML:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/scripts/v3_epoly.js"></script>

<div id="map"></div>

JS:

initialTruckLatLng = {lat: 48.8479, lng: 2.48678};
newTruckLatLng = {lat: 48.8479, lng: 2.5914};
missionLatLng = {lat: 48.8479, lng: 2.6514};


var map;
var directionDisplay;
var directionsService;
var stepDisplay;
var markerArray = [];
var position;
var marker = null;
var polyline = null;
var speed = 0.000005, wait = 1;
var infowindow = null;

var myPano;
var panoClient;
var nextPanoId;
var timerHandle = null;

function createMarker(latlng) {
  var marker = new google.maps.Marker({
    position: latlng,
    map: map
  });
  return marker;
}

function initialize() {
  infowindow = new google.maps.InfoWindow({ 
    size: new google.maps.Size(150,50)
  });
    // Instantiate a directions service.
  directionsService = new google.maps.DirectionsService();

  // Create a map and center it on mission.
  map = new google.maps.Map(document.getElementById('map'), {
    center: missionLatLng,
    zoom: 12,
    scrollwheel: false,
    disableDefaultUI: true
  });

  // Create a renderer for directions and bind it to the map.
  var rendererOptions = {
    map: map
  }
  directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);

  // Instantiate an info window to hold step text.
  stepDisplay = new google.maps.InfoWindow();

  polyline = new google.maps.Polyline({
    path: [],
    strokeColor: '#FF0000',
    strokeWeight: 3
  });

  missionMarker = new google.maps.Marker({
    position: missionLatLng,
    map: map,
    title: 'label'
  });
  marker = createMarker(initialTruckLatLng);
  markers = [marker, missionMarker];
  bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < markers.length; i++) {
   bounds.extend(markers[i].getPosition());
  }
  map.fitBounds(bounds);
}

var steps = []

function calcRoute(){

  if (timerHandle) { clearTimeout(timerHandle); }
  if (marker) { marker.setMap(null);}
  polyline.setMap(null);
  directionsDisplay.setMap(null);
  polyline = new google.maps.Polyline({
    path: [],
    strokeColor: '#1A239A',
    strokeOpacity: 0.9 ,
    strokeWeight: 5
  });

  // Create a renderer for directions and bind it to the map.
  var rendererOptions = {
    map: map
  }

  directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);

  var start = initialTruckLatLng;
  var end = newTruckLatLng;
  var travelMode = google.maps.DirectionsTravelMode.DRIVING

  var request = {
    origin: start,
    destination: end,
    travelMode: travelMode
  };

  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK){
      directionsDisplay.setDirections(response);

      var route = response.routes[0];
      startLocation = new Object();
      endLocation = new Object();

      // For each route, display summary information.
      var path = response.routes[0].overview_path;
      var legs = response.routes[0].legs;
      for (i=0;i<legs.length;i++) {
        if (i == 0) { 
          startLocation.latlng = legs[i].start_location;
          startLocation.address = legs[i].start_address;
          // marker = google.maps.Marker({map:map,position: startLocation.latlng});
          marker = createMarker(legs[i].start_location);
        }
        endLocation.latlng = legs[i].end_location;
        endLocation.address = legs[i].end_address;
        var steps = legs[i].steps;
        for (j=0;j<steps.length;j++) {
          var nextSegment = steps[j].path;
          for (k=0;k<nextSegment.length;k++) {
            polyline.getPath().push(nextSegment[k]);
            bounds.extend(nextSegment[k]);
          }
        }
      }

      polyline.setMap(map);
      startAnimation();
    }
  });

  // create a new route between the actual truck position and mission position
  directionsService = new google.maps.DirectionsService;
  directionsDisplay = new google.maps.DirectionsRenderer();

  directionsDisplay.setOptions(
  {
    suppressInfoWindow: true,
    preserveViewport: true,
    polylineOptions: {
      strokeColor: "#1A239A",
      strokeOpacity: 0.9 ,
      strokeWeight: 5
     }
   });

  directionsDisplay.setMap(map);

  calculateAndDisplayRoute(directionsService, directionsDisplay);

  function calculateAndDisplayRoute(directionsService, directionsDisplay) {
    directionsService.route({
      origin: newTruckLatLng,
      destination: missionLatLng,
      travelMode: google.maps.TravelMode.DRIVING
    }, function(response, status) {
      if (status === google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    });
  }    
}

var step = 50; // 5; // metres
var tick = 100; // milliseconds
var eol;
var k=0;
var stepnum=0;
var speed = "";
var lastVertex = 1;

//=============== animation functions ======================

function animate(d) {
  if (d >= eol) {
    polyline.setMap(null);
  }

  if (d>eol) {
    marker.setPosition(endLocation.latlng);
    return;
  }
  markers = [marker, missionMarker];
  bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < markers.length; i++) {
   bounds.extend(markers[i].getPosition());
  }
  map.fitBounds(bounds);

  var p = polyline.GetPointAtDistance(d);
  marker.setPosition(p);

  timerHandle = setTimeout("animate("+(d+step)+")", tick);
}


function startAnimation() {
  eol=polyline.Distance();
  setTimeout("animate(50)",2000);  // Allow time for the initial map display
}


//=============== ~animation functions =====================