2点間の距離とsort
はじめに
mapKitを使ってピン表示などをさせる時に距離が近い順に処理をしたい用件が出てきたのでメモとして残しておく。
以下のような構造体のリストを現在位置と比べて近い順にsortする。
struct AmusementParkPoint {
let title: String
let location: CLLocation
}
2点間の距離
CLLocationがdistanceというメソッドを保持しているのでそれを使えば簡単に距離計算を行うことが可能です。
単位はメートルで帰ってきます
let distance = CLLocation(latitude: 35.4858947 ,
longitude: 138.7800076).distance(from: CLLocation(latitude: 35.6359322 ,
longitude: 139.8786311))
print(distance)
//100983.66487796529
func distance(from location: CLLocation) -> CLLocationDistance
https://developer.apple.com/documentation/corelocation/cllocation/1423689-distance
距離の近い順にsortする
private func sortDistance(amusementParkPointList: [AmusementParkPoint], currentLocation: CLLocation) -> [AmusementParkPoint] {
return amusementParkPoitList.sorted(by: { location1, locations2 in
let dist1 = location1.location.distance(from: currentLocation)
let dist2 = locations2.location.distance(from: currentLocation)
return dist1 < dist2
})
}
コード一覧
import UIKit
import CoreLocation
struct AmusementParkPoint {
let title: String
let location: CLLocation
}
class ViewController: UIViewController {
var locationManager:CLLocationManager!
let amusementParkPoitList = [
AmusementParkPoint(title: "富士急ハイランド",
location: CLLocation(latitude: 35.4858947 ,
longitude: 138.7800076)),
AmusementParkPoint(title: "東京ディズニーランド",
location: CLLocation(latitude: 35.6359322 ,
longitude: 139.8786311)),
AmusementParkPoint(title: "ユニバーサル・スタジオ・ジャパン|USJ",
location: CLLocation(latitude: 34.6656995 ,
longitude: 135.432666))]
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .restricted, .denied:
break
case .authorizedAlways, .authorizedWhenInUse:
manager.startUpdatingLocation()
locationManager.startUpdatingLocation()
default:
break
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else {
return
}
let sortAmusementList = sortDistance(amusementParkPointList: amusementParkPoitList,
currentLocation: location)
sortAmusementList.forEach{
print($0.title)
}
}
private func sortDistance(amusementParkPointList: [AmusementParkPoint], currentLocation: CLLocation) -> [AmusementParkPoint] {
return amusementParkPoitList.sorted(by: { location1, locations2 in
let dist1 = location1.location.distance(from: currentLocation)
let dist2 = locations2.location.distance(from: currentLocation)
return dist1 < dist2
})
}
}