Google Maps. Tracking history on the map. Wrong route due to coordinate errors

My app shows vehicle tracking history on Google Map. We get the location from our mobile app every 2 minutes and store it in the database. After that we show the route (using the JS API, Directions Service) on the map.

{
  origin: 'Chicago, IL',
  destination: 'Los Angeles, CA',
  waypoints: [
    ...
     ],
  provideRouteAlternatives: false,
  travelMode: 'DRIVING',
  unitSystem: google.maps.UnitSystem.IMPERIAL
}

      

However, sometimes the location may be inaccurate as little as 3-5 meters. For example, some place may be shown on the line of oncoming traffic. As a result, Google creates a route around multiple blocks, etc. enter image description here

So the question is, is there any possible way to ignore such imprecise points and just "force" Google to create a route in one direction?

Thank!

+3


source to share


1 answer


I had an idea. It looks like it works, at least for the points I picked in a similar situation.

I put my feet (= route segments between waypoints) in a for loop. For each segment, I calculate / read the "route distance" and dividing it by the flight path distance. This ratio should be about 1. If it is much more than 1, something similar. I set the threshold to 2.0, you should probably lower it (guestimate value from 1 to 2).

When such a factor is found, I remove that waypoint (well, I make a new array "newWaypoints" without this element) and run again, this results in a red route after a 2 second setTimeout.



The function is recursive, I don't know what's going on with the multiple points that need to be removed. Perhaps this can happen again.

<style>
  #map {height: 400px;}
</style>
<div id="map"></div>
<div id="log"></div>
<input type="button" value="click" onclick="calc()">
<script>
var directionsDisplay;
var directionsService;
var map;
var maxFactor = 2.0;    // FEEL FREE TO GUESTIMATE ANOTHER VALUE
function initMap() {
  var start = new google.maps.LatLng(50.96622130043278,3.8518730520809185);
  var mapOptions = {
    zoom:7,
    center: start
  }
  map = new google.maps.Map(document.getElementById('map'), mapOptions);
  directionsService = new google.maps.DirectionsService();
}
function calcRoute(start, end, waypoints, color) {
  directionsDisplay = new google.maps.DirectionsRenderer({ map: map, polylineOptions: {strokeColor: color} });
  var request = {
    origin: start,
    destination: end,
    waypoints: waypoints,
    provideRouteAlternatives: false,
    travelMode: 'DRIVING',
    unitSystem: google.maps.UnitSystem.IMPERIAL
  };
  directionsService.route(request, function(result, status) {
    if (status == 'OK') {
      var newWaypoints = [];

      directionsDisplay.setDirections(result);
      var legs = result.routes[0].legs;
      var problemIndex = -1;
      for(var i in legs) {
        var routeSegment = legs[i].distance.value;
        var origin = legs[i].start_location;
        var destination = legs[i].end_location;
        var flightpathDistance = google.maps.geometry.spherical.computeDistanceBetween(origin, destination);
        var factor = (routeSegment / flightpathDistance);
        if(factor > maxFactor && problemIndex == -1) {
          // too long
          problemIndex = i;
          document.getElementById('log').innerHTML += 'factor ' + factor.toFixed(2) + ' - segment looks too long. romove waypoint ' + i + ' (0 based)<br/>'; 
        }
        else if(factor > maxFactor && problemIndex == i -1) {
          if(i<legs.length - 1) {  // skip the destination; this is not a waypoint
            newWaypoints.push(waypoints[i]);
          }
          document.getElementById('log').innerHTML += 'factor ' + factor.toFixed(2) + ' - segment also too long, but the problem is probably the previous segment<br/>'; 
        }
        else {
          if(i<legs.length - 1) {  // skip the destination; this is not a waypoint
            newWaypoints.push(waypoints[i]);
          }
          document.getElementById('log').innerHTML += 'factor ' + factor.toFixed(2) + '<br/>';
        }
      }
      document.getElementById('log').innerHTML += '<hr/>';
      if(problemIndex > -1) {
        setTimeout(function() {
          calcRoute(start, end, newWaypoints, 'red');
        }, 2000);

      }
    }
  });      
}
function calc() {
  calcRoute(
    '50.95487921891042,3.879781222422025', 
    '51.002379049703315,3.757394492495223',
    [
      {location: '50.96622130043278,3.8518730520809185', stopover: true},
      {location: '50.9725522849737,3.8379914402503345', stopover: true},
      {location: '50.97957292616706,3.8236401199901593', stopover: true},  // This is the problem point, on the opposite side of the road
      {location: '50.98570531465853,3.81125807762146', stopover: true},
      {location: '50.98941308813775,3.8019619700935436', stopover: true}
    ],
    "blue"
  );
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap&libraries=geometry"></script>

      

0


source







All Articles