简体   繁体   English

使用CLGeocoder将NSString Latiude / Longitude Coordinates转换为City,State和Timezone

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

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. 我知道我应该使用CLGeocoder(请参阅最后一块代码),但不知道如何将它放在一起。 I'd just need NSStrings of the city, state, and timezone. 我只需要城市,州和时区的NSStrings。 Anyone have any pointers or an example? 任何人有任何指针或一个例子? Thank you! 谢谢!

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: 在我的View Controller中,我将用户的纬度和经度作为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];
    }
}

A couple things, Brandon: 几件事,布兰登:

1) CLLocationManager might not give you an instant response to your request for coordinates. 1)CLLocationManager可能不会立即响应您的坐标请求。 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. 您应该将视图控制器设置为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的一部分。

Form a CLLocation from latitude and longitude double value. 从纬度和经度双值形成CLLocation。 Then feed that location to reverseGeocodeLocation:completionHandler: 然后将该位置提供给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 现在形成一个Location对象

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 然后你可以使用代码提供位置来反转GeocodeLocation: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];
    }
}

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($0) }

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 您可以查看此链接以了解如何获取时区

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM