Search code examples
javascriptgoogle-mapsvue.jsgoogle-maps-api-3google-directions-api

Google Directions API - Route is blurred after a new request


here is a picture with the problem.

I am using Vue.js to consume a REST API that send data about upcoming bus transfers. In the picture above each list item represents a transfer and when clicked, the map should show the route. When switching from smaller to bigger is okay, but then when I switch to a shorter route, the blue line indicating it appears blurred and bigger than normal. The problem disappears when I zoom in/out, it's just the initial display.

I've tried the setZoom(int) function on the map object after every new request, but that didn't work.

Here's the relevant code from the Vue instance:

methods: {
     ...
        calcRoute() {
          const request = {
            origin: this.start,
            destination: this.end
          }

          this.directionsService.route(request, (result, status) => {
            if (status == 'OK') {
              this.directionsRenderer.setDirections(result);
               //this.map.setZoom(12);
            }
          })
        }
},
watch: {
      start: () => {
        if (this.end && this.start) {
          this.calcRoute();
        }
      },
       ...
    }


EDIT: as suggested, I've provided a running code snippet. Click the CHANGE DIRECTIONS button to see the problem.

EDIT 2: I've implemented it in pure JS for simplicity

EDIT 3: Provide your API KEY

const transfers = [{
  "id": 29,
  "date": "2020-02-12T08:00:00.000Z",
  "pick_up": "Sofia Airport, Terminal 1",
  "drop_off": "Stara Zagora",
  "driver": "СТ",
  "vehicle": 6264,
},
{
  "id": 43,
  "date": "2020-02-13T08:30:00.000Z",
  "pick_up": "Sofia Terminal 1",
  "drop_off": "Boutique One Hotel Sofia",
  "driver": "СТ",
  "vehicle": 6264,
}];

let map, directionsService, directionsRenderer;
let selectedTrans = 0;

window.addEventListener('load', function() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 7,
    center: {
      lat: 42.698334,
      lng: 23.319941
    }
  });
  directionsService = new google.maps.DirectionsService();
  directionsRenderer = new google.maps.DirectionsRenderer();
  directionsRenderer.setMap(map);
  calcRoute();
});

function calcRoute() {
  const start = transfers[selectedTrans].pick_up;
  const end= transfers[selectedTrans].drop_off;
  const request = {
    origin: start,
    destination: end,
    travelMode: 'DRIVING'
  };

  directionsService.route(request, (result, status) => {
    if (status == 'OK') {
      directionsRenderer.setDirections(result);
    }
  })
}

document.getElementById('changeDirectionsBtn').addEventListener('click', () => {
  selectedTrans = selectedTrans == 0 ? 1 : 0;
  calcRoute();
});
#map {
  height: 100%;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<button id="changeDirectionsBtn"> Change Directions </button>
<div id="map">
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY" defer></script>


Solution

  • I'd need to investigate this a bit further when I have some time...

    The documentation mentions that

    Because the renderer is an MVCObject, it will automatically detect any changes to its properties and update the map when its associated directions have changed.

    and I am not sure about what that exactly means.

    That said, simply calling directionsRenderer.setMap(null); before calculating the new route and directionsRenderer.setMap(map); in the callback fixes the issue. See the snippet below.

    const transfers = [{
      "id": 29,
      "date": "2020-02-12T08:00:00.000Z",
      "pick_up": "Sofia Airport, Terminal 1",
      "drop_off": "Stara Zagora",
      "driver": "СТ",
      "vehicle": 6264,
    },
    {
      "id": 43,
      "date": "2020-02-13T08:30:00.000Z",
      "pick_up": "Sofia Terminal 1",
      "drop_off": "Boutique One Hotel Sofia",
      "driver": "СТ",
      "vehicle": 6264,
    }];
    
    let map, directionsService, directionsRenderer;
    let selectedTrans = 0;
    
    window.addEventListener('load', function() {
      map = new google.maps.Map(document.getElementById("map"), {
        zoom: 7,
        center: {
          lat: 42.698334,
          lng: 23.319941
        }
      });
      
      directionsService = new google.maps.DirectionsService();
      directionsRenderer = new google.maps.DirectionsRenderer();
      
      calcRoute();
    });
    
    function calcRoute() {
    
      directionsRenderer.setMap(null);
    
      const start = transfers[selectedTrans].pick_up;
      const end= transfers[selectedTrans].drop_off;
      const request = {
        origin: start,
        destination: end,
        travelMode: 'DRIVING'
      };
    
      directionsService.route(request, (result, status) => {
        if (status == 'OK') {
          directionsRenderer.setDirections(result);
          directionsRenderer.setMap(map);
        }
      })
    }
    
    document.getElementById('changeDirectionsBtn').addEventListener('click', () => {
      selectedTrans = selectedTrans == 0 ? 1 : 0;
      calcRoute();
    });
    #map {
      height: 100%;
    }
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <button id="changeDirectionsBtn"> Change Directions </button>
    <div id="map">
    </div>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk" defer></script>