2013-09-29 13 views
5

Attualmente sto lavorando alla mia prima uscita reale utilizzando Javascript per creare una mappa interattiva dei dati dei nostri clienti.Dati leaflet.js e JSON: ottimizzazione e prestazioni

Finora ho le basi che funzionano ma la performance inizia a calare quando comincio ad andare sopra a circa 500 poi con marcatori o 10.000 con indicatori di cerchio .... se qualcuno può offrire qualche consiglio su come ottimizzare ciò che hai già o forse è meglio passare a un DB corretto come mongo per i dati JSON o forse il lato server di lavoro con Node Js?

Qualche consiglio sarebbe molto apprezzato :)

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

e alcuni dati di esempio:

{ 
    "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", 

    } 
} 
+0

il collo di bottiglia non è la banca dati per dimostrare che i dati . È un vero szenario mostrare 500 punti in una vista o 10.000 indicatori di cerchio. Oppure la tua domanda indica la ricerca nel database all'interno di un limite definito contenente 10000 indicatori di cerchio? – Bernhard

+0

Le versioni demo attuali hanno un valore basso di circa 500 - 2500 ... la versione finale dovrà essere in grado di mostrare più di 10.000 punti dati alla volta ... Credo che il problema con questo sia dovuto ad esso facendo il rendering sul lato browser in tempo reale? Mi chiedo solo se c'è un altro modo in cui potrei affrontare il problema del ridimensionamento davvero – Guitaraholic

risposta

7

Ci sono un paio di Leaflet plugins che contribuire ad affrontare con il rendering grandi quantità di punti nel browser del cliente.

Il modo più semplice è utilizzare un plug-in che raggruppa i marker come Marker Clusterer. Clusterer aiuta molto il rendering sul lato client poiché significa che il computer client non deve disegnare 10.000 punti, ma solo 10-40.

Si potrebbe anche fare un Heatmap - ci sono due plugin per questo, entrambi basati su HTML5 Canvas:

+3

Stiamo usando il plug-in markercluster, ma i punti devono ancora essere creati. Può richiedere ancora circa 10 secondi su un iPad per ottenere i punti di rendering. – jelle

+0

Penso che la soluzione migliore sia il lato server. Dovresti eseguire il clustering sul server e quindi inviare i punti del cluster come punti singoli al dispositivo per la visualizzazione. In questo modo puoi fare affidamento sulla potenza del server per eseguire l'analisi, invece che su un tablet o un processore del telefono. – Josh