2011-01-08 15 views
27

Quindi mi occupo di alcuni problemi di precisione con l'iPhone GPS. Ho un'app che usa la posizione.CLLocationManager e problemi di precisione - qualche esperienza?

Nel metodo delegato locationManager: didUpdateToLocation: fromLocation: Mi viene restituita una posizione. Da un po 'di ricerca, sembra che il GPS non sia sempre preciso sul primo risultato restituito, anche quando si imposta la proprietà desiredAccuracy su kCLLocationAccuracyBest.

Per evitare questo, non chiamare stopUpdatingLocation prima che sia restituito newLocation: almeno 3 volte (questo è molto veloce). Ho anche giocato con altri due "requisiti" per stopUpdatingLocation e restituire lo newLocation. Un modo in cui ho provato è stato controllare il lat e long per newLocation e confrontare con oldLocation e se questi non erano identici, quindi mantenere l'aggiornamento della posizione in esecuzione. Ho anche provato a controllare la distanza tra lo oldLocation e lo newLocation e se è inferiore a 20 metri, va bene. Entrambi sono testati con il ritorno di almeno 3 esecuzioni. Quest'ultimo modo è meno "rigoroso", dal momento che newLocation e oldLocation è piuttosto difficile da ottenere con il 100% identico se l'utente si trova in un veicolo in movimento.

Ora, il mio problema è, che anche quando si fa il sopra (in fondo non accettare una posizione, fino a quando alcuni aggiornamenti sono verificati sulla CLLocationManager e controllando la distanza tra la CLLocations (o se sono identici) sto ancora vedendo un po ' risultati strani per le posizioni a volte, durante i test

A volte, se esco dall'app, andare in Maps.app, utilizzare il GPS, quindi aprire il multitasking, forzare l'uscita dalla mia app e quindi riaprirlo per ottenere una pulizia lancio

Eventuali esperienze e possibili soluzioni le persone hanno usato per aggirare lo stesso tipo di problema? Commenti e soluzioni apprezzate :)

risposta

45

Non ricordo quale progetto fosse esattamente il codice da cui ho preso il codice seguente, ma per me ha funzionato molto bene (ricordo che proveniva da un video del WWDC 2010). Nel mio codice ho lasciato intatti i commenti del progetto originale, quindi spero che ciò possa essere d'aiuto.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
    // test the age of the location measurement to determine if the measurement is cached 
    // in most cases you will not want to rely on cached measurements 
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow]; 

    if (locationAge > 5.0) return; 

    // test that the horizontal accuracy does not indicate an invalid measurement 
    if (newLocation.horizontalAccuracy < 0) return; 

    // test the measurement to see if it is more accurate than the previous measurement 
    if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) { 
     // store the location as the "best effort" 
     self.bestEffortAtLocation = newLocation; 

     // test the measurement to see if it meets the desired accuracy 
     // 
     // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue 
     // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of 
     // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout. 
     // 
     if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) { 
      // we have a measurement that meets our requirements, so we can stop updating the location 
      // 
      // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible. 
      // 
      [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")]; 

      // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary 
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil]; 
     } 
    } 
} 

Spero che questo aiuti!

Via GetLocationViewController.m in "Locate Me" progetto di esempio di Apple, disponibile all'indirizzo:

https://developer.apple.com/library/content/samplecode/LocateMe/Introduction/Intro.html

+0

Ah perfetto! Avrei dovuto esaminare più da vicino le proprietà per la nuova localizzazione di CLLocation restituita, non mi ero reso conto che aveva anche un timeStamp. Probabilmente userò questo insieme al mio codice. Grazie mille! – runmad

+1

che proviene dall'esempio "Locate me" di apple: https://developer.apple.com/library/ios/#samplecode/LocateMe/Listings/Classes_TrackLocationViewController_m.html#//apple_ref/doc/uid/DTS40007801-Classes_TrackLocationViewController_m-DontLinkElementID_14 – Garoal

+0

è esattamente quello che sto cercando. Grazie. – bselvan

0

Dalla risposta di donkim di sostituire questa linea

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil]; 

con la linea

[NSObject cancelPreviousPerformRequestsWithTarget: self]; 
Problemi correlati