首页 > 解决方案 > 仅堆叠具有相同位置的标记

问题描述

谷歌地图的聚类工具根据缩放级别对所有标记进行聚类。

我正在尝试(仅)将具有相同位置的标记堆叠在一起。然后在按下时继续并将信息数组传递到表格视图中。什么可能是潜在的解决方案?

最好的解决方案是在将重复坐标以某种方式添加到地图之前将它们合并到单个标记吗?或尝试以某种方式使用谷歌地图聚类工具?

当前代码:

创建数组

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
                }
        }
    }

任何帮助,将不胜感激。

标签: swiftfirebasegoogle-cloud-firestore

解决方案


聚类机制仅在有多个标记时才有用,但这里只有一个。那是因为在同一个位置添加多个标记是没有意义的,因为这很浪费,如果标记是可点击的,那么只有添加的最后一个标记才能产生动作。

考虑保留标记索引并依赖它而不是地图本身。始终将标记添加到索引中,但仅将它们添加到还没有标记的地图中。然后,当点击标记时,转到索引,如果那里只有一个标记,则将用户推送到该详细信息,如果那里有多个标记,则向用户显示这些标记的列表供用户选择。这是您可以在 Playground 中运行的内容(否则更改NSObjectGeoPoint使其成为适当的子类):

/* 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)

这种机制还允许我们向地图添加外观不同的标记,以表示哪些代表堆叠标记,哪些不代表。


推荐阅读