xcode 使用 CLGeocoder 将 NSString 纬度/经度坐标转换为城市、州和时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15308225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 02:56:08  来源:igfitidea点击:

Convert NSString Latiude/Longitude Coordinates to City, State, and Timezone with CLGeocoder

iphoneiosobjective-cxcode

提问by Brandon

I have a view controller that pulls the users latitude and longitude coordinates from the app delegate. This works well, but I also need the user's city, state, and time zone. I know I should use CLGeocoder for this (please see last chunk of code), but don't know how to put it together. I'd just need NSStrings of the city, state, and timezone. Anyone have any pointers or an example? Thank you!

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

In my App Delegate, I use CCLocationManager to get the Coordinates like this:

在我的 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;
}

In my View Controller, I get the user's Latitude and Longitude as an NSString with this:

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

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

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

I would like to get the city, state, and timezone. I understand I need CLGeocoder, but can't figure out how to meld it together:

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

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

回答by Michael Dautermann

A couple things, Brandon:

有几件事,布兰登:

1) CLLocationManager might not give you an instant response to your request for coordinates. You should set your view controller as a CLLocationManager delegate and then when the location update comes in (which will be in the locationManager:didUpdateLocations:method), then you can run your CLGeocoder method.

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

2)

2)

Which I wrote to look like this:

我写的看起来像这样:

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

Getting the location's timezone is a bit trickier. I bet there's an API or some sample code to get it within iOS, but it's not a part of the CLPlacemark API.

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

回答by K'Prime

Form a CLLocation from latitude and longitude double value. Then feed that location to reverseGeocodeLocation:completionHandler:

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

Also note that the method reverseGeocodeLocation:completionHandler: is asynchronous.

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

You can also use, CLLocationManagerDelegate's locationManager:didUpdateHeading:to asynchronously update if there is an Location available, which is better.

也可以使用 CLLocationManagerDelegate 的locationManager:didUpdateHeading:来异步更新是否有可用的位置,这样比较好。

Anyway following your approach, just modifying some of your code from AppDelegate

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

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

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

-(CLLocationManager*) getLocationManager
{
    return locationManager;
}

Now Form a Location object

现在形成一个位置对象

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

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

or you can directly get the location object from CLLocationManager

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

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

Then you can use your code feeding the location to reverseGeocodeLocation:completionHandler: and Get the CLPlaceMark

然后您可以使用您的代码将位置提供给 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];
    }
}

回答by worthbak

While I don't have a solution for the timezone issue (I agree with others who've answered this question - look for a non-Apple API), I thought I'd provide an answer in Swift, for those who are curious:

虽然我没有时区问题的解决方案(我同意回答这个问题的其他人的看法 - 寻找非 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(##代码##) }

回答by Dharmesh Vaghani

I got timezone name from placemark description. And it works for ios 8 and higher.

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

You can check this link for how to get time zone

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