检查数组是否具有相同的纬度经度 swift
Check if array has same Latitude Longitude swift
我有一个 class 有那些数据
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)
}
如何在部署图钉之前进行快速搜索,查看一个图钉是否与另一个图钉具有相同的纬度和经度,添加一些数字以显示它们都接近?
非常感谢!
使用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 { [=11=] == 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
和 ==
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
}
我有一个 class 有那些数据
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)
}
如何在部署图钉之前进行快速搜索,查看一个图钉是否与另一个图钉具有相同的纬度和经度,添加一些数字以显示它们都接近?
非常感谢!
使用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 { [=11=] == 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
和 ==
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
}