Windows 10 UWP Geofencing 地理围栏必须是一个圆圈?

Windows 10 UWP Geofencing geofence must be a circle?

我有一个 Windows 10 UWP 应用程序,我正在尝试集成地理围栏。我看过文档说Geofence必须是一个圆圈。这还是真的吗?为什么不支持矩形?这看起来很愚蠢,因为在我看来,大多数地理围栏都是矩形的。例如,我的房子、院子、建筑物、公园等……(通常)长方形比圆形多。

这是我试过的代码:

    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);
    }

大部分内容取自Windows通用样本,然后我对其进行了修改。如您所见,API 确实有一个 GeoboundingBox,它需要一个东北角和一个东南角。似乎想到了一个矩形。因此,正如您在代码中看到的那样,我构建了 NW lat/long 和 SE lat/long,并且能够成功创建一个 GeoboundingBox 对象。

但是,在我 return 使用此行的新地理围栏之后,出现异常:

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

Geofence 对象构造函数只是说它需要传入一个形状,但它显然不喜欢边界框。如果我将代码改回圆形,如下所示:

    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);
    }

它工作正常。

那么,有人知道我可以使用矩形的方法吗?

谢谢!

遗憾的是,目前唯一支持的形状是 Geocircle 地理围栏。

请查看Geoshape property of Geofenceclass的备注。

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.

所以虽然有几个Geoshape​Types,但是地理围栏必须是一个圆