朋友,
因为我们在android中有google api的geocoder getfromlocation(locationname,maximumResults)函数。
我没有在iphone sdk中看到这样的功能来从城市名称中获取纬度和经度值。
任何人都指导我如何实现此功能? 任何帮助将不胜感激。
答案 0 :(得分:25)
没有地理编码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有一个地理编码器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对象具有以下属性:
答案 1 :(得分:4)
使用以下方法从城市名称中查找位置的坐标:
来源:(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;
}
希望它会有所帮助。
答案 2 :(得分:0)
您可以在其他一些答案中使用Google地理编码器API。 或者,您可以使用geonames.org提供的地理编码服务。
您可以从ILGeoNames下载我的GitHub包装类。它们提供了一个Objective C API,用于使用geonames.org搜索功能。除此之外,您还可以按名称搜索城市并获取其坐标。