4

我有一个视图控制器,它从应用程序委托中提取用户的纬度和经度坐标。这很好用,但我还需要用户的城市、州和时区。我知道我应该为此使用 CLGeocoder(请参阅最后一段代码),但不知道如何将它们组合在一起。我只需要城市、州和时区的 NSStrings。有人有任何指示或示例吗?谢谢!

在我的 App Delegate 中,我使用 CCLocationManager 来获取坐标,如下所示:

- (NSString *)getUserCoordinates
{
    NSString *userCoordinates = [NSString stringWithFormat:@"latitude: %f longitude: %f", 
    locationManager.location.coordinate.latitude, 
    locationManager.location.coordinate.longitude];
    locationManager = [[CLLocationManager alloc] init];
    locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
    [locationManager startUpdatingLocation];
    return userCoordinates;
}

- (NSString *)getUserLatitude
{
    NSString *userLatitude = [NSString stringWithFormat:@"%f", 
    locationManager.location.coordinate.latitude];
    return userLatitude;
}

- (NSString *)getUserLongitude
{
    NSString *userLongitude = [NSString stringWithFormat:@"%f", 
    locationManager.location.coordinate.longitude];
    return userLongitude;
}

在我的视图控制器中,我将用户的纬度和经度作为 NSString 获取:

NSString *userLatitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate 
getUserLatitude];

NSString *userLongitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate 
getUserLongitude];

我想获得城市、州和时区。我知道我需要 CLGeocoder,但不知道如何将它融合在一起:

CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, 
NSError *error) {
    for (CLPlacemark * placemark in placemarks) {
        NSString *locality = [placemark locality];
    }
}
4

4 回答 4

12

布兰登,有几件事:

1) CLLocationManager 可能不会立即回复您的坐标请求。您应该将您的视图控制器设置为 CLLocationManager 委托,然后当位置更新进入时(将在locationManager:didUpdateLocations:方法中),然后您可以运行您的 CLGeocoder 方法。

2)

我写的看起来像这样:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    NSLog( @"didUpdateLocation!");
    NSLog( @"latitude is %@ and longitude is %@", [self getUserLatitude], [self getUserLongitude]);

    CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
    [geoCoder reverseGeocodeLocation:locationManager.location completionHandler:^(NSArray *placemarks, NSError *error) {
        for (CLPlacemark * placemark in placemarks) {
            NSString * addressName = [placemark name];
            NSString * city = [placemark locality]; // locality means "city"
            NSString * administrativeArea = [placemark administrativeArea]; // which is "state" in the U.S.A.

            NSLog( @"name is %@ and locality is %@ and administrative area is %@", addressName, city, administrativeArea );
        }
    }];
}

获取该位置的时区有点棘手。我敢打赌,有一个 API 或一些示例代码可以在 iOS 中获取它,但它不是 CLPlacemark API 的一部分。

于 2013-03-09T07:27:24.827 回答
2

从纬度和经度双精度值形成一个 CLLocation。然后将该位置提供给 reverseGeocodeLocation:completionHandler:

另请注意,reverseGeocodeLocation:completionHandler: 方法是异步的。

您也可以使用 CLLocationManagerDelegate 的locationManager:didUpdateHeading: 如果有可用的 Location 则异步更新,这样会更好。

无论如何遵循您的方法,只需从 AppDelegate 修改您的一些代码

- (double)getUserLatitude
{
    return retrun locationManager.location.coordinate.latitude;
}

- (double)getUserLongitude
{
    retrun locationManager.location.coordinate.longitude;
}

-(CLLocationManager*) getLocationManager
{
    return locationManager;
}

现在形成一个位置对象

double latt = [(PDCAppDelegate *)[UIApplication sharedApplication].delegate getUserLatitude];

double longt = [(PDCAppDelegate *)[UIApplication sharedApplication].delegate getUserLongitude];
CLLocation loc = [[CLLocation alloc] initWithLatitude:latt longitude:longt]

或者您可以直接从 CLLocationManager 获取位置对象

CLLocation loc = [(PDCAppDelegate *)[UIApplication sharedApplication].delegate getLocationManager].location;

然后,您可以使用将位置提供给 reverseGeocodeLocation:completionHandler: 的代码并获取CLPlaceMark

[geoCoder reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, 
NSError *error) {
    for (CLPlacemark * placemark in placemarks) {
        NSString *locality = [placemark locality];
        NSString * name =    [placemark name];
        NSString  *country  = [placemark country];
        /*you can put these values in some member vairables*/

        m_locality = [placemark locality];
        m_name =    [placemark name];
        m_country  = [placemark country];
    }
}
于 2013-03-09T07:54:45.660 回答
0

虽然我没有针对时区问题的解决方案(我同意其他回答过这个问题的人的观点 - 寻找非 Apple API),但我想我会在 Swift 中为那些好奇的人提供答案:

func provideGeocodedStringForLocation(location: CLLocation, withCompletionHandler completionHandler: (String) -> ()) {
  let geocoder = CLGeocoder()
  geocoder.reverseGeocodeLocation(location) { (placemarks: [CLPlacemark]?, error: NSError?) -> Void in
    guard let placemarks = placemarks where placemarks.count > 0 && error == nil else {
      if let error = error { print(error.localizedDescription) }
      completionHandler("Earth")
      return
    }

    let city = placemarks[0].locality ?? ""
    let state: String
    if let adminArea = placemarks[0].administrativeArea {
      state = ", \(adminArea)"
    } else {
      state = ""
    }

    completionHandler("\(city)\(state)") // produces output similar to "Boulder, CO"
  }
}

// get the lat/long from your UIAppDelegate subclass
let latitude = CLLocationDegrees("40.0176")
let longitude = CLLocationDegrees("-105.28212")
let location = CLLocation(latitude: latitude, longitude: longitude)

provideGeocodedStringForLocation(location) { print($0) }
于 2016-01-12T00:43:36.277 回答
-1

我从地标描述中获得了时区名称。它适用于 ios 8 及更高版本。

您可以查看此链接以了解如何获取时区

于 2015-02-19T07:02:38.407 回答