Reputation:
Below I have a list of cities and I compare a user's current location to the cities and use the (min) function
let closestCity = min(theDistanceInMetersFromBusselton,theDistanceInMetersFromBunbury,theDistanceInMetersFromJoondalup,theDistanceInMetersFromArmadale)
to return the closest city, though now I would like to return the second and third closest city.
I haven't been able to get this to work as yet though I'm thinking something along the lines of:
citiesArray - closestCity = SecondClosestCitiesArray
then do a secondClosestCity = min(SecondClosestCitiesArray)
to get the second closest city.
Then repeat this to find the third closest?
Any ideas?
extension HomePage {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let db = Firestore.firestore()
guard let uid = Auth.auth().currentUser?.uid else { return }
let location = locations[0]
let actualLatitude = String(location.coordinate.latitude)
let actualLongitude = String(location.coordinate.longitude)
guard let doubleActualLatitude = Double(actualLatitude) else { return }
guard let doubleActualLongitude = Double(actualLongitude) else { return }
///users current location
let usersCurrentLocation = CLLocation(latitude: doubleActualLatitude, longitude: doubleActualLongitude)
//////////////list of locations ////////////////
//////////ARMADALE/////////////////////
let ArmadaleLatitude = Double(-32.1530)
let ArmadaleLongitude = Double(116.0150)
let ArmadaleCoordinates = CLLocation(latitude:ArmadaleLatitude, longitude: ArmadaleLongitude)
let theDistanceInMetersFromArmadale = usersCurrentLocation.distance(from: ArmadaleCoordinates)
////////////////Bunbury///////////////////
let BunburyLatitude = Double(-33.3256)
let BunburyLongitude = Double(115.6396)
let BunburyCoordinates = CLLocation(latitude:BunburyLatitude, longitude: BunburyLongitude)
let theDistanceInMetersFromBunbury = usersCurrentLocation.distance(from: BunburyCoordinates)
/////////////////////////////////////////////
////////Busselton//////////////////
let busseltonLatitude = Double(-33.6555)
let busseltonLongitude = Double(115.3500)
let busseltonCoordinates = CLLocation(latitude:busseltonLatitude, longitude: busseltonLongitude)
let theDistanceInMetersFromBusselton = usersCurrentLocation.distance(from: busseltonCoordinates)
/////////////////////////////////
/////////Joondalup////////////////////
let JoondalupLatitude = Double(-32.5361)
let JoondalupLongitude = Double(115.7424)
let JoondalupCoordinates = CLLocation(latitude:JoondalupLatitude, longitude: JoondalupLongitude)
let theDistanceInMetersFromJoondalup = usersCurrentLocation.distance(from: JoondalupCoordinates)
//////////////////////////////////////
/////return the the closest city
let closestCity = min(theDistanceInMetersFromBusselton,theDistanceInMetersFromBunbury,theDistanceInMetersFromJoondalup,theDistanceInMetersFromArmadale)
func findClosestCity(){
//////////Armadale////////////////////////
if closestCity == theDistanceInMetersFromArmadale{
db.collection("Users").document(uid).setData(["Location": "Armadale" ], options: SetOptions.merge())
/////////Bunbury////////////
}else if closestCity == theDistanceInMetersFromBunbury{
let Bunbury = "Bunbury"
db.collection("Users").document(uid).setData(["Location": Bunbury ], options: SetOptions.merge())
///////////// Busselton//////////////
}else if closestCity == theDistanceInMetersFromBusselton{
let Busselton = "Busselton"
db.collection("Users").document(uid).setData(["Location": Busselton ], options: SetOptions.merge())
/////////////Joondalup//////////////////
}else if closestCity == theDistanceInMetersFromJoondalup{
db.collection("Users").document(uid).setData(["Location": "Joondalup" ], options: SetOptions.merge())
}
}
}
}
Upvotes: 0
Views: 377
Reputation: 11539
let cityLocations = [
"Armadale": CLLocation(latitude: -32.1530, longitude: 116.0150),
"Bunbury": CLLocation(latitude: -33.3256, longitude: 115.6396),
"Busselton": CLLocation(latitude: -33.6555, longitude: 115.3500),
"Joondalup": CLLocation(latitude: -32.5361, longitude: 115.7424)
]
func distanceFromCity(_ city: String, location: CLLocation) -> Double? {
return cityLocations[city].flatMap { location.distance(from: $0) }
}
func citiesClosestToLocation(_ location: CLLocation, n: Int) -> [String] {
let cities = cityLocations.sorted {
location.distance(from: $0.value) < location.distance(from: $1.value)
}
return cities.dropLast(cities.count - n).map({ $0.key })
}
let testLocation = cityLocations["Armadale"]!
print(citiesClosestToLocation(testLocation, n: 3)) // ["Armadale", "Joondalup", "Bunbury"]
Upvotes: 1
Reputation: 2897
You can add these value into an array and while adding it, make sure that they are getting added to sorting order. The array at any given point will give you closest city on the first index and second closest city on the second index.
Here is an example :
extension Array where Element == Double {
mutating func appendSorted(_ element: Double) {
if self.count == 0 {
self.append(element)
return
}
for i in 0..<self.count {
if element < self[i] {
self.insert(element, at: i)
return
}
}
self.append(element)
}
}
Upvotes: 0