Polyline Drawing

674
6
06-16-2011 07:08 AM
ScottMcNeil
New Contributor
I am deveoping a standalone c# application using the MapControl in ArcGIS 9.3.  I am currently drawing polylines on the map, using the call "PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null) to trigger an event causing my drawing code to be invoked.  This all works great however, I'd like to be able to redraw some polylines (that need to be updated/moved) and not others, and using this method all lines must get drawn each time the refresh is performed.  This causes the apperance of "flickering" as the majority of the lines did not change but get redrawn anyway.

Is there a way to just redraw some polylines and not others?  Is it possible to group polylines into different layers and only redraw some layers?  Ideas/suggestions are appreciated!
0 Kudos
6 Replies
KenBuja
MVP Esteemed Contributor
Take a look at this thread to see if there's anything in there that would help you.
0 Kudos
ScottMcNeil
New Contributor
Thanks for the suggestions.  The v10 GraphicsTracker looks promising but unfortunatley I am stuck using 9.3 for now, as my customer invested over 40K in it about a year and a half ago...   Also, I had tried using a dynamic display a while back and determined it was not well suited for the application.  Dont remember specifically but think it significantly degraded the map grahics.

I am going to experiment some more with custom layers and see where that takes me.  I'm still not sure if its possible to force a refresh on a single custom layer without causing other custom layers to be redrawn.   If anyone has tried something like that, Id appriciate any input. 

Thx,
Scott
0 Kudos
ScottMcNeil
New Contributor
I tried using separate layers for groups of polylines and using the partialrefresh method that allows a single layer to be specified for redraw as described in docs (How to redraw the display)

// Refresh a single layer.
pMap.PartialRefresh(esriViewGeography, pLayer, null);

http://edndoc.esri.com/arcobjects/9.2/net/7b7dfcf8-18bd-4b11-bc67-cf9af9bd6591.htm


This partial refresh with an object reference passed does not call Draw() on my object/layer.  Draw only gets called if I provide null as the second parameter.  And as I expected, when I do that all of my polyline layers are refreshed (Draw is called on each layer)-- exactly what I wanted to avoid.

Has anyone done something like this and been successful?  Doc also implies that using the esriViewGraphics phase individual elements can be refreshed.  Has anyone tried that?
0 Kudos
AlexanderGray
Occasional Contributor III
I have done graphics refresh and foreground refresh.  Neither will refresh a geographic layer.  Graphics refresh is for graphical elements (IElement) added to the graphics container of the activeview.  They work quite well but the elements are not stored in the geodatabase (unless it is annotation), they are stored in mxd.  Foreground drawing is trickier but I have used it with good results for non persisting geometries (custom rubber band when editing.)  Foreground objects get cleared at every refresh and must be redrawn on the screendisplay in the activeview refresh event for refresh on the foreground phase.  I found that gave me the best results for a geometry that changed quickly and often as a result of user interaction and I didn't need to store them at all.
You could code a custom layer that draws to the foreground or to the graphic phase.  ILayer.Draw method passes in the phase to draw to.  That way you can chose which phase you want to draw to. Making custom layers increases the difficulty in supporting the code over time though.
0 Kudos
ScottMcNeil
New Contributor
Hi Alex,
My original implementation was using the foreground drawing method you describe, but there is no way to only redraw some of the items-- all foreground items must be redrawn.  I need to redraw only the items (polylines) that changed, which was my original reason for posting.  I tried using esriViewGraphics, but had no luck getting that to work.

With my most recent attempts I am using a custom layer subclassed from BaseCustomLayer.  WIth this approach, no matter what draw phase parameter I provide to PartialRefresh(), my Draw() method override only gets invoked with a phase of esriDPGeography (which, I should note is actually a different enumeration type than is passed to PartialRefresh).  Neverthelss, according to ESRI documentation in my previous link, I should be able to refresh only the layer object passed to PartialRefresh. 

I found these posts of others having similar PartialRefresh problems:

http://forums.arcgis.com/threads/24958

http://forums.esri.com/Thread.asp?c=159&f=1707&t=180719

Based on suggestions in the Steven Dunn thread, I was able to make some improvements but its still not working correctly.  Draw() is now called on each of my layers independenty, but about 1/2  the time the the previous layer contents are left on the map (not removed).  Also, about once a second, it appears the entire map frame is repainted without ever needing to calling my layer's draw method... This is actually worse than redrawing all my layers since the entire map repaints, not just my layers.

Thus, still working on it...
0 Kudos