在Google地图上使用80,000个标记加快页面速度

时间:2016-04-26 10:02:57

标签: javascript jquery google-maps

我想在谷歌地图上加载80,000个标记,我有函数,setMarkers()和createMarker()。加载需要很长时间。如何加快页面速度?

代码如下:

function initialize() {
    //markers details are coming from json file
    setMarkers(map, markers);
}
function setMarkers(map, locations) {
    //from location object, all the variables get values
    //infobox code
    //loop starts for all markers
    createMarker( arguments );
    //loop end for all markers
}
function createMarker( arguments ) {
    //marker creation code
}

还可以使用谷歌地图购买的API密钥来提高速度吗?

2 个答案:

答案 0 :(得分:4)

以下是谷歌建议的方式(在文章中 Too Many Markers!)优化您的标记:

  1. Grid-based Clustering。基于网格的聚类通过将地图划分为特定大小的方块(每次缩放时大小发生变化),然后将标记分组到每个网格方块中来进行工作。
  2. Distance-based Clustering。基于距离的聚类类似于基于网格的聚类,除了不创建固定方形边界的聚类之外,基于标记与聚类质心之间的距离创建聚类。
  3. Viewport Marker Management。视口标记管理器通过获取用户可见的地图的当前边界来工作,然后 - 基于地图的边界 - 将查询发送到服务器以获取位于边界内的所有标记。当用户平移/缩放地图时,后续请求被发送到服务器以获取新标记。通常会删除不再在视图中的所有标记,以提高地图性能。
  4. Fusion Tables。通过使用JavaScript API中的FusionTablesLayer,可以在地图上显示大量的点。因为渲染是在Google服务器上而不是在您的用户中执行的。浏览器,性能得到了显着提升。
  5. markerCluster(为了我的经验,最好使用Marker Clusterer Plus,因为它具有更少的错误和更好的性能).MarkerClusterer是一个客户端实用程序库,它将基于网格的群集应用于标记集合。它的工作原理是迭代您希望聚类的集合中的标记,并将每个标记添加到最近的集群中(如果它在最小的正方形像素范围内)。
  6. MarkerManager。 MarkerManager允许您更加离散地定义您希望在不同缩放级别显示的标记。 MarkerManager具有比MarkerClusterer更复杂的设置,但它允许更多地自定义显示的内容和位置。
  7. 注意:不要忘记标记有一个优化的选项,但如果你使用GIF动画或PNG则不会是真的,所以如果你使用那种类型的文件,请考虑两次。

答案 1 :(得分:0)

之前我在项目上遇到过类似的问题。

缩放管理

根据用户使用的缩放,我必须显示太多标记。 因此,我必须找到一种方法来限制显示的标记数量,具体取决于所使用的缩放级别。

我使用了markerManager插件(http://google-maps-utility-library-v3.googlecode.com/svn/tags/markermanager/1.0/docs/examples.html)。

function initialize() {
    var mapOptions = {
        scaleControl: true,
        center: new google.maps.LatLng(50, 3),
        zoom: 17,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
    mgr = new MarkerManager(map);
};

然后,当您添加新标记时,您可以使用管理器设置标记可见的最小和最大zoomLevel。 如果不在变焦范围内,则不会显示标记。

function add_marker(lat, lng, zoomMin, zoomMax, img, path, camPos) {
    var marker = new google.maps.Marker({
    position: new google.maps.LatLng(lat, lng),
    icon: "file:///" + path + "/images/" + img + ".png"
    });

    google.maps.event.addListener(marker, 'click', function () {
    form1.jsCamPos = camPos;
    form1.changePosition();
    });

    mgr.addMarker(marker, zoomMin, zoomMax);
}

由于您可以将所有详细标记设置为最大缩放级别并设置更高的缩放级别而不是显示所有标记,请添加一些标记以建议用户放大以查看已详细标记。

这将大大提高您的应用反应性。

标记映射边界过滤

另一种方法是根据地图的边界异步加载标记。

例如,您可以向每次移动地图时触发的bounds_changed事件添加一个侦听器,然后获取新的边界并调用一个webService,它将为您提供新边界内的所有标记。

google.maps.event.addListener(map, 'bounds_changed', function () {
    var lat0 = map.getBounds().getNorthEast().lat();
    var lng0 = map.getBounds().getNorthEast().lng();
    var lat1 = map.getBounds().getSouthWest().lat();
    var lng1 = map.getBounds().getSouthWest().lng();

    var parameters = "{'lat0':'" + lat0 + "','lng0':'" + lng0 + "','lat1':'" + lat1 + "','lng1':'" + lng1 + "'}";

/*
The webService should reply something like this :
[
 {"lat":50.5215,"lng":2.515,"title":"marker1"},
 {"lat":50.5126,"lng":2.5165,"title":"marker2"},
 {"lat":50.5127,"lng":2.54564,"title":"marker3"}
];
*/

    $.ajax({
        type: "POST",
        url: webMethod,
        data: parameters,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            $.each (msg, function (idx) {
                console.log (msg[idx].lat);
                console.log (msg[idx].lng);

                var marker = new google.maps.Marker({
                    position: new google.maps.LatLng(msg[idx].lat, msg[idx].lng),
                    title: msg[idx].title,
                    map:map
                });
            });
        },
        error: function(e){
            alert('error!');
        }
    });
});