GMSMapView Clustering - iOS
About me
This is my first blog so sorry for the typo and formatting
I am a passionate ios developer from India, having more than 6 + years of experience, my key skills are:
- SWIFT
- Objective C
- Python
Why I wanted to learn GMSMapView Clustering iOS
One of my project has the functionality to show the available hotels/restaurant logo in the map view, But after trying many attempts i learned how to make the clustering with custom markers in GMSMapView.
How I approached learning GMSMapView Clustering iOS
I followed developer.google for all the basic and the tutorials they have provided along with stack overflow discussions etc.
Challenges I faced
I have achieved the simple map clustering by following the developer.google but unable to add the custom icons that I am getting from my API response. So after reading and spending 3-4 hours i have finally done that and i will share this with all of you.
Final thoughts and next steps
// Set up the cluster manager with default icon generator and renderer.
let iconGenerator = GMUDefaultClusterIconGenerator()
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let renderer = GMUDefaultClusterRenderer(mapView: self.mapView, clusterIconGenerator: iconGenerator)
clusterManager = GMUClusterManager(map: self.mapView, algorithm: algorithm, renderer: renderer)
//clusterManager.delegate = self
// 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()
- below function actually creates the cluster objects which I have created in a different class (CustomClusterItem) and adding them to the array and generateClusterItems() function will generate the clustering in the GMSMapView.
private func generateClusterItems() {
self.markersArray.removeAll()
if (self.results.count) > 0 {
for i in 0...(self.results.count) - 1 {
// let extent = 0.2
let objOffersLocations = self.results[i]
if let lat = objOffersLocations.latitude {
kLatitude = Double(lat)!
}
if let lng = objOffersLocations.longitude {
kLongitude = Double(lng)!
}
if let imageURL = objOffersLocations.initialPhoto?.photo {
let item = CustomClusterItem(position: CLLocationCoordinate2DMake(kLatitude,kLongitude), title: "test", icon: imageURL, location_Id:objOffersLocations.locationId!)
clusterManager.add(item)
markersArray.append(item)
}
else {
let item = CustomClusterItem(position: CLLocationCoordinate2DMake(kLatitude,kLongitude), title: "test", icon: "", location_Id:objOffersLocations.locationId!)
clusterManager.add(item)
markersArray.append(item)
}
}
}
else {
let item = CustomClusterItem(position: CLLocationCoordinate2DMake(kLatitude,kLongitude), title: "test", icon: "", location_Id:0)
clusterManager.add(item)
markersArray.append(item)
}
}
Now below is my class for the custom cluster item which accepts the location, id of the object and an iconURL, you can pass whatever information you want at here.
@objc public class CustomClusterItem: NSObject, GMUClusterItem {
public var position: CLLocationCoordinate2D
@objc public var pos_name: String
@objc public var locationId: Int
@objc public var iconURL: String
init(position: CLLocationCoordinate2D, title: String, icon: String, location_Id:Int)
{
self.position = position
self.pos_name = title
self.iconURL = icon
self.locationId = location_Id
}
}
And now if you want to go into the detail page of any item when user taps on the icon then then GMSMapView delegate will be executed, You can check the below code:
// MARK: - GMUMapViewDelegate
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
if let poiItem = marker.userData as? CustomClusterItem {
let selectedArray = self.results.filter() { $0.locationId == poiItem.locationId }
if selectedArray.count > 0 {
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "DetailVC") as! DetailVC
vc.nearbyLocation = selectedArray[0]
self.navigationController?.pushViewController(vc, animated: true)
}
} else {
NSLog("Did tap a normal marker")
}
return false
}
**** Dont forget to add the mapview delegate ***
// Register self to listen to both GMUClusterManagerDelegate and GMSMapViewDelegate events.
clusterManager.setDelegate(self, mapDelegate: self)
Would you please share GitHub link?