2012-05-09 55 views
16

我想在我的iPhone應用程序中獲取當前城市名稱。iPhone - 從Latitude和Longtiude獲取城市名稱

我目前得到使用CLLocationManager緯度和經度和比我通過我的座標到CLGeocoder。

CLGeocoder * geoCoder = [[CLGeocoder alloc] init]; 
    [geoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { 
     for (CLPlacemark * placemark in placemarks) { 
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Current City" message:[NSString stringWithFormat:@"Your Current City:%@",[placemark locality]] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil]; 
      [alert show]; 
     } 
    }]; 

這在iOS 5.0中工作正常,但在iOS 4.3中不工作。

作爲替代,我開始使用谷歌Web服務

-(void)findLocationFor:(NSString *)latitudeStr 
      andLontitude:(NSString *)longtitudeStr{ 
    if ([self connectedToWiFi]){ 
     float latitude = [latitudeStr floatValue]; 
     float longitude = [longtitudeStr floatValue]; 
     NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
              [NSString stringWithFormat:@"%f,%f", latitude, longitude], @"latlng", nil]; 
     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://maps.googleapis.com/maps/api/geocode/json"]]; 
     [parameters setValue:@"true" forKey:@"sensor"]; 
     [parameters setValue:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode] forKey:@"language"]; 
     NSMutableArray *paramStringsArray = [NSMutableArray arrayWithCapacity:[[parameters allKeys] count]]; 

     for(NSString *key in [parameters allKeys]) { 
      NSObject *paramValue = [parameters valueForKey:key]; 
      [paramStringsArray addObject:[NSString stringWithFormat:@"%@=%@", key, paramValue]]; 
     } 

     NSString *paramsString = [paramStringsArray componentsJoinedByString:@"&"]; 
     NSString *baseAddress = request.URL.absoluteString; 
     baseAddress = [baseAddress stringByAppendingFormat:@"?%@", paramsString]; 
     [request setURL:[NSURL URLWithString:baseAddress]]; 

     NSError  *error = nil; 
     NSURLResponse *response = nil; 
     NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 
     if (response == nil) { 
      if (error != nil) { 
      } 
     } 
     else { 
      NSDictionary *responseDict = [returnData objectFromJSONData]; 
      NSArray *resultsArray = [responseDict valueForKey:@"results"]; 
      NSMutableArray *placemarksArray = [NSMutableArray arrayWithCapacity:[resultsArray count]]; 
      for(NSDictionary *placemarkDict in resultsArray){ 
       NSDictionary *coordinateDict = [[placemarkDict valueForKey:@"geometry"] valueForKey:@"location"]; 

       float lat = [[coordinateDict valueForKey:@"lat"] floatValue]; 
       float lng = [[coordinateDict valueForKey:@"lng"] floatValue]; 

       NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
       [dict setObject:[NSString stringWithFormat:@"%.f",lat] forKey:@"latitude"]; 
       [dict setObject:[NSString stringWithFormat:@"%.f",lng] forKey:@"longitude"]; 
       [dict setObject:[placemarkDict objectForKey:@"formatted_address"] forKey:@"address"]; 

       [placemarksArray addObject:dict]; 
       [dict release]; 
      } 
      NSDictionary *placemark = [placemarksArray objectAtIndex:0]; 
     } 
    } 
} 

但我正在逐漸過長,意味着我仍然無法獲得城市的名字,因爲在某些情況下,該Web服務的響應提供有關座標的所有其他信息。

任何一個能幫助我嗎?

回答

23

按照文檔CLGeocoder不起作用下面的iOS5。你需要採取另一條路線來支持iOS4和iOS5。

你可以看一下MKReverseGeocoder,但它是在iOS5中棄用,但仍然會達到目的。爲了確認,你可以檢查so called question

+(NSString *)getAddressFromLatLon:(double)pdblLatitude withLongitude:(double)pdblLongitude 
{ 
    NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%f,%f&output=csv",pdblLatitude, pdblLongitude]; 
    NSError* error; 
    NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error]; 
    locationString = [locationString stringByReplacingOccurrencesOfString:@"\"" withString:@""]; 
    return [locationString substringFromIndex:6]; 
} 

您可以使用此功能從經度,緯度越來越地址。你可以根據需要改變。我們把這個作爲類方法,這樣我們就可以直接使用它作爲

NSString *strAddressFromLatLong = [CLassName getAddressFromLatLon:37.484848 withLongitude:74.48489]; 

編輯

請停止使用上述功能,因爲它已停止工作的意見報告(我沒測試過)。我建議開始使用SVGeocoder

+1

一段時間,這段代碼不能正常工作,請儘量找一些替代的解決方案 – btmanikandan

+1

不適合我的工作 我正在使用此http://maps.google.com/maps/geo?q=37.785834,-122.406417&output=csv 輸出爲「610,0,0,0」 –

+0

@HardikShah你正在得到這個輸出,因爲你正在使用** csv **。將其更改爲** xml **或** json **,就像'output = xml'一樣,它會告訴您這是舊的地址解析,而新的是不同的。您還將在xml或json響應中獲得新的地理編碼鏈接。 – TheTiger

5
//Place below parser code where you are reading latlng and place your latlng in the url 
NSXMLParser *parser = [[NSXMLParser alloc]initWithContentsOfURL:[NSURL URLWithString:@"http://maps.googleapis.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=false"]]; 
[parser setDelegate:self]; 
[parser parse]; 

// Below are the delegates which will get you the exact address easyly 
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{  
    if([elementName isEqualToString:@"formatted_address"]){ 
     got = YES; //got is a BOOL 
    } 
} 

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    if(got){ 
     NSLog(@"the address is = %@",string); 
    } 
} 

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ 
} 

//what we are doing is using xmlparser to parse the data which we get through the google map api copy above link and use in browser you will see the xml data brought 

對不起我的英文不好,希望它willhelp你

1
- (void)reverseGeocode:(CLLocation *)location { 
CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { 
    NSLog(@"Finding address"); 
    if (error) { 
     NSLog(@"Error %@", error.description); 
    } else { 
     CLPlacemark *placemark = [placemarks lastObject]; 
     self.myAddress.text = [NSString stringWithFormat:@"%@", ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO)]; 
    } 
}]; 
} 
13

我正在使用這個,並得到郵政編碼和城市名稱。修改了Janak添加的方法。

- (void) getAddressFromLatLon:(CLLocation *)bestLocation 
{ 
    NSLog(@"%f %f", bestLocation.coordinate.latitude, bestLocation.coordinate.longitude); 
    CLGeocoder *geocoder = [[CLGeocoder alloc] init] ; 
    [geocoder reverseGeocodeLocation:bestLocation 
        completionHandler:^(NSArray *placemarks, NSError *error) 
    { 
     if (error){ 
      NSLog(@"Geocode failed with error: %@", error); 
      return; 
     } 
     CLPlacemark *placemark = [placemarks objectAtIndex:0]; 
     NSLog(@"placemark.ISOcountryCode %@",placemark.ISOcountryCode); 
     NSLog(@"locality %@",placemark.locality); 
     NSLog(@"postalCode %@",placemark.postalCode); 

    }]; 

} 
3

試試這個要求在這裏,你會發現關於當前位置,街道/城市/地區名稱,門牌號碼,但您的要求只是粘貼的所有數據。

NSString *urlString = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",pdblLatitude, pdblLongitude]; 
NSError* error; 
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error]; 

NSData *data = [locationString dataUsingEncoding:NSUTF8StringEncoding]; 
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 

NSDictionary *dic = [[json objectForKey:kResults] objectAtIndex:0]; 
NSString *cityName = [[[dic objectForKey:@"address_components"] objectAtIndex:1] objectForKey:@"long_name"]; 
+0

我正在使用您的解決方案,它工作完美無缺,謝謝.. –

+0

檢查鏈接: http://maps.googleapis.com/maps/api /geocode/json?latlng=37.332331,-122.031219&sensor=true 它在那裏返回國家,所以代碼不是通用的,請檢查。 –

2

這很好,爲我工作。

我得到使用CLLocationManager緯度和經度和比我通過我的座標到CLGeocoder。

import @corelocation and for getting city,country #import <AddressBook/AddressBook.h> 
    -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
    { 
    CLLocation *location=[locations lastObject]; 
     CLGeocoder *geocoder=[[CLGeocoder alloc]init]; 

     CLLocationCoordinate2D coord; 
     coord.longitude = location.coordinate.longitude; 
     coord.latitude = location.coordinate.latitude; 
     // or a one shot fill 
     coord = [location coordinate]; 
     NSLog(@"longitude value%f", coord.longitude); 
     NSLog(@"latitude value%f", coord.latitude); 
     [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { 
      CLPlacemark *placemark = placemarks[0]; 
      NSDictionary *addressDictionary = [placemark addressDictionary]; 
      city = addressDictionary[(NSString *)kABPersonAddressCityKey]; 
      stateloc = addressDictionary[(NSString *)kABPersonAddressStateKey]; 
      country = placemark.country; 


      NSLog(@"city%@/state%@/country%@",city,stateloc,country); 
      [self getImagesFromServer:city]; 

     }]; 

     [self stopSignificantChangesUpdates]; 

    } 

- (void)stopSignificantChangesUpdates 
{ 
    [self.locationManager stopUpdatingLocation]; 
    self.locationManager = nil; 
} 
0

我提高@Constantin Saulenco巨大答案 - 的JSON結果在相同的順序並不總是有序的 - 所以城市是不是總是相同的指數 - 本功能將爲正確的搜索。 添加國家也是如此。

NSString *urlString = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",location.coordinate.latitude, location.coordinate.longitude]; 
NSError* error; 
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error]; 

NSData *data = [locationString dataUsingEncoding:NSUTF8StringEncoding]; 
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 

NSDictionary *dic = [[json objectForKey:@"results"] objectAtIndex:0]; 
NSArray* arr = [dic objectForKey:@"address_components"]; 
//Iterate each result of address components - find locality and country 
NSString *cityName; 
NSString *countryName; 
for (NSDictionary* d in arr) 
{ 
    NSArray* typesArr = [d objectForKey:@"types"]; 
    NSString* firstType = [typesArr objectAtIndex:0]; 
    if([firstType isEqualToString:@"locality"]) 
     cityName = [d objectForKey:@"long_name"]; 
    if([firstType isEqualToString:@"country"]) 
     countryName = [d objectForKey:@"long_name"]; 

} 

NSString* locationFinal = [NSString stringWithFormat:@"%@,%@",cityName,countryName]; 
7

它爲我:)

CLGeocoder *ceo = [[CLGeocoder alloc]init]; 
CLLocation *loc = [[CLLocation alloc]initWithLatitude:26.93611 longitude:26.93611]; 

[ceo reverseGeocodeLocation: loc completionHandler: 
^(NSArray *placemarks, NSError *error) { 
    CLPlacemark *placemark = [placemarks objectAtIndex:0]; 
    NSLog(@"placemark %@",placemark); 
    //String to hold address 
    NSString *locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "]; 
    NSLog(@"addressDictionary %@", placemark.addressDictionary); 

    NSLog(@"placemark %@",placemark.region); 
    NSLog(@"placemark %@",placemark.country); // Give Country Name 
    NSLog(@"placemark %@",placemark.locality); // Extract the city name 
    NSLog(@"location %@",placemark.name); 
    NSLog(@"location %@",placemark.ocean); 
    NSLog(@"location %@",placemark.postalCode); 
    NSLog(@"location %@",placemark.subLocality); 

    NSLog(@"location %@",placemark.location); 
    //Print the location to console 
    NSLog(@"I am currently at %@",locatedAt); 
}]; 
0

請檢查波紋管功能

func getDataCity(tmpLat:Double,tmpLong:Double) { 

    let tmpCLGeocoder = CLGeocoder.init() 
    if tmpLat > 0 , tmpLong > 0 
    { 
     let tmpDataLoc = CLLocation.init(latitude: tmpLat, longitude: tmpLong) 

     tmpCLGeocoder.reverseGeocodeLocation(tmpDataLoc, completionHandler: {(placemarks,error) in 

      guard let tmpPlacemarks = placemarks else{ 
       return 
      } 
      let placeMark = tmpPlacemarks[0] as CLPlacemark 

      guard let strLocality = placeMark.locality else{ 
       return 
      } 
      // strLocality is your city 
      guard let strSubLocality = placeMark.subLocality else{ 

       return 
      } 
      // strSubLocality is your are of city 
     }) 
    } 
} 
相關問題