hugsbrugs
hugsbrugs

Reputation: 3621

How to know zoom level to display a marker inside google marker cluster

well, almost everything is in the title :

BUT

SO

Upvotes: 3

Views: 1164

Answers (2)

Свободен Роб
Свободен Роб

Reputation: 2810

I have used this solution. It checks if selected marker is in cluster. If it is then increment the zoom level.

 var zoom = 15;
 this.map.setCenter(marker.getPosition());   

 var zoomInterval = setInterval($.proxy(function() {
     if(!marker.map) {
         this.map.setZoom(zoom++);
     } else {
         clearInterval(zoomInterval);
     }
 }, this), 400);

Note that if marker is in cluster it's 'map' property is 'null'.

Upvotes: 3

hugsbrugs
hugsbrugs

Reputation: 3621

Some code ;)

/**
 * Computes scale in meters per pixel for given zoom and latitute.
 *
 * @param {Object} opt optional parameters
 *      - zoom
 *      - lat
 *      - precision
 *
 * @returns {Number} scale in meters per pixel
 */
google.maps.Map.prototype.getMapScale = function (opt){
    var circumference = 40075040,
        zoom, lat, scale;

    if (typeof(opt['zoom']) == 'number' && typeof(opt['lat']) == 'number') {
        zoom = opt['zoom'];
        lat = opt['lat'];
    } else {
        zoom = this.getZoom();
        lat = this.getCenter().lat();
    }

    scale = (circumference * Math.cos(lat) / Math.pow(2, zoom + 8));

    if (typeof(opt['precision']) == 'number') {
        scale = Number(scale.toFixed(opt['precision']));
    }

    return scale;
}


function calculateZoomLevelMarkerAloneInCluster(VigneronID){
    var distance = 1000000000;
    var found_marker_in_cluster = false;
    /* GET ALL CLUSTERS FROM GMAP MARKER CLUSTER */
    var clustersArray = mc.getClusters();
    /* FOR ALL CLUSTERS */
    $.each(clustersArray, function(key, cluster){
        var markersClusterArray = cluster.getMarkers();
        /* FOR ALL MARKERS IN THIS CLUSTER */
        $.each(markersClusterArray, function(key, marker){
            /* IF I FIND MY MARKER */
            if(marker.VigneronID === VigneronID){
                /* MARKER IS IN CLUSTER : no need to process all markers */
                found_marker_in_cluster = true;
                /* THEN AGAIN : FOR ALL MARKERS IN THIS CLUSTER */
                var distance_tmp = 0;
                /* FOR ALL MARKERS IN THIS CLUSTER */
                $.each(markersClusterArray, function(key, marker2){
                    /* ALL MARKERS EXCEPT MINE (otherwise distance will always be 0 :-) ) */
                    if(marker.VigneronID !== marker2.VigneronID){
                        /* CALCULATE DISTANCE BETWEEN MY MARKER : http://stackoverflow.com/questions/1502590/calculate-distance-between-two-points-in-google-maps-v3 */
                        distance_tmp = google.maps.geometry.spherical.computeDistanceBetween(marker.getPosition(), marker2.getPosition());
                        /* KEEP MIN DISTANCE */
                        if(distance_tmp < distance && distance_tmp!==0){
                            distance = distance_tmp;
                        }
                    }
                });
                /* NO REASON TO CONTINUE PROCESS : BREAK */
                return false;
            }
        });
    });

    if(found_marker_in_cluster === false){
        var markersClusterArray = mc.getMarkers()
        $.each(markersClusterArray, function(key, marker){
            if(marker.VigneronID === VigneronID){
                var distance_tmp = 0;
                /* FOR ALL MARKERS IN THIS CLUSTER */
                $.each(markersClusterArray, function(key, marker2){
                    /* ALL MARKERS EXCEPT MINE (otherwise distance will always be 0 :-) ) */
                    if(marker.VigneronID !== marker2.VigneronID){
                        /* CALCULATE DISTANCE BETWEEN MY MARKER : http://stackoverflow.com/questions/1502590/calculate-distance-between-two-points-in-google-maps-v3 */
                        distance_tmp = google.maps.geometry.spherical.computeDistanceBetween(marker.getPosition(), marker2.getPosition());
                        /* KEEP MIN DISTANCE */
                        if(distance_tmp < distance && distance_tmp!==0){
                            distance = distance_tmp;
                        }
                    }
                });
            }
        });
    }

    var mapScale = map.getMapScale({}); /* meters / pixels */
    var gridSizePixels = mc.getGridSize(); /* in pixels */
    var gridSizeMeters = gridSizePixels * mapScale;

    if(distance!==1000000000 && distance!==0){
        if(distance < gridSizeMeters){
            var factor = get2Factor(gridSizeMeters, distance);
            map.setZoom(map.getZoom() + factor);
        } else{
            var factor = get2Factor(distance, gridSizeMeters);
            map.setZoom(map.getZoom() - factor + 1);
        }

    }
    /*alert(distance);*/
}

function get2Factor(grid, distance){
    var count = 0;
    while(distance < grid){
        count++;
        grid = grid / 2;        
    }
    return count;
}

Some explanations :

firstly the code is highly commeted so read it

secondly :

  • the first function getMapScale has been found over the internet

  • before I use those functions I need to set my marker an identifier (here : marker.VigneronID) before doing a push in marker cluster

  • I do a fisrt iteration in cluster to find my marker and distance to the closest marker (in meter)

  • If I don't find my marker, it means it's not in a cluster so I do a second iteration over all markers managed by marker cluster and get the distance to the closest marker (in meter)

  • then I calculate gridSize in meter (thanks to the function getMapScale which transforms pixels in meters)

  • knowing that each zoom level is a factor 2 from previous zoom level, I compute the distance between my closest marker and my cluster grid size to know how many zooms levels I can add or substract to the current zoom level

YEAH !

Upvotes: 2

Related Questions