4

I am using FusedLocationProviderClient to get location updates in a foreground service. On testing and observing for few days, I found wrong locations which was far away from my actual location by around 4 kms similar to thisimage, but the LocationResult had an accuracy of 24 meters. How is this even possible?

It can be eliminated if the accuracy was around 4 kms. This behavior does not occur very often but occurs atleast once in 4 among 10 devices. It becomes a problem when I calculate distance traveled.

I can tell it's not a cached location because I used to turn off and on Location Services everyday. (As per docs, turning off Location Services clears cache location.)

Any idea why it's giving wrong location and how to eliminate it? And also clearing cache locations without turning off Location Services?

Joshua
  • 1,167
  • 1
  • 14
  • 32
  • please tell us what you tried and show us with code preferably – Karan Harsh Wardhan Mar 29 '19 at 09:06
  • @kkarakk, I need to get continuous location updates from the device in order to calculate the distance traveled and show the user traveled path in Google Maps using polyline. Everything works fine. The only problem I face is that very few locations are wrong, similar to this - https://user-images.githubusercontent.com/352175/35806439-2ce667fe-0a88-11e8-8762-5fec24be9d37.png – Joshua Mar 29 '19 at 10:49
  • _"Any idea why it's giving wrong location..."_ Maybe they are network based locations(?) If GPS fix is temporarily lost(?) Then you could check the provider and ignore them. _"...and how to eliminate it?"_ Only accept GPS based locations and implement some sort of filtering. "Kalman filtering" is often mentioned when talking about GPS. I suppose the firmware already does some. Or maybe "bogus" locations could be rejected based on the distance from the previous location and a reasonable expected maximum speed at which the user might realistically travel. 4 km/second in unlikely to happen. :) – Markus Kauppinen Mar 29 '19 at 11:12
  • 1
    @Joshua with a glance at your content i can tell those incorrect locations are cell tower/wifi locations from when the device lost gps connectivity. i think you need to move away from fusedlocationproviderclient and use the non-google play location solution (location listener)so you can request ONLY gps locations and ignore inaccurate wifi/celltower data. fusedlocationprovider doesn't provide that fine granularity control and you will have to kalman filter on your backend – Karan Harsh Wardhan Mar 29 '19 at 11:29
  • @MarkusKauppinen, I accept that there will be network based locations but still, even if it is a network based location, it's accuracy parameter should be 4 kilometers (4000m). The provider gives only "fused", no matter from which source it comes from. Sorry, I think the unit "kms" is mislead to km/second. It's actually kilometers. – Joshua Mar 29 '19 at 11:32
  • @MarkusKauppinen, On the other had I have requested location updates based on `Interval` too with a value of 15mins, just to show the time spent in that particular place. The wrong location for me was given by the "Interval", which means even if we calculate the distance with speed, traveling 4 kilometers within 15 mins is valid right? – Joshua Mar 29 '19 at 11:32
  • https://developers.google.com/maps/documentation/roads/advanced - have a look at this, you can normalize your travel data quite easily with the use of this api concept(also available on bing or open source OSRM) – Karan Harsh Wardhan Mar 29 '19 at 11:35
  • @kkarakk, I agree with your point. But if I user Android's Location API with only GPS, will I get location updates consistently regardless of the place I stay and travel? Because in rural areas and inside buildings GPS will be very weak, I guess it won't even give a single location update. – Joshua Mar 29 '19 at 11:36
  • depends on your usecase, if you only need accurate travel data for calculation then network/wifi location data is mostly just noise. if you need to show the user accurate location ALL the time then you will have to perform normalization on the backend and "guess" where the user is by normalizing them to the nearest road/feature area using the APIs i mentioned – Karan Harsh Wardhan Mar 29 '19 at 11:39
  • @kkarakk, I knew about Snap to Roads API. Didn't want to use it since it's now paid for our plan and will be quite expensive too. But then too, it won't eliminate that wrong point right? It will just move it to it's nearest road. – Joshua Mar 29 '19 at 11:41
  • @Joshua there is a free open source solution based on open streetmaps http://project-osrm.org/ you will need to host it somewhere though... – Karan Harsh Wardhan Mar 29 '19 at 11:42
  • Oh, good. I'll try it out. – Joshua Mar 29 '19 at 12:40
  • @Joshua can you accept my answer if it helped? – Karan Harsh Wardhan Mar 29 '19 at 12:55
  • 1
    @kkarakk, yes, your answer was helpful. Accepted :) – Joshua Mar 29 '19 at 13:24

1 Answers1

10

FusedLocationProvider CAN give incorrect results like that when gps connectivity for device is down(or insufficient satellites are in "view" to provide accurate data). It will use the nearest cell tower/location data provided by the wifi router(google tracks this automatically) giving WILDLY incorrect results in places where google doesn't have a strong location mapping presence - which is anywhere outside an urban center.

You have imho two options:

  1. Use the non googleplay based solution based on location service - this has an option for ignoring non-gps location data(wifi/cellular).

    LocationManager locationManager = (LocationManager)
    getApplicationContext().getSystemService(LOCATION_SERVICE);  
    Location location = locationManager.getLastKnownLocation(LocationManager.GPS_Provider);
    

    You can even specify the number of satellites required for acceptable data so you can get REALLY accurate location data. You will lose information when the gps doesn't receive coordinates (like indoors), but in exchange will have less "noise" from incorrectly mapped location, as per your requirement.

  2. Use a "snap to roads" API. There is a free version using open street map data called Project OSRM(Open Source Routing Machine) that provides a backend when hosted (locally or in cloud) using docker or building source yourself (details in link).

    curl "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"

This request will return a location that is "snapped" to the nearest road. There are various options such as giving priority to highways etc. You can then discard the points that are not on the "path" that the user was previously on as rapidly shifting to a road 4km away and then coming back again is not likely.

piet.t
  • 11,718
  • 21
  • 43
  • 52
Karan Harsh Wardhan
  • 1,096
  • 9
  • 22