Does Location#distanceTo(Location) take Location#getAccuracy() into account? - android

I want to write a LocationListener that takes the most accurate and precise recent location as its location. I'm intending to use this code in my LocationListener:
#Override
public void onLocationChanged(Location location) {
if(location.distanceTo(mLocation)>location.getAccuracy()){
mLocation = location;
}
}
What I intend this to do is update the location if the user's old location is outside the circle of "possible locations" that the new location indicates. So, for example, if our last measurement was a GPS signal and the new one is a cell tower, and the old location was in range of the cell tower, we don't update; on the other hand, if the cell tower is sufficiently distant, we know the user has moved and record that.
However, the distanceTo(Location) function states it returns the approximate distance in metres between locations. Does it already take the accuracy into account? Will it give me a precise enough figure to let me use in this way?

Short answer is no, Location.distanceTo(Location) does not take Location.getAccuracy() value into account when measuring distance.
Here's the actual code from the Android platform that is used to calculate distance for Location.distanceTo(Location):
https://github.com/android/platform_frameworks_base/blob/master/location/java/android/location/Location.java#L272
It uses Vincenty's Inverse Formula (http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf - Section 4) based on the given latitude and longitude (accuracy not considered).
As to whether your method of updating the "true" user location will be "precise enough", it really depends on GPS sensitivity, accuracy, and precision, which can vary significantly from device to device.
The accuracy estimate value from Location.getAccuracy() can also vary widely depending on the OEM, and typically devices I've seen overestimate accuracy (i.e., the device gives an accuracy value greater than the true accuracy) more than underestimate accuracy.
You might want to check out an app I created "GPS Benchmark" (http://www.gpsbenchmark.com/) which helps quickly benchmark location provider accuracy (GPS and Network) on Android devices, as well as "estimated accuracy" accuracy. I also co-authored a paper on this topic (http://journals.cambridge.org/repo_A82eaJIy) based on GPS benchmarking results from some Java ME devices, and most of the material is also relevant to Android.

Related

It is possible to detect geofence events without requestLocationUpdates?

It is possible make the geofence exit and enter events trigger without any location request?
Even when there is no other application requesting location, only with the device GPS turned on?
Yes, it's possible. The device can know its location from the nearby wifis and the phone signal.
The location accuracy of these methods is not as good as with a gps signal stablished but if the radius is big enough as 150m or more as it's recommended in the geofencing docs this is enough. And bigger in rural areas:
Choose the optimal radius for your geofence
For best results, the minimum radius of the geofence should be set between 100 - 150 meters. When Wi-Fi is available location accuracy is usually between 20 - 50 meters. When indoor location is available, the accuracy range can be as small as 5 meters. Unless you know indoor location is available inside the geofence, assume that Wi-Fi location accuracy is about 50 meters.
When Wi-Fi location isn't available (for example, when you are driving in rural areas) the location accuracy degrades. The accuracy range can be as large as several hundred meters to several kilometers. In cases like this, you should create geofences using a larger radius.

How does Apple or Android calculate speed in devices?

There are any documentation for this? I've checked many formulas and algorithms but didn't find an explicit definition how they get the speed provided in Geolocation object.
The GPS chipset provides the current velocity to the system along with the current location.
The chipset may compute the velocity by comparing location over time and correcting for the curvature of the Earth at the current location, or from the Doppler shift of the received satellite signals.
Whichever method is used, the operating system doesn’t need to do any processing to get the speed. The velocity data is provided along with location and altitude data directly from the GPS chip (actually chips in many newer devices support both GPS and GLONASS, but which system is used is not visible to the user).
Physics.org has a simple explanation of how GPS works
Wherever you are on the planet, at least four GPS satellites are ‘visible’ at any time. Each one transmits information about its position and the current time at regular intervals. These signals, travelling at the speed of light, are intercepted by your GPS receiver, which calculates how far away each satellite is based on how long it took for the messages to arrive.
Once it has information on how far away at least three satellites are, your GPS receiver can pinpoint your location using a process called trilateration.
But you can search for more detailed explanations of the mathematics and physics involved.
It basically scans your location (i.e. your latitude and longitude) and compares with the last check. Using euclidian distance, it can get the distance in the period of time. With the time (for example, if it scans your location every 2 seconds), it can easily estimate your speed by doing Speed = Distance/2.

Experience of Location Services on Android using GPS and Network providers

I have written a piece of code to get a feel of what my customer (cab driver) will experience when I enable location services on his device for my cab booking application. I enabled location services using both Network and GPS providers on the same listener.
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
// God.KM20TIME, God.KM20DISTANCE, (LocationListener) updates);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, God.KM20TIME,
God.KM20DISTANCE, (LocationListener) updates);
My battery ran out much faster than normal. I also had my phone heating up more than normal. But the consistency I was expecting was really low. I have decided to not use GPS, and only Network provider. I am building a cab booking app, so I need to know where the cab is approximately. Even if I know that the cab was at a approximate (300 meters) location about 15 mins back, I should be good. So I guess my decision to not over engineer this logic by using both providers is correct. I wonder if anyone can relate to a different experience here ? Am I missing something ?
From my experience, the quality of the Network provider can vary quite a bit.
The network provider uses a combination of WiFi and Cell tower information to provide location information.
If you happen to be close to a Wifi network, which is common in urbanized areas, but not outside of cities, you usually get a very good accuracy.
However, outside of range of a Wifi, you're at the mercy of the cell towers. Here, the precision depends on the quality and features of the cell tower, as well as the amount of cell towers that can be used to triangulate your position.
In these situations, the quality can vary alot, both between locations, but also depending on which Carrier you use, the distance between their cell towers, but also what make and generation of cell towers they have. Newer have more features regarding location, and might for example provide bearing on its own.
My application runs in Sweden, and in some areas of our country, a carrier might have only one tower within a very large area. In those cases, all lon/lat fixes end up directly on the tower, with a precision of even up to 20.000 - 30.000 meters.
Basically, my point is that when using the network provider, if you're not near a Wifi, i'd be very satisfied with 300 meters accuracy.
Regarding the battery / heat - with your requirements, you can play around a lot with the time / distance parameters to get a "good enough" update frequency that doesn't tax the phone as much.

Authenticating location result

I have developed a location based service which identifies the location of the user using GPS. I want to authenticate the data from GPS because an attacker can spoof location information with a simulator.
I've studied an authenticating mechanism from here, but i don't know how to implement the technique they have mentioned.
The idea of the paper is to retrieve geolocation from two different providers. In your case you'd get the device's GPS position for high accuracy and the cell id position to validate this data.
Here's a full example how to get locations by cell id: http://www.devx.com/wireless/Article/40524
You need to define a threshold for the difference of these locations. So we believe the GPS location is faked when the distance between GPS and cellular is greater than our threshold.
Some abstract code example:
static final int THRESHOLD = 2000 // maximum discrepancy in meters
Location getLocationFromGPS();
Location getCellularLocation();
boolean isLocationValid(Location gps) {
Location cell = getCellularLocation();
return gps.distanceTo(cell) <= THRESHOLD;
}
Following this approach there can be two different types of mistakes:
assuming the GPS data is faked but it is not
trust the GPS data while it's faked
Setting small values for THRESHOLD will more and more lead to mistake #1. Most of all users will never fake their GPS data, so claiming they're cheaters won't make your app successful ;-)
The paper states that the Cellular Network Based accuracy is about 100 - 1500 meters. So I highly recommend you to choose values greater than 1500 meters.
Please mind that - as Rune FS mentioned - advanced users may fake both location providers at the same time.

Android get exact height above NN

How do i get the actual (accurate ~1m) height of my location?
Ive tried registering a LocationListener, receiving the Altitude, but that does not work fine or even accurate. Im around 400m above NN and it displays 7m.
As result: GPS is not a good height-provider as i assume.
Do you have any ideas how to obtain this height?
Presumably you requested a LocationManager, not a LocationListener, and getAltitude() to obtain your height.
GPS/GNSS is not as good at altitude as it is at longitude and latitude, but for a reasonable fix you should be within 10m of the correct altitude. Note that altitude is adjusted for the geoid ( http://en.wikipedia.org/wiki/Geoid ) and the datum ( http://en.wikipedia.org/wiki/Datum_(geodesy) ) in use, which can alter your reported height compared to what you are expecting.
But you may be getting your location provided by a location provider that isn't actually GPS - it could be cell tower based, or due to dead reckoning or WiFi locationing. Or perhaps the android phone you are using just has a bad GPS integreation design that is messing with your accuracy.
I would recommend downloading a test application such as GPS Test ( see https://market.android.com/details?id=com.chartcross.gpstest&hl=en ) which will show you if you have a fix, and what altitude is actually being reported by your GPS. The third box on the bottom of the GPS Test app shows altitude, heading and velocity values for each fix.
If you have a GPS, barometer, and data connection, you can send the GPS location to one of several weather APIs to get the local barometer setting (p0). If p1 is the value from the pressure sensor then SensorManager.getAltitude(p0, p1) will give you a very accurate altitude.
I don't think the altitude will have 1 meter accuracy, but it is about as accurate as you can hope for.
This SO question/answer discuses weather APIs:
Sealevel Pressure and Temperature Calculation

Categories

Resources