how to get location(coordinates) from city name in iphone sdk?

friends,

as we have geocoder getfromlocation(locationname,maximumResults) function of google api in android.

i dont see such function in iphone sdk to obtain latitude and longitude values from city name.

any one guide me how to achieve this functionality? any help would be appreciated.

Answers


iOS <5

There is no geocoding API. You need to ask Google: http://maps.googleapis.com/maps/api/geocode/json?address=YOURADDRESS&sensor=true and parse the result using JSONKit.

Something like this:

-(CLLocation*) geocodeAddress:(NSString*) address {

    NSLog(@"Geocoding address: %@", address);

    // don't make requests faster than 0.5 seconds
    // Google may block/ban your requests if you abuse the service
    double pause = 0.5;
    NSDate *now = [NSDate date];
    NSTimeInterval elapsed = [now timeIntervalSinceDate:self.lastPetition];
    self.lastPetition = now;
    if (elapsed>0.0 && elapsed<pause){
        NSLog(@"    Elapsed < pause = %f < %f, sleeping for %f seconds", elapsed, pause, pause-elapsed);
        [NSThread sleepForTimeInterval:pause-elapsed];
    }

    // url encode
    NSString *encodedAddress = (NSString *) CFURLCreateStringByAddingPercentEscapes(
                                NULL, (CFStringRef) address,
                                NULL, (CFStringRef) @"!*'();:@&=+$,/?%#[]",
                                kCFStringEncodingUTF8 );

    NSString *url = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=%@&sensor=true", encodedAddress];
    //NSLog(@"    url is %@", url);
    [encodedAddress release];

    // try twice to geocode the address
    NSDictionary *dic;
    for (int i=0; i<2; i++) { // two tries

        HttpDownload *http = [HttpDownload new];
        NSString *page = [http pageAsStringFromUrl:url];
        [http release];
        dic = [JsonParser parseJson:page];
        NSString *status = (NSString*)[dic objectForKey:@"status"];
        BOOL success = [status isEqualToString:@"OK"];
        if (success) break;

        // Query failed
        // See http://code.google.com/apis/maps/documentation/geocoding/#StatusCodes
        if ([status isEqualToString:@"OVER_QUERY_LIMIT"]){
            NSLog(@"try #%d", i);
            [NSThread sleepForTimeInterval:1];
        } else if ([status isEqualToString:@"ZERO_RESULTS"]){
            NSLog(@"    Address unknown: %@", address);
            break;
        } else {
            // REQUEST_DENIED: no sensor parameter. Shouldn't happen.
            // INVALID_REQUEST: no address parameter or empty address. Doesn't matter.
        }

    }

    // if we fail after two tries, just leave
    NSString *status = (NSString*)[dic objectForKey:@"status"];
    BOOL success = [status isEqualToString:@"OK"];
    if (!success) return nil;

    // extract the data
    {
        int results = [[dic objectForKey:@"results"] count];
        if (results>1){
            NSLog(@"    There are %d possible results for this adress.", results);
        }
    }

    NSDictionary *locationDic = [[[[dic objectForKey:@"results"] objectAtIndex:0] objectForKey:@"geometry"] objectForKey:@"location"];
    NSNumber *latitude = [locationDic objectForKey:@"lat"];
    NSNumber *longitude = [locationDic objectForKey:@"lng"];    
    NSLog(@"    Google returned coordinate = { %f, %f }", [latitude floatValue], [longitude floatValue]);

    // return as location
    CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude doubleValue] longitude:[longitude doubleValue]];

    return [location autorelease];
}

+(NSDictionary*) parseJson:(NSString*) jsonString {

    NSDictionary *rootDict = nil;
    NSError *error = nil;
    @try {
        JKParseOptionFlags options = JKParseOptionComments | JKParseOptionUnicodeNewlines;
        rootDict = [jsonString objectFromJSONStringWithParseOptions:options error:&error];
        if (error) {
            warn(@"%@",[error localizedDescription]);
        }
        NSLog(@"    JSONKit: %d characters resulted in %d root node", [jsonString length], [rootDict count]);

    } @catch (NSException * e) {
        // If data is 0 bytes, here we get: "NSInvalidArgumentException The string argument is NULL"
        NSLog(@"%@ %@", [e name], [e reason]);

        // abort
        rootDict = nil;
    }
    return rootDict;
}
iOS >= 5

iOS 5 has a geocoder API:

CLGeocoder* gc = [[CLGeocoder alloc] init];
[gc geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) 
{
    if ([placemarks count]>0) 
    {
        // get the first one
        CLPlacemark* mark = (CLPlacemark*)[placemarks objectAtIndex:0];
        double lat = mark.location.coordinate.latitude;
        double lng = mark.location.coordinate.longitude;            
    }
}];

The CLPlacemark object has the following properties:

  • name
  • addressDictionary: Address Book keys and values for the placemark.
  • ISOcountryCode
  • country
  • postalCode
  • administrativeArea
  • subAdministrativeArea
  • locality
  • subLocality
  • thoroughfare: Street address.
  • subThoroughfare: Address Book keys and values for the placemark.
  • region
  • inlandWater
  • ocean
  • areasOfInterest

Use the following method to find Coordinates of a location from city name:

Source:(http://sickprogrammersarea.blogspot.in/2014/03/programmatically-find-co-ordinates-of.html)

-(CLLocationCoordinate2D) getLocationFromAddressString: (NSString*) addressStr {
double latitude = 0, longitude = 0;
NSString *esc_addr =  [addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
    NSScanner *scanner = [NSScanner scannerWithString:result];
    if ([scanner scanUpToString:@"\"lat\" :" intoString:nil] && [scanner scanString:@"\"lat\" :" intoString:nil]) {
        [scanner scanDouble:&latitude];
        if ([scanner scanUpToString:@"\"lng\" :" intoString:nil] && [scanner scanString:@"\"lng\" :" intoString:nil]) {
            [scanner scanDouble:&longitude];
        }
    }
}
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude = longitude;
NSLog(@"View Controller get Location Logitute : %f",center.latitude);
NSLog(@"View Controller get Location Latitute : %f",center.longitude);
return center;

}

Hope it will be Helpful.


You can either use the Google geocoder API as desribed in some of the other answers. Alternatively you can use the geocoding services provided by geonames.org.

You can download my ILGeoNames wrapper classes from GitHub. They provide an Objective C API for using the geonames.org search functions. Among other things you can search for cities by name and get their coordinates.


Need Your Help

Cast T parameter in generic method to DateTime

c# .net generics casting

I have the following (simplified) method:

Is is possible to get a permanent URL to a file uploaded to Google drive?

google-drive-api

I can't find the answer to this in the API docs or elsewhere. I see in the docs says you can get a downloadURL of a file, but it refers to it as a 'short lived URL'. What does that mean?