如何从 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 <CoreLocation/CoreLocation.h>
并实现以下委托: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 中的城市名称获取位置(坐标)?的主要内容,如果未能解决你的问题,请参考以下文章