2016-11-03 14 views
6

To pytanie jest dla kogoś, kto rozumie wnętrze MapBox GL JS.Przyczyna różnicy wydajności MapBox GL JS

Używam MapBox GL JS do renderowania mapy geograficznej zawierającej do 40 000 wielokątów, z których każdy jest kolorowy w oparciu o "właściciela" tego wielokąta. Zazwyczaj istnieje wiele wielokątów na właściciela, a "właściciel" każdego wielokąta może się zmieniać z czasem. Liczba właścicieli może wynosić od jednego do około 1000. Mam problemy z wydajnością (które różnią się w zależności od tego, jak do niego podchodzę), więc wypróbowałem kilka różnych strategii.

  1. Korzystanie z stylizacji opartej na danych dla "wypełnienia kolorem", gdzie mam pojedyncze źródło i pojedynczą warstwę. Próbowałem zarówno identyfikator wielokąta i "właściciela" id jako kategorię dla stylu opartego na danych.
  2. Używanie filtrowanych warstw, w których mam pojedyncze źródło i osobną warstwę dla każdego "właściciela". Ponownie wypróbowałem zarówno identyfikator wielokąta, jak i "właściciela", jako kryteria filtrowania.
  3. Użycie osobnego źródła i warstwy dla każdego "właściciela".

Opcja trzecia ma najlepszą prędkość rysowania. Warstwy są renderowane bardzo szybko podczas przybliżania i przesuwania. Ale muszę wywołać setData za każdym razem, gdy zmienię właściciela warstwy, a setData wycieknie z pamięci, więc w końcu skończę z awarią strony. Ten numer 2607 został zamknięty, ponieważ nie można go podjąć, więc nie spodziewam się rozwiązania tego problemu.

Opcje jeden i dwa rysują dobrze przy początkowym powiększeniu, ale po powiększeniu są bardzo powolne, aby ponownie rysować płytki. Utknąłem, patrząc na poszarpane, mało szczegółowe kafelki, aż rendering dogoni po 20-30 sekundach. Zauważ, że jeśli użyję identyfikatora "owner" zamiast identyfikatora "polygon", nadal będę musiał wywołać setData, gdy zmieni się "właściciel", co doprowadzi do wycieku pamięci. Jeśli używam identyfikatora wielokąta, wystarczy zaktualizować filtry warstw lub kategorie kolorów wypełnienia, gdy zmieni się "właściciel". Jednak nie dostaję zauważalnej różnicy w wydajności, jeśli używam identyfikatora "wielokąta", więc myślę, że to w porządku.

Moje pytanie brzmi: dlaczego opcja trzecia jest o wiele szybsza do renderowania po powiększeniu? Czy ma to związek z liczbą pracowników przydzielonych do losowania? W opcjach jeden i dwa istnieje jedno źródło, więc czy oznacza to, że rysunek korzysta tylko z jednego pracownika? Podczas gdy w opcji trzeciej istnieje oddzielne źródło dla każdego "właściciela", więc mam wielu pracowników wykonujących rysunek?

+0

Wygląda na to, że wyciek pamięci związany z opcją 3 został naprawiony w wersji v0.29.0. – jasonpepper

Odpowiedz

1

Myślę, że będziesz potrzebować różnych technik, aby rozwiązać problem z poziomem szczegółowości (LOD). Zrobiłem podobne prace związane z rysowaniem poli regionów danego kraju, aby wskazać różne dzielnice w danym państwie i trzeba skalować dane, aby dopasować je do widoku.

Pierwszą rzeczą, którą polecam jest tworzenie różnych poziomów szczegółowości dla Twoich regionów. Pierwszy przebieg można wykonać automatycznie, usuwając wierzchołki regionów, które są wyrównane (w sensie geograficznym) w obrębie kilku stopni linii prostej wraz z sąsiednimi punktami. Pomyśl o tym, usuwając wiele małych punktów, które nie dodają szczegółów do granicy regionu, ponieważ są one w linii prostej. Ponieważ może to być zautomatyzowany (a nawet wstępnie zapisany) krok, możesz tworzyć różne poziomy szczegółowości na podstawie poziomu powiększenia.

Drugim zaleceniem jest uśpienie przestrzeni widoku. Oznacza to, że jeśli region nie znajduje się w porcie widoku, nie renderuj go! Jeśli spróbujesz zrobić ten vertex-perfect, skończysz z tymi samymi problemami z CPU, co poprzednio, więc polecam utworzenie ramki ograniczającej region (jeśli korzystasz tylko z widoku osiowego, propozycja jest proponowana jako najłatwiejsza rozwiązanie).

Jeśli potrzebujesz regionów bez osi, po prostu utwórz obwiednię (o promieniu opartym na wierzchołku granicy w największej odległości od geocentrum regionu).

Sugerowałbym, że twoje różne trudności są pochodną problemu złożoności sceny. Rozwiąż to i będziesz miał znacznie wydajniejszy system do pracy.

Powodzenia!

+0

Dzięki za sugestie. Ale w przypadku, który nie wydaje się praktyczne rozwiązanie. Mamy strukturę elementów mapy, które mają bardzo różne kategorie i zastosowania, a nie masywną, jednorodną ilość podobnej geometrii. Wszelkie sugestie dotyczące naszej heterogenicznej sprawy? – MrMambo007

+0

Dziękuję za odpowiedź. Przekształciłem swoje wielokątów wektorowych w kafle wektorowe i zaobserwowałem ogromną poprawę wydajności opartych na danych stylów i filtrowanych warstw. Zasadniczo płytki wektorowe wykonują dokładnie to, co polecasz, tworząc różne poziomy szczegółowości i uśpienia przestrzeni widoku. – jasonpepper

2

Polecam wykonanie data-join przy użyciu stylów opartych na kategorycznych danych. Pozwala to oddzielić aktualizacje właściwości danych od geometrii.

Zapoznaj się z https://www.mapbox.com/mapbox-gl-js/example/data-join/, aby uzyskać przykład łączenia danych JSON w przeglądarce z wektorową geometrią płytki. To powinno skalować się do ponad 100 tysięcy funkcji.

+1

To podejście działa bardzo dobrze. I to jest podejście, na które się zdecydowałem. – jasonpepper