17

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

这是我尝试过的代码片段,但我的日志在除 inplacemarkplacemark.ISOcountryCodeplacemark.country

我想要的值,placemark.localityplacemark.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);
}

提前致谢。

编辑:

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

12 回答 12

14

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

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

strAdd 将使用地理位置返回地址的位置..

享受编程!

于 2013-05-20T11:04:36.147 回答
11

带有完成块的方法:

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

这是如何使用它:

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

[self getAddressFromLocation:eventLocation complationBlock:^(NSString * address) {
        if(address) {
            _address = address;
        }
    }];
于 2015-04-09T13:03:00.347 回答
6

我在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!)"
    }
}
于 2017-01-11T14:59:53.803 回答
2

使用 google api 进行反向地理标记:

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

来自:https ://developers.google.com/maps/documentation/geocoding/

于 2013-05-20T12:37:05.063 回答
0

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

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

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

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

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

于 2013-05-20T11:02:06.530 回答
0

首先,过滤 didUpdateToLocation 中的位置,以防止使用缓存或错误的位置进行地理编码

NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

if (abs(locationAge) > 5.0) return;

if (newLocation.horizontalAccuracy < 0) return;

另外,尝试将 reverseGeoCoding 方法从 didUpdateToLocation 移开

于 2013-05-20T11:02:45.290 回答
0

一旦有了latitude,您可以 在此处longitude使用CLGeocoder的位置值是一个可能对您有所帮助的教程

于 2013-05-20T11:06:46.297 回答
0

使用此 API 获取数据并传递 lat 和 long 值。

地理位置 API

于 2013-05-20T11:07:14.037 回答
0

试试这个

[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);
        }
    } ];
于 2015-12-10T06:33:54.537 回答
0

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

我正在使用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
                                }

                            }

                        }

                    }
                }

            }

        }

    }

}

像这样调用这个函数

self.getAddressForLatLng(latitude: "\(self.lat!)", longitude: "\(self.lng!)")
于 2018-08-11T07:00:39.923 回答
0

斯威夫特 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"
                   }

               }
               })
       }
于 2020-01-09T05:45:15.613 回答
-1

这是从位置坐标(纬度,经度)获取地址的方法。

您可以使用此代码从 LocationCoordinates 获取地址信息,例如城市、国家、邮政编码等

func getReverSerGeoLocation(location : CLLocation) {
    print("getting Address from Location cordinate")

    CLGeocoder().reverseGeocodeLocation(location) {
        placemarks , error in
    
        if error == nil && placemarks!.count > 0 {
            guard let placemark = placemarks?.last else {
                return
            }
            print(placemark.thoroughfare)
            print(placemark.subThoroughfare)
            print("postalCode :-",placemark.postalCode)
            print("City :-",placemark.locality)
            print("subLocality :-",placemark.subLocality)
            print("subAdministrativeArea :-",placemark.subAdministrativeArea)
            print("Country :-",placemark.country)
        }
    }
}

只需通过传递纬度经度作为参数调用上述方法,如下所示

    getReverSerGeoLocation(location: CLLocation(latitude: 21.0225, longitude: 72.5714))

希望这可以帮助!

于 2020-10-30T05:12:17.950 回答