4

I am trying to build a live tracking with the route using Google Map JS version in ionic 4. What I am trying to achieve is to give the route to the user from source to destination and update the route if the user chooses a new path other than the google provided one. The source is the user and destination is some point in the map.

I am able to draw route and update it if the user change the provided path using

startNavigation(){
    this.geolocation.getCurrentPosition({ enableHighAccuracy: true })
      .then((position) => {
        this.userPosition = position;
        this.userVehicleMarker = new google.maps.Marker({
          map: this.map,
          position: { lat: position.coords.latitude, lng: position.coords.longitude },
          icon: this.vehicleIcon
        });
        this.addInfoWindow(this.userVehicleMarker, 'me')

        this.watchVehicle = this.geolocation.watchPosition({ enableHighAccuracy: true })
          .subscribe(async (pos) => 
                {
                    // Calling the redraw function on every 25 meters distance travelled
                    this.drawRouteFromVehicleToDestination(pos.coords.latitude, pos.coords.longitude)
            }
          }, (err: PositionError) => {
            // alert(err.message)
            console.log("error : " + err.message);
          });

      })
)



drawRouteFromVehicleToDestination(lat, lng) {
    let _self = this; 
    let directionsService = new google.maps.DirectionsService;
    let directionsRenderer = new google.maps.DirectionsRenderer({
      polylineOptions: {
        strokeColor: "#428BE8",
        strokeWeight: 2
      },
      suppressMarkers: true,
      preserveViewport: true
    });

    directionsRenderer.addListener('directions_changed', function () {
      let _data = directionsRenderer.getDirections();
      let _newData = _data['routes'][0]['legs'][0]
      console.log(_newData)
    });

    directionsService.route({
      origin: { lat: lat, lng: lng},
      destination: { lat: 27.673586, lng: 85.435131},
      travelMode: 'DRIVING',
      optimizeWaypoints: true,
      provideRouteAlternatives: false,
      avoidTolls: true,
    }, (res, status) => {
      if (status == 'OK') {
        directionsRenderer.setDirections(res);
        directionsRenderer.setMap(this.map);

      } else {
        console.warn(status);
      }
    });
  }

But the issue is, it is sending a lot of requests to google API and which does not look like a practical approach to follow.

Is there any other approach I should follow using which I could track the route and update it as per user location change and also minimize the google ping?

Thank you in advance for your help.

Sujan Gainju
  • 4,273
  • 2
  • 14
  • 34

1 Answers1

1

I think the issue is that you call drawRouteFromVehicleToDestination() very frequently (every time the vehicle position changes, from this.geolocation.watchPosition). One way to reduce the number of calls would be to "debounce" this calls, limiting them to every X ms at most, since probably it's acceptable to update every 200/300 ms. For example, you could use the lodash _.debounce function. For an in-depth explanation, see also the article Debouncing and Throttling Explained Through Examples.

this.watchVehicle = this.geolocation.watchPosition({ enableHighAccuracy: true })
    .subscribe(async (pos) => {
        _.debounce(() => {
            this.drawRouteFromVehicleToDestination(pos.coords.latitude, pos.coords.longitude);
        }, 300, { leading: true });
    }, (err: PositionError) => {
        // alert(err.message)
        console.log("error : " + err.message);
    });
Marco Pantaleoni
  • 2,529
  • 15
  • 14
  • Seems like we can not use '_.debounce' in ionic 4 typescripts. Also, I am using a distance limiter as call the redraw function after the vehicle has traveled 25meters of distance. It also does do the same as the debounce. But still getting a lot of pings to google map api – Sujan Gainju Nov 28 '19 at 13:24
  • I missed the distance limiter, but that should already reduce quite a lot the number of calls, are you sure it's working? (a vehicle moving at 60mph moves by 25m in ~1s, so you should have ~1 call/s per vehicle on avg). For reference, for the `_.debounce()`, probably you would have to use `@types/lodash` in addition to the lodash library (but if you are already debouncing with other means, you won't benefit from this). If vehicles move along the same routes, you could implement a sort of cache for api results, but that will be hardly an option I guess. – Marco Pantaleoni Nov 28 '19 at 15:06
  • yes, That is why I am looking for whether there is another option for this or not. The way I am doing corks perfectly but in the meantime is expensive – Sujan Gainju Nov 28 '19 at 16:17
  • you can use the RxJS debounce operator. In this case you'd need to have this.geolocation.watchPosition({ enableHighAccuracy: true }).pipe( debounce(() => timer(300)) ).subscribe(...) You can check more on debounce here: https://www.learnrxjs.io/operators/filtering/debounce.html – Monomachus Dec 03 '19 at 09:49