iOS - 使用地址而非经纬度在MKMapView上标注注释

40

我可以使用经纬度在我的MKMapView上标注,但是我的源数据中需要使用街道地址而不是经纬度,例如:1234 west 1234 east, San Francisco, CA ...

这是否与CLLocationManager有关?

有人之前尝试过这个吗?


你的意思是街道地址吗?我不确定你所说的“1234西1234东”是什么意思。 - QED
是的,通过街道地址。我可以获取州、城市和地址。如果可能的话,我想将该街道地址转换为纬度和经度。 - Romes
7个回答

76

参考了psoft提供的优质信息,我使用以下代码达到了我想要的效果。

NSString *location = @"some address, state, and zip";
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
            [geocoder geocodeAddressString:location 
                 completionHandler:^(NSArray* placemarks, NSError* error){
                     if (placemarks && placemarks.count > 0) {
                         CLPlacemark *topResult = [placemarks objectAtIndex:0];
                         MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];

                         MKCoordinateRegion region = self.mapView.region;
                         region.center = placemark.region.center;
                         region.span.longitudeDelta /= 8.0;
                         region.span.latitudeDelta /= 8.0;

                         [self.mapView setRegion:region animated:YES];
                         [self.mapView addAnnotation:placemark];
                     }
                 }
             ];

8
将区域中心设置为所示已被弃用,而将跨度设置为当前跨度的1/8并不总是有意义的。更简单的方法是:MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(placemark.coordinate, 5000, 5000); (这里的5000以米为单位)。 - user467105
2
始终使用 firstObject 而不是 objectAtIndex:0 - Laszlo
1
顺便提一下,if (placemarks && placemarks.count > 0) 是多余的,因为如果 placemarksnil,则 placemarks.count 将返回 0。可以用 if (placemarks.count > 0) 替换它。 - hhanesand
如果有人想知道,completionHandler会在主线程上被调用。 - keji

16

重构后的 Swift 版本:

let location = "some address, state, and zip"
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(location) { [weak self] placemarks, error in
    if let placemark = placemarks?.first, let location = placemark.location {
        let mark = MKPlacemark(placemark: placemark)

        if var region = self?.mapView.region {
            region.center = location.coordinate
            region.span.longitudeDelta /= 8.0
            region.span.latitudeDelta /= 8.0
            self?.mapView.setRegion(region, animated: true)
            self?.mapView.addAnnotation(mark)
        }
    }
}

11

你需要的是所谓的地理编码正向地理编码反向地理编码是将纬度/经度对转换为街道地址的过程。

iOS5提供了CLGeocoder类进行地理编码。MKPlacemark支持iOS >= 3.0的反向地理编码。当然,涉及的数据非常大,因此您的应用程序通常需要网络访问功能。

一个很好的起点是苹果公司的位置感知编程指南。此外,在SO上有很多关于这个问题的问题。https://stackoverflow.com/search?q=geocoding

祝你好运!


10

Swift 版本

        let location = self.txtLocation.text;
        let geocoder:CLGeocoder = CLGeocoder();
        geocoder.geocodeAddressString(location!) { (placemarks: [CLPlacemark]?, error: NSError?) -> Void in
            if placemarks?.count > 0 {
                let topResult:CLPlacemark = placemarks![0];
                let placemark: MKPlacemark = MKPlacemark(placemark: topResult);

                var region: MKCoordinateRegion = self.mkMapView.region;
                region.center = (placemark.location?.coordinate)!;
                region.span.longitudeDelta /= 8.0;
                region.span.latitudeDelta /= 8.0;
                self.mkMapView.setRegion(region, animated: true);
                self.mkMapView.addAnnotation(placemark);

            }
        }

7

自从 iOS 7 开始,placemark.region.center 已经被弃用。现在需要使用以下代码:

region.center = [(CLCircularRegion *)placemark.region center];

您还可以阅读苹果文档有关此内容的说明,以及这里


6

这里是另一个版本...

- Swift 2017语法

- 在底部显示点的地名

- 选择任何大小,比如5公里,作为显示区域

func map() {
    let 5km:CLLocationDistance = 5000
    
    let a= "100 smith avenue some town 90210 SD"
    let g = CLGeocoder()
    
    g.geocodeAddressString(a) { [weak self] placemarks, error in
        if let p = placemarks?.first, let l = placemark.location {
            
            let p = MKPlacemark(coordinate: l.coordinate, addressDictionary: nil)
            
            let cr = MKCoordinateRegionMakeWithDistance(l.coordinate, 5km, 5km)
            let options = [
                MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: cr.center),
                MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: cr.span)
            ]
            
            let m = MKMapItem(placemark: p)
            m.name = "Your House"
            m.openInMaps(launchOptions: options)
        }
    }


}

1

这是不可能的。但是您可以使用CLGeocoder类从地址获取经纬度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接