如何知道缩放级别以在google marker群集中显示标记

时间:2014-01-31 18:43:46

标签: google-maps-api-3 zoom markerclusterer

好吧,几乎所有内容都在标题中:

  • 我有数千个带谷歌标记群集的标记(不是google marker cluster plus:让我知道它是否有帮助)
  • 一切都很完美

BUT

  • 当我触发相对于特定标记的事件时,我想单独显示此标记(不再在群集内)。
  • 由于标记的空间重新分区不均匀:在某些地方,缩放级别为9将单独显示,但在另一个地方,我必须将缩放级别设置为15。

SO

  • 最终的问题是:给一个特定的制造商,如何“查询”标记簇知道:
    1. 也许离最近的制造商的距离(假设我应该能够计算相应的缩放级别)
    2. 当时我仍然应该遗漏的任何其他有用信息......

2 个答案:

答案 0 :(得分:2)

我使用过这个解决方案。它检查所选标记是否在群集中。如果是,则增加缩放级别。

 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);

请注意,如果标记位于群组中,则会映射'映射'财产是' null'。

答案 1 :(得分:1)

一些代码;)

/**
 * 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;
}

一些解释:

首先,代码受到高度赞扬,所以阅读它

其次:

  • 第一个函数getMapScale已在互联网上找到

  • 在使用这些功能之前,我需要在标记群集中进行推送之前将标记设置为标识符(此处为:marker.VigneronID)

  • 我在群集中进行了一次fisrt迭代,以找到我的标记和距离最近的标记的距离(以米为单位)

  • 如果我找不到我的标记,则表示它不在群集中,因此我对由标记群集管理的所有标记进行第二次迭代,并获得到最近标记的距离(以米为单位)

  • 然后我以米为单位计算gridSize(感谢函数getMapScale以米为单位转换像素)

  • 知道每个缩放级别是之前缩放级别的因子2,我计算我最近的标记与我的群集网格大小之间的距离,以了解我可以添加或减去当前缩放级别的缩放级别数< / p>

YEAH!