2013-01-09 28 views
29

iOSアプリケーションでは、ジオフェンシングを使用して、事前に定義された付近の場所についてユーザーに通知します。アプリケーションはある場所を見逃すことができます(ユーザーは近くの場所について通知を受けていません)が、欠落率を低く保つことが望ましいです。iOSジオフェンシングで複数(20+)の場所を追跡する

startMonitoringSignificantLocationChangesで重要な変更箇所の監視を開始し、「場所変更」イベントが発生するたびに、報告された場所の半径500mの範囲内で場所を探します。

重要な場所の変更が発生し、バッテリに影響するたびに近くの地域のクエリを実行する必要があると心配です。

もう1つの方法は、位置をstartMonitoringForRegionに登録することですが、アップルは同時にトラッキングされた領域の数を20に制限しており、20以上の場所があります。トラッキングされた領域を動的に更新する必要がありますが、それを実行する最良の方法はまだ分かりません。

どのようにしてバッテリーの消費量を低く抑えることができますか、場所の欠落率が低いという考え方はありますか?

+1

また、これを行う方法も知りたいです。 – nhisyam

+0

Swiftの回答については、[こちら](https://stackoverflow.com/questions/44946411/how-to-monitor-more-than-20-regions/45391851#45391851) – Honey

答えて

19

質問にはあまり活動していなかったので、私は現在この問題をどのように解決しているかを説明します。

重要なロケーション変更(SLC)イベントに新しい領域のリロードを結びました。 SLCが行われるとき、我々は "地張り"されるべき20の隣接する領域を調べる。 20の最も近い領域を見つけるために、我々は、単に次の式に従って緯度と経度の '1を近似している。

緯度:1℃= 110.54キロ

経度:1゜= 111.320 * COSを(緯度)キロ

だけ参照監視領域(の中心のためのデバイスの現在の位置の境界正方形をチェック:Simple calculations for working with lat/lon + km distance?)を

したがって、例えば、(10N、10E)である場合cu (10-1 '、10-1')、(X-10 '、10 + 1')、(10 + 1 '、10 + 1')、および(10 + 1 '、10-1')(緯度(10N、10E)で1つの緯度/経度分は約1,85km)。

20(またはほぼ20)ある場合は、それらをジオフェンシングに登録し、次のSCLを待ちます。 less/moreの場合は、境界矩形のサイズを増減して検索を繰り返します。

パフォーマンスを向上させるためにこの検索アルゴリズムを微調整することはできますが、ここで説明している方法ではすでにその処理が行われています。

+5

あなたはそれを行う方法を示すためにいくつかのサンプルコードを入れていただけますか? –

+1

私は同じことをしようとしていますが、アプリケーションが閉じているときに私のために働いていないのは、アプリケーションがバックグラウンドのときに動作していることだけです。私は実際にいくつかのサンプルコードを投稿していただきありがとうございます。 – HEH

+2

重要なロケーション変更イベントを既に使用しているので、iOSジオフェンシングをスキップしてみませんか?一番近いジオフェンスを見つけるのではなく、自分のジオフェンスの中にいるかどうかを確認するだけでよいのです。 –

8

現在監視されているすべての場所を含む「メタジオフェンス」の場所を予約できます。ユーザーがこのジオフェンスを離れると、アプリに通知されます。その後、アプリはそれ自体を更新し、最も遠い領域の追跡を停止し、近傍の新しい領域の追跡を開始することができます。

+2

を参照してください。上記のメソッドはここにあります:http://stackoverflow.com/questions/22297995/add-more-than-20-regions-to-geofencing-ios/24080059#24080059 – uofc

+1

@uofcそのページのあなたのソリューションはどこですか? – JAHelia

+0

携帯端末がメタジオフェンスを悪い状態(たとえば、電源が入っていない状態)にすると、通知を受けず、次のアプリが起動するまで死ぬでしょう。 – DanSkeel

3

各重要な場所の変更で近接チェックを実行することに懸念がある場合は、R-treesまたはR*-treeのような空間インデックス/検索方法を使用して、各場所の変更に必要な比較回数を減らします空間的に無関係の領域(おそらくは大)これは、近接チェックを実行するのに必要な時間/バッテリ電力を削減するはずです。

5

あなたのアプリに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]; 
     } 
    } 
} 

これは、誰かを助けるか、正しい経路でそれらを操縦することを望みます。

+1

こんにちはビル私はちょうどあなたのソリューションを読んでいた。あなたは "startMonitoringForRegion:"と "stopMonitoringForRegion:"を呼ぶことはありません。 20の地域が既に登録されていても、次の呼び出しで新しい地域を登録しようとするとどうなりますか?以前登録済みのすべての座標を停止するために、登録されたすべての領域を保存し、 "startMonitoringForRegion:"を呼び出す前に、新しい20の最も近い座標を呼び出すことは意味がありませんか? –

+1

私は20以上のときに、私のアプリがバックグラウンドに行くときだけstartMonitoringを呼び出します。私のアプリが戻ってきたら(私はアクティブにする)、私はそれをオフにする。私は絶えずジオフェンスをオフにして戻します。私がジオフェンスを追加するとき、私はそれが失敗するところに直接追加していません。私は基本的にそれを有効にするように設定し、私のマネージャーに最も近い20を追加するように指示します。 YMMV –

+0

Swiftで答えてください。 – SaiPavanParanam

1

私はこの投稿が古いと知っていますが、似たようなことをしようとする人にとっては、Skyhookは無限の会場にジオフェンスを提供します。

Skyhook's Context Acceleratorを使用すると、アプリ開発者や広告主は、簡単なWebインターフェイスを通じて、Infinite Geofenceを任意のブランドチェーン(CVSなど)や会場カテゴリ(コンビニエンスストアなど)に即座に展開できます。 Context Accelerator SDKは、Skyhookのファーストパーティのロケーションネットワークと同じ特許技術を使用して、無制限のジオフェンシングを可能にするOSの制限にかかわらず、デバイス上のアクティブなジオフェンスを管理します。

関連する問題