Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaflet.js and JSON data : optimization and performance

I'm currently working on my first real outing using Javascript to build an interactive map of our customer data .

So Far I've got the basics working but the performance starts to drop when I start going above around 500 poi's with markers or 10,000 with circle markers.... if anyone could offer some advise on how to optimize what I've already got or maybe am i best to move to a proper DB like mongo for the json data or do the work server side with Node Js maybe?

Any advice would be much appreciated :)

    var apiKey  = 'BC9A493B41014CAABB98F0471D759707',
          styleID = '108219';
    //    styleID = '997';


   // var map = L.map('map').setView([54.550, -4.433], 7);

      var southWest   = new L.LatLng(61.029031, 4.746094),
            northEast   = new L.LatLng(48.786962 ,-13.183594),
            bounds      = new L.LatLngBounds(southWest, northEast);

        var mapcenter      = new L.LatLng(53.457393,-2.900391);
        var map         = new L.Map('map',
                                {
                                    center: mapcenter,
                                    zoom: 7,
                                    // maxBounds: bounds,
                                    zoomControl: false
                                });

        var cloudmadeUrl = generateTileURL(apiKey, styleID),
            attribution = 'Map data © OpenStreetMap contributors.',
            tileLayer = new L.TileLayer(
                                cloudmadeUrl,
                                {
                                    maxZoom: 18,
                                    attribution: attribution,
                                });

            tileLayer.addTo(map);

        var zoomControl     = new L.Control.Zoom({ position: 'topleft'} );
            zoomControl.addTo(map);
        var scaleControl    = new L.Control.Scale({ position: 'bottomleft' });
            scaleControl.addTo(map);




      geojsonLayer = L.geoJson(geojson, {
          pointToLayer: function(feature, latlng) {
            return new L.CircleMarker(latlng, {fillColor: feature.properties.MarkerColour, fillOpacity: 0.5, stroke: false, radius: 6});
          // return new L.Marker(latlng, {icon: L.AwesomeMarkers.icon({icon: feature.properties.MarkerIcon, color: feature.properties.MarkerColour, iconColor: 'white'}) });
          },
        onEachFeature: function (feature, layer) {
            layer.bindPopup( '<strong><b>Customer Data</b></strong><br />' + '<b>Result : </b>' + feature.properties.Result + '<br />' + '<b>Postcode : </b>' + feature.properties.Postcode + '<br />' );
          }
      });

            console.log('starting: ' + window.performance.now());

      map.addLayer(geojsonLayer);

            console.log('ending: ' + window.performance.now());




    function generateTileURL(apiKey, styleID) {
        return 'http://{s}.tile.cloudmade.com/' + apiKey + '/' + styleID + '/256/{z}/{x}/{y}.png';
    }

and some sample data :

{
    "type": "Feature",
    "geometry": {
        "type": "Point",
         "coordinates": [
            -0.213467,
            51.494815
         ]
    },
    "properties": {
        "DateTime": "1372719435.39",
        "Result": "Cable Serviceable",
        "MarkerIcon": "ok-sign",
        "MarkerColour": "green",
        "Postcode": "W14 8UD"    
    }
},
{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [
            -0.389445,
            51.512121
        ]
    },
    "properties": {
        "DateTime": "1372719402.083",
        "Result": "Refer for National Serviceability",
        "MarkerIcon": "minus-sign",
        "MarkerColour": "red",
        "Postcode": "UB1 1NJ",

    }
 },
 {
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [
            -0.411291,
            51.508012
        ]
    },
        "properties": {
        "DateTime": "1372719375.725",
        "Result": "Cable Serviceable",
        "MarkerIcon": "ok-sign",
        "MarkerColour": "green",
        "Postcode": "UB3 3JJ" 
     }
},
{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [
            -2.11054,
            53.500752
        ]
     },
    "properties": {
        "DateTime": "1372719299.088",
         "Result": "Cable Serviceable",
         "MarkerIcon": "ok-sign",
         "MarkerColour": "green",
         "Postcode": "OL7 9LR",

     }
 }
like image 740
Guitaraholic Avatar asked Sep 29 '13 11:09

Guitaraholic


1 Answers

There are a couple of Leaflet plugins that help deal with rendering large amounts of points in the client's browser.

The simplest way is to use a plugin that clusters the markers such as Marker Clusterer. Clusterer helps the rendering on the client side greatly as it means the client computer doesn't have to draw 10,000 points, it just draws 10-40.

You could also do a Heatmap - there are two plugins for that, both based on HTML5 Canvas:

  • HeatCanvas
  • Heatmap.js
like image 145
Josh Avatar answered Nov 07 '22 13:11

Josh