sil*_*ser 30 location cllocationmanager ios geofencing
iOS应用程序使用地理围栏来通知用户有关预定义的附近位置.允许应用程序错过某个位置(用户没有收到有关附近位置的通知),但是希望保持较低的丢失率.
实现这一目标的一种方法是开始监控重要的变更位置,startMonitoringSignificantLocationChanges并且每次"位置变更"事件被触发时,查找位于报告位置的500米半径内的位置.
令我担心的是,每次发生重大位置变化时都需要对附近区域执行查询,这会影响电池.
另一种方法是注册地点,startMonitoringForRegion但Apple对同时跟踪的地区数量(合理)限制为20,我们有超过20个地点.因此需要对跟踪区域进行某种动态更新,但我仍然不确定最佳方法是什么.
有关如何做到这一点的任何想法,以便它保持低电池消耗,但也具有低位置的丢失率?
sil*_*ser 22
由于在这个问题上活动不多,我将描述我们目前如何解决这个问题.
我们将新区域的重新加载与重要的位置变更(SLC)事件联系在一起.当SLC发生时,我们检查应该"地理围栏"的20个相邻区域.为了找到20个最接近的区域,我们根据以下公式简单地逼近纬度和经度的1'':
纬度:1度= 110.54公里
经度:1度= 111.320*cos(纬度)km
然后检查设备当前位置的边界平方,以便监控区域的中心(参见:使用lat/lon + km距离进行简单计算?)
因此,例如,如果(10N,10E)是设备的当前位置,我们从边界处开始,顶点位于(10-1',10-1'),(X-10',10 + 1') ,(10 + 1',10 + 1'),(10 + 1',10-1')(在纬度(10N,10E),一个纬度/经度分钟接近1,85 km).
如果有20个(或差不多20个) - 我们将它们注册为地理围栏并等待下一个SCL.如果更少/更多,只需增加/减少边界矩形的大小并重复搜索.
您可以调整此搜索算法以获得更好的性能,但此处描述的搜索算法已经完成了这项工作.
您可以为"meta-geofence"保留一个位置,其中包含所有当前监控的位置.当用户离开此地理围栏时,将通知应用程序.然后,应用程序可以更新自己并停止跟踪最远的区域并开始跟踪附近的新区域.
我想我会添加另一个选项,在您的应用中使用超过20个Geofences.这种方式在我们的应用程序中已经运行了很长时间,并使用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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这将有助于某人或引导他们走上正确的道路.
| 归档时间: |
|
| 查看次数: |
11448 次 |
| 最近记录: |