Flutter - calculate mileage driven using geolocator and google api - google-maps

I am using the Google Directions API, initially to get the detailed from/to directions, i.e. from let's say Denver to Chicago.
What I need to do is get actual road mileage as they are driving. I am successfully streaming the coordinates from the plugin by geolocator, however, when I get distance between two GPS points it's the distance, not road mileage. This should be somewhat accurate if I take enough of these little readings and add up the distance.
Is this the best way?
I could also keep calling Google API, but that gets very expensive on a long trip with lots of users.

The API provides the distance in the route's Legs. Loop through them to add up the total distance in meters.
DirectionsService.init('API_KEY');
final directionsService = DirectionsService();
final request = DirectionsRequest(
origin: 'New York',
destination: 'San Francisco',
travelMode: TravelMode.driving,
);
directionsService.route(request, (result, status) {
if (status != DirectionsStatus.ok) {
// TODO Handle the error.
return;
}
var totalDistance = 0.0;
result.routes?.first.legs?.forEach((element) {
totalDistance += element.distance?.value?.toDouble() ?? 0.0;
});
print("This trip is $totalDistance meters.");
});

Related

how can i find or send shortest path to drawing route google distance matrix api?

I want to draw a route without traffic calculation. I try distance matrix service but ı can't find solution so when the response back from distance matrix service ı want to compare the routes and send shortest path to drawing but ı failed that too... Can you guys help or suggest anything?
directionsService
.route({
origin: document.getElementById("start").value,
destination: document.getElementById("end").value,
travelMode: "DRIVING",
unitSystem: google.maps.UnitSystem.METRIC,
drivingOptions: {
departureTime: new Date(Date.now()),
trafficModel: 'pessimistic'
}
})
.then((response) => {
directionsRenderer.setDirections(response);
console.log(response);
for (var i = 0; i < response.routes.length; i++) {
shortest.push(response.routes[0].legs[i].distance.value);
}
console.log(shortest);
})
I want to draw a route without traffic calculation.
As far as I can tell, this is not possible. It looks like you already found the traffic_model parameter for modifying traffic assumptions.

google maps direction api taking traffic in account

I am trying to write a simple script in order to calculate in a google sheet the travelling time between two locations, by taking in account the traffic.
I am using the class DirectionFinder of the google Maps API.
I have managed to calculate the time necessary for a trip, but whatever departure time I enter, my travelling time stays the same. Any idea on what am I doing wrong ? Is it even possible to take traffic into account using this class ? Do I need to be a business user to have access to this ?
Here is my code :
function DrivingSeconds(origin, destination, Y, M, D, H, S) {
Utilities.sleep(1000);
var time= new Date(Y,M,D,H,S);
var directions = Maps.newDirectionFinder()
.setDepart(time)
.setOrigin(origin)
.setDestination(destination)
.setMode(Maps.DirectionFinder.Mode.DRIVING)
.getDirections();
return directions.routes[0].legs[0].duration.value;
}
Thanks for any advice that you might have ! :)
From Google documentation:
For requests where the travel mode is driving: You can specify the departure_time to receive a route and trip duration (response field: duration_in_traffic) that take traffic conditions into account. This option is only available if the request contains a valid API key, or a valid Google Maps APIs Premium Plan client ID and signature. The departure_time must be set to the current time or some time in the future. It cannot be in the past.
https://developers.google.com/maps/documentation/directions/intro#RequestParameters
So yes, only for Premium users.Then your request should look like this:
var request = {
origin: origin,
destination: destination,
drivingOptions: {
departureTime: new Date(),
},
travelMode: google.maps.TravelMode[DRIVING]
};
var directionsService = new google.maps.DirectionsService();
directionsService.route(request, function(response,status) {
if(status == google.maps.DirectionsStatus.OK) {
console.log(response.routes[0].legs[0].duration_in_traffic);
}
});
directions.routes[0].legs[0].duration_in_traffic may be what you need.
E.g. this code:
function traffic_test() {
var threeAM = new Date();
threeAM.setDate(threeAM.getDate() + 1);
threeAM.setHours(3, 0, 0);
var eightAM = new Date(threeAM);
eightAM.setHours(8, 0, 0);
var directionFinder = Maps.newDirectionFinder()
.setOrigin('Union Square, San Francisco')
.setDestination('Golden Gate Park, San Francisco')
.setMode(Maps.DirectionFinder.Mode.DRIVING);
var directions = directionFinder.setDepart(threeAM).getDirections();
var leg = directions.routes[0].legs[0];
Logger.log('3AM: leg.duration=' + leg.duration.text +
'; leg.duration_in_traffic=' + leg.duration_in_traffic.text);
directions = directionFinder.setDepart(eightAM).getDirections();
leg = directions.routes[0].legs[0];
Logger.log('8AM: leg.duration=' + leg.duration.text +
'; leg.duration_in_traffic=' + leg.duration_in_traffic.text);
}
logs this:
[19-07-21 08:39:54:606 PDT] 3AM: leg.duration=16 mins; leg.duration_in_traffic=12 mins
[19-07-21 08:39:54:795 PDT] 8AM: leg.duration=16 mins; leg.duration_in_traffic=16 mins

How to find whether traffic is in given path or not using google maps api

geocomplete = "<?php echo $source ?>";
autocomplete = "<?php echo $destination ?>";
var request = {
origin: geocomplete,
destination: autocomplete,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
provideRouteAlternatives: true,
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
if (true) {
size = result.routes.length;
for (i = 0; i < result.routes.length; i++) {
// alert("Route "+ (i+1)+" is "+result.routes[i].summary);
summary[i] = result.routes[i].summary;
distance[i] = result.routes[i].legs[0].distance.text;
duration[i] = result.routes[i].legs[0].duration.text;
};
}
}
}
This is my code I can get the distance ,time and summary for given route using Google maps API , i need to check whether is there any traffic in given route? how to traffic details? i do not want whole traffic details . i just wanted to know . Traffic is there or not like Boolean option. Thanks in advance
Directions Service
durationInTraffic (optional) specifies whether the DirectionsLeg result should include a duration that takes into account current traffic conditions. This feature is only available for Google Maps API for Work customers. The time in current traffic will only be returned if traffic information is available in the requested area.
You also have the Traffic Layer but there is no documented method to retrieve detailed information.

Google maps how to force marker on the nearest road

I am doing a vehicle traking project, i am getting coordiantes from the databases, and showing on the google maps.
here is my code.....!!
function get_coordinates(checkbox){
var v_id=checkbox.id;
if(checkbox.checked){
var hr = new XMLHttpRequest();
hr.open("POST", "fetch_coordinates.php", true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var data = JSON.parse(hr.responseText);
var lat=data.loc.lat;
var lon=data.loc.lon;
addmarker(lat,lon,v_id);
}
}
hr.send("id="+v_id);
} else{
var mark = markers[v_id]; // find the marker by given id
mark.setMap(null);
delete markers[v_id];
}
}
function addmarker(lat,lon,v_id){
var marker = new google.maps.Marker({
id: v_id,
position: new google.maps.LatLng(lat, lon),
zoom: 8,
map: map,
title: 'Vehicle No: '+v_id,
icon: 'live.gif',
optimized:false
});
markers[v_id] = marker;
bounds.extend(new google.maps.LatLng(lat,lon));
// map.setOptions({center:new google.maps.LatLng(lat,lon),zoom:8});
map.fitBounds(bounds);
}
But the problem is, sometimes i get GPS coordiantes which are 1,2 inches away from the road (possibly because of less precison of device or signal distortion etc)
How should I force my marker to automatically adjust on the road? Is there a some way, using direction rendering or any other hint ??? please help
In 2017 the right way to do it is the Roads API Snap to Roads service.
You can read about this web service on
https://developers.google.com/maps/documentation/roads/snap
The Google Maps Roads API takes up to 100 GPS points collected along a route, and returns a similar set of data, with the points snapped to the most likely roads the vehicle was traveling along. Optionally, you can request that the points be interpolated, resulting in a path that smoothly follows the geometry of the road.
https://developers.google.com/maps/documentation/directions/intro
You can use your desired url to get json request..
In the Coding section you can write this code to get the location on the road..
Marker liveloc;
JSONObject obj1=new JSONObject(s);
JSONArray arr1=obj1.getJSONArray("routes");
for (int i=0;i<arr1.length();i++){
JSONObject obj2=arr1.getJSONObject(i);
JSONArray arr2=obj2.getJSONArray("legs");
JSONObject obj3=arr2.getJSONObject(0);
JSONObject obj4=obj3.getJSONObject("start_location");
String k=obj4.getString("lat");
String k2=obj4.getString("lng");
double k3=Double.parseDouble(k);
double k4=Double.parseDouble(k2);
LatLng myloc=new LatLng(k3,k4);
if (liveloc !=null){
liveloc.remove();
}
liveloc=mMap.addMarker(new MarkerOptions().position(myloc));
}
You need to get the first start location from the json request..
Hope it helps...

Google maps: DirectionService returns OVER_QUERY_LIMIT response

I am using google.maps.DirectionsService for getting the route between two points. This code was working from past 8 months. However, from past couple of days DirectionService route call is returning OVER_QUERY_LIMIT response status. There are only 6 set of points, out of which only 2 or 3 requests are getting the result, rest are failing. Code is unchanged from past 8 months. Below is the code snippet for reference:
var directionsService = new google.maps.DirectionsService();
var request = {
origin:originLatlng, //This is of type : google.maps.LatLng
destination:destLatlng,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
provideRouteAlternatives: true
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
polyline = new google.maps.Polyline({
path: result.routes[0].overview_path,
strokeColor: color1,
strokeOpacity: 0.8,
strokeWeight: 5,
geodesic: true
});
}
}
Almost 6 such simultaneous requests are made to DirectionService. I cannot put sleep in between the requests because, it will increase my application GUI load time.
I have tried the same code from different networks also, still problem persists.
I definitely did not come anywhere close to reaching the 2,500 daily request limit.
What could be the problem here? Please suggest a solution for this.
Any help would be greatly appreciated.
Thanks in advance
Satyapal
There are 2 kind of quota for Google Map API. You are using client side quota which blocks you if you request more than ~20 ( thats my observation ) geocode per minute.
Look here for detailed information :
https://developers.google.com/maps/articles/geocodestrat#client
Try putting your request inside a setTimeout() function: the query_limit could be referred to past requests too near from this one.
setTimeout(function(){
directionsService.route(request,function(result, status) {
if (status == google.maps.DirectionsStatus.OK)
{[...your code...]}
else alert(status);
});
},1000);
I followed Google's API for server-side directions and created a PHP page which will sleep(0.2) if an OVER_QUERY_LIMIT is returned as the status. I then used $.getJSON to retrieve this PHP page, which uses almost the exact same data and parameters. (Follow Google's directions to deal with the differences in the parameters.)
PHP:
$params = http_build_query($_GET);
$url = "http://maps.googleapis.com/maps/api/directions/json?sensor=false&" . $params;
$json = file_get_contents($url);
$status = json_decode($json)->status;
// check for over_query_limit status
while ($status=="OVER_QUERY_LIMIT") {
sleep(0.2); // seconds
$json = file_get_contents($url);
$status = json_decode($json)->status;
}
header('application/json');
echo $json;
jQuery:
request = { // construct route request object
origin: start_address,
destination: end_address,
waypoints: addresses.join('|'),
avoid: 'tolls'
};
$.getJSON('directions-lookup.php', request, function(response) {
//console.log(response);
var status = response.status;
if (status==google.maps.DirectionsStatus.OK) {
// do things here
};
});
Something I noticed is that when you're using the JavaScript Directions API, you'll get back things like lat/lng locations as Google LatLng objects, which doesn't happen here. I just used new google.maps.LatLng(..., ...) to build those back into objects.