2016-04-15 7 views
6

Próbuję stworzyć wizualizację mapy oparte który zawiera „mapę cieplną” z subpopulacji, w oparciu o zbiór MongoDB, który zawiera dokumenty takie jak ten:MongoDB: Dokumenty klastra według lokalizacji geograficznej, danego obszaru i maksymalnych punktów?

{ 
    "PlaceName" : "Boston", 
    "Location" : { 
     "type" : "Point", 
     "coordinates" : [ 42.358056, -71.063611 ] 
    }, 
    "Subpopulations": { 
     "Age": { 
       "0_4" : 37122, 
       "6_11" : 33167, 
       "12_17" : 35464, 
       "18_24" : 130885, 
       "25_34" : 127058, 
       "34_44" : 79092, 
       "45_54" : 72076, 
       "55_64" : 59766, 
       "65_74" : 33997, 
       "75_84" : 20219, 
       "85_" : 9057 
     } 
    } 
} 

Istnieją setki tysięcy pojedynczych miejsc w baza danych. Nie nakładają się one na siebie - tzn. Nie byłoby dwóch pojedynczych wpisów dla "Nowego Jorku" i "Manhattanu".

Celem jest użycie pliku Leaflet.js i niektórych wtyczek do renderowania różnych wizualizacji tych danych. Ulotka jest całkiem dobra w klastrze danych po stronie klienta - więc jeśli przekażę mu tysiąc lokalizacji z wartościami gęstości, może wygenerować mapę cieplną odpowiedniego obszaru, po prostu przez zgniatanie wszystkich indywidualnych wartości.

Problem polega na tym, że pomniejszam mapę, aby pokazać cały świat. Byłoby strasznie nieefektywne, jeśli nie niemożliwe, aby przesłać wszystkie te dane do klienta i zlecić przetworzenie tych informacji wystarczająco szybko, aby uzyskać płynną wizualizację.

Co należy zrobić, to automatycznie zgrupować serwer danych, co, jak mam nadzieję, może zostać wykonane w zapytaniu MongoDB. Czytałem, że geohashing może być dobrym punktem wyjścia do ustalenia, które punkty należą do klastra, ale jestem pewien, że ktoś zrobił to dokładnie i może mieć lepszy wgląd niż to. Idealnie chciałabym wysłać off zapytanie do mojego node.js skrypt, który wygląda tak:

http://myserver.com/popdata?top=42.48&left=-80.57&bottom=37.42&right=-62.55&stat=Age&value=6_11 

który określałby jak granulowany potrzebuje grupowanie się opierać na ile poszczególne punkty są w tym określonym obszarze geograficznym , biorąc pod uwagę maksymalną liczbę punktów danych do zwrócenia lub coś podobnego; i byłoby zwrócić dane tak:

[ 
    { "clusterlocation": [ 42.304, -72.622 ], "total_age_6_11": 59042 }, 
    { "clusterlocation": [ 36.255, -64.124 ], "total_age_6_11": 7941 }, 
    { "clusterlocation": [ 40.425, -70.693 ], "total_age_6_11": 90257 }, 
    { "clusterlocation": [ 39.773, -67.992 ], "total_age_6_11": 102752 }, 
    ... 
] 

... gdzie „clusterlocation” jest coś takiego jak średnia z wszystkich lokalizacjach dokumentów w klastrze, a „total_age_6_11” jest sumą wartości tych dokumentów dla "Subpopulations.Age.6_11".

Czy mogę to zrobić wyłącznie w zapytaniu Mongo? Czy istnieje "wypróbowany i przetestowany" sposób na zrobienie tego dobrze?

+1

To byłoby trudne na tak surowe dane bez jakiejś wcześniej przydzielonej koncepcji "klastrowania" przez dodatkowe "attrbuty" lub po prostu wstępne agregowanie do innych danych gromadzenia danych ziarnistych do "poziomu powiększenia". Podstawową kwestią, jaką widzę w przypadku pojedynczego przetwarzania zapytań, jest to, że chociaż można użyć '$ geoNear' do określenia bliskości do centralnego punktu (powiedzmy środek wyboru obszaru), to" dałoby "odległość od tego punktu do" klastra " "on, jednak nie wyjaśnia punktu bliskości do siebie. W związku z tym trzeba zasadniczo "iterować" dane punktu, aby znaleźć najbliższy każdemu. –

+1

TLDR powyższego jest, * "bez wstępnie obliczonego przypisania klastra, to nie jest bardzo wydajne" *. –

Odpowiedz

4

Nawet jeśli wykonasz te zapytania w środowisku wykonawczym, będzie to niewydajne i nieszybkie, aby można je było uznać za dobry interfejs użytkownika. Proponuję wygenerować klastry o określonych rozmiarach i przechowywać je w bieżącej kolekcji wraz z oryginalnymi dokumentami. Oto jak:

  • Każdy dokument będzie przechowywać dodatkowe pole (pozwala wywołać geolevel), co oznaczać będzie, jak małe lub duże jednostka jest. Dokumenty bazowe będą miały geolevel = 1:

    { 
        "PlaceName" : "Boston", 
        "Location" : { 
         "type" : "Point", 
         "coordinates" : [ 42.358056, -71.063611 ] 
        }, 
        "Subpopulations": { 
         "Age": { 
           "0_4" : 37122, 
           "6_11" : 33167, 
           "12_17" : 35464, 
           "18_24" : 130885, 
           "25_34" : 127058, 
           "34_44" : 79092, 
           "45_54" : 72076, 
           "55_64" : 59766, 
           "65_74" : 33997, 
           "75_84" : 20219, 
           "85_" : 9057 
         } 
        }, 
        "geolevel":1 // added geolevel 
    } 
    
    • można uruchamiać na przetwarzanie danych sprzed generować podobne dokumenty dotyczące klastrów, a na wielu poziomach. np. geolevel: 2 będzie klastrem kilku miast w promieniu 250 km, geolevel: 3 będzie skupiskiem geolitu: 2 klastry.

    • Można również przechowywać pole takie jak memberids, aby przechowywać identyfikatory dzieci w dla każdego klastra.Może to być konieczne, aby uniknąć przechodzenia jednostek do dwóch sąsiednich klastrów, można je przypisać do jednego z sąsiednich klastrów, a twoja wizualizacja nadal będzie działała dobrze. geolevel: 2 klaster doc wyglądałby następująco:

      { 
          "PlaceName" : "cluster_sdfs34535", // The id can be generated from hash like sha of a list of all children ids. 
          "Location" : { // center of the cluster 
           "type" : "Point", 
           "coordinates" : [ 42.358056, -71.063611 ] 
          }, 
          "Subpopulations": { // total population of the cluster 
           "Age": { 
             "0_4" : 371220, 
             "6_11" : 331670, 
             "12_17" : 354640, 
             "18_24" : 1308850, 
             "25_34" : 1270580, 
             "34_44" : 790920, 
             "45_54" : 720760, 
             "55_64" : 597660, 
             "65_74" : 339970, 
             "75_84" : 202190, 
             "85_" : 90570 
           } 
          }, 
          "geolevel":2 , 
          "childs":[4,5,6,7] // ids of child documents 
      } 
      
    • Teraz aplikacja wizualizacji musi wykonać mapowanie zoomlevel do geolevel, i na tej podstawie można wybrać swoje dokumenty. Do wizualizacji poziomu miasto, można zapytać o geolevel: 1 dokumentów, a jak pomniejszyć do stanu, kraju itp można zwiększyć do 2,3 geolevel ...
+0

Bardzo podoba mi się podejście polegające na budowaniu hierarchii w ten sposób. Wydaje się, że dość prostym zadaniem jest zbudowanie mechanizmu generowania tych dokumentów. Bardzo doceniane. – DanM

Powiązane problemy