As mentioned in my post about ridding my phone of Google, I’ve been using the NetworkLocation component from the microG project. However a recent situation showed up a problem: I was several miles up a valley with a fairly dense tree canopy so the phone’s GPS was not showing very good accuracy. There was cell coverage from a tower near the end of the valley by the main road. Apparently NetworkLocation was reporting zero error on location so the phone ignored the GPS location and assumed I was parked at the valley mouth. Not a good situation for mapping things for OpenStreetMap (OSM). Eventually I figured out what was happening and changed the location provider settings to “device only” (GPS) and was able to get the GPS to lock and track things well enough that I could later use satellite imagery to enter things into OSM.
Since my main reason for having NetworkLocation installed is for quicker GPS acquisition, having it fail this way was disappointing.
So I took a look at the NetworkLocation source code and while I did not see an problem that would return zero error meters in accuracy, there were things that I feel are wrong.
First, it was using the number of samples reported to OpenCellID as a metric for tower position accuracy. This is wrong as a little thinking about real world tower location in respect to highways (where OpenCellId samples are usually taken at) will reveal. And the it compounded that error by assuming tower position accuracy was a measure of phone position accuracy.
Secondly, the position was a non-weighted average of the location(s) of the cell tower(s) being seen by the phone. This is also clearly wrong as you are unlikely to be an equal distance from all towers. If you have the signal time delay for each tower, a very good proxy for range from tower, you should weight by that. Lacking time delay information, OpenCellId gives the radius/range of the signals for each tower. At least it does for newer measurements, it list zero for what appear to be older measurements. That can also be used as a proxy for possible distance from tower.
While I was able to compile my own version of NetworkLocation I could not get it to actually run on my phone. The microG project does not use the standard Android build tools so it was probably just my ignorance on how to do things but I decided to look for alternatives.
The microG‘s current network based location service is called UnifiedNlp which is a plug-in based setup where only the core piece needs root to be installed. You can duplicate the functionality of the older NetworkLocation service by installing UnifiedNlp, the Apple WiFi plug-in and a CellTower plug-in both of which are available through f-droid.
Except that the CellTower plug-in has some problems too:
- It assumes equal weighting for all cell towers.
- It assumes a position accuracy for each tower of 800 meters.
- It uses an undocumented format for storing the cell tower database and its most recent database is at least 6 months old so it does not have any towers in my area.
- The author has not responded to my query about how to generate a new database.
At least the source code for the cell tower plug-in is available and it can be compiled with the standard Android tool kit.
My New Solution
Having a working prototype that compiles with standard Android tools allowed me to play around some. I’ve come up with a version of a cell tower plug-in that:
- Uses a SQLite database compatible with NetworkLocation but with tower coverage radius information included.
- Uses the tower coverage information to weight the locations and to provide an estimate of accuracy of the result.
So far, with about a week of testing, this seems to do what I want. In suburban and urban areas it shows my location within about 500 meters. In rural areas with infrequently located cell towers it shows an appropriate error, sometimes many kilometers, based on the reported coverage of the tower(s) it sees. In both cases that is enough that the GPS get its “first fix” pretty quickly.
At present my setup is a bit of a hack: The database needs to be generated and placed in a specific location on the phone for everything to work. This works for me but is not a reasonable way for it to work for the average person. If I add a way to specify the location of the database file it would be more useful for others. . .