Faster Geolocation with pre-warmed GPS - example for ODK Build users

Geolocation capture is useful but the wait for a GPS fix can feel slow.
Adding an automatically captured geopoint (start-geopoint) to an ODK form "warms up" the GPS chip speeds up location capture.
Initial testing shows reductions from originally ca 15 seconds to sub 3 seconds.
Some use cases require the enumerator to capture a precise location (e.g. a turtle nest), which is not always the location in which the form is opened initially. Here, the initial location itself is not of interest, but the speed from a pre-warmed GPS chip is most appreciated.

XLSForm

Add field of type start-geolocation to survey

Adding a start-geopoint to an XLSForm is as simple as adding one line to the sheet survey (see docs):
type: start-geopoint
name: start_location
label: Any label

You can choose your own name for the field (here: start_location), and adding a label (although it will never be shown) silences a warning when importing the form into ODK Central.
An example XLSForm start_geolocation.xslx is attached. The example form is based on this form demonstrating how to calculate the name of the saved form from form data.

XForms

Unfortunately, ODK Build does not yet support this field type, and form maintainers who prefer to build their forms in ODK Build must hand-edit the exported XForms XML before uploading it into ODK Central as follows. Note we'll use the arbitrarily chosen field name start_location from our example.

Add additional namespaces

Replace the opening <h:html> tag with:

<h:html 
  xmlns="http://www.w3.org/2002/xforms"
  xmlns:h="http://www.w3.org/1999/xhtml"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:jr="http://openrosa.org/javarosa"
  xmlns:ev="http://www.w3.org/2001/xml-events"
  xmlns:odk="http://www.opendatakit.org/xforms">

This adds the namespaces ev and odk. The line breaks are only for readability.

Add the field to data model

Insert the field name <start_location/> as child of the <data id="" version=""> tag:

<start_location/>

Substitute the example name start_location with your chosen name.

Bind field type and trigger action on instance first load

Insert as children of the <model> node and siblings of the <bind> nodes:

<bind nodeset="/data/start_location" type="geopoint" />
<odk:setgeopoint event="odk-instance-first-load" ref="/data/start_location" />

As per the Xforms spec on actions, we're using the action <odk:setgeopoint> to set the start_location on event form start.
XForms action can also set the location on other events, such as adding a repeat.

Considerations

Warning message

The background location capture of the start-geopoint field generates a warning message, which pops up as a "toast" from the bottom of the screen each time. This needs to be communicated to the enumerators to prevent anxiety.

Give start-geopoint a 20 second head start

The start-geopoint runs for exactly 20 seconds and returns the most accurate location captured in this time span. The form should be designed such that the enumerator will only capture the first "proper" geopoint/trace/shape after these 20 seconds. An easy way of achieving this is to move the first geo field a few questions down, so that the enumerator spends a few seconds answering other questions while the start-geopoint runs in the background.

Conversion

An XLSForm can be converted to the corresponding XForm with the command line tool pyxform's function xls2xform:

$> xls2xform start_geolocation.xlsx
$> Conversion complete!

Source: pyxform on GitHub

Attachments:

XLSForm and XForms versions with and without start-geolocation:
start_geolocation.zip (14.9 KB)

I'd be interested to hear back about time savings (which devices did you use, how much faster is the pre-warmed vs the cold GPS), and which use cases you're using this in.

1 Like

Thanks for sharing! You mentioned in Slack that you also use the map view to see locations you've already filled forms about. Do you start filling new forms from there? It seems this would be natural so that data collectors can see where they're going and have been before they start a new form. This view shows the current user location so it should also have the effect of warming your GPS. You may find that this is sufficient and that you don't need the additional background GPS call.

The core team unfortunately doesn't have capacity to work on Build at the moment. We're very interested in new contributors and maintainers and this should be a relatively straightforward one to add for someone who wants to get involved! I have marked the corresponding GitHub issue accordingly.

OK, so I had a week in the field with unlimited access to coffee and turtles. Having never worked on Rack/Build/Livescript I think I tick the box of a new contributor :wink:
https://github.com/getodk/build/pull/241 and https://github.com/getodk/build2xlsform/pull/12 will add metadata of kind "Start Geopoint" to ODK Build (and export to XML as well as XLSForm).

Here's the metadata field of kind "Start Geopoint":


Export to XML: start_location is highlighted, the extra XML namespaces are scrolled out of the frame.

Further down in the XML are the bind and setgeopoint nodes.

@LN re filling in a form from map view - neat, will totally steal for a future use case.
In our production campaigns however we never start filling a form from the map view, there's a reason for that: Our surveys are like a box of chocolate, we never know what entity type we encounter next - a turtle track or nest, tracks of a predator, some human disturbance, a stranded turtle, and so on. Each entity has its own form and we've laid out shortcuts on our devices' home screen. Our enumerators can simply pick and choose which form they need to fill. Therefore, we never idle in the map view of one particular form.
However, it's great to know that this also warms the GPS, I'm sure we can use that somewhere.

2 Likes