使用iOS Geofencing跟踪多个(20+)位置

iOS应用程序使用地理围栏来通知用户预定义的附近位置。 允许应用程序错过某个位置(用户没有收到关于附近位置的通知),但希望保持低丢失率。

实现这一点的一种方法是开始监控重要的变更地点,并使用startMonitoringSignificantLocationChanges和每次“地点变更”事件被触发时,在报告地点的半径500m内寻找地点。

我担心的是每次发生重大的位置变化时都要对附近的区域进行查询,这会影响电池。

另一种方法是使用startMonitoringForRegion注册位置,但是苹果已经对同时跟踪的区域的数量进行了(合理的)限制,这个数量是20,而且我们有20多个位置。 因此,需要对跟踪区域进行某种dynamic更新,但我仍然不确定最好的方法是什么。

关于如何做到这一点的任何想法,以保持电池消耗低,但也有低失踪率的位置?

既然在这个问题上没有太多的活动,我会描述我们目前如何解决这个问题。

我们将重新装载的新区域与重要的位置更改(SLC)事件联系起来。 当SLC发生时,我们检查20个应该“geofenced”的邻近地区。 要find20个最接近的区域,我们只需根据以下公式近似经度和纬度的1“:

纬度:1度= 110.54公里

经度:1度= 111.320 * cos(纬度)km

只需要检查设备当前位置的边界平方就是监测区域的中心(参见: 使用纬度/经度+ km距离的简单计算? )

因此,例如,如果(10N,10E)是设备的当前位置,我们从顶点在(10-1',10-1'),(X-10',10 + 1')的边界正方形开始, ,(10 + 1',10 + 1'),(10 + 1',10-1')(纬度(10N,10E),纬度经度分钟约为1,85公里)。

如果有20个(或几乎20个) – 我们注册他们的地理围栏和等待下一个SCL。 如果更less/更多,只需增加/减小边界矩形的大小并重复search。

你可以调整这个searchalgorithm以获得更好的性能,但是这里描述的algorithm已经可以完成这项工作。

您可以预留一个包含所有当前监控位置的“meta-geofence”的位置。 当用户离开这个geofence,应用程序将被通知。 然后,应用程序可以自行更新,并停止跟踪最远的地区,并开始追踪附近的新地区。

我想我会添加另一个在您的应用程序中使用超过20个地理栅栏的选项。 这种方式在我们的应用程序中已经运行良好,并使用内置的CLLocation方法。

 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { if (locations.count > 0) { CLLocation *location = locations[0]; NSMutableArray *sortedFences = [[NSMutableArray alloc] init]; // add distance to each fence to be sorted for (GeofenceObject *geofence in enabledFences) { // create a CLLocation object from my custom object CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(geofence.latitude, geofence.longitude); CLLocation *fenceLocation = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude]; // calculate distance from current location CLLocationDistance distance = [location distanceFromLocation:fenceLocation]; // save distance so we can filter array later geofence.distance = distance; [sortedFences addObject:geofence]; } // sort our array of geofences by distance and add we can add the first 20 NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:@"distance" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName]; NSArray *sortedArray = [sortedFences sortedArrayUsingDescriptors:sortDescriptors]; // should only use array of 20, but I was using hardcoded count to exit for (GeofenceObject *geofence in sortedArray) { CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(geofence.latitude, geofence.longitude); CLLocationDistance radius = geofence.radius; NSString *ident = geofence.geofenceId; CLCircularRegion *fenceRegion = [[CLCircularRegion alloc] initWithCenter:coordinate radius:radius identifier:ident]; fenceRegion.notifyOnEntry = geofence.entry; fenceRegion.notifyOnExit = geofence.exit; [locationController.locationManager startMonitoringForRegion:fenceRegion]; } } } 

希望这会帮助别人,或者把他们引导到正确的道路上。

如果您担心对每个重要位置更改执行邻近检查,则可以使用空间索引/search方法(如R树或R *树)来减less每个位置更改所需的比较次数,因为这些searchalgorithm将过滤掉(可能很大的)空间不相关的区域。 这应该减less执行接近检查所需的时间/电池电量。

我知道这个post是旧的,但对于那些想要做类似的事情, Skyhook提供了geofence无限数量的场地的能力。

从他们的营销:Skyhook的上下文加速器使应用程序开发人员和广告商通过简单的Web界面即时将任意地理围栏部署到任何品牌链(如CVS)或场地类别(如便利店)。 使用Skyhook第一方定位networking的相同专利技术,Context Accelerator SDKpipe理设备上的这些活动地理围栏,无论操作系统限制如何,都允许进行无限的地理围栏。