CLLocationManager Coordinates

2019-07-03 23:34发布

I have been working to implement route trace map for walking,biking and driving.

However, as you see in the following screenshot, my coordinate jumps all of a sudden from time to time even though I did not walk/bike or drive that location. The circle has been drawn on the image to point out the problem. My question is why all of a sudden coordinates jumps ?

enter image description here

Here is my implementation snapshot:

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation
{
    CoordinateModel *coord = [[CoordinateModel alloc] init];
    coord.latitude = newLocation.coordinate.latitude;
    coord.longitude = newLocation.coordinate.longitude;

    ActivityType currentActivityType = [DataManager sharedInstance].activityType;

        if (currentActivityType == 0) {
            // walking
            [appDelegate.walkingCoordinates addObject:coord];
        }
        else if(currentActivityType == 1) {
            [appDelegate.bikingCoordinates addObject:coord];
        }
        else if(currentActivityType == 2) {
            // driving
            [appDelegate.drivingCoordinates addObject:coord];
        }

     self.coordinate = newLocation.coordinate;
}

2条回答
Viruses.
2楼-- · 2019-07-03 23:58

I suggest you not to use the delegate method locationManager:didUpdateToLocation:fromLocation: anymore and it has been deprecated.

You should use locationManager:didUpdateLocations instead.

About your question, the location "jumping" like you mention is due to the GPS that is unable to determine the accuracy of your location during a certain time. If you record down the coordinate and also the accuracy for all the time including when you are indoor, you will realize that the accuracy when you are staying indoor is not good, you might see the accuracy 1414 when you are connected to Wifi. GPS does not work well when you are indoor. So, your code has to be smart enough to only draw a path or send the coordinate to the server when only the coordinate is good enough.

The below code are some of the criteria that I use to filter out the bad coordinates.

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

for(int i=0;i<locations.count;i++){
  CLLocation * newLocation = [locations objectAtIndex:i];
  CLLocationCoordinate2D theLocation = newLocation.coordinate;
  CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
  NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

  if (locationAge > 30.0)
      continue;

  //Select only valid location and also location with good accuracy
  if(newLocation!=nil&&theAccuracy>0
     &&theAccuracy<2000
     &&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){
      self.myLastLocation = theLocation;
      self.myLastLocationAccuracy= theAccuracy;
      NSMutableDictionary * dict = [[NSMutableDictionary alloc]init];
      [dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"];
      [dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"];
      [dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"];
      //Add the valid location with good accuracy into an array
      //Every 1 minute, I will select the best location based on accuracy and send to server
      [self.shareModel.myLocationArray addObject:dict];
    }
   }
 }

After a certain period (eg: 3 minutes), I will again choose the best coordinate from self.shareModel.myLocationArray before drawing the coordinate on map and send the coordinate to the server.

You may see the full solution and sample project from here: Background Location Services not working in iOS 7

Don't forget to upvote if my answer is good enough. ;)

查看更多
干净又极端
3楼-- · 2019-07-04 00:18

Same Problem has been still in the code.

enter image description here

  -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{


    iNEAT_o_GamesAppDelegate *appDelegate = (iNEAT_o_GamesAppDelegate *)[[UIApplication sharedApplication] delegate];

    CoordinateModel *coord = [[CoordinateModel alloc] init];

    ActivityType currentActivityType = [DataManager sharedInstance].activityType;

    for(int i=0;i<locations.count;i++){
        CLLocation * newLocation = [locations objectAtIndex:i];
        CLLocationCoordinate2D theLocation = newLocation.coordinate;
        CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
        NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

        if (locationAge > 30.0)
            continue;

        //Select only valid location and also location with good accuracy
        if(newLocation!=nil&&theAccuracy>0
           &&theAccuracy<2000
           &&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){
            coord.latitude = theLocation.latitude;
            coord.longitude = theLocation.longitude;

                   if (currentActivityType == 0) {
                        // walking
                        [appDelegate.walkingCoordinates addObject:coord];
                    }
                    else if(currentActivityType == 1) {
                        [appDelegate.bikingCoordinates addObject:coord];
                    }
                    else if(currentActivityType == 2) {
                        // driving
                        [appDelegate.drivingCoordinates addObject:coord];
                    }
        }
    }
}
查看更多
登录 后发表回答