为用户

时间:2017-09-02 01:25:25

标签: ios swift3 mapkit

我已经找到了如何使用关键字查找用户周围的位置。现在我的斗争是如何自动选择最近的项目,任何关于如何实现这一点的想法?谢谢,非常感谢。 `

//Map
@IBOutlet weak var map: MKMapView!
var matchingItems: [MKMapItem] = [MKMapItem]()

let manager = CLLocationManager()

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
    let location = locations[0]

    let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
    let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
    map.setRegion(region, animated: true)

    matchingItems.removeAll()
    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = "Hopital"
    request.region = map.region

    let search = MKLocalSearch(request: request)

    search.start(completionHandler: {(response, error) in

        if error != nil {
            print("Error occured in search: \(error!.localizedDescription)")
        } else if response!.mapItems.count == 0 {
            print("No matches found")
        } else {
            print("Matches found")

            for item in response!.mapItems {
                print("Name = \(item.name)")
                print("Phone = \(item.phoneNumber)")

                self.matchingItems.append(item as MKMapItem)
                print("Matching items = \(self.matchingItems.count)")

                let annotation = MKPointAnnotation()
                annotation.coordinate = item.placemark.coordinate
                annotation.title = item.name
                self.map.addAnnotation(annotation)
            }
        }
    })

    self.map.showsUserLocation = true

}

编辑后的新代码,标有*

的行上的错误代码
  

extension Array其中Iterator.Element:MKAnnotation {

func closest(to fixedLocation: CLLocation) -> Iterator.Element? {
    guard !self.isEmpty else { return nil}

    var closestAnnotation: Iterator.Element? = nil
    var smallestDistance: CLLocationDistance = 9999999

    for annotation in self {

        *let locationForAnnotation = CLLocation(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude)
        let distanceFromUser = fixedLocation.distance(from:locationForAnnotation)

        if distanceFromUser < smallestDistance {
            smallestDistance = distanceFromUser
            closestAnnotation = annotation
        }
    }

    // now you can do whatever you want with the closest annotation
    return closestAnnotation
    }
}

并且错误显示“类型'元素'的值没有成员'坐标'

1 个答案:

答案 0 :(得分:0)

解决方案1 ​​

extension Array where Iterator.Element == MKAnnotation {

    func closest(to fixedLocation: CLLocation) -> Iterator.Element? {
        guard !self.isEmpty else { return nil}

        // create variables you'll use to track the smallest distance measured and the
        // closest annotation
        var closestAnnotation: Iterator.Element? = nil
        var smallestDistance: CLLocationDistance = 9999999

        // loop through your mapview's annotations (if you're using a different type of annotation,
        // just substitude it here)
        for annotation in self {
            // create a location object from the coordinates for the annotation so you can easily
            // compare the two locations
            let locationForAnnotation = CLLocation(latitude: annotation.coordinate.latitude, longitude:annotation.coordinate.longitude)

            // calculate the distance between the user's location and the location you just created
            // from the annoatation's coordinates
            let distanceFromUser = fixedLocation.distance(from:locationForAnnotation)

            // if this calculated distance is smaller than the currently smallest distance, update the
            // smallest distance thus far as well as the closest annotation
            if distanceFromUser < smallestDistance {
                smallestDistance = distanceFromUser
                closestAnnotation = annotation
            }
        }

        // now you can do whatever you want with the closest annotation
        return closestAnnotation
    }
}


解决方案2(使用sorted

extension Array where Iterator.Element == MKAnnotation {

    func closest(to fixedLocation: CLLocation) -> Iterator.Element? {

        return self.sorted { (annotation1, annotation2) -> Bool in
            let location1 = CLLocation(latitude: annotation1.coordinate.latitude, longitude:annotation1.coordinate.longitude)
            let location2 = CLLocation(latitude: annotation2.coordinate.latitude, longitude:annotation2.coordinate.longitude)

            let distanceFromUser1 = fixedLocation.distance(from: location1)
            let distanceFromUser2 = fixedLocation.distance(from: location2)

            return distanceFromUser1 < distanceFromUser2
        }.first

    }
}

公用事业扩展:

extension MKMapView {
    func closestAnnotationToUser() -> MKAnnotation? {
        let userLoc = CLLocation(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
        return annotations.closest(to: userLoc)
    }
}

用法:

// Works on any [MKAnnotation]
let nearestPin = self.map.annotations.closest(to: self.map.userLocation.location)

// OR

let nearestPin = self.map.closestAnnotationToUser()



基于https://stackoverflow.com/a/25517497/2124535(objc)

的解决方案