【问题标题】:Loop through coordinates and find the closest shop to a point Swift 3遍历坐标并找到离点最近的商店 Swift 3
【发布时间】:2017-05-23 17:46:57
【问题描述】:

想法:

应用程序可让司机查看离客户最近的商店/餐厅。

我有什么:

  • 保存为字符串的坐标

let clientLat = "24.449384" let clientLng = "56.343243"

  • 查找我当地所有商店的功能

我尝试保存了我当地一家商店的所有坐标,我成功了:

  var coordinates: [CLLocationCoordinate2D] = [CLLocationCoordinate2D]()

 func performSearch() {
    coordinates.removeAll()

    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = "starbucks"
    request.region = mapView.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 {

                self.coordinates.append(item.placemark.coordinate)


               // need to sort coordinates

                // need to find the closest


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

}

我需要什么:

我希望遍历坐标并找到离经纬线最近的商店(公里),然后在上面放一个别针。

更新

  func performSearch() {
    coordinates.removeAll()

    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = "starbucks"
    request.region = mapView.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 {

                self.coordinates.append(item.placemark.coordinate)

                let pointToCompare = CLLocation(latitude: 24.741721, longitude: 46.891440)
              let  storedCorrdinates =  self.coordinates.map({CLLocation(latitude: $0.latitude, longitude: $0.longitude)}).sorted(by: {
                    $0.distance(from: pointToCompare) < $1.distance(from: pointToCompare)


                })
                self.coordinate = storedCorrdinates
            }

            let annotation = MKPointAnnotation()
            annotation.coordinate = self.coordinate[0].coordinate
            self.mapView.addAnnotation(annotation)
        }
    })

} 谢谢@brimstone

【问题讨论】:

  • coordinates 是 CLLocationCoordinate2D 还是 CLLocation 的数组?
  • 也许你可以使用距离公式?参见This question 2 lat/longs 之间距离公式的 JavaScript 实现。 (Haversine 公式)
  • @brimstone 是 var coordinates: [CLLocationCoordinate2D] = [CLLocationCoordinate2D]()

标签: ios swift swift3 google-play


【解决方案1】:

您可以通过将坐标转换为 CLLocation 类型然后使用distance(from:) 方法来比较坐标之间的距离。例如,获取您的坐标数组并将其映射到 CLLocation,然后根据与它们进行比较的点的距离对其进行排序。

let coordinates = [CLLocationCoordinate2D]()
let pointToCompare = CLLocation(latitude: <#yourLat#>, longitude: <#yourLong#>)

let sortedCoordinates = coordinates.map({CLLocation(latitude: $0.latitude, longitude: $0.longitude)}).sorted(by: {
    $0.distance(from: pointToCompare) < $1.distance(from: pointToCompare)
})

然后,要将注释的坐标设置为最近的坐标,只需为 sortedCoordinates 数组下标。

annotation.coordinate = sortedCoordinates[0].coordinate

【讨论】:

  • 非常感谢。第一个排序的坐标在哪里?我的意思是我怎样才能把它放在annotation.coordinate = item.placemark.coordinate 中?
  • @leo0019 查看编辑以获取最近的坐标
  • 它现在显示离我最近的一个和另一个星巴克的别针!!!为什么我有两个别针?
  • @leo0019 您可能在代码中的某处设置了另一个注释。您是否将代码放入循环中?这也不是必须的。
  • 如果我将它设置在循环之外,它会给我错误unresolved identifier。我再次更新了我的问题,请检查@brimstone
【解决方案2】:

我想分享我的解决方案:)

1) 就我而言,我从 API 上传数据,所以我需要创建一个模型。

import MapKit

struct StoresMap: Codable {
    let id: Int?
    let title: String?
    let latitude: Double?
    let longitude: Double?
    let schedule: String?
    let phone: String?
    let ukmStoreId: Int?
    var distanceToUser: CLLocationDistance?
}

最后一个变量不是来自API,而是来自我自己来定义每个商店的距离。

2) 在 ViewController 我定义:

func fetchStoresList() {
    NetworkManager.downloadStoresListForMap(firstPartURL: backendURL) { (storesList) in
        self.shopList = storesList
        let initialLocation = self.locationManager.location!

        for i in 0..<self.shopList.count {
            self.shopList[i].distanceToUser = initialLocation.distance(from: CLLocation(latitude: self.shopList[i].latitude!, longitude: self.shopList[i].longitude!))
        }
        self.shopList.sort(by: { $0.distanceToUser! < $1.distanceToUser!})
        print("Closest shop - ", self.shopList[0])
    }
}

3) 不要忘记调用viewDidLoad()import MapView framework 中的函数:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 2011-02-02
    • 2019-03-20
    • 1970-01-01
    相关资源
    最近更新 更多