【问题标题】:Get latitude/longitude from address从地址获取纬度/经度
【发布时间】:2010-12-02 22:50:18
【问题描述】:

如何使用 iPhone SDK 3.x 从用户输入的完整地址(街道、城市等)获取纬度和经度?

【问题讨论】:

    标签: ios maps geocoding


    【解决方案1】:

    这是 unforgiven 代码的更新、更紧凑的版本,它使用最新的 v3 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;
    }
    

    它假设“位置”的坐标首先出现,例如在“视口”之前,因为它只采用在“lng”和“lat”键下找到的第一个坐标。如果您担心这里使用的这种简单的扫描技术,请随意使用适当的 JSON 扫描器(例如 SBJSON)。

    【讨论】:

    • 这种方法效果很好。我发现了一个错误,可能是因为谷歌改变了响应格式。 scanUpToString 和 scanString 在 : 之前应该有另一个空格。它应该看起来像:scanUpToString:@"\"lat\" :" 和 scanString:@"\"lat\" :"(对于 lat 和 lng)。
    • @cberkley 我进行了更改,但为了安全起见,应更改扫描仪以不介意 lat/lng 和冒号之间的空格。我们永远不知道 Google 何时会再次“修复”这种糟糕的格式。事实上,'russes' 的版本可能更干净。
    • 我发布了我的解决方案,因为字符串扫描器在 2011 年似乎无法正常工作。让 SBJson 解析 Google 的响应对于从斯坦福 CS193 在线课程学习 iOS 编码的初学者来说很有意义。
    • 地址参数中输入“test”会怎样?
    【解决方案2】:

    您可以使用谷歌地理编码for this。就像通过 HTTP 获取数据并解析一样简单(可以返回 JSON KML、XML、CSV)。

    【讨论】:

      【解决方案3】:

      这是从 Google 获取纬度和经度的类似解决方案。注意:此示例使用 SBJson 库,您可以在 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】:

        更新版本,使用 iOS 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;
            }
        }
        

        【讨论】:

          【解决方案5】:

          以下方法可以满足您的要求。您需要插入 Google 地图密钥才能正常工作。

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

          【讨论】:

          • 这段代码现在不能工作,因为这段代码我的实时应用程序不能正常工作......!?!
          【解决方案6】:

          对于 google map key 解决方案,正如上面 unforgiven 所描述的,不是必须让应用程序免费吗?根据 google 条款和条件:9.1 免费、公开访问您的 Maps API 实施。您的 Maps API 实施必须通常可供用户免费访问。

          借助 sdk 3.0 中的地图工具包,这可以使用 SDK 轻松完成。参见苹果手册或关注:https://developer.apple.com/documentation/mapkit

          【讨论】:

            【解决方案7】:

            还有 CoreGeoLocation,它将功能封装在框架 (Mac) 或静态库 (iPhone) 中。支持通过 Google 或 Yahoo 进行查找,如果您更喜欢其中一个。

            https://github.com/thekarladam/CoreGeoLocation

            【讨论】:

              【解决方案8】:
              - (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;
              
              }
              

              【讨论】:

                【解决方案9】:
                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
                }
                

                【讨论】:

                • 在最新的 swift 3.0 中回答
                猜你喜欢
                • 1970-01-01
                • 2013-07-04
                • 1970-01-01
                • 2012-02-15
                • 1970-01-01
                • 2017-10-19
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多