Michael Bedford
Michael Bedford

Reputation: 1814

Windows 10 UWP Geofencing geofence must be a circle?

I have a Windows 10 UWP app and I am trying to get Geofencing integrated. I have read the documents that the Geofence must be a circle. Is this true still? Why is a rectangle not supported? It seems silly because most Geofences in my mind are going to be rectangle. For example, my house, my yard, buildings, parks, etc... are more rectangle (usually) than they are circle.

Here is the code I tried:

    private Geofence GenerateGeofence()
    {
        string fenceKey = new string(Id.Text.ToCharArray());

        BasicGeoposition positionNW;
        positionNW.Latitude = double.Parse(LatitudeNW.Text);
        positionNW.Longitude = double.Parse(LongitudeNW.Text);
        positionNW.Altitude = 0.0;

        BasicGeoposition positionSE;
        positionSE.Latitude = double.Parse(LatitudeSE.Text);
        positionSE.Longitude = double.Parse(LongitudeSE.Text);
        positionSE.Altitude = 0.0;

        // the geofence can be a circular region. However, we are going to use a rectangle
        GeoboundingBox geoRect = new GeoboundingBox(positionNW, positionSE);

        //Lock into false for single use because we don't want that feature for now.
        bool singleUse = false;

        // want to listen for enter geofence, exit geofence and remove geofence events
        // you can select a subset of these event states
        MonitoredGeofenceStates mask = MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited | MonitoredGeofenceStates.Removed;

        TimeSpan dwellTime;
        TimeSpan duration;
        DateTimeOffset startTime;
        var maxTimeSpan = TimeSpan.MaxValue;

        try
        {
            //We are going to just hard set the dwell time to 5 seconds for now.
            dwellTime = new TimeSpan(ParseTimeSpan("0", defaultDwellTimeSeconds));
            // setting up how long you need to be in geofence for enter event to fire
            //if (string.Empty != DwellTime.Text)
            //{
            //    dwellTime = new TimeSpan(ParseTimeSpan(DwellTime.Text, defaultDwellTimeSeconds));
            //}
            //else
            //{
            //    dwellTime = new TimeSpan(ParseTimeSpan("0", defaultDwellTimeSeconds));
            //}

            // setting up how long the geofence should be active
            if (string.Empty != Duration.Text)
            {
                duration = new TimeSpan(ParseTimeSpan(Duration.Text, 0));
            }
            else
            {
                duration = maxTimeSpan;
            }

            // setting up the start time of the geofence
            if (string.Empty != StartTime.Text)
            {
                startTime = DateTimeOffset.Parse(StartTime.Text);
            }
            else
            {
                // if you don't set start time in C# the start time defaults to 1/1/1601
                calendar.SetToNow();
                startTime = calendar.GetDateTime();
            }
        }
        catch (ArgumentNullException)
        {
        }
        catch (FormatException)
        {
            _rootPage.NotifyUser("Entered value is not a valid string representation of a date and time", NotifyType.ErrorMessage);
        }
        catch (ArgumentException)
        {
            _rootPage.NotifyUser("The offset is greater than 14 hours or less than -14 hours.", NotifyType.ErrorMessage);
        }

        return new Geofence(fenceKey, geoRect, mask, singleUse, dwellTime, startTime, duration);
    }

This was taken from the Windows Universal samples for the most part and then I modified it. As you can see, the API does have a GeoboundingBox which requires a north east corner and a southeast corner. It seems a rectangle was thought of. So, as you can see in the code, I build up NW lat/long and SE lat/long and I am able to successfully create a GeoboundingBox object.

However, after I return the new Geofence with this line, I get an exception:

return new Geofence(fenceKey, geoRect, mask, singleUse, dwellTime, startTime, duration);

The Geofence object constructor just says it needs a shape to be passed in but it obviously does not like the bounding box. If I change the code back to a circle, like this:

    private Geofence GenerateGeofence()
    {
        string fenceKey = new string(Id.Text.ToCharArray());

        BasicGeoposition positionNW;
        positionNW.Latitude = double.Parse(LatitudeNW.Text);
        positionNW.Longitude = double.Parse(LongitudeNW.Text);
        positionNW.Altitude = 0.0;

        BasicGeoposition positionSE;
        positionSE.Latitude = double.Parse(LatitudeSE.Text);
        positionSE.Longitude = double.Parse(LongitudeSE.Text);
        positionSE.Altitude = 0.0;

        // the geofence can be a circular region. However, we are going to use a rectangle
        Geocircle geoCircle = new Geocircle(positionNW, 5.0);

        //Lock into false for single use because we don't want that feature for now.
        bool singleUse = false;

        // want to listen for enter geofence, exit geofence and remove geofence events
        // you can select a subset of these event states
        MonitoredGeofenceStates mask = MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited | MonitoredGeofenceStates.Removed;

        TimeSpan dwellTime;
        TimeSpan duration;
        DateTimeOffset startTime;
        var maxTimeSpan = TimeSpan.MaxValue;

        try
        {
            //We are going to just hard set the dwell time to 5 seconds for now.
            dwellTime = new TimeSpan(ParseTimeSpan("0", defaultDwellTimeSeconds));
            // setting up how long you need to be in geofence for enter event to fire
            //if (string.Empty != DwellTime.Text)
            //{
            //    dwellTime = new TimeSpan(ParseTimeSpan(DwellTime.Text, defaultDwellTimeSeconds));
            //}
            //else
            //{
            //    dwellTime = new TimeSpan(ParseTimeSpan("0", defaultDwellTimeSeconds));
            //}

            // setting up how long the geofence should be active
            if (string.Empty != Duration.Text)
            {
                duration = new TimeSpan(ParseTimeSpan(Duration.Text, 0));
            }
            else
            {
                duration = maxTimeSpan;
            }

            // setting up the start time of the geofence
            if (string.Empty != StartTime.Text)
            {
                startTime = DateTimeOffset.Parse(StartTime.Text);
            }
            else
            {
                // if you don't set start time in C# the start time defaults to 1/1/1601
                calendar.SetToNow();
                startTime = calendar.GetDateTime();
            }
        }
        catch (ArgumentNullException)
        {
        }
        catch (FormatException)
        {
            _rootPage.NotifyUser("Entered value is not a valid string representation of a date and time", NotifyType.ErrorMessage);
        }
        catch (ArgumentException)
        {
            _rootPage.NotifyUser("The offset is greater than 14 hours or less than -14 hours.", NotifyType.ErrorMessage);
        }

        return new Geofence(fenceKey, geoCircle, mask, singleUse, dwellTime, startTime, duration);
    }

It works fine.

So, does anybody know of a way I can get it work with a rectangle?

Thanks!

Upvotes: 0

Views: 186

Answers (1)

Sunteen Wu
Sunteen Wu

Reputation: 10627

Unfortunately, the only shape that is currently supported is Geocircle for geofence.

Please check the remarks of Geoshape property of Geofence class.

The type of this property, IGeoshape, is an interface to enable the possibility of supporting multiple shapes for geofences. The only shape that is currently supported is Geocircle, so this is the class you should use when initializing your geofences.

So although there're sevral Geoshape​Types, but geofence must be a circle.

Upvotes: 1

Related Questions