MKLocalSearchRequest给了我奇怪的结果

时间:2016-02-06 16:07:08

标签: swift mapkit

所以我已经为我的地图应用程序实现了searchBar,它给了我一些奇怪的结果。如果我搜索"奥斯陆"例如,它指向了一个位于城市北部的一个非常具体但奇怪的地方,并且远远地缩小了。在这里,我必须在代码中做错。有人能发现这个问题吗?

// When user submits search query
func searchBarSearchButtonClicked(searchBar: UISearchBar){
    // resign first responder and dismiss the searchbar.
    searchBar.resignFirstResponder()
    dismissViewControllerAnimated(true, completion: nil)

    // Create and start search request
    localSearchRequest = MKLocalSearchRequest()
    localSearchRequest.naturalLanguageQuery = searchBar.text
    localSearch = MKLocalSearch(request: localSearchRequest)

    localSearch.startWithCompletionHandler { (localSearchResponse, error) -> Void in

        if localSearchResponse == nil{
            let alertController = UIAlertController(title: nil, message: "Place Not Found", preferredStyle: UIAlertControllerStyle.Alert)
            alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
            self.presentViewController(alertController, animated: true, completion: nil)
            return
        }

        let center = CLLocationCoordinate2D(latitude: localSearchResponse!.boundingRegion.center.latitude, longitude: localSearchResponse!.boundingRegion.center.longitude)
        self.updateCurrentMapRegion(center, distance: 5000)
        NSNotificationCenter.defaultCenter().postNotificationName("LocationUpdate", object: nil, userInfo: ["latitude": center.latitude, "longitude": center.longitude])
    }
}

另外,一个问题是我在获得搜索结果后更新地图区域时将距离硬编码为5000米。我怎样才能以更动态的方式处理这个问题?

什么是使用MKLocalSearchRequest()的替代品,在我看来,这听起来像是在寻找附近的东西时应该使用的东西,而不是像城市等更大的实体。

2 个答案:

答案 0 :(得分:3)

首先要做的事情是:MKLocalSearch是您使用的正确API,即使它对您正在做的事情听起来有点奇怪!

MKLocalSearch会为您提供一个位置列表,然后返回位置周围的边界框,以最符合您认为自己正在寻找的内容。我尝试运行你的代码并在奥斯陆找到了这个:

Oslo place mark in bounding box

您遇到的问题是您使用边框的中心作为引脚位置,而不是奥斯陆地标。

所以代替你的代码行:

let center = CLLocationCoordinate2D(latitude: localSearchResponse!.boundingRegion.center.latitude,
    longitude: localSearchResponse!.boundingRegion.center.longitude)

你会使用:

let center = localSearchResponse?.mapItems.first?.placemark.coordinate

(这是一个可选项,但您可以选择如何处理它。我会稍微向您展示我的首选方式。)

此外,这解决了您放大多远的问题。简单来说,您可以使用区域的边界框作为缩放级别。我不确定您的updateCurrentMapRegion:distance方法是如何工作的,但MKMapView有一个方便的setRegion:animated方法,您可以使用(如果您有权访问)。

mapView.setRegion(localSearchResponse!.boundingRegion, animated: true)

总结一下,如果你有一个MapView的引用,你应该可以用这个替换你的完成块并让它工作:

guard let localSearchResponse = localSearchResponse, mapItem = localSearchResponse.mapItems.first else {
    let alertController = UIAlertController(title: nil, message: "Place Not Found", preferredStyle: UIAlertControllerStyle.Alert)
    alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
    self.presentViewController(alertController, animated: true, completion: nil)
    return
}

let center = mapItem.placemark.coordinate
self.mapView.setRegion(localSearchResponse.boundingRegion, animated: true)
NSNotificationCenter.defaultCenter().postNotificationName("LocationUpdate", object: nil, userInfo: ["latitude": center.latitude, "longitude": center.longitude])

在此块中,我还将if语句替换为guard以设置两个值,因此我们不再需要强制解包选项。如果您无法在此方法中访问mapView,则可以切换updateCurrentMapRegion:center以使其更适合,或者进行一些数学运算以使边界区域适合这些值。

答案 1 :(得分:-1)

您不应该使用MKLocalSearchRequest()而是使用MKLocalSearchCompleter,它可以提供更好的结果,并且可以在当前的Apple Maps中使用。

您可以在
中了解如何实现此操作 answer