Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

100k or more markers on google maps without clustering

I have some data which is collect though a GPS device installed in a car. So the data I have is basically lying on/around the street/road. Every coordinates have some value. The format of the data is something like this.

lat         | long        | value
---------------------------------
12.979155   | 77.644925   | 6 
---------------------------------
12.97916833 | 77.64493667 | 2
---------------------------------
12.97917167 | 77.64492167 | 8 

My task here is to plot these lat-long on google map. It seems to be quite easy task when we talk about placing 10, 100 or 1000 markers. But as I have mentioned above we are collecting the data by drive and the distance between a two lat-long or two points will be in few feets(say 2-3 feet).

So at the end of the survey, I'll be having 90-100k lat-long for a small part of a city and might go up to one million for whole city.

I have tried adding 9-10k marker and its woking fine but when I am trying to load 40k, 50k, 60k it is making my browser very slow and this is the error message I am ending with.

Uncaught RangeError: Maximum call stack size exceeded      main.js:1

I have been googling a lot about it, but I m not able to find any example or tutorial which will lead me to place 1 million marker by using technologies I know a bit.(which is asp.net). Found this example http://www.scribblemaps.com/markerComplex/ By Jonathan Wagner, but I m not able to understand it and implement it in my existing code which goes like this.

//To fetch lat-long from the MSSQL server.

function PushValues(ParameterID) {
         a = ParameterID.slice(5);
    var CityID = $('#ddlCity').val().split('|');
    $.ajax({
        type: "POST",
        url: "index.aspx/PushLatLong",
        data: "{CityID:'" + CityID[0] + "',OperatorID:'" + $('#ddlOperator').val() + "',ParameterID:'" + ParameterID.slice(4) + "'}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        async: false,
        cache: false,
        success: function (response) {
            GooglePlaces = response.d.split('#');
            if (GooglePlaces != "Blank") {
                HasValues = 1;
            } else {
                HasValues = 0;
            }

        },
        Error: function (r) {

        }
    });
}

// Places values in google map.

function PlaceValues() {
    var options = { zoom: 3, center: new google.maps.LatLng(37.09, -95.71), mapTypeId: google.maps.MapTypeId.ROADMAP };
    var map = new google.maps.Map(document.getElementById('map'), options);
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < GooglePlaces.length; i = i + 2) {
        ltlg = new google.maps.LatLng(GooglePlaces[i], GooglePlaces[i + 1]);
        var marker = new google.maps.Marker({
            position: ltlg,
            map: map,
            title: 'Place number',
            icon: "img/GoogleIcons/" + legendfirstvalue[1]
        });
        bounds.extend(ltlg);
    }
    map.fitBounds(bounds)
    $('#DivLoadImage').hide();
}

One more thing i would like to mention here is that the color of marker depend on the value of lat-long. So i'll be having multiple color markers. I have could have easily try clustring the marker but, then I wont be able to see the marker color until i zoon in to the area. So there is no way i can use clustring.

I am sure there will be million errors in my code. I m willing to change my approach if needed. Here is the demo of the application.

like image 804
Jas Avatar asked Nov 13 '22 09:11

Jas


1 Answers

Closest you can get (without clustering) is to use fusion tables to store data and retrieve it from there - which is probably something similar your example is using already - and since its flash it can render them much faster than normal api can accomplish.

Fusion tables itself will render markers at server side to tiles and retrieves those.

The Google Maps API allows you to render data contained in Google Fusion Tables as a layer on a map using the FusionTablesLayer object.

Example about it in this link.

Together with fusiontables I would do something like viewport based rendering which basically means drawing only markers visible to viewport - not really "clustering technique" but very useful when we are considering speed of rendering. Read more about them google docs (fusiontables) and viewport marker management. Same page also contais more detailed link to Fusiontables api and tutorials.

If you eventually decide to cluster at server side - be prepared that its not an easy task - but if you do, implement something similar to grid based clustering. (Also explained withing the same page - damn good links?)

Also to be noted that:

Only the first 100,000 rows of data in a table are mapped or included in query results.

To read more, see from here.

Cheers.

like image 116
Mauno Vähä Avatar answered Nov 15 '22 13:11

Mauno Vähä