Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistent behaviour drawing a route between two points in Google Maps v3

The scenario

I'm trying to draw a route between n points (lat,lan) using Google Maps v3. To do this I'm using DirectionsService which provides me with a route, then I'm pushing that coordinates into a MVCArray and then drawing that path by using a Polyline.

The code

Here is a jsfiddle demonstrating that part of code here.

HTML:

<div id='map'></div>

CSS:

#map{
    width:400px;
    height:400px;
}

JavaScript:

$(function () {
    //The list of points to be connected
    var markers = [
        {
            "title": 'Duero',
            "lat": '40.480243',
            "lng": '-3.866172',
            "description": '1'
        },
        {
            "title": 'Reyes Catolicos',
            "lat": '40.477997',
            "lng": '-3.870865',
            "description": '2'
        },
        {
            "title": 'Guadarrama',
            "lat": '40.478998',
            "lng": '-3.878755',
            "description": '3'
        }
    ];

    var map;

    var mapOptions = {
        center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
        zoom: 15  ,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var path = new google.maps.MVCArray();
    var service = new google.maps.DirectionsService();

    var infoWindow = new google.maps.InfoWindow();
    var map = new google.maps.Map(document.getElementById("map"), mapOptions);
    var poly = new google.maps.Polyline({
        map: map,
        strokeColor: '#F3443C'
    });
    var lat_lng = new Array();

    path.push(new google.maps.LatLng(markers[0].lat, markers[0].lng));
    for (var i = 0; i < markers.length; i++) {
        if ((i + 1) < markers.length) {
            var src = new google.maps.LatLng(markers[i].lat, markers[i].lng);
            var des = new google.maps.LatLng(markers[i+1].lat, markers[i+1].lng);

            poly.setPath(path);
            service.route({
                origin: src,
                destination: des,
                travelMode: google.maps.DirectionsTravelMode.DRIVING
            }, function (result, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                    for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
                        path.push(result.routes[0].overview_path[i]);
                    }
                }
            });
        }
    }
});

Expected behaviour

I should get a set of straight lines drawn, connecting the points (lat,lan) specified in the variable markers, with the specified width and color. More specifically Point 1 being connected just to Point 2 which in turn is connected to Point 3

With the code in the fiddle, I would want to see, this: enter image description here

Actual behaviour

I get the previous image, but not always. If you refresh, a few times you will end up getting this, which I believe is the result of adding one extra line connecting the points as the crow flies, however, being an inconsistent behaviour I'm struggling to find the source of it, I simplified the example yo have an array of vertices as small as possible, and as far as I can see, the path being drawn should be the same, since the data is the same. Admittedly I've never delved into google maps api in great depth, so the source code is mainly the result of copying and pasting from working online samples, particularly this one which is also suffering from the same issue.

This means that I may be using an outdated version of Google maps, initializing it incorrectly or any other basic problem or flawed setup. Or on the other side of things, it could be a problem with the client, say Mac Chrome latest version, since apparently it's not happening in Chrome for Android on my phone (Nexus 5, latest, stock)

enter image description here

like image 301
Juan Cortés Avatar asked Apr 19 '14 22:04

Juan Cortés


1 Answers

Don't add the destination, source and waypoint locations to the polyline, just points from the directions service:

working fiddle

screenshot or resulting map

var map = null;
var infowindow = new google.maps.InfoWindow();
var bounds = new google.maps.LatLngBounds();

//The list of points to be connected
var markers = [{
  "title": 'Duero',
  "lat": '40.480243',
  "lng": '-3.866172',
  "description": '1'
}, {
  "title": 'Reyes Catolicos',
  "lat": '40.47806',
  "lng": '-3.870937',
  "description": '2'
}, {
  "title": 'Guadarrama',
  "lat": '40.478998',
  "lng": '-3.878755',
  "description": '3'
}];


//    var map;
function initialize() {
  var mapOptions = {
    center: new google.maps.LatLng(
      parseFloat(markers[0].lat),
      parseFloat(markers[0].lng)),
    zoom: 15,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var service = new google.maps.DirectionsService();

  var infoWindow = new google.maps.InfoWindow();
  map = new google.maps.Map(document.getElementById("map"), mapOptions);
  var lat_lng = new Array();

  var marker = new google.maps.Marker({
    position: map.getCenter(),
    map: map,
    draggable: true
  });
  bounds.extend(marker.getPosition());
  google.maps.event.addListener(marker, "click", function(evt) {
    infowindow.setContent("coord:" + marker.getPosition().toUrlValue(6));
    infowindow.open(map, marker);
  });
  for (var i = 0; i < markers.length; i++) {
    if ((i + 1) < markers.length) {
      var src = new google.maps.LatLng(parseFloat(markers[i].lat),
        parseFloat(markers[i].lng));
      createMarker(src);

      var des = new google.maps.LatLng(parseFloat(markers[i + 1].lat),
        parseFloat(markers[i + 1].lng));
      createMarker(des);
      //  poly.setPath(path);
      service.route({
        origin: src,
        destination: des,
        travelMode: google.maps.DirectionsTravelMode.DRIVING
      }, function(result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
          var path = new google.maps.MVCArray();
          var poly = new google.maps.Polyline({
            map: map,
            strokeColor: '#F3443C'
          });
          for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
            path.push(result.routes[0].overview_path[i]);
          }
          poly.setPath(path);
          map.fitBounds(bounds);
        }
      });
    }
  }
}

function createMarker(latLng) {
  var marker = new google.maps.Marker({
    position: latLng,
    map: map,
    draggable: true
  });
  bounds.extend(marker.getPosition());
  google.maps.event.addListener(marker, "click", function(evt) {
    infowindow.setContent("coord:" + this.getPosition().toUrlValue(6));
    infowindow.open(map, this);
  });
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map {
  width: 100%;
  height: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id='map'></div>
like image 85
geocodezip Avatar answered Sep 23 '22 20:09

geocodezip