从 iOS 中的纬度和经度获取位置名称

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16647996/
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-08-30 23:38:43  来源:igfitidea点击:

Get location name from Latitude & Longitude in iOS

iphoneiosipadcllocationmanagerreverse-geocoding

提问by Krunal

I want to find current location name from latitude and longitude,

我想从纬度和经度中找到当前的位置名称,

Here is my code snippet I tried but my log shows null value in all the places except in placemark, placemark.ISOcountryCodeand placemark.country

这是我尝试过的代码片段,但我的日志在除 in 之外的所有地方都显示空值placemarkplacemark.ISOcountryCode并且placemark.country

I want value of placemark.localityand placemark.subLocalitybut it is showing null values.

我想要的价值placemark.locality,并placemark.subLocality却是露出空值。

- (void)viewWillAppear:(BOOL)animated
{
     [super viewWillAppear:animated];

    // this creates the CCLocationManager that will find your current location
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    [locationManager startUpdatingLocation];

}

// this delegate is called when the app successfully finds your current location
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:locationManager.location
                   completionHandler:^(NSArray *placemarks, NSError *error) {
                       NSLog(@"reverseGeocodeLocation:completionHandler: Completion Handler called!");

                       if (error){
                           NSLog(@"Geocode failed with error: %@", error);
                           return;

                       }

                       NSLog(@"placemarks=%@",[placemarks objectAtIndex:0]);
                       CLPlacemark *placemark = [placemarks objectAtIndex:0];

                       NSLog(@"placemark.ISOcountryCode =%@",placemark.ISOcountryCode);
                       NSLog(@"placemark.country =%@",placemark.country);
                       NSLog(@"placemark.postalCode =%@",placemark.postalCode);
                       NSLog(@"placemark.administrativeArea =%@",placemark.administrativeArea);
                       NSLog(@"placemark.locality =%@",placemark.locality);
                       NSLog(@"placemark.subLocality =%@",placemark.subLocality);
                       NSLog(@"placemark.subThoroughfare =%@",placemark.subThoroughfare);

                   }];
}

// this delegate method is called if an error occurs in locating your current location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"locationManager:%@ didFailWithError:%@", manager, error);
}

Thanks In Advance.

提前致谢。

EDIT:

编辑:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil)
        NSLog(@"longitude = %.8f\nlatitude = %.8f", currentLocation.coordinate.longitude,currentLocation.coordinate.latitude);

    // stop updating location in order to save battery power
    [locationManager stopUpdatingLocation];


    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error)
     {
         NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
         if (error == nil && [placemarks count] > 0)
         {
             CLPlacemark *placemark = [placemarks lastObject];

             // strAdd -> take bydefault value nil
             NSString *strAdd = nil;

             if ([placemark.subThoroughfare length] != 0)
                 strAdd = placemark.subThoroughfare;

             if ([placemark.thoroughfare length] != 0)
             {
                 // strAdd -> store value of current location
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark thoroughfare]];
                 else
                 {
                     // strAdd -> store only this value,which is not null
                     strAdd = placemark.thoroughfare;
                 }
             }

             if ([placemark.postalCode length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark postalCode]];
                 else
                     strAdd = placemark.postalCode;
             }

             if ([placemark.locality length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark locality]];
                 else
                     strAdd = placemark.locality;
             }

             if ([placemark.administrativeArea length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark administrativeArea]];
                 else
                     strAdd = placemark.administrativeArea;
             }

             if ([placemark.country length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark country]];
                 else
                     strAdd = placemark.country;
             }
         }
     }];
}

采纳答案by Niru Mukund Shah

I'm giving you snippet which I'm using for resolving address. I'm including comment also at neccessary place to understand the code for you. Besides that feel free to ask any question from snippet if you get fail to understand anything.

我给你我用来解析地址的片段。我也在必要的地方添加了评论,以便为您理解代码。除此之外,如果您无法理解任何内容,请随时从片段中提出任何问题。

Write following snippet in didUpdateToLocationmethod

didUpdateToLocation方法中编写以下代码段

NSLog(@"didUpdateToLocation: %@", newLocation);
CLLocation *currentLocation = newLocation;

if (currentLocation != nil)
    NSLog(@"longitude = %.8f\nlatitude = %.8f", currentLocation.coordinate.longitude,currentLocation.coordinate.latitude);

// stop updating location in order to save battery power
[locationManager stopUpdatingLocation];


// Reverse Geocoding
NSLog(@"Resolving the Address");

// “reverseGeocodeLocation” method to translate the locate data into a human-readable address.

// The reason for using "completionHandler" ----
   //  Instead of using delegate to provide feedback, the CLGeocoder uses “block” to deal with the response. By using block, you do not need to write a separate method. Just provide the code inline to execute after the geocoding call completes.

[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error)
 {
    NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
    if (error == nil && [placemarks count] > 0)
    {
        placemark = [placemarks lastObject];

        // strAdd -> take bydefault value nil
        NSString *strAdd = nil;

        if ([placemark.subThoroughfare length] != 0)
            strAdd = placemark.subThoroughfare;

        if ([placemark.thoroughfare length] != 0)
        {
            // strAdd -> store value of current location
            if ([strAdd length] != 0)
                strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark thoroughfare]];
            else
            {
            // strAdd -> store only this value,which is not null
                strAdd = placemark.thoroughfare;
            }
        }

        if ([placemark.postalCode length] != 0)
        {
            if ([strAdd length] != 0)
                strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark postalCode]];
            else
                strAdd = placemark.postalCode;
        }

        if ([placemark.locality length] != 0)
        {
            if ([strAdd length] != 0)
                strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark locality]];
            else
                strAdd = placemark.locality;
        }

        if ([placemark.administrativeArea length] != 0)
        {
            if ([strAdd length] != 0)
                strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark administrativeArea]];
            else
                strAdd = placemark.administrativeArea;
        }

        if ([placemark.country length] != 0)
        {
            if ([strAdd length] != 0)
                strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark country]];
            else
                strAdd = placemark.country;
        }

Where strAdd will return address using geolocation..

其中 strAdd 将使用地理定位返回地址..

Enjoy Programming !!

享受编程!!

回答by AndrewK

Method with completion block:

带有完成块的方法:

typedef void(^addressCompletion)(NSString *);

-(void)getAddressFromLocation:(CLLocation *)location complationBlock:(addressCompletion)completionBlock
{
    __block CLPlacemark* placemark;
    __block NSString *address = nil;

    CLGeocoder* geocoder = [CLGeocoder new];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error)
     {
         if (error == nil && [placemarks count] > 0)
         {
             placemark = [placemarks lastObject];
             address = [NSString stringWithFormat:@"%@, %@ %@", placemark.name, placemark.postalCode, placemark.locality];
             completionBlock(address);
         }
     }];
}

This is how to use it:

这是如何使用它:

CLLocation* eventLocation = [[CLLocation alloc] initWithLatitude:_latitude longitude:_longitude];

[self getAddressFromLocation:eventLocation complationBlock:^(NSString * address) {
        if(address) {
            _address = address;
        }
    }];

回答by Paula Hasstenteufel

I implemented Niru's solution in Swift 3, posting here should anybody need it:

我在Swift 3 中实现了 Niru 的解决方案,如果有人需要,请在此处发布:

let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(self.location!) { (placemarksArray, error) in

    if (placemarksArray?.count)! > 0 {

        let placemark = placemarksArray?.first
        let number = placemark!.subThoroughfare
        let bairro = placemark!.subLocality
        let street = placemark!.thoroughfare

        self.addressLabel.text = "\(street!), \(number!) - \(bairro!)"
    }
}

回答by iOS

In Swift 4.1 and Xcode 9.4.1, this is one of my solution. Here i'm using geocodeAPI to get the complete address. With this api i can get the village names also.

在 Swift 4.1 和 Xcode 9.4.1 中,这是我的解决方案之一。在这里,我使用地理编码API 来获取完整地址。有了这个api,我也可以得到村庄的名字。

I'm using reverseGeocodeLocationbut it's not getting village address details or village names, it's getting only near by city names. It's one of the finest solution....

我正在使用reverseGeocodeLocation但它没有获得村庄地址详细信息或村庄名称,它只能通过城市名称获得。这是最好的解决方案之一......

func getAddressForLatLng(latitude: String, longitude: String)  { // Call this function

     let url = NSURL(string: "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(latitude),\(longitude)")//Here pass your latitude, longitude
     print(url!)
     let data = NSData(contentsOf: url! as URL)

     if data != nil {
        let json = try! JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
        print(json)

        let status = json["status"] as! String
        if status == "OK" {

            if let result = json["results"] as? NSArray   {

                if result.count > 0 {
                    if let addresss:NSDictionary = result[0] as? NSDictionary {
                        if let address = addresss["address_components"] as? NSArray {
                            var newaddress = ""
                            var number = ""
                            var street = ""
                            var city = ""
                            var state = ""
                            var zip = ""
                            var country = ""

                            if(address.count > 1) {
                                number =  (address.object(at: 0) as! NSDictionary)["short_name"] as! String
                            }
                            if(address.count > 2) {
                                street = (address.object(at: 1) as! NSDictionary)["short_name"] as! String
                            }
                            if(address.count > 3) {
                                city = (address.object(at: 2) as! NSDictionary)["short_name"] as! String
                            }
                            if(address.count > 4) {
                                state = (address.object(at: 4) as! NSDictionary)["short_name"] as! String
                            }
                            if(address.count > 6) {
                                zip =  (address.object(at: 6) as! NSDictionary)["short_name"] as! String
                            }
                            newaddress = "\(number) \(street), \(city), \(state) \(zip)"
                            print(newaddress)

                            // OR 
                            //This is second type to fetch pincode, country, state like this type of data

                            for i in 0..<address.count {
                                print(((address.object(at: i) as! NSDictionary)["types"] as! Array)[0])
                                if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "postal_code" {
                                    zip =  (address.object(at: i) as! NSDictionary)["short_name"] as! String
                                }
                                if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "country" {
                                    country =  (address.object(at: i) as! NSDictionary)["long_name"] as! String
                                }
                                if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "administrative_area_level_1" {
                                    state =  (address.object(at: i) as! NSDictionary)["long_name"] as! String
                                }
                                if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "administrative_area_level_2" {
                                    district =  (address.object(at: i) as! NSDictionary)["long_name"] as! String
                                }

                            }

                        }

                    }
                }

            }

        }

    }

}

Call this function like this

像这样调用这个函数

self.getAddressForLatLng(latitude: "\(self.lat!)", longitude: "\(self.lng!)")

回答by Gurjinder Singh

Swift 5

斯威夫特 5

import CoreLocation

func printAddress() {
  if let lat = Double(30.710489), lat != 0.0, let long = Double(76.852386), long != 0.0 {
  // Create Location
  let location = CLLocation(latitude: lat, longitude: long)
  // Geocode Location
  CLGeocoder().reverseGeocodeLocation(location) { (placemarks, error) in
           // Process Response
           self.processResponse(withPlacemarks: placemarks, error: error)
         }
     }
}

private func processResponse(withPlacemarks placemarks: [CLPlacemark]?, error: Error?) {
       var address = ""
        if let error = error {
            address = "Unable to Reverse Geocode Location (\(error))"
        } else {
            if let placemarks = placemarks, let placemark = placemarks.first {
                address = placemark.compactAddress ?? ""
            } else {
                address = "No address found"
            }
        }
        print(address)
    }
extension CLPlacemark {
var compactAddress: String? {
    if let name = name {
        var result = name

        if let street = thoroughfare {
            result += ", \(street)"
        }
        if let city = locality {
            result += ", \(city)"
        }
        if let postalCode = postalCode {
            result += ", \(postalCode)"
        }
        if let country = country {
            result += ", \(country)"
        }
        return result
    }

    return nil
}
}
// 2nd Way

func updateLocation(lat:Double,long:Double) {
           CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: Double(lat), longitude: Double(long)), completionHandler: { (placemarks, error) -> Void in
               if error != nil {
                   return
               }
               else {
                  var location = ""
                   let pm = placemarks![0]
                   if pm.addressDictionary!["FormattedAddressLines"] != nil    {
                       location =  "\n" + (pm.addressDictionary!["FormattedAddressLines"] as! NSArray).componentsJoined(by: ", ")
                   }else{
                       location = "\n" + "NO_ADDRESS_FOUND"
                   }

               }
               })
       }

回答by kalpesh

Try this

尝试这个

[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        //..NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            lblgetaddrees.text = [NSString stringWithFormat:@"%@,%@,%@,%@,%@,%@",
                                  placemark.subThoroughfare, placemark.thoroughfare,
                                  placemark.postalCode, placemark.locality,
                                  placemark.administrativeArea,
                                  placemark.country];
        } else {
            //..NSLog(@"%@", error.debugDescription);
        }
    } ];

回答by Deepesh Gairola

Once you have latitude, longitudevalues of a location you can use CLGeocoderhere is a tutorialwhich might help you.

一旦你有latitudelongitude位置值可以使用CLGeocoder这里是一个教程这可能会帮助你。

回答by Balu

use this API for getting the data and pass lat and long values.

使用此 API 获取数据并传递经纬度值。

API for Geo location

地理位置 API

回答by Ahmed Z.

If the location you are trying to get is listed in this list then there is something wrong in your code..

如果您尝试获取的位置列在此列表中,则您的代码有问题。

http://developer.apple.com/library/ios/#technotes/tn2289/_index.html#//apple_ref/doc/uid/DTS40011305

http://developer.apple.com/library/ios/#technotes/tn2289/_index.html#//apple_ref/doc/uid/DTS40011305

otherwise CLGeoCoder doesnt have addresses to other countries.

否则 CLGeoCoder 没有其他国家的地址。

I faced the same problem so i used this to get the address.. Gives a really accurate address.

我遇到了同样的问题,所以我用它来获取地址..给出了一个非常准确的地址。

http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false

http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false