Coder Social home page Coder Social logo

Comments (18)

breautek avatar breautek commented on May 28, 2024 1

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024 1

Here you go: https://github.com/ninaDeimos/geolocationTesting

from cordova-plugin-geolocation.

breautek avatar breautek commented on May 28, 2024

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

breautek avatar breautek commented on May 28, 2024

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

breautek avatar breautek commented on May 28, 2024

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.

if (enableHighAccuracy) {
__highAccuracyEnabled = YES;
// Set distance filter to 5 for a high accuracy. Setting it to "kCLDistanceFilterNone" could provide a
// higher accuracy, but it's also just spamming the callback with useless reports which drain the battery.
self.locationManager.distanceFilter = 5;
// Set desired accuracy to Best.
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
} else {
__highAccuracyEnabled = NO;
self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
}

from cordova-plugin-geolocation.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

breautek avatar breautek commented on May 28, 2024

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

breautek avatar breautek commented on May 28, 2024

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

ninaDeimos avatar ninaDeimos commented on May 28, 2024

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.

tuckernuck avatar tuckernuck commented on May 28, 2024

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.

breautek avatar breautek commented on May 28, 2024

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.

breautek avatar breautek commented on May 28, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.