Geofence Application: The Geofence

It's finally time to actually implement our Geofence. We'll store a single active geofence on the device, containing a location and a radius. If the device goes outside this radius then we will send an alert to the client device.

Setting the radius to 0 will signify that there is no geofence active.

We will define the serialised geofence with the following XML.

<geofence>
    <location>
        <latitude>-41.21</latitude>
        <longitude>174.90</longitude>
    </location>
    <radius>200</radius>
</geofence>

To store the geofence on the device we can create the following struct

struct Geofence
{
    double latitude;
    double longitude;
    double radius;
};

We can then create our variable to hold the geofence, defaulting to no geofence set.

Geofence fence = {0};

We then need to add command handlers for getting and setting the fence,

#define SET_GEOFENCE ("SET GEOFENCE")
#define GET_GEOFENCE ("GET GEOFENCE")

define the commands and

FlowCommandHandler.attach(SET_GEOFENCE, setGeofence);
FlowCommandHandler.attach(GET_GEOFENCE, getGeofence);

map the commands to the functions.

We can then implement these functions with

// command handler for setting the geofence
void setGeofence(ReadableXMLNode &params, XMLNode &response)
{
    #define LAT_LOCATION "geofence/location/latitude"
    fence.latitude = params.getChild(LAT_LOCATION).getFloatValue();

    #define LNG_LOCATION "geofence/location/longitude"
    fence.longitude = params.getChild(LNG_LOCATION).getFloatValue();

    fence.radius = params.getChild("geofence/radius").getFloatValue();
}

// command handler for getting the existing geofence
void getGeofence(ReadableXMLNode &params, XMLNode &response)
{
    XMLNode &geofence = response.addChild("geofence");
    XMLNode &location = geofence.addChild("location");
    location.addChild("latitude").setContent(fence.latitude, 9);
    location.addChild("longitude").setContent(fence.longitude, 9);
    geofence.addChild("radius").setContent(fence.radius, 5);
}

Note the use of / in getChild to navigate the XML we defined earlier. This works in a similar way to the forward-slash separator used in XPATH.

This version can be found in commit 58cd12e.

We now have a geofence stored on our device and we can get on to generating an alert for when the GPS reading is outside the geofence.