Comments (18)
I had a quick look at the iOS CLLocationManager documentation and saw no way to control the frequency of updates... but I did found something interesting.
Apple recommends using the requestLocation
method for obtaining a single update. Cordova getCurrentPosition
does not use that method and instead uses startUpdatingLocation
, which is a method used to watch for GPS continuously.
I'm not sure if there is any particular reason why it's done that way but I do think it's worth checking out to see if using requestLocation
for getCurrentPosition
on the native side changes behaviour. I unfortunately don't have easy access to a mac so I can't really experiment this myself.
If you're not comfortable looking at or changing the native code yourself, then I would suggest sharing a reproduction repo that can be used as a testing ground.
from cordova-plugin-geolocation.
Here you go: https://github.com/ninaDeimos/geolocationTesting
from cordova-plugin-geolocation.
The timestamp attached to the geolocation event reflects the time of when the event was captured. When requesting GPS point, the native SDK will return the last known good GPS point, which could be several seconds in the past. It is also entirely possible that a second GPS request could return you the same GPS location event, if the phone hasn't received an updated location event for some time.
I don't think this is a bug, I think this should be the intended behaviour. In my apps I tend to use both the GPS timestamp and a timestamp of when the callback is called (using Date.now()
) to determine how trustworthy a GPS point is.
from cordova-plugin-geolocation.
But isn't it confusing:
You have an option (maximumAge) for exactly that, and you set the option to 0, which means you only want completely fresh GPS locations. And then if you check the data you get, you see it's actually NOT completely fresh.
I mean, what's the maximumAge for in that case? Or does the plugin have another layer of cache in addition to the native SDK?
from cordova-plugin-geolocation.
You have an option (maximumAge) for exactly that
Note quite. You can see the javascript callback for getCurrentPosition
on starting on line 79
If maximumAge
is set and greater than 0, it will use a cache if the cached GPS point is within the acceptable age. A value of 0 means the phone will always go to the native side to request a GPS point. It doesn't guarantee you will get a "completely fresh" GPS point.
I think it's worth noting that receiving a completely fresh GPS point (within milliseconds that is) will be incredibly rare, if not impossible. GPS receivers in most phones only give location updates roughly every 1 second. Then you have overhead of receiving and handling the GPS code in the native code, and of course calling back to the javascript.
A GPS point you receive will always be sometime in the past. A healthy GPS connection should give you on average GPS point of where the phone was 1 second ago.
from cordova-plugin-geolocation.
Ok.
A healthy GPS connection should give you on average GPS point of where the phone was 1 second ago.
So how old can it be in a case of a bad connection then? I mean in the example I had an interval of 5 seconds, so the timestamps are not very old, but when I increase the interval to 30 seconds, the timestamps I get are 25 - 30 seconds old. This behaviour is not entirely covered by your explanation. I mean, why do the timestamps get older, the less I query the plugin, if the GPS points are measured independently of the plugin queries?
E.g. the values I'm seeing right now are:
Timestamp_Call - Timestamp_GPS
11:9:54.962 - 11:9:25.642
11:9:24.944 - 11:8:55.696
11:8:54.944 - 11:8:27.336
It looks to me like every time I query, I get the gps point from the last query...
from cordova-plugin-geolocation.
Ok, so until now I always tested inside a building. Just now I went to the roof of the building and tested there with different but inconsistent results. Sometimes the returned GPS point was only 2-3 seconds old, sometimes it was up to 30 seconds old. While I was walking around it was 12-14 seconds old.
What can I do to guarantee that it's not more than 2 seconds old?
To clarify: I had clear sky on the roof of a 8-floor-building. Why would the GPS connection in these circumstances be so unstable?
from cordova-plugin-geolocation.
Yes, being in buildings can hinder the ability to receive accurate GPS points, or hinder the ability to receive at all. Being surrounded by tall buildings like in a city can do this too. Same with mountain regions... lots of variables usually out of our control unfortunately.
To clarify: I had clear sky on the roof of a 8-floor-building. Why would the GPS connection in these circumstances be so unstable?
iOS by default have a distanceFilter implemented in native code. A concept that I don't think android has. So you won't receive new GPS points unless if the GPS point has moved greater than this distance filter. By default this range is 5 meters when enableHighAccuracy
is true, or 10 meters when falsey. So by walking around on a rooftop, you were likely not breaking this range frequently.
While the distanceFilter is 5 meters, you still need to account for GPS accuracy, which is usually around 5m radius around your actual point. So you may have to walk upwards of 10 meters before you break that 5 meter filter.
cordova-plugin-geolocation/src/ios/CDVLocation.m
Lines 140 to 151 in 6fd7847
from cordova-plugin-geolocation.
So that explains the inconsistencies.
But why, when not moving, do I get GPS points that have (pretty consistently) a timestamp very close to my last request?
Does the device receive a GPS point every time I ask for one, but it still returns the last cached one?
from cordova-plugin-geolocation.
If you use the getCurrentPosition
API like in your original post, it will always return the last known GPS point received.
If you use the watchPosition
API (which you should be using if you need a continuous stream, instead of using setInterval
), you will receive GPS points as they become available.
from cordova-plugin-geolocation.
If you use the getCurrentPosition API like in your original post, it will always return the last known GPS point received.
I understand that. But the question is: I request a point and get the last known one. 30 seconds later I do the same and the last known one at the time of the second request has a timestamp that is shortly after the first request. So does the requesting of the GPS point influence the receiving of the GPS point?
request time - GPS time
11:9:54.962 - 11:9:25.642
11:9:24.944 - 11:8:55.696
11:8:54.944 - 11:8:27.336
from cordova-plugin-geolocation.
So does the requesting of the GPS point influence the receiving of the GPS point?
request time - GPS time
I don't believe so, but we are getting into quite technical specifics here that I probably can't answer accurately.
But in my past observations in my apps, especially using my app in a building where GPS strength is poor, iOS will always give me a GPS point very quickly when I start requesting GPS points. I use the watch
api however, not the getCurrentPosition
api. I think iOS's native locationManager will give you the most recent GPS point immediately when it first starts up, regardless of how accurate or old it is.
When you use the getCurrentPosition
api, the locationManager is started, then is stopped after it receives the GPS point if there are no more callbacks waiting for a GPS point from what I can tell glancing at the codebase.
For me I never thought much of it cause since I was using the watch API, I just usually ignore the first point and wait for the second one to come in. But if the same behaviour happens on getCurrentPosition
then I can definitely see how that could be troublesome.
I'm just speculating.... but I'd try switching to use the watchPosition
instead of using getCurrentPosition / setInterval
to see how that changes the behaviour.
from cordova-plugin-geolocation.
Ok, I tried watchPosition and on the Device I get GPS points regularly, even in a building (ca. every 7 seconds). (Interestingly enough on the browser I observe a very strange behaviour).
So I guess the problem is really about the combination of getCurrentPosition and setInterval.
I just can't get my head around why this behaviour is the way it is...
Anyway, the problem with watchPosition is that you can't let the customer decide the interval (which we want to be customizable for power usage purpose). In my book it should be possible to query the GPS position in a fixed interval and get results that are 'relatively' fresh...
from cordova-plugin-geolocation.
So I had someone program the native version of my test app for me and it turns out, if you request the location periodically (via the method requestLocation
) you won't get an GPS point for every request, and when you get one, it is also not brand new, but it's not dependent on when you did the last request. To visualize:
request time - gps time
15:32:28.551915 - no point received
15:32:31.545426 - no point received
15:32:34.544831 - no point received
15:32:37.544831 - no point received
15:32:38.578818 - 15:32:29
You can see, the point received is from 15:32:29, but it's only received 4 requests after that time. I don't know why it's the case, but anyway: the behaviour seems to be different than from the plugin. I will share my repo soon, so others can do their own experiments.
Edit: The test above was done within a building. Outside every new request returned a GPS point (new or old, but never too old).
from cordova-plugin-geolocation.
If anyone cares, heres our modified fork
In this version getCurrentPosition takes longer to answer but it always returns a 'fresh' data point on ios.
from cordova-plugin-geolocation.
After reading all this with interest, I have a question:
What exactly does the position.timestamp value represent?
Is it local device time, or satellite/GNSS timestamp?
I'm interested in using the GNSS timestamps for synchronization, but
a) the values returned by postion.timestamp , via watchPosition() callback,
are often rounded to nearest second,although the spec says it's in milliseconds.
b) the position.timestamp is often greater than the device Date() time, which seems to imply
that the phone clock is behind the satellite UTC time, which would be expected.
c) I see no way of telling, in terms of local device UTC clock, the age of the position.timestamp
What I want is the GNSS timestamp which was part of the last location fix - and a device-clock timestamp indicating the time when the last fix was received, both precise to at least millisecond.
By adding elapsed device time to the GNSS timestamp value, I should be able to infer the current
satellite time pretty accurately....
How can this be accomplished?
from cordova-plugin-geolocation.
What exactly does the position.timestamp value represent?
Is it local device time, or satellite/GNSS timestamp?
This is the apple docs, which unfortunately doesn't define what the the source of the timestamp is, so I'm not sure.
from cordova-plugin-geolocation.
After a couple of years...
I feel confident that the timestamp is as reported by satellites (and sometimes the received data can be old data, according to the timestamp) and depending on what you're using GPS for that may have to be taken into account and checked.
As for the seconds, most GPS hardware only report data every second, but I do see it land on sub fractions in my datasets.
Closing this because I don't believe this is really a bug, but the nature of GPS hardware.
from cordova-plugin-geolocation.
Related Issues (20)
- geoocation not returning anything when device has no internet connection HOT 1
- iOS 14: Infinite value in returned location data causes app crash HOT 2
- Geolocation getcurrent position passing 0 (Time out error) HOT 5
- !important Android 12 new approximate location and precise location HOT 4
- IOS 15 Geolocation permission message issue. HOT 12
- iOS 15 - ionic app geolocation permission prompt message showing ionic://localhost HOT 2
- geolocation plugin is throwing an error on location request on electron (windows) platform
- [iOS] Location update are disabled after one kCLErrorLocationUnknown HOT 6
- Ionic - Position error:application does not have sufficient geolocation permission HOT 2
- GeoLocation permissions not being asked [SOLUTION] HOT 1
- [iOS permission bug] wrong logic in didChangeAuthorizationStatus hook, permission can be asked in some unexpected cases HOT 10
- [question android api 31 32] approximate access to geolocation for getCurrentLocation HOT 6
- Unable to fetch Location on VIVO Devices HOT 70
- iOS 16 CDVLocation.m throwing UI unresponsiveness warning in XCode - causing app to crash. HOT 7
- Next version release HOT 2
- Description String override in android as in iOS HOT 4
- this.geolocation.clearWatch is not a function HOT 1
- Android 33 issue when initializing HOT 3
- Geolocation working on android 13,14 even 8 but not on android 12 function does not call no error in console HOT 11
- Heading is set to NaN if speed is 0 or null. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cordova-plugin-geolocation.