如何在Google地图上通过轻触更改聚合标记图标?

5
我有一个类型为GMSMapView的谷歌地图,上面有标记,并且我已经在该地图视图中实现了Google集群。
因此,我真正想要实现的是,我想点击集群图标并更改特定集群的图标。 但是目前发生的是,当我单击选定的标记时,只有个别标记会更改,而不是集群项。

我的地图上显示了群集组

My CLuster Map Image Link

我真正想要实现的是什么

What I want to achieve On Cluster Tap Image Link

我实际为个人标记取得了什么成就。

what I have achieved for individual marker Image Link

上面的图片是聚合标记,我想在该聚合项上渲染一个图标,但不幸的是,由于在 GMUClusterManagerDelegate GMUClusterRendererDelegate 的委托中无法访问任何图像,因此它没有呈现。 我找不到任何方法可以在聚合标记的点击操作中更改聚合图标。
注意:我想更改聚合项的图标,而已经实现了对所选个体标记的更改。
以下是我迄今为止完成的代码。
   override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        propertyMapView.delegate = self
        createListOfPOIItems()
    }

    // MARK : -- Map related functions
//creating POOitems for the map
    func createListOfPOIItems() {
        self.propertyPOIItemList = []
        for index in 0..<self.propertyListModalArray.count {
            let propertylistmodal = self.propertyListModalArray[index]
            if UtilitySharedClass.sharedInstance.isvalidGeoLat(propertylistmodal.propertylat) && UtilitySharedClass.sharedInstance.isvalidGeoLong(propertylistmodal.propertyLong) {
                let coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(Float(propertylistmodal.propertylat!)!), longitude: CLLocationDegrees(Float(propertylistmodal.propertyLong!)!))
                if universityLocation == coordinate{
                    continue
                }
                let item = POIItem(position: coordinate, name: propertylistmodal.propertyName ?? "", propertyListModal: propertylistmodal)
                self.propertyPOIItemList?.append(item)
            }
        }
        initiateClustering()
    }

    func initiateClustering() {
        // Set up the cluster manager with the supplied icon generator and
        // renderer.
        let iconGenerator = ClusterIconGenerator()
        let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
        let renderer = GMUDefaultClusterRenderer(mapView: propertyMapView,
                                                 clusterIconGenerator: iconGenerator)
        clusterManager = GMUClusterManager(map: propertyMapView, algorithm: algorithm,
                                           renderer: renderer)
        renderer.delegate = self
        renderer.minimumClusterSize = 2
        
        //renderer.animationDuration = 0.2
        
        // Generate and add random items to the cluster manager.
        generateClusterItems()
        
        // Call cluster() after items have been added to perform the clustering
        // and rendering on map.
        clusterManager.cluster()
        
        clusterManager.setDelegate(self, mapDelegate: self)
        
        self.setUniversityLocation()
    }

为地图添加集群

    /// adds property location to the cluster manager.
    private func generateClusterItems() {
        guard let items = self.propertyPOIItemList else { return }
        items.forEach({ (item) in
            clusterManager?.add(item)
            clusterManager?.cluster()
        })
    }

实现集群的代理

extension SearchViewController:  GMSMapViewDelegate, GMUClusterManagerDelegate, GMUClusterRendererDelegate {
    
    func renderer(_ renderer: GMUClusterRenderer, markerFor object: Any) -> GMSMarker? {
        let marker = CustomMarker()
        if let itemMarker = object as? GMUCluster {
            marker.markerType = .clusterType
            marker.markerCount = itemMarker.items.count
        } else if let itemMarker = object as? POIItem {
            marker.markerType = .itemType
            itemMarker.marker = marker
            marker.propertyListModal = itemMarker.propertyListModal
        }
        return marker
    }
    
    func renderer(_ renderer: GMUClusterRenderer, didRenderMarker marker: GMSMarker) {
        if let customMarker = marker as? CustomMarker {
            if customMarker.markerType == .itemType {
                let propertyMarker = createMarkerView(isSelected: customMarker.isSelected)
                propertyMarker.markerPriceLabel.text = customMarker.propertyListModal?.propertyPrice
                marker.icon = propertyMarker.asImage()
                marker.groundAnchor = CGPoint(x: 0.5, y: 1)
            }
        }
    }
    
    // MARK: - GMUClusterManagerDelegate
    func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool {
        let newCamera = GMSCameraPosition.camera(withTarget: cluster.position,
                                                 zoom: propertyMapView.camera.zoom)
        let update = GMSCameraUpdate.setCamera(newCamera)
        propertyMapView.moveCamera(update)

        isClusterTapped = true

        clusterPropertyList = []
        let properties = cluster.items
        properties.forEach({ (property) in
            if let propertyModal = property as? POIItem, propertyModal.propertyListModal != nil{
                clusterPropertyList.append(propertyModal.propertyListModal!)
            }
        })
        
        if let previousMarker = propertyMapView.selectedMarker as? CustomMarker{
            previousMarker.isSelected = !previousMarker.isSelected
            let propertyMarker = createMarkerView(isSelected: previousMarker.isSelected)
            propertyMarker.markerPriceLabel.text = previousMarker.propertyListModal?.propertyPrice
            previousMarker.icon = propertyMarker.asImage()
        }
        self.propertyMapView.selectedMarker = nil

        self.propertyListContainerForMap.isHidden = false
        self.propertyViewForMapCollectionView.reloadData()
        return true
    }
    
    
    func clusterManager(_ clusterManager: GMUClusterManager, didTap clusterItem: GMUClusterItem) -> Bool {
        let newCamera = GMSCameraPosition.camera(withTarget: clusterItem.position,
                                                 zoom: propertyMapView.camera.zoom)
        let update = GMSCameraUpdate.setCamera(newCamera)
        propertyMapView.moveCamera(update)
        
        if let previousMarker = propertyMapView.selectedMarker as? CustomMarker{
            previousMarker.isSelected = !previousMarker.isSelected
            let propertyMarker = createMarkerView(isSelected: previousMarker.isSelected)
            propertyMarker.markerPriceLabel.text = previousMarker.propertyListModal?.propertyPrice
            previousMarker.icon = propertyMarker.asImage()
        }
        
        let item = clusterItem as? POIItem
        if let tappedMarker = item?.marker as? CustomMarker{
            tappedMarker.isSelected = !tappedMarker.isSelected
            let propertyMarker = createMarkerView(isSelected: tappedMarker.isSelected)
            propertyMarker.markerPriceLabel.text = tappedMarker.propertyListModal?.propertyPrice
            tappedMarker.icon = propertyMarker.asImage()
            propertyMapView.selectedMarker = tappedMarker
        }
        
        isClusterTapped = false
        self.propertyListContainerForMap.isHidden = false
        self.propertyViewForMapCollectionView.reloadData()
        return true
    }
}

我的POItem类

import Foundation
import GoogleMapsUtils
import GoogleMaps

class POIItem: NSObject, GMUClusterItem {
    var position: CLLocationCoordinate2D
    var name: String!
    var propertyListModal: PeropertyListModel?
    var marker: GMSMarker?
    
    init(position: CLLocationCoordinate2D, name: String, propertyListModal: PeropertyListModel) {
        self.position = position
        self.name = name
        self.propertyListModal = propertyListModal
    }
}

IconGenerator的类

import Foundation
import GoogleMapsUtils

class ClusterIconGenerator: GMUDefaultClusterIconGenerator {
    
    override func icon(forSize size: UInt) -> UIImage {
        let image = textToImage(drawText: String(size) as NSString,
                                inImage: UIImage(named: "clusterMarker")!,
                                font: UIFont(name: "Futura-Medium", size: 12.0) ?? UIFont.systemFont(ofSize: 12))
        return image
    }
    
    private func textToImage(drawText text: NSString, inImage image: UIImage, font: UIFont) -> UIImage {
        
        UIGraphicsBeginImageContext(image.size)
        image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
        
        let textStyle = NSMutableParagraphStyle()
        textStyle.alignment = NSTextAlignment.center
        let textColor = UIColor.black
        let attributes=[
            NSAttributedString.Key.font: font,
            NSAttributedString.Key.paragraphStyle: textStyle,
            NSAttributedString.Key.foregroundColor: textColor]
        
        // vertically center (depending on font)
        let textH = font.lineHeight
        let textY = (image.size.height-textH)/2
        let textRect = CGRect(x: 0, y: textY, width: image.size.width, height: textH)
        text.draw(in: textRect.integral, withAttributes: attributes)
        let result = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return result!
    }
}

上面是我迄今为止所做的代码,但并不值得,请问你能否帮我找到解决方案,如何在点击操作时在聚合项标记上呈现图标。

尽管我也在寻找解决方案,但只有在通过集群管理器呈现时,图标才不会在轻拍时更改。 - Sharon Nathaniel
1个回答

0

如果您有兴趣使用存储桶索引更改图标,我猜您可以使用以下代码来更改图像。您可以分别使用存储桶索引并显示聚类标记的图标。

let iconGenerator = GMUDefaultClusterIconGenerator(buckets: [5, 10, 15], backgroundImages: [#imageLiteral(resourceName: "clusterSelectedMarker"), #imageLiteral(resourceName: "clusterSelectedMarker"), #imageLiteral(resourceName: "clusterSelectedMarker")])
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
                                                clusterIconGenerator: iconGenerator)
var renderer = CustomClusterRenderer(mapView: propertyMapView, clusterIconGenerator: iconGenerator)
clusterManager = GMUClusterManager(map: propertyMapView, algorithm: algorithm,
                                           renderer: renderer)

你的回答是有道理的,但我想要的是每当我点击聚合项时,委托都会被调用,而且我想改变聚合图标。 - Manish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接