swift - 仅堆叠具有相同位置的标记
问题描述
谷歌地图的聚类工具根据缩放级别对所有标记进行聚类。
我正在尝试(仅)将具有相同位置的标记堆叠在一起。然后在按下时继续并将信息数组传递到表格视图中。什么可能是潜在的解决方案?
最好的解决方案是在将重复坐标以某种方式添加到地图之前将它们合并到单个标记吗?或尝试以某种方式使用谷歌地图聚类工具?
当前代码:
创建数组
var events = [CreatedEvent]()
检索自定义标记(单个)。
weak var createdevent:CreatedEvent?
func createNewMarker(firebasePath: CollectionReference) {
let Eventref = firebasePath
Eventref.getDocuments() { (querySnapshot, err) in
if err == nil && querySnapshot != nil {
var tempEvent = [CreatedEvent]()
if querySnapshot!.documents.count > 0 {
self.mapIsEmpty = false
for document in querySnapshot!.documents {
let data = document.data()
let author = data["author"] as? [String:AnyObject]
let uid = author!["uid"] as? String
let username = author!["username"] as? String
let photoURL = author!["photoURL"] as? String
let url = URL(string:photoURL!)
let eventname = data["eventname"] as? String
let userProfile = UserProfile(uid: uid!, username: username!, photoURL: url!)
let createdevent = CreatedEvent(eventid: document.documentID, author: userProfile, eventname: eventanme)
let marker = GMSMarker()
self.createdevent = createdevent
if let dict = UserDefaults.standard.object(forKey: "ImageCache") as? [String:String] {
if let path = dict[createdevent.eventphotoURL.absoluteString] {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
let imageA1 = UIImage(data: data)
let customMarker = CustomMarkerView(frame: CGRect(x: 0, y: 0, width: self.customMarkerWidth, height: self.customMarkerHeight), image: imageA1!)
marker.iconView = customMarker
marker.userData = createdevent
}
}
}
marker.position = CLLocationCoordinate2D(latitude: eventlatitude, longitude: eventlongitude)
marker.map = self.myMapView
tempEvent.append(createdevent)
}
}
else {
print("no data")
}
self.events = tempEvent
}
}
}
任何帮助,将不胜感激。
解决方案
聚类机制仅在有多个标记时才有用,但这里只有一个。那是因为在同一个位置添加多个标记是没有意义的,因为这很浪费,如果标记是可点击的,那么只有添加的最后一个标记才能产生动作。
考虑保留标记索引并依赖它而不是地图本身。始终将标记添加到索引中,但仅将它们添加到还没有标记的地图中。然后,当点击标记时,转到索引,如果那里只有一个标记,则将用户推送到该详细信息,如果那里有多个标记,则向用户显示这些标记的列表供用户选择。这是您可以在 Playground 中运行的内容(否则更改NSObject
为GeoPoint
使其成为适当的子类):
/* A GeoPoint is an NSObject with 2 properties (lat and lon).
We can subclass it to add an identifer which will give
us a string key for our index (a concatenation of lat and lon). */
class GPoint: NSObject {
let identifier: String
let latitude: Double
let longitude: Double
init(latitude: Double, longitude: Double) {
self.latitude = latitude
self.longitude = longitude
identifier = "\(latitude)\(longitude)"
}
}
// This represents the marker that is added to the map
struct Marker {
let identifier: String
let geoPoint: GPoint
}
// This represents the marker index
var mapMarkers = [String: [Marker]]()
func addMarkerToMap(_ marker: Marker) {
let geoId = marker.geoPoint.identifier // get the marker's “location”
if mapMarkers.contains(where: { $0.key == geoId }) {
print("add to index")
mapMarkers[geoId]?.append(marker) // a marker exists here only add marker to index
} else {
print("add to map and index")
mapMarkers[geoId] = [marker] // no marker here yet, add to map and index
}
}
let marker1 = Marker(identifier: "abc123", geoPoint: GPoint(latitude: -118.1, longitude: 33.3))
let marker2 = Marker(identifier: "mno789", geoPoint: GPoint(latitude: -117.0, longitude: 34.8))
let marker3 = Marker(identifier: "xyz456", geoPoint: GPoint(latitude: -118.1, longitude: 33.3))
addMarkerToMap(marker1)
addMarkerToMap(marker2)
addMarkerToMap(marker3)
print(mapMarkers)
这种机制还允许我们向地图添加外观不同的标记,以表示哪些代表堆叠标记,哪些不代表。
推荐阅读
- arm - FLASH bank 和处理器内核指令获取 stm32f7
- python - 如何找到 ortools vrp 的优秀示例
- django - 如何在 Django admin 中为函数编写单元测试?
- android-studio - Gradle 不断强制下载到 4.6
- unity3d - 3D 声音不适用于设置为 3d 的空间混合
- python - 模板在 Django 中不存在
- javascript - 如何在文件上传器中检索文件的内容
- swift - 如何将包含自定义结构数组的自定义类型对象保存到领域(快速)?
- reactjs - 在服务器端(nextjs/apiRoutes)使用firebase/firestore获取多个数据=问题=>在数据准备好之前输出
- ajax - WP_Query 在插件 WP_AJAX 中不起作用