Search code examples
javascriptgoogle-mapsmarkerclusterer

Google Maps Disable Zoom on Cluster Click


I have a map with cluster based markers. I want a way when the user clicks on a cluster with more than 100 markers, don't zoom in and do something else like I am opening a popup; else just decluster.

On Load Page, I am calling a service and getting list of customers with locations. I am passing the customers to the Clustering function. Now when the user clicks on the cluster I want to put some conditions. if true open a popup but do not zoom in neither decluster. I am not able to do this. This is the code

Customers.html

<div [hidden]="!MapView" style="height: 100%" #map id="map"></div>

Customers.ts

    @ViewChild('map') mapElement: ElementRef;

    ngOnInit() {


            this.initMap();

        }

    initMap = () => {

            this._customerservice.GetCustomersWithLocations().subscribe(res => {

                if (res != null || res != undefined) {

                    this.CustomersLocation = res;

                    let latLng = new google.maps.LatLng(-31.563910, 147.154312);

                    let mapOptions = {
                        center: latLng,
                        zoom: 6,
                        mapTypeId: google.maps.MapTypeId.TERRAIN,
                        fullscreenControl: false
                    }

                    setTimeout(() => { // LOAD THE MAP FIRST
                        this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
                    }, 1000);

                    setTimeout(() => { //LOAD THE CLUSTER
                        this.mapCluster.addCluster(res, this.map);
                    }, 3000);


                }

            }, error => {
            }, () => {
           });

    }

GoogleMapsCluster.ts

addCluster(Customers: any, map) {
    //console.log(Customers);

    if (google.maps) {

      //Convert locations into array of markers
      let markers = Customers.map((location) => {

        var marker = new google.maps.Marker({
          position: location.loc,
          label: location.name,
        });

        return marker;

      });

      this.markerCluster = new MarkerClusterer(map, markers, { imagePath: 'assets/m' });

      google.maps.event.addListener(this.markerCluster, 'clusterclick', (cluster) => {

        var markers = cluster.getMarkers();

        var CustomerInsideCluster = [];

        for (var i = 0; i < markers.length; i++) {
          CustomerInsideCluster.push({BusinessName: markers[i].label})
        }
        this.OpenCustomerDetails(CustomerInsideCluster);
        //I OPEN A POPUP HERE. I DONT WANT TO ZOOM IN TO DECLUSTER. AT THEN END IF THE CLUSTER HAS MORE THAN 100 CUSTOMERS I DONT WANT TO ZOOM IN WHEN I CLICK ON IT.
        //map.setZoom(8); GIVING ME ERROR

      });


    } else {
      console.warn('Google maps needs to be loaded before adding a cluster');
    }

  }
  OpenCustomerDetails(Customers: any) {
    let popover = this.popoverCtrl.create(MapPopover, { Customers: Customers }, { cssClass: 'custom-popover' });
    popover.present({
      ev: event
    });
  }

Solution

  • This is a possible solution. Just set the markerClusterer property zoomOnClick to false.

    var markerCluster = new MarkerClusterer(map, markers, { 
        imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',
        zoomOnClick: false
      });
    

    Within your clusterclick event, pass the counter object to the callback function and by using a conditional statement based on your requirements, open an infowindow (or else if you prefer).

    markerCluster.addListener('clusterclick', function(cluster){
          if (markers.length > 5){ // change #5 if you need to test different scenarions
                infowindow.setPosition(cluster.getCenter());
                infowindow.setContent("Simple Test");
                infowindow.open(map);
    
                }
    

    If the markers are less or more than the required parameters, reset the zoomOnClick to true again and use the following map and clusterObject methods:

      else {
         markerCluster.zoomOnClick = true;
         map.fitBounds(cluster.getBounds());
    
            } 
    

    Proof of concept in this JSBIN