2011-01-08 6 views
27

Also habe ich es mit einigen Genauigkeitsprobleme mit iPhone GPS zu tun. Ich habe eine App, die den Standort verwendet.CLLocationManager und Genauigkeitsprobleme - irgendwelche Erfahrungen?

In der Delegate-Methode locationManager: didUpdateToLocation: fromLocation: bin ich ein Ort zurückgegeben. Nach ein wenig Nachforschungen scheint das GPS beim ersten Ergebnis, das es zurückgibt, nicht immer genau zu sein, selbst wenn die Eigenschaft desiredAccuracy auf kCLLocationAccuracyBest gesetzt wird.

Um dies zu umgehen, ich rufe nicht stopUpdatingLocation bevor es newLocation: mindestens 3 Mal zurückgegeben wird (das ist sehr schnell). Ich habe auch mit zwei anderen "Voraussetzungen" herumgespielt, ob stopUpdatingLocation und die newLocation zurückgeben. Eine Möglichkeit, die ich versuchte, war die Überprüfung der Lat und lange für newLocation und vergleichen Sie mit oldLocation und wenn diese nicht identisch waren, dann halten Sie die Standortaktualisierung läuft. Ich habe auch versucht, mit der Überprüfung der Abstand zwischen oldLocation und newLocation und wenn es weniger als 20 Meter ist, ist es in Ordnung. Beide werden mit der Rückgabe von mindestens 3 Läufen getestet. Der letztere Weg ist weniger "streng", da newLocation und oldLocation ziemlich schwer wegzukommen ist, wenn er 100% identisch ist, wenn sich der Benutzer in einem sich bewegenden Fahrzeug befindet.

, nun mein Problem ist, dass selbst dann, wenn die oben tun (im Grunde nicht eine Position zu akzeptieren, bis vor ein paar Updates auf CLLocationManager aufgetreten ist und den Abstand zwischen dem CLLocations Überprüfung (oder ob sie identisch sind) Ich bin immer noch zu sehen, etwas seltsame Ergebnisse für Standorte manchmal, beim Testen.

Es wäre manchmal zu beheben, wenn ich die App verlassen, gehen Sie in Maps.app, verwenden Sie das GPS, dann öffnen Multitasking, zwingen, meine App zu beenden und dann wieder öffnen, um eine saubere Einführung

Irgendwelche Erfahrungen und mögliche Lösungen, die Leute verwendet haben, um die gleiche Art von Problem zu umgehen? Kommentare und Lösungen geschätzt :)

Antwort

45

Ich erinnere mich nicht, welches Projekt es genau war, dass ich den folgenden Code bekam, aber das hat für mich wirklich gut funktioniert (ich erinnere mich, dass es von einem WWDC 2010 Video war). In meinem Code habe ich die Kommentare aus dem ursprünglichen Projekt in Takt gelassen, also hoffentlich wird das helfen.

- (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]; 
     } 
    } 
} 

Hoffe, das hilft!

Via GetLocationViewController.m in Apples "Locate Me" Beispielprojekt unter:

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

+0

Ah , perfekt! Ich hätte mir die Eigenschaften für den zurückgegebenen CLLocation newLocation näher angesehen, ich wusste nicht, dass es auch einen timeStamp hatte. Ich werde wahrscheinlich dieses zusammen mit meinem eigenen Code verwenden. Vielen Dank! – runmad

+1

das ist von Apples "Locate me" Beispiel: 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

dies ist genau das, wonach ich suche. Vielen Dank. – bselvan

0

Von donkim Antwort betrachten diese Linie ersetzt

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

mit Linie

[NSObject cancelPreviousPerformRequestsWithTarget: self];