DDRBoxman/google-maps-ios-utils

How can we zoom until Cluster breaks, when tap on cluster?

Closed this issue · 2 comments

hyd00 commented

When I tap on a cluster, is it possible to zoom the map to certain zoom level, until that cluster breaks?

I was able to do this with some modifications to the default cluster renderer. You need to store references to all the items being clustered into the user data of the cluster marker. This can be done in the clustersChanged method. Then when you tap on the cluster you'll need code in the tap handler method that pulls out all the data from the cluster and then calculates the zoom based on the bounds of those coordinates.

- (void)clustersChanged:(NSSet*)clusters {
    for (GMSMarker *marker in _markerCache) {
        marker.map = nil;
    }

    [_markerCache removeAllObjects];

    for (id <GCluster> cluster in clusters) {
        GMSMarker *marker;
        marker = [[GMSMarker alloc] init];
        [_markerCache addObject:marker];

        NSUInteger count = cluster.items.count;
        if (count > 1) {
            marker.icon = [self generateClusterIconWithCount:count withItems:cluster.items];
        }
        else {
            marker.icon = cluster.marker.icon;
        }

        marker.userData = cluster.items;

        marker.position = cluster.marker.position;
        marker.map = _map;
    }
}

Here I handle both clusters and single markers in my map view controller:

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
    //handle clusters vs singular vehicles
    if ([marker.userData isKindOfClass:[Vehicle class]]) {
        self.detailViewController.vehicleInView = marker.userData;
        [self openDetailView];
    } else {
        [self moveMapToClusterSet:marker.userData];
    }
    return YES;
}

-(void)moveMapToClusterSet:(NSSet *)cluster {

    NSMutableArray *vehicles = [NSMutableArray array];

    for (id idItem in [cluster allObjects]) {
        if ([idItem isKindOfClass:[GQuadItem class]]) {
             //this is a cluster
            GQuadItem *item = idItem;
            GIVehicleCluster *vehicleCluster = [item.items anyObject];
            [vehicles addObject:vehicleCluster.vehicles[0]];
            [self focusVehicles:vehicles];
        } else {
            //this is a solitary marker
            GIVehicleCluster *vehicleCluster = idItem;
            Vehicle *vehicle = vehicleCluster.vehicles[0];
            self.detailViewController.vehicleInView = vehicle;
            [self openDetailView];
        }
    }
}
hyd00 commented

@jkunzelman Thanks a lot man! I already had implemented the logic to get objects inside a cluster, all I just implemented the calculation of the zoom based on the bounds of those markers coordinates, inside a cluster. Thank you so much for guiding me in the right direction!