Google Maps JS API V3多个标记呈现

时间:2016-06-20 04:58:24

标签: javascript angularjs google-maps google-maps-api-3 google-maps-markers

我坚持在谷歌地图上加载2000个标记的性能问题。这个问题概述可以在很多地方找到,但仍然无法为我找出问题所在。

所以,问题简而言之:谷歌地图初始化挂起浏览器10-20秒。

环境:

  • 来自后端的标记数据在单个get请求中收到。在0.3秒内装载
  • 使用Marker Clusterer(https://googlemaps.github.io/js-marker-clusterer/docs/examples.html)库。 但是,无论有没有,浏览器仍然挂在同一时间。
  • 标记很丰富。与自定义图片,infowindows和事件。
  • InfoWindows正在设置为AngularJS指令

标记设置代码:

function showMarkers(scope,data) {
    var locations = data;
    console.log("Starting markers setup: ", new Date());
    for(var i = 0; i < locations.length; i++) {

        var MarkerImage = '/img/reasestate.png';
        markers[i] = new google.maps.Marker({
            position: {lat:locations[i].latitude, lng:locations[i].longtitude},
            map: map,
            id: locations[i].id,
            icon: MarkerImage
        });


        var infowindow = new google.maps.InfoWindow();
        var contentString = '<infowindow></infowindow>';
        var compiled = $compile(contentString)(scope);

        google.maps.event.addListener(markers[i], 'click', (function(i, scope) {
            return function(){
                scope.placeInfo = null;

                //for search around
                scope.condo_LatLng = new google.maps.LatLng(locations[i].latitude,locations[i].longtitude);

                //update scope
                scope.$apply();

                //////////////////
                ///INFOWINDOW SETUP
                ///////////////////
                //you can change url to your url . '/maps/api/getcondo?CondoID='+scope.place.id'
                $http.get('/maps/api/condo/items?CondoID='+locations[i].id).then(function(success) {
                    //a bit of additional received data processing, not important.
                }, function(error) {
                }).finally(function() {})
            };
        })(i, scope, locations[i]));
    }
    setClustering(markers);
    console.log("Finished markers setup: ", new Date());

    /////////////
    ///context menu
    ////////////
    var menuStyle = {
        menu: 'context_menu'
        //menuSeparator: 'context_menu_separator',
        //menuItem: 'context_menu_item'
    };

    var contextMenuOptions  = {
        classNames: menuStyle,
        menuItems: [
            { label:'Add your condo...', id:'menu_option1',
                className: 'menu_item', eventName:'option1_clicked' },
            { label:'Exit', id:'menu_option2',
                className: 'menu_item', eventName:'option2_clicked' }
        ],
        pixelOffset: new google.maps.Point(10, -5),
        zIndex: 5
    };

    var contextMenu = new ContextMenu(map, contextMenuOptions);
    google.maps.event.addListener(contextMenu, 'menu_item_selected',
        function(latLng, eventName, source){
            switch(eventName){
                case 'option1_clicked':
                    createDraggableMarker(latLng);
                    break;
                case 'option2_clicked':
                    // do something else
                    break;
                default: break;
            }
        });

    google.maps.event.addListener(map, 'rightclick', function(mouseEvent) {
        contextMenu.show(mouseEvent.latLng, map);
    });
}

function setClustering(markers){
    var mcOptions = {gridSize: 150};
    mc = new MarkerClusterer(map,markers, mcOptions);
}

在console.out上获取此内容:

Starting markers setup:  Sun Jun 19 2016 16:43:57 
jsAllMain.js:240 Finished markers setup:  Sun Jun 19 2016 16:43:57
jsAllMain.js:256 Show markers method done at:  Sun Jun 19 2016 16:43:57
jsAllMain.js:256 Initialize searchmap done at:  Sun Jun 19 2016 16:43:57

但是在我在console.out中得到这个之后,浏览器会再挂10-20秒,直到它显示带有标记的地图。

UPDATE:问题在于AngularJS绑定处理(infowindow指令)。知道怎么处理吗?

2 个答案:

答案 0 :(得分:1)

解决方案:将AngularJS指令初始化放在click事件侦听器中。

    google.maps.event.addListener(markers[i], 'click', (function(i, scope) {
        return function(){
            var infowindow = new google.maps.InfoWindow();
            var contentString = '<infowindow></infowindow>';
            var compiled = $compile(contentString)(scope);

            scope.placeInfo = null;

            //for search around
            scope.condo_LatLng = new google.maps.LatLng(locations[i].latitude,locations[i].longtitude);

            //update scope
            scope.$apply();

            //////////////////
            ///INFOWINDOW SETUP
            ///////////////////
            //you can change url to your url . '/maps/api/getcondo?CondoID='+scope.place.id'
            $http.get('/maps/api/condo/items?CondoID='+locations[i].id).then(function(success) {


                //setup infowindow
                infowindow.close();
                infowindow = new google.maps.InfoWindow({
                    id: markers[i].id,
                    content:compiled[0],
                    position:new google.maps.LatLng(locations[i][1],locations[i][2])
                });

                //infowindow.setContent(compiled[0]);
                infowindow.open(map, markers[i]);

            }, function(error) {
            }).finally(function() {})
        };
    })(i, scope, locations[i]));

答案 1 :(得分:1)

我还没有使用Angular,所以我无法帮助你。但作为一般规则,我建议您花一些时间在服务器端进行群集,然后不惜一切代价加载您提到的所有丰富环境,尽可能充分利用它们,仅在用户请求时可用。这需要一些工作,但如果你的应用程序有计划增加其标记人口,将在以后欣赏它。在聚类算法的情况下,我发现这个StackOverflow参考希望它可以帮助你 Server-side clustering for google maps api v3