iOS应用程序使用,用于通知预定义的附近位置,用户的地理范围。 该应用程序允许错过一些位置(在用户没有得到关于附近位置的通知),但它需要保持漏检率较低。
实现这一点的一种方法是开始监控与显著的变化位置startMonitoringSignificantLocationChanges
并且每个“位置改变”事件被触发时,寻找内的位置,让说,该报告的位置500个半径。
我担心的是执行查询邻近地区各显著位置发生变化时的要求,它的电池影响。
其他的方式做这将是注册地点startMonitoringForRegion
但苹果已经把一个(合理)限制上同时跟踪的区域是20号,我们有显著超过20个地点。 所以还需要一些跟踪区域的动态更新的,但我仍然不能确定是什么做的最好的方式。
如何任何想法能不能做到,使其保持电池的消耗低,但也有位置低丢失率是多少?
因为没有太多的活动上的问题,我将介绍我们目前如何解决这个问题。
我们追平了新的区域,以显著位置的变化(SLC)事件重装。 当SLC发生,我们检查应该是“地理围栏” 20邻近地区。 为了找到我们只是根据以下公式的纬度和经度的逼近1'的20米最接近的区域:
纬度:1你=110.54公里
经度:1你= 111320个* COS(纬度)公里
和公正的检查监视区域内的中心设备的当前位置的边界方(参见: 简单的计算与经/纬度+公里距离工作? )
因此,例如,如果(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。 如果以下/以上,只是增加/减小边框的大小和重复搜索。
你可以调整该搜索算法有更好的表现,但这里所描述的都已经做的工作。
你可以保留一个位置,以一个“元地理围栏”包括所有当前监视的位置。 当用户离开该地理围栏之后,应用程序将另行通知。 然后,应用程序可以自我更新并停止跟踪最远的地区,并开始在附近跟踪新的领域。
我以为我会添加其他选项,在您的应用程序中使用超过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];
}
}
}
希望这会帮助别人或引导他们走上正确的道路。
如果你关心的每个显著位置的变化进行近距离检查,你可以使用像一个空间索引/搜索方法的R-tree或R * -树 ,以减少所需的每个位置变化比较的次数,因为这些搜索算法将过滤掉(可能很大)在空间上不相关的区域。 这应该减少执行接近检查所需的时间/电池电量。
我知道这个帖子是旧的,但对于那些希望做类似的事情, 天棚提供了栅栏场馆无限数量的能力。
从他们的营销:Skyhook的语境加速器使应用开发商和广告商快速地部署通过一个简单的Web界面无限地理围栏的任何品牌连锁(如CVS)或场地类别(如便利店)。 从Skyhook的第一方定位网络使用相同的专利技术,上下文加速器SDK管理设备上的那些活跃地理围栏,无论操作系统的限制,允许无限的地理围栏。