如何从iphone sdk中的城市名称获取位置(坐标)?

Abd*_*han 10 iphone google-maps

朋友们,

因为我们在android中有google api的地理编码器getfromlocation(locationname,maximumResults)功能.

我没有在iphone sdk中看到这样的功能来从城市名称获取经度和纬度值.

任何人都指导我如何实现这一功能?任何帮助,将不胜感激.

Jan*_*ano 25

iOS <5

没有地理编码API.您需要向Google询问:http: //maps.googleapis.com/maps/api/geocode/json?address = YOURADDRESS&_sensor = true并使用JSONKit解析结果.

像这样的东西:

-(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;
}
Run Code Online (Sandbox Code Playgroud)

iOS> = 5

iOS 5有一个地理编码器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;            
    }
}];
Run Code Online (Sandbox Code Playgroud)

CLPlacemark对象具有以下属性:

  • 名称
  • addressDictionary:地址簿的地址簿键和值.
  • ISOcountryCode
  • 国家
  • 邮政编码
  • administrativeArea
  • subAdministrativeArea
  • 局部性
  • subLocality
  • 通路:街道地址.
  • subThoroughfare:地址簿的地址簿键和值.
  • 区域
  • inlandWater
  • 海洋
  • 兴趣范围