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

Posted

技术标签:

【中文标题】如何从 iphone sdk 中的城市名称获取位置(坐标)?【英文标题】:how to get location(coordinates) from city name in iphone sdk? 【发布时间】:2011-05-19 13:55:22 【问题描述】:

朋友们,

因为我们在 android 中有 google api 的 geocoder getfromlocation(locationname,maximumResults) 函数。

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

任何人指导我如何实现此功能? 任何帮助将不胜感激。

【问题讨论】:

this question 的可能重复项 【参考方案1】:

ios

没有地理编码 API。你需要问谷歌: 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;

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;            
    
];

CLPlacemark 对象具有以下属性:

姓名 addressDictionary:地标的地址簿键和值。 ISO国家代码 国家 邮政编码 行政区 子行政区 地区 子区域 thoughfare:街道地址。 subThoroughfare:地标的地址簿键和值。 地区 内陆水域 海洋 感兴趣的领域

【讨论】:

感谢您的大力帮助。只需执行上述代码即可解决问题。再次感谢 我需要导入哪个框架才能使用“HttpDownload”类..? 那是我编的课对不起。删除该行并将下一行替换为 NSError *error; NSString *page = [NSString initWithContentsOfURL:[NSURL URLWithString:url] encoding: NSUTF8StringEncoding error:&error] 或类似的东西。 对于 iOS>5 方法,只需通过转到您的项目设置导入 CoreLocation 框架,然后将二进制文件与库链接。还包括以下内容:#import &lt;CoreLocation/CoreLocation.h&gt; 并实现以下委托:CLLocationManagerDelegate【参考方案2】:

使用以下方法从城市名称中查找位置的坐标:

来源:(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;


希望对您有所帮助。

【讨论】:

【参考方案3】:

您可以使用其他一些答案中描述的 Google geocoder API。 或者,您可以使用geonames.org 提供的地理编码服务。

您可以从GitHub 下载我的ILGeoNames 包装类。他们为使用 geonames.org 搜索功能提供了一个 Objective C API。除此之外,您还可以按名称搜索城市并获取它们的坐标。

【讨论】:

以上是关于如何从 iphone sdk 中的城市名称获取位置(坐标)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用纬度和经度获取位置名称或城市?

如何从用户位置绘制路线到iphone sdk中的某个引脚?

如何从 iphone sdk 中的 ISOCountryCode 获取 ISOCurrencyCode?

从城市名称获取地理位置

如何在 iPhone sdk 中以编程方式获取设备名称?

Javascript,使用地理位置获取城市名称