2013-09-29 3 views
5

Ich arbeite gerade an meinem ersten echten Ausflug mit Javascript, um eine interaktive Karte unserer Kundendaten zu erstellen.Leaflet.js- und JSON-Daten: Optimierung und Leistung

Bisher habe ich die Grundlagen funktionieren, aber die Leistung beginnt zu fallen, wenn ich über 500 Poi mit Markern oder 10.000 mit Kreismarker gehen .... wenn jemand Ratschläge geben könnte, wie ich was optimieren kann habe schon oder vielleicht bin ich am besten zu einer richtigen DB wie Mongo für die JSON-Daten oder die Arbeit Server-Seite mit Node Js vielleicht?

würde Ratschläge sehr geschätzt :)

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

und einige Beispieldaten:

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

Ihr Engpass ist nicht die Datenbank, die Daten zu zeigen, . Ist es ein echtes Szenario, 500pis in einer Ansicht oder 10.000 Kreismarker zu zeigen? Oder bedeutet Ihre Frage die Suche in der Datenbank innerhalb einer definierten Grenze mit 10000 Kreismarkierungen? – Bernhard

+0

Die aktuellen Demo-Versionen haben niedrige Werte von etwa 500 - 2500 ... die endgültige Version muss in der Lage sein, mehr als 10.000 und mehr Datenpunkte gleichzeitig anzuzeigen ... Ich glaube, das Problem ist damit zu erklären das Rendering auf der Browserseite in Echtzeit durchführen? Ich frage mich nur, ob es eine andere Möglichkeit gibt, wie ich das Skalierungsproblem lösen könnte. – Guitaraholic

Antwort

7

Es gibt ein paar Leaflet plugins, die mit Rendering beschäftigen helfen große Anzahl von Punkten im Browser des Kunden.

Der einfachste Weg ist die Verwendung eines Plugins, das die Marker wie Marker Clusterer anhäuft. Clusterer hilft beim Rendering auf der Client-Seite, da der Client-Computer nicht 10.000 Punkte ziehen muss, sondern nur 10-40.

Sie auch eine Heatmap tun könnte - es gibt zwei Plugins für das, beide basierend auf HTML5 Canvas:

+3

Wir benutzen das markercluster-Plugin, aber trotzdem müssen die Punkte erstellt werden. Es kann immer noch etwa 10 Sekunden auf einem iPad dauern, bis die Punkte gerendert sind. – jelle

+0

Ich denke, deine beste Wette ist dann Server-Seite. Sie würden das Clustering auf dem Server durchführen und dann die Clusterpunkte als einzelne Punkte an das Gerät zur Anzeige senden. Auf diese Weise können Sie sich anstelle eines Tablet- oder Telefonprozessors auf die Leistung des Servers für die Analyse verlassen. – Josh