2013-09-29 11 views
5

Obecnie pracuję nad moim pierwszym prawdziwym wyjazdem, używając Javascript do budowy interaktywnej mapy naszych danych klientów.Dane Leaflet.js i JSON: optymalizacja i wydajność

Do tej pory mam podstawy działa, ale wydajność zaczyna spadać, gdy zaczynam wychodzić ponad 500 poi ze znacznikami lub 10 000 z markerami kół ... jeśli ktoś mógłby zaoferować radę, jak zoptymalizować to, co ja już mam, a może najlepiej przenieść do odpowiedniego DB jak mongo dla danych json lub może po stronie serwera pracy z Node Js może?

Wszelkie porady będą mile widziane :)

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

a niektóre przykładowe dane:

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

Twój gardłem nie jest baza danych, aby pokazać, że dane . Czy to prawdziwy szenario, aby pokazać 500pois w jednym widoku lub 10 000 znaczników okręgu. Czy też twoje pytanie oznacza wyszukiwanie w bazie danych wewnątrz zdefiniowanego powiązania zawierającego 10000 markerów koła? – Bernhard

+0

Obecne wersje demonstracyjne mają niskie wartości około 500 - 2500 ... Ostateczna wersja będzie musiała być w stanie wyświetlić 10 000+ i więcej punktów danych jednocześnie ... Uważam, że problem z tym jest spowodowany renderowanie po stronie przeglądarki w czasie rzeczywistym? Zastanawiam się, czy istnieje inny sposób, w jaki mogę rozwiązać problem skalowania. – Guitaraholic

Odpowiedz

7

Istnieje kilka Leaflet plugins, które pomagają radzić sobie z renderowania duża ilość punktów w przeglądarce klienta.

Najprostszym sposobem jest użycie wtyczki, która grupuje markery, takie jak Marker Clusterer. Clusterer pomaga w renderowaniu po stronie klienta, ponieważ oznacza to, że komputer kliencki nie musi pobierać 10 000 punktów, a jedynie 10-40.

Można również zrobić termiczna - Istnieją dwie wtyczki za to zarówno w oparciu o HTML5 Canvas:

+3

Używamy wtyczki Markcluster, ale wciąż musimy stworzyć punkty. Wciąż może zająć około 10 sekund na iPadzie, aby uzyskać punkty. – jelle

+0

Myślę, że najlepiej wtedy, gdy jesteś po stronie serwera. Zrobiłbyś klastrowanie na serwerze, a następnie wysłałeś punkty klastra jako pojedyncze punkty do urządzenia do wyświetlenia. W ten sposób możesz polegać na sile serwera do przeprowadzenia analizy zamiast na procesorze tabletu lub telefonu. – Josh