-3

Current location value -

let currentLatitide = 19.1553902

le currentLongitude = 72.8528602

And Demo model of coordinates is

[[19.5,71.0],[18.5,72.0],[19.15,72.85],[19.1,75.0],[19.2,70.0],[19.3,70.0],[19.4,70.0],[19.6,70.0],[19.7,70.2],[19.9,70.3],[25,62.0],[24.5,73.4],[23.5,65.0],[21.5,68.0],[20.5,69.0]]

I am looking for 5 nearest value with respective to currentLatitide, currentLongitude,

I tried Bad solution like

    for value in modelBeacons {
         if value.latitude > 19.13 && value.latitude < 19.17 && value.longitude > 72.82 && value.longitude < 72.88 {
         print("Nearest will be here")
     } 

But i am looking for better solution like using map/filter/High order function function.

Ramesh
  • 147
  • 1
  • 17

2 Answers2

4

Convert the current location to a CLLocation.

Map your array of coordinates into an array of structs that contain the coordinates and a distance to your current location (In your map statement create a temporary CLLocation from each coordinate in the array, and use distance(from:) to calculate the distance.)

Then sort the resulting array of structs by distance and take the first 5 items from the array using array.prefix(_:)

Note that distance(from:) uses "great circle" 3D trig to calculate distances, so it will be slower that treating the lat/longs as cartesian coorindates and using the distance formula, but it will be more accurate. If your distances are less than 50 kilometers then doing cartesian math should be accurate enough.

import CoreLocation
let currentLatitide = 19.1553902
let currentLongitude = 72.8528602
struct CoordStruct: CustomStringConvertible {
    let coord: CLLocationCoordinate2D
    let distance: Double

    var description: String {
        return "lat: " + String(format: "%.4f",coord.latitude) +
            ", long: " + String(format: "%.4f",coord.longitude) + ", distance: " + distance.description
    }
}

let location = CLLocation(latitude: currentLatitide, longitude: currentLongitude)

 let points =   [[19.5,71.0],[18.5,72.0],[19.15,72.85],[19.1,75.0],[19.2,70.0],[19.3,70.0],[19.4,70.0],[19.6,70.0],[19.7,70.2],[19.9,70.3],[25,62.0],[24.5,73.4],[23.5,65.0],[21.5,68.0],[20.5,69.0]]

let structs: [CoordStruct] = points.map {
    let thisCoord = CLLocationCoordinate2D(latitude: $0[0], longitude: $0[1])
    let thisLocation = CLLocation(latitude:$0[0], longitude: $0[1])
    let distance = location.distance(from: thisLocation)
    return CoordStruct(coord: thisCoord, distance: distance)
    }
    .sorted { $0.distance < $1.distance }
let first5Structs = structs.prefix(5)

first5Structs.forEach { print($0) }

This outputs:

lat: 19.1500, long: 72.8500, distance: 668.232670102048
lat: 18.5000, long: 72.0000, distance: 115513.034301754
lat: 19.5000, long: 71.0000, distance: 198407.990357831
lat: 19.1000, long: 75.0000, distance: 225952.852274862
lat: 19.9000, long: 70.3000, distance: 280913.847369699
Duncan C
  • 128,072
  • 22
  • 173
  • 272
1
let array = [[19.5,71.0],[18.5,72.0],[19.15,72.85],[19.1,75.0],[19.2,70.0],[19.3,70.0],[19.4,70.0],[19.6,70.0],[19.7,70.2],[19.9,70.3],[25,62.0],[24.5,73.4],[23.5,65.0],[21.5,68.0],[20.5,69.0]]

let coordinate = CLLocation(latitude: 19.1553902, longitude: 72.8528602)

let distanceArray = array.map({ coordinate.distance(from: CLLocation(latitude: $0[0], longitude: $0[1])) } )

distanceArray = distanceArray.sorted()
distanceArray.prefix(5)

// print(distanceArray) : [668.23267010204756, 115513.03430175369, 198407.99035783144, 225952.85227486189, 280913.84736969916] 
Akshansh Thakur
  • 5,163
  • 2
  • 21
  • 38