2012-05-09 12 views
16

Quiero obtener mi nombre de Ciudad actual en mi aplicación de iPhone.iPhone - Obtener el nombre de la ciudad de Latitude y Longtiude

Actualmente estoy obteniendo la latitud y la longitud con CLLocationManager y de lo que estoy pasando mis coordenadas en 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]; 
     } 
    }]; 

Esto funciona bien en iOS 5.0 pero no funciona en iOS 4.3.

Como alternativa, empecé a usar el servicio web de Google

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

Pero la respuesta de la que estoy recibiendo es demasiado largo, significa que soy todavía no ha podido obtener el nombre de la ciudad debido a que en algunos casos este servicio web dar toda la demás información con respecto a las coordenadas esperan Nombre de la ciudad.

¿Alguien me puede ayudar, por favor?

Respuesta

23

Según la documentación CLGeocoder no funciona debajo de iOS5. Debes tomar otra ruta para admitir iOS4 e iOS5.

Puede consultar MKReverseGeocoder, sin embargo, está desaprobado en iOS5 pero aún servirá para este propósito. Para la confirmación se puede comprobar 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]; 
} 

Se puede usar esta función para obtener la dirección de latitud, longitud. Puede cambiar según los requisitos. Ponemos esto como método de clase para que podamos usar directamente como

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

EDITAR

Por favor, deje de usar la función anterior, ya que ha dejado de funcionar reportado en los comentarios (No se ha probado por mí). Recomiendo comenzar a usar SVGeocoder

+1

algún tiempo este código no funciona por favor, tratar de encontrar alguna solución alternativa – btmanikandan

+1

No trabajo para mí Uso este http://maps.google.com/maps/geo?q=37.785834,-122.406417&output=csv La salida es "610,0,0,0" –

+0

@HardikShah Obtiene este resultado porque está utilizando ** csv **. Cámbielo a ** xml ** o ** json ** como 'output = xml' le dirá que esto es geocodificación anterior y que lo nuevo es diferente. También obtendrá un nuevo enlace de geocodificación en la respuesta xml o 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 

Lo siento por mi mala Inglés esperanza que willhelp que

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

Estoy usando esto y obtengo el código postal y el nombre de la ciudad. Modificó el método agregado por 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

probar este pedido aquí encontrará todos los datos acerca de la ubicación actual, ciudad/región Nombre, número de la calle/casa, pero para su solicitud simplemente pega este.

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

Estoy usando su solución, y está funcionando perfectamente bien, gracias .. –

+0

Compruebe ese enlace: http://maps.googleapis.com/maps/api /geocode/json?latlng=37.332331,-122.031219&sensor=true Está volviendo el país allí, por lo que el código no está generalizado, compruebe. –

2

Esto está bien, funcionó para mí.

Estoy obteniendo la latitud y longitud usando CLLocationManager y de lo que estoy pasando mis coordenadas en 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

he mejorado @Constantin Saulenco grandes respuesta- los resultados JSON en no siempre ordenado en mismo orden - por lo que la ciudad no está siempre en el mismo índice - esto func buscará la correcta. País agregado también.

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

Funciona para mí :)

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

Por favor, compruebe la función de abajo

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 
     }) 
    } 
} 
Cuestiones relacionadas