Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google maps API: calculate remaining time according to predefined route

I'm trying to implement some kind of personal real-time bus tracker and I'm stuck with this problem: let's say that point A is my origin and point E is my destination. Points B, C and D are waypoints defining the specific route for the bus. Every 15 seconds I get the updated location of the bus, and then I need to show the user the estimated time left for it to reach the destination, based on its route.

It happens that in Google Directions API every stop point is taken into account unregarding the bus's current position inside the specified route. In reality, if I get past point C, for example, then points A, B and C sould be out of the calculation because the bus have already stopped by those points.

How can I achieve something like that using GMaps APIs? Is it possible?

EDIT: If it's any help, I'm doing this on a Node.js server and I have no control over the location's update interval. That's because I make an external call to an API which returns me the location of the specified bus. Sure, I can make the calls how many times I want, but the returned location only get updated every 15 seconds. There's also a call that returns me all lat/lon coordinates that compose the route to use them as waypoints parameters to Google Directions.

I see that, knowing the start and end points of the route, and knowing the bus current position on the route, I can determine which waypoints I have to disconsider on the next call to Google Directions API. But how can I determine if the bus is inside it's route? And how can I determine its "progress" inside the route? I can't find an obvious way to do it.

UPDATE:

So I've followed Loreda L's answer and checked if I could make use of Google Distance Matrix API instead of Google Directions. But I still couldn't work it out. For example, let's use this sample call:

https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=-23.307339,-51.171461&destinations=-23.306628,-51.165768|-23.312134,-51.167751|-23.320006,-51.166655|-23.324167,-51.160821

Here I have an origin of lat = -23.307339 and lon = -51.171461, but let's say that the bus made a progress on the route such that it's position now is: lat = -23.315229; lon = -51.170670, which is half the way between two points on this route. Then let's make the call again:

https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=-23.315229,-51.170670&destinations=-23.306628,-51.165768|-23.312134,-51.167751|-23.320006,-51.166655|-23.324167,-51.160821

You can make these calls on your browser to see the results. As I've seen it, this data doesn't tell me anything about the travel time inside the given route. It just returns me individual travel distances and times between the destinations and the origin, but the calculation of those distances doesn't take into account the route I chose. You can check it on Google maps:

https://www.google.com.br/maps/dir/'-23.307339,-51.171461'/Condom%C3%ADnio+Comercial+Paula+Center,+Rua+Borba+Gato,+1170+-+Jd+Am%C3%A9rica,+Londrina+-+PR,+86010-630/@-23.3191734,-51.1753824,14.75z/data=!4m22!4m21!1m13!2m2!1d-51.171461!2d-23.307339!3m4!1m2!1d-51.1655654!2d-23.3066109!3s0x94eb44a453d12405:0x4fe6589ceb2a7640!3m4!1m2!1d-51.1679874!2d-23.3121241!3s0x94eb44a7b0b222bd:0xebae4eed90aa817!1m5!1m1!1s0x94eb436e990ab02f:0xbea600ba72575bee!2m2!1d-51.1606428!2d-23.324045!3e0

You can also check the same call, this time using Google Directions:

https://maps.googleapis.com/maps/api/directions/json?origin=-23.307339,-51.171461&destination=-23.324167,-51.160821&waypoints=-23.306628,-51.165768|-23.312134,-51.167751|-23.320006,-51.166655

I'm still not grasping how to make use of this data to achieve what I want.

like image 668
Pedro Corso Avatar asked Dec 18 '17 00:12

Pedro Corso


2 Answers

If you can get the bus current location at every 15s, shouldn't it be easy to use the longitude and latitude of the new point and the end point? Below is such a call to google API in their web sample, just supply them with your data

https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=40.6655101,-73.89188969999998&destinations=40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.659569%2C-73.933783%7C40.729029%2C-73.851524%7C40.6860072%2C-73.6334271%7C40.598566%2C-73.7527626%7C40.659569%2C-73.933783%7C40.729029%2C-73.851524%7C40.6860072%2C-73.6334271%7C40.598566%2C-73.7527626&key=YOUR_API_KEY

https://developers.google.com/maps/documentation/distance-matrix/intro

like image 63
Loredra L Avatar answered Sep 24 '22 10:09

Loredra L


As mentioned in the docs, the result of the distrance-matrix call consists of rows containing duration and distance values for each pair. This means that you have to form your pairs before making the call. So, let's say your route consists of the following points:

Your entire route:

Point 1: Lat_1,Lon_1
Point 2: Lat_2,Lon_2
Point 3: Lat_3,Lon_3
Point 4: Lat_4,Lon_4
Point 5: Lat_5,Lon_5

This means you need to make a distance-matrix call with the following parameters:

Your origins for the distance-matrix API call:

Lat_1,Lon_1
Lat_2,Lon_2
Lat_3,Lon_3
Lat_4,Lon_4

Your destinations for the distance-matrix API call:

Lat_2,Lon_2
Lat_3,Lon_3
Lat_4,Lon_4
Lat_5,Lon_5

When you send this to the distance-matrix API call (https://maps.googleapis.com/maps/api/distancematrix), it will return distance and duration for the following routes:

Point 1 --> Point 2
Point 2 --> Point 3
Point 3 --> Point 4
Point 4 --> Point 5

You can already see that to get the total duration of a trip, you need to add all the durations that are returned when you are using this method. Also, in your question you mention that you are able to disconsider points already traversed. So if you want to update the duration of the trip as you move through the route, all you need to do is to remove points that have already been traversed from your array, and use the most current location as the origin for the first pair that is still left to be traversed. This is assuming that the bus driver is not skipping any of the points.

  • Note: For your problem, in order to disconsider a point in your route (after it has been traversed), you can check if the distance between the current location and the location of the point in question is lower than a certain threshold (let's say 10m). Once this happens, you can just assume that the point has been traversed, and you can remove it from the array.
like image 31
JMA Avatar answered Sep 21 '22 10:09

JMA