Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Speed up the page with 80,000 markers on google map [closed]

I want to load 80,000 markers on google map, I have functions, setMarkers() and createMarker(). It is taking very long time to load. How can I speed the page?

code is below:

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
}

Also is it possible to increase speed using google map purchased API key?

like image 857
Eleena Avatar asked Apr 26 '16 10:04

Eleena


2 Answers

Here are some ways to optimize your markers:

  1. Grid-based Clustering. Grid-based clustering works by dividing the map into squares of a certain size (the size changes at each zoom) and then grouping the markers into each grid square.
  2. Distance-based Clustering. Distance-based clustering is similar to grid-based clustering, except instead of creating clusters of fixed square bounds, clusters are created based on the distance between the marker and a cluster centroid.
  3. Viewport Marker Management. A viewport marker manager works by getting the current bounds of the map that is visible to the user, then — based on the map's bounds — a query is sent to the server to get all the markers that lie within the bounds. As the user pans/zooms the map subsequent requests are sent to the server to get the new markers. All markers that are no longer in view are generally removed to improve map performance.
  4. Fusion Tables. By using FusionTablesLayer from the JavaScript API, a large number of points can be displayed on the map. Because rendering is performed on Google servers rather than within your users' browsers, performance is improved dramatically.
  5. markerCluster.The MarkerClusterer is a client side utility library that applies grid-based clustering to a collection of markers. It works by iterating though the markers in the collection that you wish to cluster and adding each one into the closest cluster if it is within in a minimum square pixel bounds.
  6. MarkerManager. The MarkerManager allows you to more discretely define what markers you want visible at different zoom levels. The MarkerManager has a more involved setup than the MarkerClusterer, but it does allow for more customization of what and where it displays.

Note: Don't forget that markers have an option optimized, but will not be true if you use animated gifs or PNG, so if you use that type of file think about it twice.

like image 87
Thomas Karachristos Avatar answered Oct 19 '22 20:10

Thomas Karachristos


I had a similar problem on a project before.

Zoom management

Depending on the zoom used by the user I had to show way too much markers. So I had to find a way to limit the numbers of markers displayed depending on the zoom level that was used.

I used the markerManager plugin (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);
};

Then when you add a new marker you use the manager to set a minimum and maximum zoomLevel where the marker is visible. The marker won't be displayed if not in the zoom range.

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

Thanks to that you can set all your detailled marker at the max zoom level and for higher zoom levels instead of displaying all the markers add some more marker to suggest your user to zoom in in order to see the detailled markers.

This will greatly improve your application reactivity.

Markers map bounds filtering

Another way to do would be to load asynchronously the markers depending on the bounds of the map.

You can for example add a listener to the bounds_changed event which is fired each time the map is moved, then you get the new bounds and call a webService which will give you all the markers inside the new bounds.

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!');
        }
    });
});
like image 3
Nicolas Avatar answered Oct 19 '22 21:10

Nicolas