Checking a Point within a Polygon

1. What is the issue? Please be detailed.
We are creating a polygon for each facility we visit, saving it into our entities.
We want to check a point captured by an enumerator to confirm they are within the facility they are collecting the data from.

2. What steps can we take to reproduce this issue?
Currently we use a single point and check the distance between the one on the entities table and the one captured to ensure they are within an acceptable distance.

1 Like

What you are referring to is typically called a geofence.

There are a few different way you can do this, the simplest probably being a purely circular fence, which you can enforce by just measuring your distance to the center of the circle. A distance() function will accomplish this for you, which sounds like what you are doing already.

A slightly complicated rectangular fence can be enforced by checking your GPS latitude and longitude each lie within a certain prescribed range. A long-ish if() statement comparing your location to each min & max latitude/longitude will do this for you.

An even more complicated (convex) polygon fence can be enforced with a rather more sophisticated algorithm and form; see ODK geofence (v1), and Geofencing in ODK forms

But, wait for it...

...there is actually a new dedicated ODK geofence feature coming out Real Soon Now™ (!) If you poke around javarosa - the form engine underneath ODK Collect - you might spot it:

(or if you like deciphering code, start digging around https://github.com/getodk/javarosa/blob/master/src/main/java/org/javarosa/xpath/expr/XPathFuncExpr.java)

This should show up in an upcoming release of ODK Collect/KoboCollect.

[Disclaimer: written by yours truly :wink:]

2 Likes

Thanks for bringing this up! The geofence function that @Xiphware implemented is in fact released but we are behind on updating documentation.

You can use it by specifying first a point to test followed by the shape to use as a fence. Here is a sample form with a default fence that is roughly the state of Nevada in the USA (with apologies to Arizona for stealing some of its land). You can copy the form definition and edit it to try another default fence or change the fence when you fill out the form.

The second parameter that specified the polygon fence has to be a reference to another field in the form, it can't be a literal text value currently. That field value can come from anywhere including a geometry property from an Entity.

Please note that point accuracy indoors is generally not very good. If there is no cell or wifi signal available, you most likely won't be able to get a point reading at all.

If your facilities are indoors, you may get better results by first capturing the location of the entrance as part of your baseline and having follow-up locations also captured at the entrance with a simple distance check as it sounds like you're already doing. You'll want to do some experiments to compare approaches in your specific context with the devices you have.

You may find some of these examples of using the distance function helpful.

Currently the geofence function is binary: there's no way to specify an acceptable tolerance and the point is either in the fence or it isn't. That means you'll either have to tell data collectors to be well within the established bounds or that you'll want to build in some buffer area into the fence itself. For example, you could draw the bounds 5m outside of the area you really want.

3 Likes

Thanks for confirming! I see now that the new geofence() XPath function is now in pyxform too, so yes you should be able to start deploying XLSForms with it. :tada:

2 Likes

We've updated the geofence documentation with examples on how to geofence.

4 Likes