cdop.pt

Convincing Termux to become a well behaved GPS logger

(published: 2024-07-11)

Most GPS loggers suck for what I need to do, so I hacked my own.

There is an ongoing initiative in Portugal to georeference all non-urban properties (essentially all properties that are not buildings). For property owners, that means collecting all landmarks into a huge government managed GIS. A ton of work, but absolutely necessary. The way things were going, without this GIS, in twenty years no one would know where anything is.1

Certain properties do not need to be surveyed on-site, as they can be readily identified from current or past satellite and orthophotographic images. Others are much more difficult, as the dense forests and other wild vegetation are currently covering all but the most prominent landmarks.

Walking around with with a pen, a sheet of paper, and your phone with SatStat open to jot down all the landmark coordinates, while attempting to maintain good GPS reception beneath the foliage and keeping exposed skin away from thorny bushes2 is not exactly the most widely accepted definition of fun. Obviously, there are better ways to do this.

Hikers would be quick to ask themselves why I didn't just use one of the many readily available GPS logging apps from the start. And while I did try just that, I quickly gave up on that route. Those apps make acquiring geolocation data easier, but a garden variety GPS logger is usually made for tracking paths and not landmarks or borders. When we get to the landmark, we need to acquire exactly one point with good enough accuracy, and every point with more than 3 meters of error or along the path to and between landmarks is completely irrelevant in this context. These apps generate too much noise to be useful.

While I'm very confident that I could coerce one of those apps to do what I need it to do given enough time and effort, in the end the hacker inside my brain prevailed and came up with this instead:

#!/data/data/com.termux/files/usr/bin/env bash

echo -n "file? "
read NAME
[ -z "$NAME" ] && echo "no name given!" && exit 1
FILE="$NAME.csv"
[ -f "$FILE" ] && echo "file exists!" && exit 1

echo "lat,lon,err" >> "$FILE"

while true
do
  clear

  cat "$FILE"

  COORDS=`termux-location`
  LAT=`echo "$COORDS" | jq '.latitude'`
  LON=`echo "$COORDS" | jq '.longitude'`
  ERR=`echo "$COORDS" | jq '.accuracy'`

  echo
  echo current measurement $LAT, $LON, $ERR
  echo -n "('x' to take, any other key to drop):"
  read ACTION
  [ x"$ACTION" == "xx" ] && echo "$LAT,$LON,$ERR" >> "$FILE"
done

This small contraption is meant to run inside Termux. Your phone will need two Android packages: Termux, which is a terminal environment for Android, and Termux:API, which makes Android APIs available to programs running inside Termux. On newer versions of Android, it will also need a way to prevent the GPS receiver from sleeping (e.g. GPS Locker), otherwise measurement accuracy will be absolute garbage.

The jq command is part of the Termux package with the same name, and the termux-location is part of the termux-api package, both of which can be installed with the pkg install command.

If you've made it this far, usage is simple:

Now the only hard part is finding the precise location of landmarks. For obvious reasons, this is left as an exercise to the reader.4


  1. The people I have to talk to to find some of my family's properties are almost always over the age of retirement. In a few years they wouldn't even be able to go to these locations at all. ↩︎

  2. That, and trying really hard to prevent your lungs and eyes from melting should you suffer from allergies. ↩︎

  3. A common phone's GPS can only get to about 2 meters of error on a clear day and away from obstacles, due to hardware and coordinate reference system limitations. ↩︎

  4. Actually two kinds of exercise. It's like Where's Waldo meets Parkour, but Waldo is disguised as a rock and every obstacle and surface is trying to scratch you. ↩︎