Hey guys i'm developing a tracking system in which i have to use the API of google maps to calculate ETA (estimated time of arrival).
I have the driving distance.
But I need the kilometers away to the arrival point in order to be able to predict the time of arrival.
How do I call the driving distance value below?
directionsService.route(request,
function(response, status) {
if ( status == google.maps.DirectionsStatus.OK ) {
(response.routes[0].legs[0].distance.value); // the distance in metres
return((response.routes[0].legs[0].distance.value)/1000); //distance e kilometres
}
else {
// oops, there's no route between these two locations
// every time this happens, a kitten dies
// so please, ensure your address is formatted properly
}
});
function getArrivalTime(distance, vel) {
return distance / vel;
};
console.log(getArrivalTime(distance,vel));
You can actually put your directions request in your function, getArrivalTime. Then you could simply create a var to hold the distance and set it equal to response.routes[0].legs[0].distance.value)/1000 Please see code sample here:
function getArrivalTime(vel) {
var distance;
directionsService.route(request,
function(response, status) {
if ( status == google.maps.DirectionsStatus.OK ) {
(response.routes[0].legs[0].distance.value); // the distance in metres
distance = ((response.routes[0].legs[0].distance.value)/1000); //distance e kilometres
}
else {
// oops, there's no route between these two locations
// every time this happens, a kitten dies
// so please, ensure your address is formatted properly
}
});
return distance / vel;
};
console.log(getArrivalTime(distance,vel));
You may need to put a timeout around return(distance,vel) to ensure the API call has had time to respond to the request before you return the data. One other option would be to create a global variable to hold distance so that you can access it in any function. It's typically best to avoid global variables though, so I'd recommend the first way I mentioned.
I hope this helps!
Related
I am developing an app using jQuery Mobile with PHP. I am not using Phonegap or other frameworks. I need to find user's geolocation. If user device's GPS is off, then I cant get a location. now I need to find user device's GPS is on or off.
this is what i using now.
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
var lat=position.coords.latitude;
var long=position.coords.longitude;
}
You can call this function on load
// Function to get location
function getLocation(){
navigator.geolocation.getCurrentPosition(function (pos) {
var lat = pos.coords.latitude;
var lng = pos.coords.longitude;
if (lat == null) {
alert("GPS not activated!");
} else {
alert("Latitude: "+ lat + " , Longitude: " + lng );
}
});
}
There is no way to check if the device has a GPS module or if it has it enabled through the browser's API. Your laptop will, for example, try to estimate the position based on the IP address with very poor accuracy.
You can, however, use a trick that will likely be good enough for many applications: instead of using the getCurrentPosition(), use the watchPosition() function with an options object { enableHighAccuracy: true } and set a threshold of accuracy that the measurement has to reach for you to accept it as most likely a result based on the GPS module.
What happens when you start to listen to the watchPosition() with enableHighAccuracy set to true is that if GPS module is available, the API will let it know that you're trying to get a measurement and after up to a few seconds the accuracy distance will go from very high (often thousands of meters - based on IP address, cell tower triangulation, etc.) to a very low (few meters - based on the GPS) and that means that the GPS kicked in. If the accuracy stays at hundreds or thousands of meters, it probably means that there is no GPS module available.
Here's the documentation for the GeolocationCoordinates object (the result within the callback passed to the watchPosition()) which comes with the accuracy field. I wrote a longer post that also contains a code snippet showing how I use the API within React.
I just solved this one. I am using:
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {maximumAge: 60000});
In the successCallback i written the codes for what it should do once I got the positions and in the error callback i wrote a simple alert message to prompt the user to turn the GPS on.
I Implemented This In Real World Project
KMaps-API GPS.js
<script>
function getLocationw() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPositionw);
} else {
x.innerHTML = "Something Is Wrong";
}
}
function showPositionw(position) {
lat = position.coords.latitude;
if(lat != null){
document.write('<center><div class="alert alert-info" role="alert"> Please Turn On Your GPS </div></center>')
}
}
getLocationw();
</script>
Here is my fiddle . Here i have displayed current location and end location by balloons.
And i am trying to put directions between start and end point in the map. In this case no markers for the directions are displayed may be because both shares common location. But the zoom is too great , results in it is not covering start and end point. User have to make double right click to see both start and location.
I have also tried,
new_boundary = new google.maps.LatLngBounds();
new_boundary.extend(new google.maps.LatLng(start));
new_boundary.extend(new google.maps.LatLng(end));
map.fitBounds(new_boundary);
But it is not working. Whats wrong with my map configuration ?
your script breaks (at least for me) at this line:
dir=((Math.atan2(z.lng()-a.lng(),z.lat()-a.lat())*180)/Math.PI)+360
take a look at this line:
z=(step.lat_lngs.length)?step.lat_lngs[1]:step.end_point,
for the first step lat_lngs.length is 1 , so step.lat_lngs[1] is undefined, the call of z.lng() fails with "Cannot call method 'lng' of undefined"
Possible fix for that error:
z=(step.lat_lngs.length>1)?step.lat_lngs[step.lat_lngs.length-1]:step.end_point,
Related to the zoom:
When you wouldn't have disabled the complete UI you would have seen that the result (zoom ) is correct.
The DirectionsRenderer by default will refresh the viewport of the map so that the complete route is visible.
This will be done(the bounds initally set in your script will be discarded).
To have another result(preserve the current viewport, but extend it that also the route is visible), you must:
set the preserveViewPort-option of the DirectionsRenderer to true(default is false)
extend the bounds of the map with the bounds of the route
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.set('preserveViewport',true);
map.fitBounds(map.getBounds().union(response.routes[0].bounds));
//continue with your code
This code is correct for example
Your map change resolution when you add
directionsDisplay.setDirections(response);
setDirections(directions:DirectionsResult) None Set the renderer to
use the result from the DirectionsService. Setting a valid set of
directions in this manner will display the directions on the
renderer's designated map and panel.
Hope, that i understand problem right, English i not my native language
Try to add validation as
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
if(!response.routes[0].bounds.getNorthEast().equals(response.routes[0].bounds.getSouthWest())){
directionsDisplay.setDirections(response);
}
addDirections(response.routes[0]);
}
});
To check if answer contains different point
I've found a lot of questions about GPS Coordinates but not one that confirms using the mobile hardware GPS instead of Web GPS like geoLocation and such like.
My actual method:
I'm using navigator.geolocation.getCurrentPosition(), the Lat/Long comes from the Web, here's the code:
function getGPS(funcCallBack)
{
if (navigator.geolocation)
{
var timeoutVal = getCookie("GPSTimeout");
navigator.geolocation.getCurrentPosition(sucess
,error
,{enableHighAccuracy: true
,timeout: timeoutVal
,maximumAge: 0}
);
}
else{
alert('GPS is turned off, or was not possible to find it. Now, doing the login without localization.');
window.gpsLat = 0;
window.gpsLng = 0;
window.gpsAcc = 0;
funcCallBack();
}
function sucess(position) //sucess
{
window.gpsLat = position.coords.latitude;
window.gpsLng = position.coords.longitude;
window.gpsAcc = position.coords.accuracy;
funcCallBack();
}
function error() //error
{
window.gpsLat = 0;
window.gpsLng = 0;
window.gpsAcc = 0;
funcCallBack();
}
}
My problem:
Sometimes when I do the login I am not getting the GPS Coordinates (they come 0) and sometimes I am getting coordinates with more than 2,000 Accuracy (that is not precise).
By the way, I am testing the GPS on a data internet service, when I do use a Wi-Fi connection it works perfectly with less than 100 Accuracy.
Details:
Maybe you are complaining about:
timeoutVal: it is a cookie with the number 5000 inside it.
funcCallBack: it is a function that continues the login operation.
window.gpsLat: it is a global var containing the Latitude value got from the geoLocation.
window.gpsLng: it is a global var containing the Longitude value got from the geoLocation.
window.gpsAcc: it is a global var containing the Accuracy value got from the geoLocation.
What do I want?
I want a solution in JavaScript or PHP that can get coordinates from the mobile hardware device, the Native GPS, not the geolocation, and when the Native GPS is turned off, ask the user to turn it on.
You should get the location with javascript not PHP. PHP is only capable of doing an IP lookup which is the least accurate method for determining location.
The way navigator.geolocation.getCurrentPosition() works is it uses the most accurate data currently available. In the case of a mobile device it will use GPS first if enabled, then wi-fi.
If native GPS is enabled javascript will access that data instead of the wi-fi data, but there is no way of preventing a check against the wi-fi data if the GPS data isn't available.
Your best solution is to check the accuracy field and if it's not within a range you're happy with ask the user to enable GPS.
Alternatively if you're building a hybrid app, most of the frameworks (PhoneGap .etc.) have APIs to query the device GPS directly. Use PhoneGap to Check if GPS is enabled
Geolocation API does not expose a direct way to check whether GPS is on or off, but you can catch the errors of geolocation and base on error type can draw conclusions from there.
E.g. POSITION_UNAVAILABLE (2) if the network is down or the positioning satellites can’t be contacted.
But its not sure short way you have to handle some conditions!
I will suggest use watchPostion { i agree its meant to watch and continuous to locate position} u can keep it on and if GPS throw the error u can prompt custom alert to make user turn on the GPS device/wifi/internet .. and if its come to success callback u can clear the watch.
var watch =null;
function success(position)
{
var lat = position.coords.latitude;
var lon= position.coords.longitude;
if (watch != null )
/*Need to take care .. as maybe there is no gps and user
want it off so keep attempt 3 times or some kind a way out otherwise it will
infinite loop */
{
navigator.geolocation.clearWatch(watch);
watch = null;
}
}
function getLatLon()
{
var geolocOK = ("geolocation" in navigator);
if ( geolocOK )
{
var option = {enableHighAccuracy:true, maximumAge: 0,timeout:10000 };
watch = navigator.geolocation.watchPosition(success, fails, option);
}
else {
//disable the current location?
}
}
function fails()
{
alert("please turn on the GPS !");
}
getLatLon();
I am using javascript, google direction service
I have multiple source points on the map and one destination point. I need to find the closest source point to the destination point. As direction service works asynchronously I need to map points with their lat/lang. However the problem is that, the response format sent by direction service changes.
function calcRoute(start, end) {
var request = {
origin:start,
destination:end,
travelMode:google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request,
function (response, status) {
distanceCount++;
if (status == google.maps.DirectionsStatus.OK) {
var dist = computeTotalDistance(response);
console.log(dist);
if (dist < minDistance) {
minDistance = dist;
minDistanceIndex = locationsMap[response.ug.origin.Ua+""+response.ug.origin.Va];
}
if (distanceCount == vl.length) {
drawWay(vl[minDistanceIndex], fsl);
}
}
}
);
}
The problem occurs on the line
minDistanceIndex = locationsMap[response.ug.origin.Ua+""+response.ug.origin.Va];
response.ug.origin.Va and response.ug.origin.Ua comes from google direction service, however it sometimes changes to response.ug.origin.Xa and response.ug.origin.Ya.
Do you have any ideas why it changes from time to time? or any ideas how to deal with that problem?
You don't have to access those internal properties, they are not a part of the API so they may change.
Use only the properties/methods defined inside the specification, all data provided by the response are accessible through them,
example:
response.routes[0].legs[0].start_location
//returns latLng of the origin
Apart from that:
Your description sounds as if you better should use a DistanceMatrixRequest
I'm trying to make a web application with google maps api, that gives directions. Right now, It gives directions fine unless the user types in something wrong, it either doesn't show anything or it tries to figure it out and gives the wrong address. I want to make functionality where if the address is not recognized it has "did you mean" and then make a suggestion that's close to what you were trying to enter. I couldn't find anything in the google code that talked about that, but I'm wondering if anyone knows if it's possible, and how I can do it?
Thanks!
loadFromWayPoints() draws polyline only if the inputs provided to it maps to any definite point on the earth. You can avoid the confusion to function by fixing your from point in form of latitude and longitude, instead of address. Then using following function you may create Did you mean for To point if multiple points returned for toInput.
Code is self explanatory. If you dont understand. Reply in comment.
One of the point you want to plot should return definite point from google geocoder system.
In my I used the from point as definite point. And had it coordinates with me. So there is no chance of getting
geo.getLocations(toInput, function (result){
//map.clearOverlays();
if (result.Status.code == G_GEO_SUCCESS) {
// ===== If there was more than one result, "ask did you mean" on them all =====
if (result.Placemark.length > 1) {
document.getElementById("textualdirectionscontainer").innerHTML = "Did you mean:";
// Loop through the results
for (var i=0; i<result.Placemark.length; i++) {
var p = result.Placemark[i].Point.coordinates;
document.getElementById("textualdirectionscontainer").innerHTML += "<br>"+(i+1)+": <a href='javascript:place(" +p[1]+","+p[0]+")'>"+ result.Placemark[i].address+"<\/a>";
}
}
// ===== If there was a single marker =====
else {
document.getElementById("textualdirectionscontainer").innerHTML = "";
var p = result.Placemark[0].Point.coordinates;
toLatLang = new GLatLng(p[1], p[0]);
// place(p[1],p[0]);
directionsPanel = $('textualdirectionscontainer');
directionsPanel.getElements('div').each(function(item) {
item.dispose();
});
directions.clear();
directions.loadFromWaypoints([hotelLatLng.toString(), toLatLang.toString()], {getPolyline:true});
/*var gp = directions.getPolyline();
map.addOverlay(gp); */
}
}
});