15

When I try to display the map I get this exception :

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region <center:+inf, +0.00000000 span:+1.00000000, +0.50000000>'

My relevant code is this :

-(void)viewWillAppear:(BOOL)animated
{   
    [mapView removeAnnotations:mapView.annotations];
    
    // locationManager update as location
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    locationManager.distanceFilter = kCLDistanceFilterNone; 
    [locationManager startUpdatingLocation];
    CLLocation *location = [locationManager location];
    //Configure the new event with information from the location
    CLLocationCoordinate2D coordinate = [location coordinate];
    
    latitudeOfUserLocation=coordinate.latitude;
    longitudeOfUserLocation=coordinate.longitude;
    
    location2D = (CLLocationCoordinate2D){ .latitude = latitudeOfUserLocation, .longitude = longitudeOfUserLocation };
    MyLocation *annotation=[[[MyLocation alloc]initWithName:@"You are here" distanceVersLaStation:@"" coordinate:location2D]autorelease];
    annotation.pinColor = MKPinAnnotationColorRed;  
    [mapView addAnnotation:annotation];
    
    MKCoordinateSpan span={latitudeDelta:1,longitudeDelta:0.5};
    MKCoordinateRegion region={location2D,span};
    [mapView setRegion:region];

}

Edit

I tried to do as you said in the comments. The exception is solved, however, when I try to display the longitude/latitude of the user in the console I get nothing. This is my code which is mostly correct:

    -(void)viewWillAppear:(BOOL)animated
    {  
            
        [mapView removeAnnotations:mapView.annotations];
        
        // locationManager update as location
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate = self; 
        locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
        locationManager.distanceFilter = kCLDistanceFilterNone; 
        [locationManager startUpdatingLocation];
        NSURL *url=[NSURL         URLWithString:@"http://ipho.franceteam.org/ad_V1/stations/"];
    ASIFormDataRequest * request=[ASIFormDataRequest requestWithURL:url];
[request setPostValue:[NSNumber numberWithFloat:longitudeOfUserLocation] forKey:@"longitude"];
    [request setDelegate:self];
    [request startAsynchronous];
    MBProgressHUD *hud=[MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.labelText=@"Recherche en cours..";// this never stop loading

    }

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    CLLocation *location = [locationManager location];
    //Configure the new event with information from the location
    CLLocationCoordinate2D coordinate = [location coordinate];
    latitudeOfUserLocation=coordinate.latitude;
    longitudeOfUserLocation=coordinate.longitude;
    NSLog(@"your latitude :%f",latitudeOfUserLocation);//here nothing is shown
    NSLog(@"your longitude :%f",longitudeOfUserLocation);// and here too
    location2D = (CLLocationCoordinate2D){ .latitude = latitudeOfUserLocation, .longitude = longitudeOfUserLocation };
    MyLocation *annotation=[[[MyLocation alloc]initWithName:@"Vous êtes ici" distanceVersLaStation:@"" coordinate:location2D]autorelease];
    annotation.pinColor = MKPinAnnotationColorRed;  //or red or whatever
    [mapView addAnnotation:annotation];
    //
    MKCoordinateSpan span={latitudeDelta:1,longitudeDelta:0.5};
    MKCoordinateRegion region={location2D,span};
    [mapView setRegion:region];

}//End function

Even I work on the simulator, I should get something on the console right?

Edit

Hi again, i had the opportunity to test my code on iPhone (device) and i have noticed that when i try to search, the application has succeeded to track my position and to find me the stations that meet my search (purple annotation), however, the map isn't displayed and the searching progress is still loading and never stop.

hud.labelText=@"Recherche en cours..";// this never stop loading

Here is a screenshot that could explain better:

screenshot

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Luca
  • 20,399
  • 18
  • 49
  • 70
  • I found an issue for this question. It's the length of coordinate: CLLocationCoordinate2D coordinate2D = {26.6374655768,106.6458781604}; – CrazerYJ Apr 18 '17 at 04:19

5 Answers5

13

"Invalid Region" exception is through because the region you set to mapView is invalid. As I know now, there are 2 reasons can cause this exception: region's center point is invalid, or region's span is invalid.

To avoid this exception:
1) Check the center point value: latitude is in range [-90;90], longitude is in range [-180;180]
2) Use [mapView regionThatFits:region] to get a region with valid span then set to mapview:
[mapView setRegion:[mapView regionThatFits:region]]

Cao Huu Loc
  • 1,569
  • 15
  • 18
  • how do you check if center point is withing range as you mentioned? – marciokoko Dec 12 '12 at 02:34
  • 6
    `if ( (region.center.latitude >= -90) && (region.center.latitude <= 90) && (region.center.longitude >= -180) && (region.center.longitude <= 180) { [mapView setRegion:[mapView regionThatFits:region]] }` – Cao Huu Loc Jan 15 '13 at 01:50
  • 24
    There is a nice helper function for this: if(CLLocationCoordinate2DIsValid( CLLocationCoordinate2D coord)) – Daniel Bowden Mar 21 '13 at 22:34
13

In some situations (when the app becomes active from background) didUpdateUserLocation method is fired, but without updated location. In these cases there is no valid region, and setRegion: method can throw an exception. Stupid, a simple solution can be checking if its region is valid before you set it:

 if(region.center.longitude == -180.00000000){
    NSLog(@"Invalid region!");
}else{
    [aMapView setRegion:region animated:YES];
}
Daniel Romero
  • 1,581
  • 1
  • 20
  • 33
dormitkon
  • 2,526
  • 4
  • 39
  • 60
  • This way is also fine we just need to check for the invalid region ,that would be if(region.center.longitude == 0.00000000){ NSLog(@"Invalid region!"); }else{ [aMapView setRegion:region animated:YES]; } – Sabby Jan 27 '12 at 11:13
  • This didnt work for me but then again im getting nan error in my mapview – marciokoko Dec 12 '12 at 02:36
4

After calling startUpdatingLocation, it may take a few seconds for the location to be updated so you can't try to retrieve it immediately afterwards. Until it is updated, location contains invalid values which is what the error tells you.

Instead, implement the locationManager:didUpdateToLocation:fromLocation: delegate method and read the location in there.

Move all the code after startUpdatingLocation to that method:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    CLLocation *location = [locationManager location];
    //etc...
}

Note: above method is depriciated: Apple Doc

Zulqarnain Mustafa
  • 1,615
  • 2
  • 22
  • 25
  • Hi Anna, thx for your useful answer, i have solved the exception issue thanks to you, but now i try just to display the value of the longitude/latitude on the console to make sure i am on the right road however i got nothing, can you please help me there ?i have edited my post, thx in advance :) – Luca May 13 '11 at 19:07
  • 1
    Do you mean it shows 0,0 or no message at all? Did you wait a few seconds? _Add this method_ and let me know if you see anything from it: `- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); }` –  May 13 '11 at 19:23
  • Hi, well, nothing is shown, even the message `didFailWithError:` is not displayed, i have edited my code for the `viewWillAppear` method, i have doubt it's not calling the delegate method for updating position and it pass directly to send the request to the web-service without waiting the user location update, what do you think? i may be wrong :) – Luca May 13 '11 at 19:35
  • Well you can't call the web service with the user's location before you get it (in didUpdateToLocation). But that shouldn't stop the locationManager from getting the location. Remove/comment-out the web service call for now. You'll need to move it to didUpdateToLocation anyway. –  May 13 '11 at 19:40
  • ok, i have wait approximatively 30 seconds to see the faiError message : `2011-05-13 20:42:13.130 TopStation[2125:207] didFailWithError: Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"` , what does this mean please ? is it due to simulator stuff ? – Luca May 13 '11 at 19:43
  • Error 0 is [`kCLErrorLocationUnknown`](http://developer.apple.com/library/ios/#DOCUMENTATION/CoreLocation/Reference/CoreLocationConstantsRef/Reference/reference.html) which means "The location manager was unable to obtain a location value right now." Try moving somewhere else. Also note that when it is able to get the location, it will keep calling didUpdateToLocation when the location changes or it gets a more accurate fix. You have to either call stopUpdatingLocation or be prepared to handle multiple updates (and multiple annotations). –  May 13 '11 at 19:50
  • ok, so to recapitulate, my web-service call is moved to `didUpdateToLocation` and it's ok, my logic is also ok, however because i work on simulator i keep getting that error, should i keep my code like this and wait to test it on a device ? and shouldn't i be afraid of the two `NSLog` which wasn't displaying me nothing or that is normal reporting to this error ??? thx in advance :) – Luca May 13 '11 at 19:54
  • I don't think it's the simulator. It could also happen on a device. It's not a code/logic problem. Core Location was not able to get the location for physical/technical reasons. –  May 13 '11 at 19:56
  • the Base SDK for my xcode is `iPhone simulator 4.0` and in this topic there is somebody who was saying that apple has replaced the default cupertino position by an error message since the iOS version 4 http://stackoverflow.com/questions/3110708/cllocationmanager-on-iphone-simulator-fails-with-kclerrordomain-code-0 – Luca May 13 '11 at 19:59
  • Ok, I've never gotten that error on the simulator but if that's true then it's good for you. Even in the simulator, CL reports the location for me. In any case, be careful to handle didUpdateToLocation in case it's called multiple times and it is still important to handle didFailWithError which can happen for other reasons even on the device (like user did not allow location update). –  May 13 '11 at 20:04
  • what you mean please by `be careful to handle didUpdateToLocation in case it's called multiple times `, do you mean i need the `stopUpdatingLocation` delegate method ? – Luca May 13 '11 at 20:11
  • The first time CL calls didUpdateToLocation, the location might not be the most accurate. If your app requires great accuracy or needs constant updates as the user moves, then you will have to process multiple calls to didUpdateToLocation. Call stopUpdatingLocation when you are happy with the accuracy (which could be the first time it gets called). –  May 13 '11 at 20:21
  • Hi Anna, i have tested my app on the device and i had problem with map displaying, also, the stations are displayed once for two try, i meen, i test it twice, once i succeded to show the stations on the map and once it failed, i have updated my post for more information, hope you can help me there , thx :) – Luca May 14 '11 at 11:04
  • I don't think those problems are related to the original question. Perhaps it's something to do with how you're making the web service call or just network issues. I think you should start a new question. –  May 14 '11 at 13:04
  • Ok, but please before posting new question, i want to make sure, if the longitude/latitude are both `0.000000` on the simulator, does this means that the location is pretty operational ? – Luca May 14 '11 at 16:43
  • You should only use the coordinates after you get them in didUpdateToLocation. If you look at or use the coordinate variables before didUpdateToLocation succeeds, they are not reliable. A value of 0,0 probably means you're trying to use the coordinates before didUpdateToLocation succeeds. –  May 14 '11 at 18:28
  • Hi Anna, i have created new topic, actually i have to think in another manner to get it work, so i will be happy if i get the longitude /latitude of the user even once and i don't need to keep tracking and updating the user location, actually i need to get the longitude/latitude of the user to send them to web-service to search service stations which are around the user, that's the idea, you can help me in my problem here : http://stackoverflow.com/questions/6016665/getting-the-user-longitude-latitude-of-the-user-when-the-viewdidload – Luca May 16 '11 at 11:30
  • As Vladimir answered and as my answer here says, you have to get the coordinates in the didUpdateToLocation delegate method. –  May 16 '11 at 12:02
1
[mapView setRegion:[mapView regionThatFits:region] animated:TRUE];
musefan
  • 47,875
  • 21
  • 135
  • 185
dave
  • 11
  • 1
0

Can not be greater than 180

CLLocationDegrees delta = MAX(maxLatitude - minLatitude, maxLongitude - minLongitude) * 1.1;

delta = points.count < 2 ? 0.5 : delta;
delta = MIN(delta, 180);

CLLocationDegrees centerX = (maxLatitude-minLatitude)/2.0 + minLatitude;
CLLocationDegrees centerY = (maxLongitude-minLongitude)/2.0 + minLongitude;

CLLocationCoordinate2D theCoordinate = {centerX,centerY};
MKCoordinateSpan span = MKCoordinateSpanMake(delta, delta);
self.mapView.region = MKCoordinateRegionMake(theCoordinate, span);
Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123