Firstly, I'm not a developer or programmer so any help here would be really appreciated! I have a form for use on android mobile devices which launches in Google Chrome. The users can use this form when offline and I was wondering how best to get offline GPS co-ordinates in lat and long. I've been doing some digging around and the code below seems to work. I pull the lat, long and accuracy result from this code into a separate field on my form.
What I am not sure about is how to pull in a timestamp so that I can be assured the reading is current and not something cached on the device. The currency and reliability of the coordinates is very important to me.
Any help at all on this would be marvellous!!
Thanks, Angela
<!DOCTYPE html>
<html>
<body>
<p>Get your latitude and longitude (test this to ensure it works when out of coverage)</p>
<button onclick="getLocation()">Get your coordinates</button>
<p id="demo"></p>
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
"<br>Accuracy: " + position.coords.accuracy + '<br />'
}
function showPosition(position) {
var latlon = position.coords.latitude + "," + position.coords.longitude +", Accuracy " + position.coords.accuracy;
$('input[name="coords"]').val(latlon).trigger('input');
}
</script>
</body>
</html>
getCurrentPosition accepts a second parameter, PositionOptions. There are a few options you can experiment with to achieve desired results, but specifically you'll want to use maximumAge and enableHighAccuracy. To ensure uncached results:
navigator.geolocation.getCurrentPosition(function(pos){
console.log('Got position', pos);
}, {
// can be `0` = uncached, any number in milliseconds,
// or `Infinity` which will only retrieve cached results
maximumAge: 0,
// may take longer, but browser will do everything possible
// to get the most accurate position
enableHighAccuracy: true
});
It's also worth noting the returned Position comes with an accuracy property, which returns a positive double indicating the accuracy of your lat and long in meters. Depending on the use case, you may want to require a certain accuracy threshold for users to interact with your app. You can see the full spec here.
Related
To substitute my usage of native apps that allow to keep track of my position, I wanted to generate a PWA using the HTML5 Goelocation API.
The result I have been able to achieve so far seems to point a inferior functionality of the HTML5 Goelocation API compared to native Android API.
Below is the code I have used and the issue is, that the PWA/ website application only receives infrequent updates. Additionally the app only receives position while the screen is not off.
This puts a huge obstacle into having a PWA being to track for instance my bike tour, since I cannot keep the screen and browser in the foreground, while ideed I wished the PWA would simply continues running even when the screen is off.
Now I am aware that in most cases a device user and privacy aware person would benefit from the useragent/browser to cut the waste of resources and limit privacy loss by disabling the very feature I search.
In essence however I have looked over the MDN documentation and besides the PositionOptions I was yet unable to find any clue about the guarantees of the API.
Find below the way I have sought to make it work as a code.
Does + Should HTML5 Goelocation API work when screen of on a mobile?
Is there a concrete information about if and how much geolocation information is returedn? like frequency/delay of update and like geofencing imprecision ?
Could for instance google maps navigation work in the browser itself?
My platform is Gecko on Android. If better results could be achieved in Chromium on Android I would be happy to hear about that too.
On Android I use firefox. In it I wanted to have my website provide a page that keeps track of my movements via the geolocation API, in order to replace my strave.
window.addEventListener("load",function(){
var a= document.createElement("div");
var textarea = document.createElement("textarea");
//textarea.value="aaaa"
textarea.style.display="block"
textarea.style.minHeight="5cm"
textarea.style.width="100%"
document.body.appendChild(a);
document.body.appendChild(textarea);
if(confirm("reset data?")){
localStorage.clear() ;
}
localStorage.setItem("start"+Date.now(),startInfo);
var startInfo = Object.keys(localStorage).length+ " " +Date.now()+ " " + (Date.now() % 864000);
var lastTime=0,lastLat=0,lastLon=0,count=0,lastDistance=0;
var startTime = Date.now();
var distance = 0;
if('geolocation' in navigator) {
a.innerHTML="<h2>super wir haben geolocation!</h2>";
setInterval(()=>{
navigator.geolocation.getCurrentPosition((position) => {
// var a = document.createElement("div");
count++;
a.innerHTML="<h1>"+(((Date.now()-startTime)/1000)|0)+" "+((distance*100|0)/100)+"</h1><h3>"+startInfo+"</h3><h2>date="+(new Date()).toString()+"<br>lang="+position.coords.latitude+" long="+ position.coords.longitude+"</h2>";
var lat = ((position.coords.latitude * 10000000) | 0)
var lon = ((position.coords.longitude * 10000000) | 0)
var time = Date.now();
var deltaTime = time - lastTime;
var deltaLat = lat - lastLat;
var deltaLon = lon - lastLon;
if(Math.abs(deltaLat)>100000 || Math.abs(deltaLon) > 100000)
{
} else{
distance += Math.sqrt(deltaLat*deltaLat+deltaLon*deltaLon);
}
var deltaDistance = distance - lastDistance;
lastLat=lat;
lastLon=lon;
lastTime=time;
lastDistance=distance;
newline = (((Date.now()-startTime)/1000)|0) + " dist=" + distance + "("+deltaDistance+") lat=" + lat + "("+deltaLat+") lon=" + lon + "("+deltaLon+") ";
textarea.value = newline + "\n" + textarea.value;
localStorage.setItem("P"+(Date.now()%864000),deltaLat+" "+deltaLon+" "+deltaTime);
},function(){},{timeout:900});
},1000);
} else {
a.innerHTML="<h2> shit</h2>";
}
});
Hi everyone! What I want:
I have a background video (duration 2 sec) on the homepage. Video should be played from the middle forward when the mouse cursor moves to the right and backward when the mouse cursor moves to the left. And is it possible to implement the same only on Android/iPhone? To play the video when the Android/iPhone is tilted. Maybe someone knows the examples. Please attach links to the examples.
You want to look at deviceOrientation - https://caniuse.com/#search=deviceorientation
Based on that you can use code similar to below to track the movement (in this case I think it would be the beta, though per CanIUse you should note Safari and Chrome use different coordinate systems) to determine where in the video you want to scroll to
<body>
<div id="status">Loading...</div>
<div id="alpha"></div>
<div id="beta"></div>
<div id="gamma"></div>
<script>
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', deviceOrientationHandler, false);
document.getElementById("status").innerText = "Supported!";
} else {
alert("Sorry, your browser doesn't support Device Orientation");
}
function deviceOrientationHandler(event) {
var time = new Date();
showTime = ("0" + time.getHours()).slice(-2) + ":" + ("0" + time.getMinutes()).slice(-2) + ":" + ("0" + time.getSeconds()).slice(-2);
document.getElementById("status").innerText = "triggered: " + showTime
document.getElementById("alpha").innerText = "Alpha: " + Math.round(event.alpha)
document.getElementById("beta").innerText = "Beta: " + Math.round(event.beta)
document.getElementById("gamma").innerText = "Gamma: " + Math.round(event.gamma)
}
</script>
</body>
I am working on an application that sends an e-mail with several information. Among the information is a link to the location of the user to Google Maps. A sample of the link would be:
http://www.google.com.ph/maps/place/14°39'3.8952"N121°2'57.4116"E/#14.651082,121.049281,17z
The code looks like this:
"Google Maps Link: http://www.google.com.ph/maps/place/" +
degToDMS(location.getLatitude()) + "\"N" +
degToDMS(location.getLongitude()) + "\"E/#" +
location.getLatitude() + "," + location.getLongitude() + ",17z");
I converted the degrees longitude and latitude to DMS using a formula I found online and it seemed to be returning good data. However, when I go check the email, the link looks like:
http://www.google.com.ph/maps/place/14°39'3.8952"N121°2'57.4116"E/#14.651082,121.049281,17z
and the hyperlink ends at the first double quote (") right before the N. This is actually a bit irritating and troubling because it doesn't link the entire link properly and it is cut.
How can I escape a double quote in a link? Or is there a better way to link to Google Maps?
I used URLEncode, thanks to for3st for the lead, as such:
final String urlRaw = degToDMS(location.getLatitude()) + "\"N" +
degToDMS(location.getLongitude()) + "\"E/#" +
location.getLatitude() + "," + location.getLongitude() + ",17z";
String encodedURL = "";
try {
encodedURL = URLEncoder.encode(urlRaw, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
where urlRaw is the "problematic' part of your url (where characters don't get escaped properly or something). You DON'T put in the http://.... because it will appear as such http%3A%2F%2Fwww.google.com.ph and yeah you don't want that.
Hence, I only escaped the latter part of my url, the one that starts with the DMS coordinates.
Once I have my encodedURL variable, I simply concat it to the rest of the starting URL as such:
String link = "Google Maps Link: http://www.google.com.ph/maps/place/" + encodedURL;
and not it works.
I try to obtain the GPS-Location of my Android Phone in Python (using QPython3 app). This kind of works, but it seems there are several LocationProviders in Android:
gps: pure gps location, slow, energy consuming, but very accurate,
and exactly what I need.
network: mix of gps and wifi/cell locating, faster, but less accurate
passive: like above but completely without using gps
Problem:
When I run my script (below) I only get my location provided by "network"
wich is not accurate enough.
But I can't find a way to force a specific LocationProvider.
Code:
# import needed modules
import android
import time
import sys, select, os #for loop exit
#Initiate android-module
droid = android.Android()
#notify me
droid.makeToast("fetching GPS data")
print("start gps-sensor...")
droid.startLocating()
while True:
#exit loop hook
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
line = input()
print("exit endless loop...")
break
#wait for location-event
event = droid.eventWaitFor('location',10000).result
if event['name'] == "location":
try:
#try to get gps location data
timestamp = repr(event['data']['gps']['time'])
longitude = repr(event['data']['gps']['longitude'])
latitude = repr(event['data']['gps']['latitude'])
altitude = repr(event['data']['gps']['altitude'])
speed = repr(event['data']['gps']['speed'])
accuracy = repr(event['data']['gps']['accuracy'])
loctype = "gps"
except KeyError:
#if no gps data, get the network location instead (inaccurate)
timestamp = repr(event['data']['network']['time'])
longitude = repr(event['data']['network']['longitude'])
latitude = repr(event['data']['network']['latitude'])
altitude = repr(event['data']['network']['altitude'])
speed = repr(event['data']['network']['speed'])
accuracy = repr(event['data']['network']['accuracy'])
loctype = "net"
data = loctype + ";" + timestamp + ";" + longitude + ";" + latitude + ";" + altitude + ";" + speed + ";" + accuracy
print(data) #logging
time.sleep(5) #wait for 5 seconds
print("stop gps-sensor...")
droid.stopLocating()
Sample Output (fake coordinates):
net;1429704519675;37.235065;-115.811117;0;0;23
net;1429704519675;37.235065;-115.811117;0;0;23
net;1429704519675;37.235065;-115.811117;0;0;23
Summarization:
How do I get a precise GPS location in Android using Python?
Thanks in advance everyone!
EDIT: already tested:
inside / outside
enabled / disabled
WiFi GPS enabled (before running script)
I had the same problem. You Can do something Like this if you want to enforce GPS as LocationProvider
import android, time
droid = android.Android()
droid.startLocating()
print('reading GPS ...')
event=droid.eventWaitFor('location', 10000)
while 1:
try :
provider = event.result['data']['gps']['provider']
if provider == 'gps':
lat = str(event['data']['gps']['latitude'])
lng = str(event['data']['gps']['longitude'])
latlng = 'lat: ' + lat + ' lng: ' + lng
print(latlng)
break
else: continue
except KeyError:
continue
I was trying to do something like this today and I had a similar problem. I was getting the same output over and over again. Long story short, I discovered this. Putting this in at the bottom of the loop should solve the problem.
droid.eventClearBuffer()
If you look at the original post sample output, you will notice that the time stamps are all the same. Clearing the buffer resets the object returned by the 'location' event.
droid = android.Android()
droid.startLocating(0, 0)
event = droid.eventWait(1000).result
if event['name'] == "location":
print(event['data']['gps'])
droid.stopLocating()
How can I get the exact Latitude and Longitude? I only get whole numbers. From my understanding, in order to get down to the meter I need to get down to 5 decimal places. I have tried the horizontal and vertical accuracy but they don't match my phones GPS reading.
How can I get an exact GPS reading with Geolocation API, Down to the meter?
here is my code
var my_geo:Geolocation = new Geolocation();
my_geo.setRequestedUpdateInterval(2000);
my_geo.addEventListener(GeolocationEvent.UPDATE, onGeoUpdate);
function onGeoUpdate(e:GeolocationEvent):void
{
gpsLat1 = (e.latitude);
gpsLon1 = (e.longitude);
gpsHeading = (e.heading);
gpsHorAcc = (e.horizontalAccuracy);
gpsVerAcc = (e.verticalAccuracy);
gpsCheck = 2;
my_txt.text = "My Latitude is "+ gpsLat1 + " and my Longitude is "+ gpsLon1 + " Bearing is " + gpsHeading+ " HorAcc "+ gpsHorAcc+ " VertAcc "+gpsVerAcc;
}
Make sure your variables (gpsLat1, gpsLon1, gpsHeading, etc.) are of type Number and not a uint or int. Unsigned Integers and Integers only allow for whole numbers, whereas Number is the equivalent of float in most other languages (and allows for incredibly larger values, as well). If you save a decimal to an integer, it is rounded off/floored (I can't remember which), which sounds exactly like the problem you are having.
Alternatively, the API is restricted by the hardware you are testing on. If the hardware only returns a certain value for GPS coordinates, AIR cannot be any more precise. Odds are this is not the issue since a whole lat long point can be miles and miles in distance, meaning any device with that inaccurate of a GPS chip is absolutely useless.
Try this:
function onGeoUpdate(e:GeolocationEvent):void
{
gpsLat1 = (e.latitude.toString());
gpsLon1 = (e.longitude.toString());
gpsHeading = (e.heading.toString());
gpsHorAcc = (e.horizontalAccuracy.toString());
gpsVerAcc = (e.verticalAccuracy.toString());
gpsCheck = 2;
my_txt.text = "My Latitude is "+ gpsLat1 + " and my Longitude is "+ gpsLon1 + " Bearing is " + gpsHeading+ " HorAcc "+ gpsHorAcc+ " VertAcc "+gpsVerAcc;
}