How to Implement Gmuclusterrenderer in Swift

How to implement GMUClusterRenderer in Swift

I found a clean solution for clustered markers, on Swift 4, to use a custom image for the cluster with the number of cluster inside:

class MapClusterIconGenerator: GMUDefaultClusterIconGenerator {

override func icon(forSize size: UInt) -> UIImage {
let image = textToImage(drawText: String(size) as NSString,
inImage: UIImage(named: "cluster")!,
font: 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=[
NSAttributedStringKey.font: font,
NSAttributedStringKey.paragraphStyle: textStyle,
NSAttributedStringKey.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!
}

}

Than the setup for the cluster manager:

private func setupClustering() {
guard let mapView = self.mapView else { return }

let iconGenerator = MapClusterIconGenerator()
let renderer = MapClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
}

I also used a custom cluster renderer MapClusterRenderer.

Customize the marker on google map with clusters

After creating your GMUDefaultClusterRenderer set its delegate I used the view controller I was working in, and then implement the GMUClusterRendererDelegate

let iconGenerator = GMUDefaultClusterIconGenerator()
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
renderer.delegate = self
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)

After that you implement the func renderer(_ renderer: GMUClusterRenderer, willRenderMarker marker: GMSMarker) from the protocol. This method gives you access to the marker and the data enclosed in the marker.
Use an If let statement to access the data and give the marker the iconView you want if let markerData = marker.userData

How to clustered markers from Firebase in GoogleMaps for iOS

Firstly loadMarker() should be called after the clusterManager is initialized i.e

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

then

clusterManager.cluster()
clusterManager.setDelegate(self, mapDelegate: self)

should be placed in loadMarker() after for loop ends.

Your viewcontroller should conform to this protocol GMUClusterManagerDelegate then add these 2 methods in viewcontroller.

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
}

Try this and let me know if this works else we will try something else.

How to change the cluster color of google map In Swift 4

I found an answer with a perfect solution.

@Andr3a88 Answer :
How to implement GMUClusterRenderer in Swift

The correct answer was to create the image rather than draw a circle in the script.

In the above script could also change the text.

The number of questions proves that many people like me are experiencing errors.

So I will leave a few questions to help you find a more complete solution.

How to customize default pin marker using Google Cluster Manager?

marker has a property iconView which is a UIView. Since it's a UIView you can customize however you want.

func renderer(_ renderer: GMUClusterRenderer, willRenderMarker marker: GMSMarker) {
marker.iconView = MyView()
}

Changing google maps POIItem markers

Here is the Google Documentation link: Customizing Marker Clusters

SO answer here in SWIFT: Its not pretty but apprently works.

How to implement GMUClusterRenderer in Swift

For other basic markers:

Documentation at Google for basic markers here is the link:
change the marker color

marker.icon = GMSMarker.markerImage(with: .black)

Very slow scrolling/zooming experience with GMUClusterRenderer (Google Maps Clustering) on iOS

I was facing the same issue. After debugging a lot and checking google's code even, i come to the conclusion that, issue was from GMUDefaultClusterIconGenerator. This class is creating images at runtime for given cluster size that you are displaying. So, when you zoom in or zoom out the map, the cluster size is going to update, and this class creates new image for new number(Even it keep images cached, if same number get repeated).

So, the solution that i found is to use buckets. You will get surprised by seeing this new term. Let me explain the bucket concept by giving simple example.

suppose you kept bucket sizes as 10, 20, 50, 100, 200, 500, 1000.

  • Now, if your cluster is 3, then it will show 3.
  • If cluster size = 8, show = 8.
  • If cluster size = 16, show = 10+.
  • If cluster size = 22, show = 20+.
  • If cluster size = 48, show = 20+.
  • If cluster size = 91, show = 50+.
  • If cluster size = 177, show = 100+.
  • If cluster size = 502, show = 500+.
  • If cluster size = 1200004, show = 1000+.

Now here, for any cluster size, the marker images that are going to be rendered will be from 1, 2, 3, 4, 5, 6, 7, 8, 9, 10+, 20+, 50+, 100+, 200+, 500+, 1000+. As it caches the images, so this images is going to be reused. So, the time+cpu that it was using for creating new images is lowered(only few images required to be created).

You must have got the idea, about buckets now. As, if cluster is having very small number, then cluster size matters, but if increases, then bucket size is enough to get idea about cluster size.

Now, question is how to achieve this.

Actually, GMUDefaultClusterIconGenerator class has already this functionality implemented, you just need to change its initialisation to this:

let iconGenerator = GMUDefaultClusterIconGenerator(buckets: [ 10, 20, 50, 100, 200, 500, 1000])

GMUDefaultClusterIconGenerator class have other init methods, by using which you can give different background colors to different buckets, different background images to to different buckets and many more.

Let me know, if any further help required.



Related Topics



Leave a reply



Submit