so i'm currently working on an exercise application for a mobile device that tracks the location of the user while constantly updating the distance they have traveled. I can get the starting location of the user easy enough but its actually tracking them that I have no idea how to even start. I have a button for the user to get the current location called 'location' and i have a button called 'record' that will actually start the tracking process.
I know it has something to do with watchPosition() but im not quite sure how to use it and how to make it work with what i currently have. This is the first time ive done anything that required geoLocation.
Any helped would be much apreciated.
<script>
var c = function(position){
var latitude = position.coords.latitude,
longitude = position.coords.longitude,
acc = accuracy.coords.accuracy,
coords = position+ ', ' + long;
timeStamp = position.timestamp;
document.getElementById('google_map').setAttribute('src', 'https://maps.google.co.uk/?q=' + coords + '&z=50&output=embed');
}
var e = function(error){
switch(error.code){
case 0:
updateStatus("There was an error while retrieving your location: " +
error.message);
break;
case 1:
alert("The user prevented this page from retrieving a location.");
break;
case 2:
updateStatus("The browser was unable to determine your location: " +
error.message);
break;
case 3:
updateStatus("The browser timed out before retrieving the location.");
break;
}
}
document.getElementById('location').onclick = function() {
var watchId = navigator.geolocation.getCurrentPosition(c, e, {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 1000
});
return false;
}
document.getElementById("stop").onclick = function(){
navigator.geolocation.clearWatch(watchId);
}
</script>
Related
I created a custom teams application using Microsoft Teams Toolkit for VS Code. I am trying to read the location from the app. I am able to load the coordinates in the Browser and Android version of teams but it fails in the Desktop version of teams with the below error.
Network location provider at 'https://www.googleapis.com/' : No response received.
The function to load the Location-
const getLocation = () => {
let that = this;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
alert('got position');
var positionInfo = "Your current position is (Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude + ")";
alert(positionInfo);
}, (error) => {
alert("Error: " + error.message);
}, { timeout: 30000, enableHighAccuracy: true, maximumAge: 75000 });
} else {
alert("Geolocation is not supported by this browser.");
}
}
It might be a problem with the navigator.geolocation().getCurrentPosition API. Any leads on this will be useful.
I will let this question be here for anyone looking for an answer or if anyone finds an update to this.
I found this official documentation from MSFT that states geolocation API is not fully supported in the teams desktop client currently and they suggest using the getLocation API of TeamsSDK.
https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/device-capabilities/native-device-permissions?tabs=desktop
I'm creating a webapp/pwa where I need a precise user location, say under 30-40 meters, I have tried using Radar.io, as well as the geolocation api but still have not been able to get a precise enough location on my iphone on safari. I usually get 60-70 meter accuracy, how would I get more accurate than this? I want the accuracy to be that of the Nike Run Club app for reference.
I have used the Geolocation API many times and it's very precise if you configure it properly.
Here's a snippet I've used in a similar project:
// check if geolocation is supported on this browser
if (navigator.geolocation) {
const timeoutVal = 10 * 1000 * 1000; // set a timeout value for the query
navigator.geolocation.getCurrentPosition(
// what to do if query succeeds
((position) => alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude)),
((error) => {
// what to do if query fails:
const errors = {
1: 'Permission denied',
2: 'Position unavailable',
3: 'Request timeout'
};
alert("Error: " + errors[error.code]); // print the error
}),
// these 3 parameters are very important, especially the first one
{ enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
);
}
else {
alert("Geolocation is not supported by this browser");
}
Overall Picture:
I want to add geocoding to my application. I was able to get it working in straight up JavaScript, but the callbacks are not getting triggered after converting to Angular/TypeScript.
Example: if a user enters 1 Microsoft Way, Redmond, WA. The longitude and latitude should be returned: latitude: 47.64006815850735, longitude: -122.12985791265965
Code examples are built off the following resources:
Bing Maps Ajax API - get location from address
https://msdn.microsoft.com/en-us/library/hh868062.aspx
Error Details:
The errors are occurring specifically within the variable name: geocodeRequest. searchModuleLoaded() gets loaded, but my geocodeRequest never triggers geocodeCallback or errCallback. I'm thinking it has something to do with the scope of my methods, but can't seem to isolate what is causing the error. Any ideas on how to get my callbacks to trigger?
Angular/TypeScript (Not Working)
$onInit() {
this.getMap();
}
getMap() {
this.map = new Microsoft.Maps.Map(document.getElementById('myMap'), {credentials: "your key here"});
Microsoft.Maps.loadModule('Microsoft.Maps.Search', { callback: this.searchModuleLoaded });
};
searchModuleLoaded() {
var searchManager = new Microsoft.Maps.Search.SearchManager(this.map);
var geocodeRequest = {
where: "1 Microsoft Way, Redmond, WA",
count: 10,
callback: this.geocodeCallback,
errorCallback: this.errCallback
};
searchManager.geocode(geocodeRequest);
}
geocodeCallback(geocodeResult, userData) {
// this callback never gets triggered
alert("The first geocode result is " + geocodeResult.results[0].location + ".");
}
errCallback(geocodeRequest) {
// this callback never gets triggered
alert("An error occurred.");
}
Working Version (Works, but no Angular/TypeScript)
function GetMap(){
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), {credentials: "key goes here", center: new Microsoft.Maps.Location(47.5, -122.3), zoom: 9 });
Microsoft.Maps.loadModule('Microsoft.Maps.Search', { callback: searchModuleLoaded });
}
function searchModuleLoaded(){
var searchManager = new Microsoft.Maps.Search.SearchManager(map);
var geocodeRequest = {where:"1 Microsoft Way, Redmond, WA", count:10, callback:geocodeCallback, errorCallback:errCallback};
searchManager.geocode(geocodeRequest);
debugger;
}
function geocodeCallback(geocodeResult, userData){
alert("The first geocode result is " + geocodeResult.results[0].location + ".");
}
function errCallback(geocodeRequest){
alert("An error occurred.");
}
After furthing investigation, I was able to resolve my issue.
What was the problem?
The issue was occurring within the searchModuleLoaded. Both callbacks were undefined. One issue is that it was trying to execute searchModuleLoaded before the module had loaded and another issue was caused because it didn't know the context of this.
To fix the issue, I had to modify the callback while loading Microsoft.Maps.Search. The module's callback is now converted to a lambda function, which calls this.searchModuleLoaded(). Once this gets compiled into JavaScript, it sets the this context appropriatly i.e _this = this. My code looks like this now:
getMap() {
this.map = new Microsoft.Maps.Map(document.getElementById('myMap'), {credentials: "put your key here"});
Microsoft.Maps.loadModule('Microsoft.Maps.Search', {
callback: () => {
this.searchModuleLoaded();
}
});
};
searchModuleLoaded() {
var searchManager = new Microsoft.Maps.Search.SearchManager(this.map);
var geocodeRequest = {
where: "1 Microsoft Way, Redmond, WA",
count: 10,
callback: this.geocodeCallback,
errorCallback: this.errCallback
};
searchManager.geocode(geocodeRequest);
};
geocodeCallback(geocodeResult, userData) {
alert("The first geocode result is " + geocodeResult.results[0].location + ".");
};
errCallback(geocodeRequest) {
alert("An error occurred.");
};
I'm writing an Cordova/Phonegap app and I use a Geolocation plugin...this is my code...
var onSuccess = function(position) {
longitude = position.coords.longitude;
latitude = position.coords.latitude;
console.log("Latitude: "+position.coords.latitude);
console.log("Longitude: "+position.coords.longitude);
};
function onError(error) {
logService.debug("Code: "+error.code);
logService.debug("Message: "+error.message);
};
navigator.geolocation.getCurrentPosition(onSuccess, onError, { maximumAge: 3000, timeout: 15000, enableHighAccuracy: true });
Now, I test it on browser and when I don't the permission I receive Error code 1 (PositionError.PERMISSION_DENIED), when I do the permission it works very well on browser...Now born che question...When I test this on device and the GPS is off I don't receive the Error code 1 (PositionError.PERMISSION_DENIED) but receive always timeout...in this way I don't discern the difference...I set the timeout to 150000 but I receive always code 3 (PositionError.TIMEOUT)...Why? How can use it in the rigth way?
I've found the handling of the geolcation errors to be platform-specific. Since setting enableHighAccuracy: true causes your app to ask the OS retreive a position using the GPS hardware, the effect of turning off GPS on an Android device varies depending on the Android version: either the OS is never able to retreive a high-accuracy position, so the TIMEOUT error occurs (PERMISSION_DENIED will not be received on Android) or a low accuracy position will be retrieved and passed instead using Wifi/cell triangulation.
I'd suggest using watchPosition() instead of getCurrentPosition() to retrieve the location; getCurrentPosition() makes a single request for the device position at that current point in time, so the position timeout may occur before the GPS hardware on the device has had a chance to get a position fix, whereas using watchPosition() you can setup a watcher which will call the success function each time the OS receives a location update from the GPS hardware. If you only want a single location, clear the watcher after receiving a position of sufficient accuracy. If GPS is turned off on the Android device when the watcher is added, it will continue to return a TIMEOUT error; my workaround for this is to clear and re-add the watcher after a number of consequetive errors.
So try something along these lines:
var MAX_POSITION_ERRORS_BEFORE_RESET = 3,
MIN_ACCURACY_IN_METRES = 20,
positionWatchId = null,
watchpositionErrorCount = 0,
options = {
maximumAge: 60000,
timeout: 15000,
enableHighAccuracy: true
};
function addWatch(){
positionWatchId = navigator.geolocation.watchPosition(onWatchPositionSuccess, onWatchPositionError, options);
}
function clearWatch(){
navigator.geolocation.clearWatch(positionWatchId);
}
function onWatchPositionSuccess(position) {
watchpositionErrorCount = 0;
// Reject if accuracy is not sufficient
if(position.coords.accuracy > MIN_ACCURACY_IN_METRES){
return;
}
// If only single position is required, clear watcher
clearWatch();
// Do something with position
var lat = position.coords.latitude,
lon = position.coords.longitude;
}
function onWatchPositionError(err) {
watchpositionErrorCount++;
if (watchpositionErrorCount >= MAX_POSITION_ERRORS_BEFORE_RESET) {
clearWatch();
addWatch();
watchpositionErrorCount = 0;
}
}
addWatch();
I'm really new to Javascript, and I'm trying to jump into it.
I want to have a script get geolocation data and pass it to a variable, and then have the information displayed in an alert.
I have a jsFiddle here: http://jsfiddle.net/yJrtR/
When I run it, I get an "undefined" in the alert box. Can someone help me with this?
Here is my code:
function lat() {
navigator.geolocation.getCurrentPosition(function (position) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
}, function (error) {
console.log("Something went wrong: ", error);
});
}
function alert() {
var lat="";
var lon="";
lat();
alert("lat + lon");
}
There are several weird things in your code. Your fiddle is set to run onLoad, which means the functions you defined in your JavaScript won't be available globally - they'll be defined in the window.onload handler...which doesn't code outside of that to access them (especially inline event handlers). This is a perfect example of why not to use inline event handlers (even though the problem is really because of the jsFiddle settings).
So that means, when you call alert(); in your button's inline click handler, it calls the native window.alert() function, which brings up a dialog window. Since you pass nothing to it, it shows undefined. It's not actually calling your created alert function.
Also, since the getCurrentPosition method seems to be asynchronous, you should pass a callback function to lat, so that you can call it when it gets position.
Try this:
function lat(callback) {
navigator.geolocation.getCurrentPosition(function (position) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
callback.call(null, lat, lon);
}, function (error) {
console.log("Something went wrong: ", error);
});
}
function getPosition() {
lat(function (latitude, longitude) {
alert("lat: " + latitude + ", lon: " + longitude);
});
}
http://jsfiddle.net/yJrtR/1/
UPDATE:
Per your comment, if you'd like it to be shown "live", you can use something like this:
window.onload = function () {
var latElement = document.getElementById("lat"),
lonElement = document.getElementById("lon"),
lastUpdatedElement = document.getElementById("last_updated"),
getPositionOptions = {
enableHighAccuracy: false,
timeout: 10000,
maximumAge: 0
},
getPos = function () {
console.log("getPos function called");
navigator.geolocation.getCurrentPosition(function (position) {
console.log("Successfully retrieved position: ", position);
var coords = position.coords;
latElement.innerHTML = coords.latitude;
lonElement.innerHTML = coords.longitude;
lastUpdatedElement.innerHTML = new Date(position.timestamp);
setTimeout(getPos, 5000);
}, function (error) {
console.log("Something went wrong retrieving position: ", error);
setTimeout(getPos, 5000);
}, getPositionOptions);
};
getPos();
};
with the following HTML (just to "simulate" the dialog you speak of):
<div id="dialog">
<div>Your latitude is: <span id="lat"></span></div>
<div>Your longitude is: <span id="lon"></span></div>
<div>Last Updated: <small id="last_updated"></small></div>
</div>
DEMO: http://jsfiddle.net/yJrtR/12/
So what this code does is from the time the window has loaded, it continually re-gets the geo position. There are special options you can pass to the getCurrentPosition, that I declared in getPositionOptions.
As I said before, the getCurrentPosition is asynchronous, so the position could be retrieved at any time after calling getCurrentPosition is called...that's what the callbacks are for. In the options object, I set a timeout - 10000 - that says "don't take any longer than 10 seconds to retrieve the position", and if it does, it will call the error callback. The maximumAge option makes sure it always tries to grab the current location (instead of using a cached version, within a certain period of time.
So when either callback is called (could be 1 second later, could be 20 seconds later...although we set a timeout of 10 seconds), it will update the HTML with the details, and then do it all again 5 seconds later - that's what the setTimeout is for. This is because if we continually tried to get the position (without any kind of delay), the page would be very busy getting the position. 5 second delays, or even up to 15, should be fine.
Reference:
https://developer.mozilla.org/en-US/docs/DOM/window.navigator.geolocation.getCurrentPosition
UPDATE:
There is a specific method for the geolocation feature that lets you watch the position, called watchPosition, doing exactly what I was trying to emulate, but more efficiently. You could try this:
window.onload = function () {
var latElement = document.getElementById("lat"),
lonElement = document.getElementById("lon"),
lastUpdatedElement = document.getElementById("last_updated"),
watchPositionOptions = {
enableHighAccuracy: false,
timeout: 10000,
maximumAge: 0
};
navigator.geolocation.watchPosition(function (position) {
console.log("Successfully retrieved position: ", position);
var coords = position.coords;
latElement.innerHTML = coords.latitude;
lonElement.innerHTML = coords.longitude;
lastUpdatedElement.innerHTML = new Date(position.timestamp);
}, function (error) {
console.log("Something went wrong retrieving position: ", error);
}, watchPositionOptions);
};
DEMO: http://jsfiddle.net/yJrtR/14/
Reference:
https://developer.mozilla.org/en-US/docs/DOM/window.navigator.geolocation.watchPosition?redirect=no