2008-09-29 9 views
5

El proyecto en el que estoy trabajando necesita renderizar un archivo de forma ESRI, que puede tener una gran cantidad de polígonos/formas. Cuando agrego todos estos polígonos, líneas, puntos, etc. al lienzo que estoy utilizando, se vuelve realmente lento.¿Cómo mejorar el rendimiento y el uso de memoria con una gran cantidad de polígonos en un lienzo?

Para dibujar las formas en el mapa, estoy creando un objeto de ruta de acceso y estableciendo su propiedad Data en un StreamGeometry. Originalmente utilicé un Polígono, pero según MSDN, un StreamGeometry es mucho más liviano.

¿Cómo puedo mejorar el rendimiento? ¿Convertiría el producto final en un mapa de bits o ayuda de VisualBrush? ¿Hay una forma más eficiente de representar todas estas formas en el lienzo?

EDITAR: Olvidé mencionar que esto debe poder funcionar en un XBAP de confianza parcial.

Respuesta

0

Está a punto de descubrir la motivación detrás de las GPU y las tarjetas gráficas increíblemente overclockeadas y enfriadas. Y doble buffering.

Y: convertir la cosa a un mapa de bits: ¿cuál es la diferencia a la prestación?

Después de todo, tiene n objetos que/de alguna manera/tienen que renderizar (a menos que pueda averiguar qué objetos están ocultos detrás de otros objetos pero eso no le ayuda mucho ya que tendría que mirar n! Object relaciones).

Además: quizás valga la pena abandonar el enfoque OOP ortodoxo e ir a procedimientos en su lugar.

0

@xmjx

Y: convertir la cosa a un mapa de bits: ¿cuál es la diferencia de que lo hacen?

Mi pensamiento aquí fue que mi ralentización podría deberse a tener n cantidad de objetos en un lienzo, en comparación con 1 mapa de bits. Dicho esto, no conozco el rendimiento, o lo que ocurre en segundo plano al convertir un lienzo con n cantidad de objetos en un mapa de bits.

Preferiría no utilizar un mapa de bits, de modo que pueda permitir al usuario interactuar (modificar/desviar) con la forma/polígonos.

1

Es posible que el rendimiento del widget de lienzo sea limitado. Si tiene la opción de utilizar un juego de herramientas de terceros, mire QT. Tiene un alto rendimiento canvas widget que está diseñado para procesar formas complejas rápidamente. Esto ya se ha usado para at least one GIS application, por lo que tiene un registro de seguimiento en este espacio.

Puede usar wrap QT as an ActiveX control o usar Qyoto/Kimono enlaces .Net para la interfaz de una aplicación .Net. Troll Tech acaba de renovar su sitio web y no puedo encontrar la demo descargable que solían tener allí, pero muestra el widget QGraphicsView que representa un dibujo vectorial muy grande y que se aleja en tiempo real.

+0

Gracias por el enlace a QT, sin saber si va a trabajar para mi implementación, porque necesito implementarlo como un XBAP. – Dylan

+0

QT también tiene una función de complemento de navegador: si busca en el área de soporte para desarrolladores, debería poder encontrarla. Es posible que desee editar su publicación original para aclarar el requisito de XBAP. – ConcernedOfTunbridgeWells

2

Puede intentar usar GDI + o x directo en lugar de WPF.

Hice un proyecto similar (representación de datos de mapas a través de WPF), para un artículo de la revista MSDN que escribí hace un año.

Fue algo que escribí bastante rápido (el artículo + la aplicación tomó aproximadamente 1 semana), y fue diseñado para ser solo "esto es algo ordenado que puedes hacer", así que no me enfoqué en el rendimiento mucho. En cualquier caso, me encontré con el mismo problema.Una vez que el número de polígonos en el lienzo se hizo grande, el rendimiento de la representación comenzó a sufrir. Por ejemplo, cambiar el tamaño de la ventana implicaría aproximadamente un retraso de 1/2 segundo más o menos.

Mucho de esto tiene que ver con la sobrecarga de WPF. Está diseñado principalmente como un conjunto de herramientas GUI, en lugar de un motor gráfico de alto rendimiento. Eso significa que se enfoca en la riqueza de características sobre la representación eficiente. Con un número menor de objetos (lo que es probable encontrar en la mayoría de las aplicaciones GUI), el rendimiento es bastante bueno y las funciones de enlace de datos, animación y estilo declarativo (y todo el enrutamiento de eventos y otras cosas que requieren) pueden ser útiles. .

Al dibujar un mapa, sin embargo, el gran volumen de datos puede causar que todas esas características de enlace de datos limpios causen problemas de perfusión, como parece muy consciente.

Si no necesita un estilo y animación declarativos, simplemente eliminaría WPF y usaría GDI + para dibujar el mapa usted mismo. Básicamente implica configurar la matriz de transformación correcta para que el mapa dibuje sobre una superficie de control, y luego iterar a través de todos los polígonos y llamar a un grupo de métodos DrawPolygon.

Para habilitar la interacción, tendrá que escribir su propio código de prueba de impacto, y tendrá que volver a dibujar el mapa cada vez que se cambie el tamaño del formulario. También tendrá que codificar a mano cualquier animación o cambio de estilo o cosas así que desee (como resaltar regiones cuando el mouse está sobre ellas). Pero no debería ser tan difícil escribir ese código. Imaginé que podrías hacerlo en aproximadamente 1,5 semanas.

Hacerlo de esa manera, sin embargo, debería mejorar el rendimiento, ya que se reduciría a hacer solo unas 20-30K transformaciones de vectores, lo que no requiere mucha potencia de procesador en la mayoría de las CPU modernas. También podría considerar el uso de Direct X, lo que le permitiría aprovechar la GPU también, lo que podría aumentar aún más el rendimiento.

+1

Según lo que esté haciendo, las clases GeometryDrawing y StreamGeometry de WPF en realidad pueden ser mucho más rápidas que GDI +, ya que usa Direct3D en modo retenido. GDI + funciona bien para imágenes estáticas, pero no tan bien para imágenes que son principalmente estáticas pero con algunos cambios. GDI + tampoco funciona tan bien en escenarios de escritorio remoto. En general, recomendaría usar las capas de dibujo de bajo nivel de WPF sobre las de GDI + en la mayoría de los casos, porque todas las transformaciones se solucionan por usted y no tiene que lidiar con el espacio aéreo y problemas similares. –

+0

En lo que respecta a DirectX, puede ser más rápido que WPF en el escenario local (aunque imposible en el control remoto), pero es mucho más difícil codificar que StreamGeometry o GDI +. Tampoco se puede ejecutar en un XBAP. –

+0

GDI + tiene un bloqueo global para la mayoría de las operaciones, por lo que solo puede hacer una cosa a la vez dentro de un proceso. Como WPF puede hacer muchas cosas a la vez, esto solo puede aumentar el rendimiento si dibuja varias imágenes a la vez. – AndyJ

7

No es necesario recurrir a GDI, solo tiene que bajar una capa en las API de WPF y combinar su geometría en menos efectos visuales. Pablo Fermicola tiene información útil acerca de picking which layer para usar en función de sus necesidades de rendimiento.

He logrado obtener un excelente rendimiento usando DrawingVisual y la clase DrawingContext.

+0

DrawingVisual with DrawingContext funciona rápido y bien. También consulte GeometryDrawing y StreamGeometry si se encuentra en una situación donde tiene sentido guardar y reutilizar partes de su geometría. (DrawingContext solo puede actualizar la vista como un todo, mientras que StreamGeometryContext actualiza una Geometría que puede ser una pequeña porción de DrawingVisual) –

0

Si el rendimiento es un problema, querrás evitar Visual Brushes. Estos pinceles se usan mejor para proyectar una parte visible de la pantalla en otro lugar de la pantalla. Causan un gran golpe de rendimiento porque estos pinceles se actualizan automáticamente cuando cambia el contenido del pincel.

Cualquier uso de este pincel se realizará por software, y no podrá aprovechar las capacidades de hardware de su tarjeta gráfica.

More info from MSDN on VisualBrush

0

si usted no tiene que mostrar todos los polígonos a la vez (por ejemplo, debido al zoom, panorámica, etc.), echa un vistazo a la muestra de tela virtualización de here

Cuestiones relacionadas