Alternatywy OpenLayers obsługujące więcej funkcji po stronie klienta [zamknięte]

14

Rozważam różne architektury systemu, który idealnie wykorzystuje renderowanie po stronie klienta dla funkcji punktowych i musi być wolny od wtyczek. Korzystam z tej aplikacji opracowanej w odpowiedzi na to pytanie, aby przetestować mój laptop (który jest całkiem zdolny - czterordzeniowy procesor 2,6 GHz, pamięć 4 GB, nie pod żadnym innym obciążeniem, Firefox 8) z różną liczbą punktów w OpenLayers i zauważalnie pozostaje w tyle na poziomie 500 i zaczyna walczyć o ponad 1000. Losowo generowane funkcje nie wydają się mieć żadnych procedur obsługi zdarzeń i wszystkie używają tej samej symboliki.

Oczekuję, że pokażę do 1000 funkcji, z maksymalnie 10 różnymi symbolami, wszystkie z uchwytami do klikania i najechania myszką oraz na mniej wydajnych platformach.

Miałem nadzieję na lepszą wydajność po stronie klienta, zwłaszcza po zapoznaniu się z przykładem GIS Cloud - wiem, że działa inaczej (płótno HTML5 vs. SVG), ale różnica w wydajności jest naprawdę uderzająca.

Moje kluczowe pytania (jeśli byłbyś tak miły) to:

  1. Czy aplikacja generująca punkty losowe reprezentuje wydajność w innych aplikacjach OpenLayers, które napisałeś / wykorzystałeś?
  2. Czy istnieje sprawdzony i bezpłatny alternatywny interfejs API do mapowania stron internetowych, który obsługuje usługi WMS (z których muszę korzystać) i jest szybszy dzięki funkcjom po stronie klienta, bez użycia Flash / Silverlight / jakichkolwiek innych wtyczek?
  3. Wszelkie inne sugestie dotyczące tego, co powinienem badać?

Opieranie się przede wszystkim na renderowaniu po stronie serwera jest opcją, ale zarówno ja, jak i klient chcielibyśmy tego uniknąć ze względu na obawy związane ze zwiększeniem liczby użytkowników i szybkości reakcji interfejsu użytkownika.

tomfumb
źródło
Na moim 5-letnim dwurdzeniowym pulpicie RAM o pojemności 3 GB, korzystającym z tej aplikacji w Firefoksie 8 (podczas pobierania ISO dystrybucji Linux 1 GB), 1000 punktów rysuje się niemal natychmiast, bez problemów ... 10 000 zajmuje około 1,5 sekundy.
user2856
@LukePinner to szybkie rysowanie * i płynne przesuwanie / powiększanie? Pobieranie danych i rysowanie funkcji również jest dla mnie w porządku, ale problem stanowi interakcja z mapą.
tomfumb
Właśnie wypróbowałem twoją aplikację na moim iPadzie i poradziła sobie bardzo dobrze z 1000 punktami. Przy 10 000 punktów początkowo renderowanie zajmuje kilka sekund, ale potem radzi sobie całkiem nieźle. Jeśli chcesz, zawsze możesz podklasować klasę warstw OL Vector i zaimplementować niestandardową. Mogę wskazać ci jeden przykład.
unicoletti
Tak, nie ma problemów z panoramowaniem / powiększaniem. Punkty 1K spowalniają jednak trochę na moim netbooku Atom 1.6 GHz :)
user2856

Odpowiedzi:

23

Odpowiedź na pierwsze pytanie brzmi: tak . Używasz OL z dość powszechną konfiguracją. Są sztuczki, których możesz użyć, aby poprawić wydajność, przejdę do tego później.

Odpowiedź na pytanie 2 może być (szczególnie jeśli chodzi o szybkość). Możesz przeszukać tę stronę, aby znaleźć listę alternatyw (ta, która przychodzi Ci teraz na myśl, to Ulotka ).

Odpowiedź na pytanie 3: zacznij od pomiaru:

Zredagowałem lokalną kopię aplikacji, tak aby renderer został wyraźnie określony na liście opcji dla warstwy Vector. Podczas testów pominąłem renderer Canvas, a następnie ponownie załadowałem stronę eksperymentu z innym:

var pts = new OpenLayers.Layer.Vector("Points", {renderers: ["Canvas", "SVG", "VML"]});

Dodałem licznik do funkcji przerysowania, aby wydrukował ile czasu spędził na rysowaniu :

function redraw() {
var start = (new Date).getTime();
[...]
var diff = (new Date).getTime() - start;
console.log("redraw completed in "+diff+"ms");

Potem wypróbowałem kilka uruchomień zarówno w Chrome 17, jak i Firefox 8.0.1 na OSX SL, rysując funkcje 1000 i 5000. Ku mojemu zdziwieniu renderer SVG jest średnio o 20% szybszy niż renderer Canvas! (Uwaga: w systemie Windows czas js nie jest tak dokładny jak w OSX, więc wyniki mogą być mniej spójne).

To i twoje opowiadanie

problem stanowi interakcja z mapą

, IMHO, informuje nas, że punkt aktywny znajduje się w obsłudze funkcji Vector. Pracując nad moją aplikacją, niedawno ją obejrzałem i postanowiłem podklasować ją, a następnie pozbyć się całego skomplikowanego kodu, który nie nadaje się na proste punkty. Trzeba przyznać, że zwariowałem i nawet usunąłem zależność od OpenLayers.Geometry.Point, a moja wersja działa teraz na prostych obiektach js z atrybutami x, y.

Dostępne są następujące opcje w kolejności korzyści / kosztów:

Pierwszą opcją jest filtrowanie widocznych punktów po stronie serwera poprzez skonfigurowanie opcji strategii do warstwy wektorowej w następujący sposób:

 strategies: [new OpenLayers.Strategy.Refresh({force:true}), new OpenLayers.Strategy.BBOX({ratio:2, resFactor: 3})],

W ten sposób powiększenie liczby rysowanych elementów po stronie klienta będzie ograniczone do widocznych w tym zakresie, a nie wszystkich.

Jako drugą opcję możesz rozważyć napisanie dostosowanego Vector / Renderer . Przykład niestandardowej, uproszczonej i szybszej implementacji jest dostępny na mojej stronie github tutaj . Chociaż nie nadaje się do wszystkich zastosowań, powinno wystarczyć, aby z grubsza zorientować się, co sugeruję.

Trzecią opcją, gdy użytkownik jest całkowicie pomniejszony, jest zaimplementowanie pewnego rodzaju klastrowania funkcji po stronie serwera, tak aby punkty bliskie były scalane w jeden, ponownie zmniejszając liczbę rysowanych elementów.

unicoletti
źródło
Wielkie dzięki za szczegółową i dokładną odpowiedź. Najprawdopodobniej przyjrzę się klastrowaniu po stronie serwera, mam nadzieję, że w połączeniu ze strategią buforowania, aby operacja była wykonywana tylko w razie potrzeby. Jedną z opcji po stronie serwera jest MapGuide, więc podejście do pobierania i grupowania punktów może być całkowicie niestandardowe. Będę też miał okazję zapoznać się z opcjami renderera, aby zobaczyć, jaką to robi różnicę.
tomfumb
1
Dodałem link do przykładowego renderera wektor / płótno, którego używam w moim zestawie.
unicoletti
Wow, uproszczony przykład robi ogromną różnicę, to naprawdę imponujące. Przeszedłem od zmagania się z tysiącem funkcji do latania z 10.000
tomfumb
Zmodyfikowałem pierwszy przykład (swingley.appspot.com), aby użyć renderera OL Canvas i solidnego wypełnienia punktów, a skuteczność powiększania i przesuwania jest w rzeczywistości bardzo podobna do TagCanvas & TagVector. Ponownie wdrożyłem funkcjonalność testu trafienia, którą usunąłeś w swoich modyfikacjach, aby móc przetestować wydajność porównawczą - podejście Tag * było o około 20% szybsze w identyfikacji, która funkcja została trafiona (spośród 5000). Biorąc pod uwagę znaczny wysiłek w pisaniu / aktualizowaniu klas niestandardowych i podobną wydajność (w moich testach), myślę, że zobaczę, co może zrobić waniliowy OL
tomfumb
Wynika to z faktu, że test trafień przerysowuje wszystkie elementy na inne płótno, dlatego są rysowane dwukrotnie przy każdym odświeżeniu.
unicoletti
0

Za pomocą UTFGrid i TileMill możesz wyświetlać nieograniczoną liczbę punktów z całkiem dobrą wydajnością. Wyświetlanie n losowych punktów jest rodzajem wymyślonego przykładu, który nie zadziałałby w tej sytuacji ani z GISCloud lub inną podobną magią - ponieważ hacki do wydajności wektorów zwykle wymagają znajomości pełnego zestawu danych i niektórych procedur wstępnego przetwarzania: zarówno TileMill, jak i GISCloud dużo płytek.

tmcw
źródło