Способ определения местоположения iOS для фильтрации недопустимых/неточных местоположений

Я использую Location Services в некоторых моих приложениях. У меня есть метод, который я использую в моем locationManager:didUpdateToLocation:fromLocation: метод для фильтрации плохих, неточных или слишком далеких местоположений. И чтобы минимизировать gps "джиттер". Вот что я использую:

/**
 * Check if we have a valid location
 *
 * @version $Revision: 0.1
 */
+ (BOOL)isValidLocation:(CLLocation *)newLocation withOldLocation:(CLLocation *)oldLocation {

    // Filter out nil locations
    if (!newLocation) return NO;

    // Filter out points by invalid accuracy
    if (newLocation.horizontalAccuracy < 0) return NO;
    if (newLocation.horizontalAccuracy > 66) return NO;

    // Filter out points by invalid accuracy
    #if !TARGET_IPHONE_SIMULATOR
    if (newLocation.verticalAccuracy < 0) return NO;
    #endif

    // Filter out points that are out of order
    NSTimeInterval secondsSinceLastPoint = [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp];
    if (secondsSinceLastPoint < 0) return NO;

    // Make sure the update is new not cached
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
    if (locationAge > 5.0) return NO;

    // Check to see if old and new are the same
    if ((oldLocation.coordinate.latitude == newLocation.coordinate.latitude) && (oldLocation.coordinate.longitude == newLocation.coordinate.longitude)) 
        return NO;

    return YES;

}//end

У кого-нибудь есть какие-либо улучшения в этом методе, чтобы сделать его более точным? 66 слишком высока horizontalAccuracy и получит много неверных местоположений? Должен ли я снизить это?

Есть ли способ избавиться от "джиттера", который дает gps на iPhone?

Ответ 1

В дополнение к этому есть еще один я использую:

if(self.lastKnownLocation)
{
     CLLocationDistance dist = [newLocation distanceFromLocation:self.lastKnownLocation];

     if(dist > newLocation.horizontalAccuracy)
     {
          //.....
     }
}

Где self.lastKnownLocation на самом деле последнее действительное местоположение, которое у меня есть, и оно:

@property(nonatomic, copy) CLLocation *lastKnownLocation;

Ответ 2

-(void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
 if (!newLocation)
    {
        NSLog(@"Filter out points by invalid accuracy");
        return;
    }

    // Filter out points by invalid accuracy
    if (newLocation.horizontalAccuracy < 0)
    {
        return;
    }
    if(oldLocation.coordinate.latitude>90 && oldLocation.coordinate.latitude<-90 && oldLocation.coordinate.longitude>180 && oldLocation.coordinate.longitude<-180)
    {   
       NSLog(@"old");
       return;
    }
    if(newLocation.coordinate.latitude>90 || newLocation.coordinate.latitude<-90 || newLocation.coordinate.longitude>180 || newLocation.coordinate.longitude<-180)
    {
       NSLog(@"new");
       return;
    }

    ///////   
    NSDate *eventDate=newLocation.timestamp;   
    NSTimeInterval eventinterval=[eventDate timeIntervalSinceNow];


    if (abs(eventinterval)<30.0)
    {           
       if (newLocation.horizontalAccuracy>=0 && newLocation.horizontalAccuracy<20)
       { 
          **//finally you are getting right updated value here....**
       }          
    }           
 }  

Ответ 3

Вы можете проверить это

https://medium.com/@mizutori/make-it-even-better-than-nike-how-to-filter-locations-tracking-highly-accurate-location-in-774be045f8d6

Основная идея заключается в фильтрации данных в методе didUpdateLocation:

Метод фильтра выглядит так:

func filterAndAddLocation(_ location: CLLocation) -> Bool{
    let age = -location.timestamp.timeIntervalSinceNow

    if age > 10{
        return false
    }

    if location.horizontalAccuracy < 0{
        return false
    }

    if location.horizontalAccuracy > 100{
        return false
    }

   locationDataArray.append(location)

    return true

}