2008-09-29 7 views
5

Projekt, nad którym pracuję, musi renderować plik kształtu ESRI, który może mieć dużą liczbę wielokątów/kształtów. Kiedy dodaję wszystkie te wielokąty, linie, punkty, itp. Do płótna, którego używam, robi się bardzo wolno.Jak poprawić wydajność i zużycie pamięci przy dużej liczbie wielokątów na płótnie?

Aby narysować kształty na mapie, utworzę obiekt Path i ustawię właściwość Data na StreamGeometry. Początkowo używałem wielokąta, ale według MSDN StreamGeometry ma znacznie mniejszą wagę.

Jak mogę poprawić wydajność? Czy konwertowanie gotowego produktu do pomocy Bitmap lub VisualBrush? Czy istnieje skuteczniejszy sposób renderowania wszystkich tych kształtów na płótnie?

EDYCJA: Zapomniałem wspomnieć, że musi to być możliwe do pracy w XBAP z Częściowym Zaufaniem.

Odpowiedz

0

Za chwilę odkryjesz motywy układów GPU i niesamowicie podkręcone i schłodzone karty graficzne. I podwójne buforowanie.

I: konwersja rzeczy na bitmapę: jaka jest różnica w renderowaniu?

Po wszystkim masz n obiektów, które/w jakiś sposób/muszą zostać wyrenderowane (chyba, że ​​możesz dowiedzieć się, które obiekty są ukryte za innymi obiektami, ale to nie pomaga, ponieważ musiałbyś patrzeć na obiekt! relacje).

Poza tym: może opłaca się opuścić ortodoksyjne podejście do OOP i zamiast tego przejść do procedury.

0

@xmjx

oraz: przekształcenie rzecz do bitmapy: jaka jest różnica do renderowania to?

Moją myślą było, że moje spowolnienie może być spowodowane przez n liczby obiektów na płótnie, w porównaniu do 1 bitmapy. Powiedział, że nie wiem wydajności, ani co dzieje się w tle podczas konwersji płótna z liczbą obiektów na bitmapę.

Wolałbym nie używać mapy bitowej, aby umożliwić użytkownikowi interakcję (modyfikowanie/delte) z kształtem/wielokątami.

1

Możesz być ograniczony przez działanie widgetu kanwy. Jeśli masz możliwość skorzystania z zestawu narzędzi innej firmy, spójrz na numer QT.. Ma on wysoką wydajność canvas widget, zaprojektowaną do szybkiego renderowania złożonych kształtów. To zostało już użyte do at least one GIS application, więc ma pewne osiągnięcia w tej przestrzeni.

Możesz wrap QT as an ActiveX control lub użyć powiązań .NET Qyoto/Kimono do interfejsu do aplikacji .Net. Firma Troll Tech właśnie przebudowała swoją stronę internetową i nie mogę znaleźć pobranego dema, które kiedyś tam było, ale pokazuje widżet QGraphicsView, który renderuje bardzo duży rysunek wektorowy i pomniejsza go w czasie rzeczywistym.

+0

Dzięki za link do QT, nie wiem, czy to będzie działać na moim implementacja, ponieważ muszę wdrożyć jako XBAP. – Dylan

+0

QT ma również funkcję wtyczki przeglądarki - jeśli polujesz w obszarze wsparcia programisty, powinieneś być w stanie go znaleźć. Możesz edytować swój oryginalny wpis, aby wyjaśnić wymagania XBAP. – ConcernedOfTunbridgeWells

2

Możesz spróbować użyć GDI + lub bezpośredniego x zamiast WPF.

Zrobiłem podobny projekt (renderowanie danych mapy przez WPF), dla artykułu czasopisma MSDN napisałem około rok temu.

To było coś, co napisałem dość szybko (artykuł + aplikacja trwała około 1 tygodnia) i został zaprojektowany tak, aby po prostu być "to jest coś, co możesz zrobić", więc nie skupiałem się na wydajności dużo. W każdym razie wpadłem na ten sam problem.Po zwiększeniu liczby wielokątów na płótnie wydajność renderowania zaczęła spadać. Na przykład zmiana rozmiaru okna wymagałaby około 1/2 sekundy opóźnienia.

Wiele z tego ma związek z obciążeniem WPF. Został zaprojektowany przede wszystkim jako zestaw narzędzi GUI, a nie jako wydajny silnik graficzny. Oznacza to, że koncentruje się na bogactwie funkcji w porównaniu do renderingu efektywnego. Przy mniejszej liczbie obiektów (co prawdopodobnie znajdzie się w większości aplikacji GUI), wydajność jest całkiem dobra, a funkcje łączenia danych, animacji i deklaratywnych stylów (oraz wszystkie routing zdarzeń i inne rzeczy, których wymagają) mogą się bardzo przydać .

Podczas rysowania mapy, sama objętość danych może spowodować, że wszystkie te zgrabne funkcje wiązania danych spowodują problemy związane z perfekcją, co wydaje się być dobrze znane.

Jeśli nie potrzebujesz deklaratywnego stylu i animacji, to po prostu wyeliminowałbym WPF i używałbym GDI +, aby narysować mapę jako swoją. Zasadniczo polega ona na ustawieniu odpowiedniej macierzy transformacji, aby mapa narysowała na powierzchni kontrolnej, a następnie iterowała przez wszystkie wielokąty i wywoływała kilka metod DrawPolygon.

Aby włączyć interakcję, musisz napisać własny kod testowy trafień, a będziesz musiał przerysować mapę w dowolnym momencie zmiany rozmiaru formularza. Będziesz także musiał ręcznie kodować wszelkie animacje lub zmiany stylu lub rzeczy, które chcesz zrobić (takie jak podświetlanie regionów, gdy mysz znajduje się nad nimi). Ale nie powinno być tak trudno napisać ten kod. Chciałbym zobrazować, że można to zrobić za około 1,5 tygodnia.

Wykonanie tego w ten sposób powinno poprawić wydajność, ponieważ sprowadza się tylko do transformacji wektorowej 20-30K, która nie wymaga dużej mocy obliczeniowej na większości nowoczesnych procesorów. Możesz także zajrzeć do Direct X, który pozwoli Ci również skorzystać z GPU, co może dać jeszcze większy wzrost wydajności.

+1

W zależności od tego, co robisz, klasy GeometryDrawing i StreamGeometry w WPF mogą być znacznie szybsze niż GDI +, ponieważ używają Direct3D w trybie zachowanym. GDI + działa dobrze w przypadku obrazów statycznych, ale nie tak dobrze w przypadku obrazów, które są w większości statyczne, ale z pewnymi zmianami. GDI + również nie działa tak dobrze w scenariuszach zdalnego pulpitu. Generalnie polecam używanie warstw rysunkowych niskiego poziomu WPF na GDI + w większości przypadków, ponieważ wszystkie transformacje są dla ciebie zadbane i nie musisz zajmować się przestrzenią powietrzną i podobnymi problemami. –

+0

Jeśli chodzi o DirectX, może on być szybszy niż WPF w lokalnym scenariuszu (choć niemożliwym w zdalnym), ale o wiele trudniej jest go kodować niż StreamGeometry lub GDI +. Również nie może działać w XBAP. –

+0

GDI + ma globalną blokadę dla większości operacji, więc może wykonywać tylko jedną rzecz na raz w ramach procesu. Ponieważ WPF może robić wiele rzeczy naraz, tylko to może przynieść przyrost wydajności w przypadku rysowania wielu obrazów naraz. – AndyJ

7

Nie trzeba uciekać się do GDI, wystarczy przesunąć warstwę w interfejsie API WPF i połączyć swoją geometrię w mniejszą liczbę elementów wizualnych. Pablo Fermicola ma kilka użytecznych informacji o tym, jak używać picking which layer w zależności od twoich potrzeb.

Udało mi się uzyskać doskonałą wydajność przy użyciu klasy DrawingVisual i DrawingContext.

+0

DrawingVisual z DrawingContext działa szybko i dobrze. Sprawdź także GeometryDrawing i StreamGeometry, jeśli jesteś w sytuacji, w której ma sens zapisywanie i ponowne wykorzystanie części geometrii. (DrawingContext może aktualizować tylko wizualny jako całość, podczas gdy StreamGeometryContext aktualizuje Geometry, które mogą być małą częścią całego DrawingVisual) –

0

Jeśli wydajność jest problemem, to chcesz uniknąć pędzli wizualnych. Szczotki te najlepiej służą do rzutowania widocznej części ekranu w inne miejsce na ekranie. Powodują one duży hit wydajności, ponieważ te pędzle są automatycznie aktualizowane po zmianie zawartości pędzla.

Użycie tego pędzla spowoduje renderowanie oprogramowania i nie będzie w stanie wykorzystać możliwości sprzętowych karty graficznej.

More info from MSDN on VisualBrush

0

jeśli nie masz, aby pokazać wszystkie wielokąty na raz (na przykład z powodu powiększania, przesuwania itp), sprawdzić próbkę Wirtualizacja płócienną here

Powiązane problemy