0

i`m building an app wich notify the user when getting to the max speed limit "120 km/h"

but i`m not getting the exact speed value when testing the app while driving

lets say i`m driving at 80 km/h speed , the value i get from the app is a range between 60 - 100 sometimes more changing every second.

this is my whole code i`m using

viewController.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import "CoreLocationController.h"
#import <MapKit/MapKit.h>

@interface ViewController : UIViewController <CLLocationManagerDelegate,     CoreLocationControllerDelegate> {
MKMapView *mapview;
CLLocationManager *locationManager;
IBOutlet UILabel *speedLabel;
CoreLocationController *CLController;

int distance;
int currentSpeed;
int maxSpeed;
IBOutlet UILabel *distanceLbl;
IBOutlet UILabel *maxSpeedLbl;
IBOutlet UILabel *currentSpeedLbl;
}

- (IBAction)Getlocation:(id)sender;

@property (nonatomic, retain) IBOutlet UILabel *distanceLbl;
@property (nonatomic, retain) IBOutlet UILabel *maxSpeedLbl;
@property (nonatomic, retain) IBOutlet UILabel *currentSpeedLbl;
@property (retain, nonatomic) IBOutlet UILabel *speedLabel;
@property (nonatomic, retain) CoreLocationController *CLController;
@property (retain, nonatomic) IBOutlet MKMapView *mapview;
@property (strong, nonatomic) IBOutlet CLLocationManager *locationManager;

viewController.m

@synthesize distanceLbl,maxSpeedLbl,currentSpeedLbl;
@synthesize locationManager;
@synthesize mapview;
@synthesize speedLabel;
@synthesize CLController;

- (void)locationChange:(CLLocation *)newLocation:(CLLocation *)oldLocation {

    NSTimeInterval difference = [[newLocation timestamp] timeIntervalSinceDate:[oldLocation timestamp]];

    double temp_distance = [newLocation getDistanceFrom:oldLocation];

    distance += temp_distance;
    distanceLbl.text = [NSString stringWithFormat:@"%.2d",distance];
    currentSpeed = (temp_distance/difference) * (18.0/5.0);
    if (currentSpeed > maxSpeed) {
        maxSpeed = currentSpeed;
        maxSpeedLbl.text = [NSString stringWithFormat:@"%.2d",maxSpeed];
    }
    currentSpeedLbl.text = [NSString stringWithFormat:@"%.2d",currentSpeed];
}

- (void)locationUpdate:(CLLocation *)location {
    speedLabel.text = [NSString stringWithFormat:@"SPEED: %f", [location speed]];
    self.mapview.showsUserLocation = YES;
}

- (void)locationError:(NSError *)error {
    speedLabel.text = [error description];
}

- (IBAction)Getlocation:(id)sender {
    locationManager = [[CLLocationManager alloc] init];
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.delegate = self;
    [locationManager startUpdatingLocation];

    [mapview setMapType:MKMapTypeStandard];
    [mapview setZoomEnabled:YES];
    [mapview setScrollEnabled:YES];
    self.mapview.showsUserLocation = YES;
    MKCoordinateRegion region = { {0.0, 0.0 }, {0.0, 0.0 } };
    region.center.latitude = locationManager.location.coordinate.latitude;
    region.center.longitude = locationManager.location.coordinate.longitude;
    region.span.longitudeDelta = 0.007f;
    region.span.latitudeDelta = 0.007f;
    [mapview setRegion:region animated:YES];
    [mapview setDelegate:sender];
}

- (IBAction)setMap:(id)sender {

    switch (((UISegmentedControl *) sender).selectedSegmentIndex) {
        case 0:
            mapview.mapType = MKMapTypeStandard;
            break;
        case 1:
            mapview.mapType = MKMapTypeSatellite;
            break;
        case 2:
            mapview.mapType = MKMapTypeHybrid;
            break;
        default:
            break;
    }

}

- (void)viewDidLoad
{
    [super viewDidLoad];

    CLController = [[CoreLocationController alloc] init];
    CLController.delegate = self;
    [CLController.locMgr startUpdatingLocation];

    [self Getlocation:self];

    maxSpeed = 120;
}

CoreLocationController.h

@protocol CoreLocationControllerDelegate
@required

- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)locationChange:(CLLocation *)newLocation:(CLLocation *)oldLocation;

@end


@interface CoreLocationController : NSObject <CLLocationManagerDelegate> {
    CLLocationManager *locMgr;
    id delegate;

    //new speed method
    int distance;
    int currentSpeed;
    int maxSpeed;
    IBOutlet UILabel *distanceLbl;
    IBOutlet UILabel *maxSpeedLbl;
    IBOutlet UILabel *currentSpeedLbl;
}

@property (nonatomic, retain) IBOutlet UILabel *distanceLbl;
@property (nonatomic, retain) IBOutlet UILabel *maxSpeedLbl;
@property (nonatomic, retain) IBOutlet UILabel *currentSpeedLbl;

@property (nonatomic, retain) CLLocationManager *locMgr;
@property (nonatomic, assign) id delegate;

CoreLocationController.m

@synthesize locMgr;
@synthesize delegate = _delegate;
@synthesize distanceLbl,maxSpeedLbl,currentSpeedLbl;


- (id)init {
    self = [super init];

    if(self != nil) {
        self.locMgr = [[CLLocationManager alloc] init];
        self.locMgr.delegate = self;
    }

    return self;
}

- (void)locationChange:(CLLocation *)newLocation:(CLLocation *)oldLocation {

    NSTimeInterval difference = [[newLocation timestamp] timeIntervalSinceDate:[oldLocation timestamp]];

    double temp_distance = [newLocation getDistanceFrom:oldLocation];

    distance += temp_distance;
    distanceLbl.text = [NSString stringWithFormat:@"%.2d",distance];
    currentSpeed = (temp_distance/difference) * (18.0/5.0);
    if (currentSpeed > maxSpeed) {
        maxSpeed = currentSpeed;
        maxSpeedLbl.text = [NSString stringWithFormat:@"%.2d",maxSpeed];
    }
    currentSpeedLbl.text = [NSString stringWithFormat:@"%.2d",currentSpeed];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    if([self.delegate conformsToProtocol:@protocol(CoreLocationControllerDelegate)]) {
        [self.delegate locationUpdate:newLocation];
        [self.delegate locationChange:newLocation :oldLocation];
    }
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    if([self.delegate conformsToProtocol:@protocol(CoreLocationControllerDelegate)]) {
        [self.delegate locationError:error];
    }
}
aLFaRSi
  • 559
  • 2
  • 12
  • 29
  • I believe the location manager will tell you when a reading isn't completely accurate and therefore you should skip those until you have better information ... just a guess. – Ja͢ck Dec 03 '12 at 10:11
  • 2
    You'll probably need to apply a low pass filter to the data to get a smoothed value. – Paul R Dec 03 '12 at 10:11
  • The speedometer will not show the exact speed either. They are designed that way for safety reasons. – Mark Byers Dec 03 '12 at 10:12
  • @Jack its not telling me anything – aLFaRSi Dec 03 '12 at 10:15
  • I would suggest, you should check the accuracy of every location update, as well as, sum speed for 3..4 seconds and get the avarage speed of that 3..4 secs, – Adeel Pervaiz Dec 03 '12 at 10:15
  • @PaulR can you please explain to me how could i do that ? :) – aLFaRSi Dec 03 '12 at 10:15
  • @MarkByers then how could some navigation apps give the exact speed ? – aLFaRSi Dec 03 '12 at 10:16
  • @AdeelPervaiz but i think that will not show the speed when accelerating. it will be something like 0 km/h the after 3 sec it will jump to 50 km/h – aLFaRSi Dec 03 '12 at 10:18
  • @aLFaRSi: They get a more precise estimate by using GPS signals from satellites above the Earth. It's not *exact* but it's a lot more reliable than the speedometer (assuming good GPS coverage). – Mark Byers Dec 03 '12 at 10:21
  • @MarkByers Ok, what will be the best option for me to get a more _reliable_ value ? – aLFaRSi Dec 03 '12 at 10:25
  • 1
    @aLFaRSi: Perhaps check out related questions. For example: http://stackoverflow.com/questions/1134579/smooth-gps-data – Mark Byers Dec 03 '12 at 10:27

0 Answers0