2009-10-01 46 views

Respuesta

30

He aquí una versión actualizada, más compacto, versión del código de Unforgiven, que utiliza la última versión 3 del API:

- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address 
{ 
    double latitude = 0, longitude = 0; 
    NSString *esc_addr = [address 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; 
    return center; 
} 

Se hace la suposición de que las coordenadas de "localización" son lo primero , p.ej antes de los de "viewport", porque solo toma las primeras coords que encuentra bajo las teclas "lng" y "lat". Siéntase libre de utilizar un escáner JSON adecuado (por ejemplo, SBJSON) si le preocupa esta técnica de escaneo simple que se utiliza aquí.

+4

Este método funciona bien. Encontré un error, posiblemente porque Google cambió el formato de respuesta. scanUpToString y scanString deberían tener otro espacio antes de:. Debería verse así: scanUpToString: @ "\" lat \ ":" y scanString: @ "\" lat \ ":" (ambos para lat y lng). – cberkley

+0

@cberkley Hice el cambio, pero para estar seguro, el escáner debe cambiarse para que no importe los espacios entre lat/lng y colon. Nunca sabemos cuándo Google "corrige" este mal formato nuevamente. De hecho, la versión de 'russes' podría ser la más limpia para esto. –

+1

Publiqué mi solución porque el escáner de cadenas no pareció funcionar en 2011. Permitir que SBJson analice la respuesta de Google tendrá sentido para los principiantes que aprenden la codificación de iOS del curso en línea Stanford CS193. – russes

9

Puede utilizar la geocodificación de Google for this. Es tan simple como obtener datos a través de HTTP y analizarlos (puede devolver JSON KML, XML, CSV).

+0

enlace ya no está disponible. U puede actualizarlo. – CRDave

3

El siguiente método hace lo que usted solicitó. Debe insertar su clave de Google Maps para que esto funcione correctamente.

- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address{ 

    int code = -1; 
    int accuracy = -1; 
    float latitude = 0.0f; 
    float longitude = 0.0f; 
    CLLocationCoordinate2D center; 

    // setup maps api key 
    NSString * MAPS_API_KEY = @"YOUR GOOGLE MAPS KEY HERE"; 

    NSString *escaped_address = [address stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; 
    // Contact Google and make a geocoding request 
    NSString *requestString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv&oe=utf8&key=%@&sensor=false&gl=it", escaped_address, MAPS_API_KEY]; 
    NSURL *url = [NSURL URLWithString:requestString]; 

    NSString *result = [NSString stringWithContentsOfURL: url encoding: NSUTF8StringEncoding error:NULL]; 
     if(result){ 
      // we got a result from the server, now parse it 
      NSScanner *scanner = [NSScanner scannerWithString:result]; 
      [scanner scanInt:&code]; 
      if(code == 200){ 
       // everything went off smoothly 
       [scanner scanString:@"," intoString:nil]; 
       [scanner scanInt:&accuracy]; 

       //NSLog(@"Accuracy: %d", accuracy); 

       [scanner scanString:@"," intoString:nil]; 
       [scanner scanFloat:&latitude]; 
       [scanner scanString:@"," intoString:nil]; 
       [scanner scanFloat:&longitude]; 


       center.latitude = latitude; 
       center.longitude = longitude; 

       return center; 


      } 
      else{ 
       // the server answer was not the one we expected 
       UIAlertView *alert = [[[UIAlertView alloc] 
             initWithTitle: @"Warning" 
             message:@"Connection to Google Maps failed" 
             delegate:nil 
             cancelButtonTitle:nil 
             otherButtonTitles:@"OK", nil] autorelease]; 

       [alert show]; 

       center.latitude = 0.0f; 
       center.longitude = 0.0f; 

       return center; 


      } 

     } 
     else{ 
      // no result back from the server 
      UIAlertView *alert = [[[UIAlertView alloc] 
            initWithTitle: @"Warning" 
            message:@"Connection to Google Maps failed" 
            delegate:nil 
            cancelButtonTitle:nil 
            otherButtonTitles:@"OK", nil] autorelease]; 

      [alert show]; 

      center.latitude = 0.0f; 
      center.longitude = 0.0f; 

      return center; 
     } 

    } 

     center.latitude = 0.0f; 
     center.longitude = 0.0f; 

     return center; 

} 
+0

Este código no funciona ahora, para este código mi aplicación en vivo no funciona correctamente ...!?! –

1

Para la solución llave en Google mapa, como se describe por encima sin perdón, no hay que hacer que la aplicación gratuita? Según los términos de Google & condiciones: 9.1 Acceso gratuito y público a la implementación de su API de Maps. Los usuarios deben tener acceso a la implementación de API de Google Maps sin cargo.

Con el kit de mapas en sdk 3.0 esto se hace fácilmente usando el SDK. Vea los manuales de manzana o seguir: http://www.devworld.apple.com/iphone/program/sdk/maps.html

7

Aquí hay una solución similar para obtener la latitud y la longitud de Google. Nota: En este ejemplo se utiliza la biblioteca SBJson, que se puede encontrar en GitHub:

+ (CLLocationCoordinate2D) geoCodeUsingAddress: (NSString *) address 
{ 
    CLLocationCoordinate2D myLocation; 

// -- modified from the stackoverflow page - we use the SBJson parser instead of the string scanner -- 

     NSString  *esc_addr = [address stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; 
     NSString   *req = [NSString stringWithFormat: @"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr]; 
    NSDictionary *googleResponse = [[NSString stringWithContentsOfURL: [NSURL URLWithString: req] encoding: NSUTF8StringEncoding error: NULL] JSONValue]; 

    NSDictionary *resultsDict = [googleResponse valueForKey: @"results"]; // get the results dictionary 
    NSDictionary *geometryDict = [ resultsDict valueForKey: @"geometry"]; // geometry dictionary within the results dictionary 
    NSDictionary *locationDict = [ geometryDict valueForKey: @"location"]; // location dictionary within the geometry dictionary 

// -- you should be able to strip the latitude & longitude from google's location information (while understanding what the json parser returns) -- 

    DLog (@"-- returning latitude & longitude from google --"); 

    NSArray *latArray = [locationDict valueForKey: @"lat"]; NSString *latString = [latArray lastObject];  // (one element) array entries provided by the json parser 
    NSArray *lngArray = [locationDict valueForKey: @"lng"]; NSString *lngString = [lngArray lastObject];  // (one element) array entries provided by the json parser 

    myLocation.latitude = [latString doubleValue];  // the json parser uses NSArrays which don't support "doubleValue" 
    myLocation.longitude = [lngString doubleValue]; 

    return myLocation; 
} 
4

Actualizar versión, iOS usando JSON:

- (CLLocationCoordinate2D)getLocation:(NSString *)address { 

    CLLocationCoordinate2D center; 
    NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
    NSString *req = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr]; 
    NSData *responseData = [[NSData alloc] initWithContentsOfURL: 
         [NSURL URLWithString:req]]; NSError *error; 
    NSMutableDictionary *responseDictionary = [NSJSONSerialization 
               JSONObjectWithData:responseData 
               options:nil 
               error:&error]; 
    if(error) 
    { 
     NSLog(@"%@", [error localizedDescription]); 
     center.latitude = 0; 
     center.longitude = 0; 
     return center; 
    } 
    else { 
     NSArray *results = (NSArray *) responseDictionary[@"results"]; 
     NSDictionary *firstItem = (NSDictionary *) [results objectAtIndex:0]; 
     NSDictionary *geometry = (NSDictionary *) [firstItem objectForKey:@"geometry"]; 
     NSDictionary *location = (NSDictionary *) [geometry objectForKey:@"location"]; 
     NSNumber *lat = (NSNumber *) [location objectForKey:@"lat"]; 
     NSNumber *lng = (NSNumber *) [location objectForKey:@"lng"]; 

     center.latitude = [lat doubleValue]; 
     center.longitude = [lng doubleValue]; 
     return center; 
    } 
} 
0
- (void)viewDidLoad 
{ 
    app=(AppDelegate *)[[UIApplication sharedApplication] delegate]; 
    NSLog(@"%@", app.str_address); 


    NSLog(@"internet connect"); 

    NSString *Str_address=_txt_zipcode.text; 

    double latitude1 = 0, longitude1 = 0; 
    NSString *esc_addr = [ Str_address 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:&latitude1]; 
      if ([scanner scanUpToString:@"\"lng\" :" intoString:nil] && [scanner scanString:@"\"lng\" :" intoString:nil]) 
      { 
       [scanner scanDouble:&longitude1]; 
      } 
     } 
    } 


    //in #.hfile 
    // CLLocationCoordinate2D lat; 
    // CLLocationCoordinate2D lon; 
    // float address_latitude; 
    // float address_longitude; 


    lat.latitude=latitude1; 
    lon.longitude=longitude1; 

    address_latitude=lat.latitude; 
    address_longitude=lon.longitude; 

} 
0
func geoCodeUsingAddress(address: NSString) -> CLLocationCoordinate2D { 
    var latitude: Double = 0 
    var longitude: Double = 0 
    let addressstr : NSString = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=\(address)" as NSString 
    let urlStr = addressstr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) 
    let searchURL: NSURL = NSURL(string: urlStr! as String)! 
    do { 
     let newdata = try Data(contentsOf: searchURL as URL) 
     if let responseDictionary = try JSONSerialization.jsonObject(with: newdata, options: []) as? NSDictionary { 
      print(responseDictionary) 
      let array = responseDictionary.object(forKey: "results") as! NSArray 
      let dic = array[0] as! NSDictionary 
      let locationDic = (dic.object(forKey: "geometry") as! NSDictionary).object(forKey: "location") as! NSDictionary 
      latitude = locationDic.object(forKey: "lat") as! Double 
      longitude = locationDic.object(forKey: "lng") as! Double 
     }} catch { 
    } 
    var center = CLLocationCoordinate2D() 
    center.latitude = latitude 
    center.longitude = longitude 
    return center 
} 
+0

respuesta en la última versión 3.0 –

Cuestiones relacionadas