javascript - Google Maps Api v3,使用地点库时的动态缩放级别

标签 javascript jquery google-maps google-maps-api-3

我有一个(相当大的)JSON 对象数组,每个对象都包含一个纬度和一个经度值。当我的 Google map 加载时,我循环遍历该数组并创建一个添加到 map 中的新标记。

除此之外,我还使用了 Google Maps Api v3 Places 插件(在本示例中几乎是开箱即用的:https://developers.google.com/maps/documentation/javascript/examples/places-searchbox)

当我搜索给定地址时,我需要确保至少 N 个标记在 map 上可见。现在,我始终将缩放级别设置为 10。但是,当我搜索法罗群岛(大约有 5 个标记)时,缩放级别太近,用户看不到 5 个标记中的任何一个。

是否有任何方法可以动态设置缩放级别,以便用户至少可以看到 4 或 5 个标记? :-)

我的代码如下:

$(document).ready(function () {
    var map = null;
        var markers = [];
        var overlays = [];

        var infowindow = new google.maps.InfoWindow();

        // Init google map (API v. 3)
        var mapOptions = {
            center: new google.maps.LatLng(56.161, 10.77),
            zoom: 7,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

        var marker, i;

        for (i = 0; i < data.length; i++) {
            // Create a new marker
            marker = new google.maps.Marker({
                position: new google.maps.LatLng(data[i].Latitude, data[i].Longitude),
                map: map,
                title: data[i].Name
            });

            // Add the marker to a global array for filtering
            markers.push(marker);
        }

        // Create the search box and link it to the UI element.
        var input = /** @type {HTMLInputElement} */(
            document.getElementById('pac-input'));
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);

        var searchBox = new google.maps.places.SearchBox(
          /** @type {HTMLInputElement} */(input));

        // [START region_getplaces]
        // Listen for the event fired when the user selects an item from the
        // pick list. Retrieve the matching places for that item.
        google.maps.event.addListener(searchBox, 'places_changed', function () {
            var places = searchBox.getPlaces();

            for (var i = 0, marker; marker = markers[i]; i++) {
                if (markers[i].type == "userMarker") {
                    marker.setMap(null);
                }
            }

            // For each place, get the icon, place name, and location.
            var bounds = new google.maps.LatLngBounds();
                for (var i = 0, place; place = places[i]; i++) {
                var image = {
                    url: place.icon,
                    size: new google.maps.Size(71, 71),
                    origin: new google.maps.Point(0, 0),
                    anchor: new google.maps.Point(17, 34),
                    scaledSize: new google.maps.Size(35, 35)
                };

                // Create a marker for each place.
                var marker = new google.maps.Marker({
                    map: map,
                    icon: image,
                    title: place.name,
                    position: place.geometry.location
                });

                marker.type = "userMarker";
                markers.push(marker);

                bounds.extend(place.geometry.location);                    
            }

            map.fitBounds(bounds);
            map.setZoom(11);
        });
        // [END region_getplaces]

        // Bias the SearchBox results towards places that are within the bounds of the
        // current map's viewport.
        google.maps.event.addListener(map, 'bounds_changed', function () {
            var bounds = map.getBounds();               
            searchBox.setBounds(bounds);
        });
}

提前非常感谢!

最佳答案

这就是我用来确保通过搜索或位置更改等登陆 map 时至少有一个标记可见的方法。它仅确保 View 中存在一个标记以及用户/搜索查询的当前位置(marker_location) )。

我的标记数组称为mapMarkers[],我认为查看您的代码,您需要将其更新为标记。

它当前找到距离 map 中心 (c) 最近的标记,但您可以将其更新为另一个位置。

每当您想要更新时运行 setBounds()。

希望您能够扩展此功能,以确保页面上有您需要的所有标记。每个标记距离都存储在 distances[] 数组中,因此也许可以对其进行数组排序,for 循环并返回标记数组和每个标记的边界。扩展?

function rad(x) {return x*Math.PI/180;}

var c = map.getCenter(),
lat = c.lat(),
lng = c.lng();

center_location = new google.maps.LatLng(lat, lng);

function find_closest_marker() {
    var R = 6371; // radius of earth in km
    var distances = [];
    var closest = -1;
    for( i=0; i<mapMarkers.length; i++ ) {
        var mlat = mapMarkers[i].position.lat();
        var mlng = mapMarkers[i].position.lng();
        var dLat  = rad(mlat - lat);
        var dLong = rad(mlng - lng);
        var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2);
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        var d = R * c;
        distances[i] = d;
        if ( closest == -1 || d < distances[closest] ) {
                closest = i;
        }
    }

    return mapMarkers[closest];
}

function setBounds(){
    var closestMarker = find_closest_marker();

    var bounds = new google.maps.LatLngBounds();
    bounds.extend(closestMarker.position);
    bounds.extend(center_location); 
    map.fitBounds(bounds);
}

关于javascript - Google Maps Api v3,使用地点库时的动态缩放级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20480813/

相关文章:

javascript - 如何在JS中进行REAL对象赋值(浅拷贝)

javascript - 尝试打开底页时收到 "TypeError: undefined is not a function"

javascript - 当我使用 jquery 函数单击时,IE 11 显示错误

jQuery 插件可以实现纽约时报风格的疯狂悬停缩放?

android - Android 应用程序在城市附近的 Activity

javascript - 如何稍后加载网站缓慢的部分?

javascript - SAPUI5:如何将点击事件绑定(bind)到水平布局?

php - 使用 jQuery 自动刷新 Div 从 5 秒到零

Javascript onClick 双击

google-maps - 如何启用和禁用 Google map 中的drawingControlOptions?