1
votes

I'm developing an app on which I want to show a lot of event on the map. The user can click on an event and see a lot of information about it. I customized the marker icon of each event with a custom image and now I want to cluster each custom markers. I'm able to cluster the default icon of GoogleMaps API but if I want to cluster my own marker icon I'm not able to do it.

Here's my current code :

var mapView: GMSMapView!
var clusterManager: GMUClusterManager!
let isClustering: Bool = true
let isCustom: Bool = true

override func viewDidLoad() {
    super.viewDidLoad()

    mapView = GMSMapView(frame: view.frame)
    mapView.camera = GMSCameraPosition.camera(withLatitude: 13.756331, longitude: 100.501765, zoom: 12.0)
    mapView.mapType = .normal
    mapView.delegate = self
    view.addSubview(mapView)

    if isClustering {
        var iconGenerator: GMUDefaultClusterIconGenerator!
        if isCustom { // Here's my image if the event are clustered
            var images: [UIImage] = [UIImage(named: "m1.png")!, UIImage(named: "m2.png")!, UIImage(named: "m3.png")!, UIImage(named: "m4.png")!, UIImage(named: "m5.png")!]
            iconGenerator = GMUDefaultClusterIconGenerator(buckets: [5, 10, 15, 20, 25], backgroundImages: images)
        } else {
            iconGenerator = GMUDefaultClusterIconGenerator()
        }

        let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
        let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)

        clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
        clusterManager.cluster()
        clusterManager.setDelegate(self, mapDelegate: self)
    } else {
    }

    // Here's my personal marker icon (for one location)
    let firstLocation = CLLocationCoordinate2DMake(48.898902, 2.282664)
    let marker = GMSMarker(position: firstLocation)
    marker.icon = UIImage(named: "pointeurx1") //Apply custom marker
    marker.map = mapView

    let secondLocation = CLLocationCoordinate2DMake(48.924572, 2.360207)
    let secondMarker = GMSMarker(position: secondLocation)
    secondMarker.icon = UIImage(named: "pointeurx1")
    secondMarker.map = mapView

    let threeLocation = CLLocationCoordinate2DMake(48.841619, 2.253113)
    let threeMarker = GMSMarker(position: threeLocation)
    threeMarker.icon = UIImage(named: "pointeurx1")
    threeMarker.map = mapView

    let fourLocation = CLLocationCoordinate2DMake(48.858575, 2.294556)
    let fourMarker = GMSMarker(position: fourLocation)
    fourMarker.icon = UIImage(named: "pointeurx1")
    fourMarker.map = mapView

    let fiveLocation = CLLocationCoordinate2DMake(48.873819, 2.295200)
    let fiveMarker = GMSMarker(position: fiveLocation)
    fiveMarker.icon = UIImage(named: "pointeurx1")
    fiveMarker.map = mapView
}

/// Point of Interest Item which implements the GMUClusterItem protocol.
class POIItem: NSObject, GMUClusterItem {
    var position: CLLocationCoordinate2D
    var name: String!

    init(position: CLLocationCoordinate2D, name: String) {
        self.position = position
        self.name = name
    }
}

func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) {
    let newCamera = GMSCameraPosition.camera(withTarget: cluster.position, zoom: mapView.camera.zoom + 1)
    let update = GMSCameraUpdate.setCamera(newCamera)
    mapView.moveCamera(update)
}
}

How can I do it?

Look at these screenshots of my app then maybe you could understand better my issue.

First one there are the red default markers icons of the Google Maps, you can see in blue the cluster icon I was added in my project. Then you understand I added some locations on the viewDidLoad(), then the red markers are that. You can also see two others differents markers, the google one is orange and another one is my personal marker icon that I want to use for each marker icon of a location. But you can also see the issue, the issue is the blue cluster icon don't add the markers icons I added on the map (it shows 4 inside the blue cluster icon, it's the 4 icons around it but when the blue cluster icon appears the markers icons around it don't disappear.

Second image, if I make a zoom, the blue cluster icon disappears but you can also see another issue, the locations I was added have another red default markers icons of the Google Maps appears above them (you can see it at less because of my personal orange marker icon

1
You are having issues clustering or changing the cluster's icon ?nathan
Clustering works and I can change cluster's icon. In fact I customed the google markers (the red one) by an image of myself but I can't cluster these customs markers. Only the default marker of Google Maps can be clustered. Do u understand what I mean?user8381604
Have a look at studyswift.blogspot.com/2016/07/…, It's the same as your situation (and part of your code)nathan
Thank you Nathan, but I can do it with the red default marker icon of Google Maps not with my personal marker icon or if I changed the color of the Google marker icon. I added two screenshots in my post, you can see it when you click on the description on each screenshot, maybe you could understand better what I mean, it's difficult to explain it without show you.user8381604

1 Answers

6
votes

You are actually clustering first then adding markers thats why this is happening.

What you should actually do is

class MarkerModel: NSObject, GMUClusterItem {
var position: CLLocationCoordinate2D
var name: String

init(position: CLLocationCoordinate2D, name: String) {
    self.position = position
    self.name = name
}
}


override func viewDidLoad() {
super.viewDidLoad()

mapView = GMSMapView(frame: view.frame)
mapView.camera = GMSCameraPosition.camera(withLatitude: 13.756331, longitude: 100.501765, zoom: 12.0)
mapView.mapType = .normal
mapView.delegate = self
view.addSubview(mapView)

if isClustering {
    var iconGenerator: GMUDefaultClusterIconGenerator!
    if isCustom { // Here's my image if the event are clustered
        var images: [UIImage] = [UIImage(named: "m1.png")!, UIImage(named: "m2.png")!, UIImage(named: "m3.png")!, UIImage(named: "m4.png")!, UIImage(named: "m5.png")!]
        iconGenerator = GMUDefaultClusterIconGenerator(buckets: [5, 10, 15, 20, 25], backgroundImages: images)
    } else {
        iconGenerator = GMUDefaultClusterIconGenerator()
    }

    let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
    let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)

    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)

} else {
}
}

func addMarkers(cameraLatitude : Float, cameraLongitude : Float) {
    let extent = 0.01
    for index in 1...clusterItemCount {
        let lat = cameraLatitude + extent * randomScale()
        let lng = cameraLongitude + extent * randomScale()
        let name = "Item \(index)"

        let position = CLLocationCoordinate2DMake(lat, lng)

        let item = MarkerModel(position: position, name: name)
        item.icon = #imageLiteral(resourceName: "marker")
        clusterManager.add(item)
    }
     clusterManager.cluster()
        clusterManager.setDelegate(self, mapDelegate: self)
}

func randomScale() -> Double {
    return Double(arc4random()) / Double(UINT32_MAX) * 2.0 - 1.0
}

func renderer(_ renderer: GMUClusterRenderer, markerFor object: Any) -> GMSMarker? {

    let marker = GMSMarker()
    if let model = object as? MarkerModel {
         // set image view for gmsmarker
    }

    return marker
}

func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool {
    let newCamera = GMSCameraPosition.camera(withTarget: cluster.position, zoom: mapView.camera.zoom + 1)
    let update = GMSCameraUpdate.setCamera(newCamera)
    mapView.moveCamera(update)
    return false
}