如何在不清除 GoogleMap 的情况下更新多个位置

Posted

技术标签:

【中文标题】如何在不清除 GoogleMap 的情况下更新多个位置【英文标题】:How to update multiple location without clearing GoogleMap 【发布时间】:2019-12-03 17:02:02 【问题描述】:

我已经通过集群在地图中加载了几个用户,现在我想根据我从服务器收到的用户新位置更新用户位置。

我可以通过清除地图并从服务器加载新用户数据来做到这一点,但看起来标记正在跳跃并且看起来不正确。

有没有办法在不清除GoogleMap的情况下更新标记位置?

这是我的问题的链接:Google Map with Cluster and Custom view marker lagging too much while zoomIn and zoomOut

参考屏幕

如果有人从他的位置移动,那么一旦我从服务器收到更新的数据,我该如何更新他/她的位置。 (不清除地图)

我的代码

func setMarkers() 
        for i in 0..<SharedData.sharedInstance.allFriends.count 
            let marker = GMSMarker()
            let friend = SharedData.sharedInstance.allFriends[i]
            marker.position = CLLocationCoordinate2D.init(latitude: friend.user_details.latitude , longitude: friend.user_details.longitude)
            marker.accessibilityHint = String(i)
            marker.icon = #imageLiteral(resourceName: "trans")
            marker.tracksViewChanges = true
            marker.map = mapView

            arrMarkers.append(marker)
            self.generatePOIItems(String(format: "%d", i), position: marker.position, icon: nil, friend: friend, userIndex: i)
        
        clusterManager.cluster()
        clusterManager.setDelegate(self, mapDelegate: self)
    

    func updateMarkers() 
        for i in 0..<arrMarkers.count 
            let marker = arrMarkers[i]
            let friend = SharedData.sharedInstance.allFriends[i]
            marker.position = CLLocationCoordinate2D.init(latitude: friend.user_details.latitude , longitude: friend.user_details.longitude)
            marker.accessibilityHint = String(i)
            marker.icon = #imageLiteral(resourceName: "trans")
            marker.tracksViewChanges = true
            marker.map = mapView
        
        self.defaultCamera(latitude: SharedData.sharedInstance.userLocation.coordinate.latitude, longitude: SharedData.sharedInstance.userLocation.coordinate.longitude)
    

编辑

func generatePOIItems(_ accessibilityLabel: String, position: CLLocationCoordinate2D, icon: UIImage?, friend: WallBeeppClass, userIndex: Int) 
        let name = "Item \(accessibilityLabel)"
        let item = POIItem(position: CLLocationCoordinate2DMake(position.latitude, position.longitude), name: name, friend: friend, userIndex: userIndex)
        clusterManager.add(item)
    


func updateMarkers() 
        for i in 0..<arrMarkers.count 
            let marker = arrMarkers[i]
            let friend = SharedData.sharedInstance.allFriends[i]

            CATransaction.begin()
            CATransaction.setAnimationDuration(1.0)
            marker.position = CLLocationCoordinate2D.init(latitude: friend.user_details.latitude , longitude: friend.user_details.longitude)
            CATransaction.commit()
        
    

编辑 1

如果我从后端更改了一些用户位置,并且当我获得用户新位置时,我会使用上面的代码更新标记位置,但问题是新位置用户仍位于旧位置。如果我清除并重绘用户数据,那么它工作正常。

编辑 2

func renderer(_ renderer: GMUClusterRenderer, willRenderMarker marker: GMSMarker) 
        marker.groundAnchor = CGPoint(x: 0.1, y: 0.45)
        if let markerData = (marker.userData as? POIItem) 
            let infoWindow = Bundle.main.loadNibNamed("InitialMapInfoView", owner: self, options: nil)?.first as! InitialMapInfoView
            infoWindow.imgUser.sd_setImage(with: URL(string: markerData.friend.user_details.user_photo_small), placeholderImage: #imageLiteral(resourceName: "User_profile"), options: .highPriority, completed: nil)

            if !markerData.friend.user_details.isUserOnline 
                infoWindow.imgCar.image = UIImage.init(named: "small_inactive_" + markerData.friend.user_details.car_personality_name)
            
            else 
                infoWindow.imgCar.image = UIImage.init(named: "small_" + markerData.friend.user_details.car_personality_name)
            

            if markerData.friend.user_details.user_id == 88 
                print("Will Rendrer Marker: \(markerData.friend.user_details.latitude)")
                print("Will Rendrer Marker: \(markerData.friend.user_details.longitude)")
            

            infoWindow.lblName.text = markerData.friend.user_details.name
            infoWindow.btnImgVW.tag = markerData.userIndex
            infoWindow.btnImgVW.addTarget(self, action: #selector(btnUserTapped(_:)), for: .touchUpInside)
            marker.accessibilityHint = String(markerData.userIndex)
            marker.iconView = infoWindow
            marker.tracksViewChanges = false
        

请指导我这样做。

【问题讨论】:

任何代码 sn-p 来可视化应用程序的当前状态以及您在代码中的哪个位置遇到此问题? 您可以继承 GMSMarker,添加对象的 id,然后通过从服务器获取的对象 id 获取标记并更新位置 @rags2riches,我添加了参考屏幕和评论 @AlexandrKolesnik,目前我已将所有标记存储在 GMSMarker 类型数组中,并且我已经更新了用户新的纬度。请查看我添加的代码 【参考方案1】:

您可以继承 GMSMarker,添加对象的 id,然后通过从服务器获得的对象 id 获取标记并更新位置。这是一些代码来解释我的意思

    class MyMarker: GMSMarker 

         var id: String? = nil

    

将 id 添加到您的标记中

func setMarkers() 

        let marker = MyMarker()
        let friend = SharedData.sharedInstance.allFriends[I]
        marker.id = friend.id

比通过 id 更新

for friend in SharedData.sharedInstance.allFriends 
        guard
            let marker = array.first  $0.id == friend.id 
        else  contiunue 
        marker.position = CLLocationCoordinate2D.init(latitude: friend.user_details.latitude , longitude: friend.user_details.longitude)
    

不要再在地图上添加标记,只需改变它的位置

【讨论】:

新协调已成功更新,但是当我进行分区/缩放时,地图用户会在同一位置显示我。用户需要移动到新位置,但仍留在旧位置 相机放大/缩小时你的动作是什么,我没有看到你的代码,但是当你更新标记位置时尝试更新 self.generatePOIItems(你的集群) 如果我尝试 generatePOIItems 那么它将在旧标记上添加新标记。 在添加之前从集群中删除项目 在添加之前清除集群想法会起作用,但会消耗大量内存。如果我从服务器获取新数据 5 次,那么内存将从 90MB 增加到 300MB。有其他解决方案吗?

以上是关于如何在不清除 GoogleMap 的情况下更新多个位置的主要内容,如果未能解决你的问题,请参考以下文章

安卓——SurfaceView。在不清除屏幕的情况下更新。 (注:我是菜鸟)

如何在不注销的情况下清除所有会话变量

如何在不保留任何到期时间的情况下清除 javascript 中的 cookie [重复]

如何在不使用值的情况下清除 TextInput

如何在不造成内存泄漏的情况下清除自定义对象的 NSMutableArray?

如何在不清除整个队列的情况下从 Resque 队列中删除特定作业?