检查数组是否具有相同的Latitude Longitude swift

时间:2017-02-28 21:02:52

标签: ios swift swift3 mkmapview mapkit

我有一个有这些数据的课

class Events {
   var name: String!
   var latitude: Double!
   var longitude: Double!
}

我用json的数据填写。

所以有些事件具有相同的纬度和经度,但它们不是连续的,我的意思是它不是event3与event4等相同。

所以我试图在地图上展示它们

填写此数组

var events = [Events]()

在这个for循环中,我制作了针脚。

 for events in events {
            let annotation = MKPointAnnotation()
            annotation.title = events.name

            annotation.coordinate = CLLocationCoordinate2D(latitude: events.latitude, longitude: events.longitude)
            mapView.addAnnotation(annotation)
        }

如何在部署引脚之前进行快速搜索,看看引脚是否与另一个引脚具有相同的lat和lon,添加一些数字只是为了显示它们都接近?

非常感谢!

1 个答案:

答案 0 :(得分:3)

使用Set查找唯一的实例。要使用Set您的基本元素,在这种情况下,Events必须为Hashable,并且含义为Equatable

class Events : Hashable {
    var name: String!
    var latitude: Double!
    var longitude: Double!

    // implement Hashable        
    var hashValue: Int {
        return latitude.hashValue | longitude.hashValue
    }

    // Implement Equatable
    static func ==(lhs:Events, rhs:Events) -> Bool {
        return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
    }
}

然后你的主循环是你已经拥有的东西的直接扩展,注意这会将所有匹配折叠到一个点并更改名称以指示有多少匹配:

// Use a Set to filter out duplicates
for event in Set<Events>(events) {
    let annotation = MKPointAnnotation()
    // Count number of occurrences of each item in the original array
    let count = events.filter { $0 == event }.count

    // Append (count) to the title if it's not 1
    annotation.title = count > 1 ? "\(event.name) (\(count))" : event.name

    // add to the map
}

相反,如果您想要移动积分以便它们不会叠加,那么您需要类似的东西,我们在这里建立一组占用位置并改变点以移动它们小。

func placeEvents(events:[Events], mapView:MKMapView) {
    var placed = Set<Events>()

    for event in events {
        if placed.contains(event) {
            // collision: mutate the location of event as needed,
        }

        // Add the mutated point to occupied points
        placed.formUnion([event])

        // Add the point to the map here
    }
}

如果这些值不是完全相同,而是仅在彼此的例如.0001之内,那么您可以使用以下hashValue== < / p>

fileprivate let tolerance = 1.0 / 0.0001

private var tolerantLat : Long { return Long(tolerance * latitude) }
private var tolerantLon : Long { return Long(tolerance * longitude) }

var hashValue : Int {
    return tolerantLat.hashValue | tolerantLon.hashValue
}

static func ==(lhs:Events, rhs:Events) -> Bool {
    return lhs.tolerantLat == rhs.tolerantLat && lhs.tolerantLon == rhs.tolerantLon
}