MKMapView route update issue - iphone

I would like to create a route in mkmapview whenever user moves to some new coordinates, Eg i i am in position A, now i am moving towards position B then the route should also be update.
Thanks
I think i didnt provide sufficient information for my issue, Here it is now, I have started doing cycling from point a and now i am going to point b then c, d etc, But i didnt reached to point b yet, i am in middle of the way, i like to achieve that my route also updates as i move to point b or c, Do i get the updated lat long value from didupdatetolocation delegate method, store them in an array and then draw, Because if i do so, then i am drawing the path everytime from the array? or is there any other approach which only refresh the updated route with the previous path?

By using this you can update the route..
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// update the route.
}

following code is use for the draw path on map.
-(void) showRouteFrom: (Place*) f to:(Place*) t {
if(routes) {
[mapView removeAnnotations:[mapView annotations]];
[routes release];
}
PlaceMark* from = [[[PlaceMark alloc] initWithPlace:f] autorelease];
PlaceMark* to = [[[PlaceMark alloc] initWithPlace:t] autorelease];
[mapView addAnnotation:from];
[mapView addAnnotation:to];
routes = [[self calculateRoutesFrom:from.coordinate to:to.coordinate] retain];
[self updateRouteView];
[self centerMap];
}
For more detail and sample code grab from here.
hope this help lot..

Related

How Can I Get Current Location on iOS? [duplicate]

This question already has answers here:
how to get the current location position in map on iphone
(2 answers)
Closed 9 years ago.
I can't get current location. When I launch my app in different place, App can get last location. But I don't want to last location. If you close the app and restart it, now app can get current location. How can I get current location even if it is first launch of application?
- (void)viewDidLoad
{
[super viewDidLoad];
[locationManager startUpdatingLocation];
self.mapView.delegate = self;
[self.mapView setShowsUserLocation:YES];
locationManager.delegate=self;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;
location = [locationManager location];
CLLocationCoordinate2D coord;
coord.longitude = location.coordinate.longitude;
coord.latitude = location.coordinate.latitude;
lat = coord.latitude;
longt = coord.longitude;
}
You are doing [locationManager startUpdatingLocation]; before setting its delegate
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
And implement its delegate method
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
}
You should read the documentation provided in the Location Awareness Programming Guide.
Specifically, when you ask for the current location, the system returns the last known location right away so you can do something useful with it. If you don't care about past locations, you can discard it and only use more recent location information by looking at the timestamp property of the CLLocation returned to determine how recent it is.
You should really read the CLLocationManager documentation.
Wat you are doing will not work, since it will take some time determine the device location.
Therefor you will need to wait until the CLLocationManager notifies you that a location has been determent.
You will need to implement the CLLocationManagerDelegate which will tell you if a location is determent or if the location determination failed.
Also you should also check if location can be determent with:
if ([CCLocationManager locationServicesEnabled]) {
// The location services are available.
}
You should also check wether you are authorize to use the location services with [CCLocationManager authorizationStatus].

Can't get location from Wifi connection on iPhone

I am trying to write an app that will get a users location for a mass transit app which works great when I am above ground. When I am underground the location doesn't update even if I have a wifi and/or a cell signal. Below is the code that I am using. From what I understood the iPhone is able to get a location from wifi signal only, is this incorrect? Any help would be greatly appreciated, thank you in advance!
- (void)viewDidLoad
{
[super viewDidLoad];
//********************** Add map ******************************************
//setup location manager
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
//setup map view
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 160.0f)];
mapView.showsUserLocation = YES;
mapView.userTrackingMode = MKUserTrackingModeFollow;
//run loop in background
loopTimer = [[NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:#selector(tick:) userInfo:nil repeats:YES]retain];
}
// Search for n seconds to get the best location during that time
- (void) tick: (NSTimer *) timer
{
// Check for valid coordinate
CLLocationCoordinate2D coord = mapView.userLocation.location.coordinate;
if (!coord.latitude && !coord.longitude) return;
//get coordinates to update map
[mapView setRegion:MKCoordinateRegionMake(coord, MKCoordinateSpanMake(0.005f, 0.005f)) animated:NO];
//update current location in view
currentLatView.text = [NSString stringWithFormat:#"%.2f", coord.latitude];
currentLonView.text = [NSString stringWithFormat:#"%.1f", coord.longitude];
}
The locationManager you setup in viewDidLoad is your instance of the CL Location Manager whereas MapKit uses its own instance when you set showsUserLocation to true.
So your settings for the distance filter and desired accuracy are not being used by MapKit, and in any case, you haven't started your location manager with startUpdatingLocation.
So, try starting your location manager instance and then use the delegate method
locationManager:(CLLocationManager *)manager didUpdateToLocation:
to get what your location manager says.
Here is what I came up with, seems to work well needs more testing.
- (void)viewDidLoad
{
[super viewDidLoad];
//********************** Add map ******************************************
// Create the manager object
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
// When "tracking" the user, the distance filter can be used to control the frequency with which location measurements
// are delivered by the manager. If the change in distance is less than the filter, a location will not be delivered.
locationManager.distanceFilter = kCLLocationAccuracyBest;
// Once configured, the location manager must be "started".
[locationManager startUpdatingLocation];
//initialize newCoord
currentCoord = [[CLLocation alloc] initWithLatitude:0 longitude:0];
//setup map view
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 160.0f)];
mapView.showsUserLocation = YES;
mapView.userTrackingMode = MKUserTrackingModeFollow;
//create map view
[self.view addSubview:mapView];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
// 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;
// store all of the measurements, just so we can see what kind of data we might receive
currentCoord = newLocation;
[self tick];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
// The location "unknown" error simply means the manager is currently unable to get the location.
if ([error code] != kCLErrorLocationUnknown) {
[self stopUpdatingLocation:NSLocalizedString(#"Error", #"Error")];
}
}
- (void)stopUpdatingLocation:(NSString *)state
{
[locationManager stopUpdatingLocation];
locationManager.delegate = nil;
}
- (void) tick
{
//do stuff here
}

Any side effect of CLLocationManager with NSTimer using such approach?

I am working on an iPhone app which needs Location Updates with intervals specified by the user.
Here is the code sample, which I am using to do this:
#implementation TestLocation
- (void)viewDidLoad{
if ([Utils getDataWithKey:TIMER_INTERVAL] == nil) {
[Utils saveDataWithKey:TIMER_INTERVAL withValue:#"60.0"];
}
locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
}
- (void)startLocationManager:(NSTimer *)timer{
[locationManager startUpdatingLocation];
[timer invalidate];
timer = nil;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// Here is code to handle location updates...
[manager stopUpdatingLocation];
// Timer will start getting updated location.
NSTimeInterval timeInterval = [[Utils getDataWithKey:TIMER_INTERVAL] doubleValue];
[NSTimer scheduledTimerWithTimeInterval:timeInterval
target:self
selector:#selector(startLocationManager:)
userInfo:nil
repeats:NO];
}
// other implementations ...
#end
The code is working like a charm.
The question is:
I'm using CLLocationManager along with NSTimer, does this effect memory or battery consumption? I mean any negative effect on User Experience?
If so, any suggestion, helping links to do such task with optimization will be much appreciated.
Note: Utils is my class to store or retrieve data.
Yes this will have some side effects, you will not get the desired accuracy. Since it will call the locationManager:didUpdateToLocation:fromLocation: every time the GPS signal will
be come more accurate.
That isn't a good strategy because you can receive multiple asynchronous location events before the first call to [manager stopUpdatingLocation]. That will lead to exponential number of timers getting created.
Instead, just start the repeating timer after creating your location manager and still stop the location manager after each received event.

CoreLocation startMonitoringRegion not firing didenterregion /didexitregion delegates

i cant seem to get any of the didenterregion/didexitregion delegates firing , been stuck for 2 days on it
im using xcode4.2 with ios5 sdk and location simulation,
has anyone any luck getting this to work? is a 100m radius too small?(ive tried 1000 doesnt work too) or is there something wrong with my code
checked also with normal location updating and user location indeed enters region. could not find an answer anywhere as well
MainViewController(also CLLocationManagerDelegate)'s ViewDidLoad method:
mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeStandard;
mapView.delegate = self;
[self.view addSubview:mapView];
MKCoordinateRegion region;// = {{0.0,0.0},{0.0,0.0}};
MKCoordinateSpan span;
span.latitudeDelta = 0.02;
span.longitudeDelta = 0.02;
CLLocationCoordinate2D coordinates =CLLocationCoordinate2DMake(1.34537, 103.84515);
region.span = span;
region.center = coordinates;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
if (locationManager==nil){
locationManager = [[CLLocationManager alloc] init];
}
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
self.locationManager.delegate =self;
if ([CLLocationManager regionMonitoringAvailable]){
NSLog(#"regionMonitoring available");
CLRegion* region3 = [[CLRegion alloc] initCircularRegionWithCenter:coordinates radius:100 identifier:#"region3"];
[self.locationManager startMonitoringForRegion:region3 desiredAccuracy:1.0];
NSLog(#"region = %#",region3);
NSLog(#"loc max = %f",self.locationManager.maximumRegionMonitoringDistance);
NSLog(#"location manger monitored regions = %#",self.locationManager.monitoredRegions);
also implemented all delegate methods neccessary
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didfailwitherror");
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"latitude %+.10f, longitude %+.10f\n",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(#"didenterregion");
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
NSLog(#"didexitregion");
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{NSLog(#"monitoringDidFailForRegion");}
thanks for any help
How have you been testing the location? The regions are a little tricky, but once they are set up, they usually work great. What I usually do to test the region is just use the custom location in the Simulator. Use the same coordinates you are adding your region. 1000M is pretty large. I've tested with regions as small as 15-20M. If you have the right coordinates, it should be fine. Try switching back and forth from Apple HQ and your custom coordinates. You should be able to see the didEnter and didExit methods trip almost instantly if you have them logged out.
The one area you may have issues with is that the callbacks might not be getting to your method. None of my regions worked until I set up my AppDelegate as the CLLocationManagerDelegate. The app delegate finally got the updates and processed them correctly. I would try adding these callbacks there first, then work your way back to your mainviewcontroller. Hope this helps.
UPDATE
Since answering this question, I have learned a few things more about region monitoring. Regions get added with a minimum region size despite what you add for default. I was told by an Apple engineer that the minimum region size is 100M. I still feel they are very accurate, but it might help to understand why it will check you in. If you need precision better than 100M, you may need to look at other options.

CLLocationManager weird issues

I have a MKMapView whereby I drop an annotation everytime the view loads, or when showLocation custom class method is called.
I need the accuracy to be the best
-(void)viewDidLoad {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[locationManager startUpdatingLocation];
}
-(IBAction) showLocation:(id) sender{
[locationManager startUpdatingLocation];
}
- (void) locationManager:(CLLocationManager *) manager
didUpdateToLocation:(CLLocation *) newLocation
fromLocation:(CLLocation *) oldLocation {
// start geocoding with newLocation coordinate which will automatically set annotation.
SVGeocoder *geocodeRequest = [[SVGeocoder alloc]
initWithCoordinate:CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude)];
[geocodeRequest setDelegate:self];
[geocodeRequest startAsynchronous];
[geocodeRequest release];
[locationManager stopUpdatingLocation];
}
My question is when will the didUpdateToLocation method be called? Only after a new location is found when I perform [locationManager startUpdatingLocation]?
I am facing some weird issue when the user is travelling and on stationary.
Say the user is travelling from point A->B->C->D with 1 min intervals between points. When I call my method at point C, sometime it returns the coordinates of point A, sometimes point B and sometimes C. It's just random.
It's even more weird when I am on stationary. I get different coordinates when I calls showLocation method even though I am hooked up on my house WiFi.
I was thinking of implementing the didUpdateToLocation to get the best result it can within 5secs. If within the 5secs, it finds a particular location of an accuracy I had defined, then use the coordinate. If not, use the best it has found within the 5sec time frame. But as I am new I am not sure how to code something like that. I read up NSTimer and it seems like it might work.
Any advices guys?
Thanks a lot in advance!
One of the reasons you are receiving the location from point A is that CoreLocation is returning the last valid location it had first until it can obtain a more accurate location. When you call [locationManager startUpdatingLocation]; it will return the -didUpdateToLocation over and over until you are statisfied and finally call -stopUpdatingLocation.
I think you just need to allow a bit of time for it to get a better location fix before you stop updating your location. I would consider moving the stop updating location from your -didUpdateToLocation to a different method.
Remove [locationManager stopUpdatingLocation]; from your code and try .