Working with multi-layer symbols

322
4
03-18-2012 09:52 PM
JoeHershman
MVP Regular Contributor
Hi All,

I am writing an application that deletes elements (lines, markers, text, etc) from a page layout based on the color of the symbol.  For the most part everything works fine.  I cast the element to the appropriate Element type (ITextElement, ILineElement, etc) get the Symbol property and the Color.  There is one exception, for a few of the elements the Symbol has multi-layers and it is the second layer of the symbol that is the Color I am looking for.  I do not seem to get a reference to this part of the symbol.  I have searched and I cannot find a way to loop through the layers in a multi-layer symbol.  Does anyone know how you would go about doing that?  Seems there should be an Interface I can cast my Symbol to and determine if it is multi-layer and then loop through each layer, get the symbol on the layer and check the color.  But I do not see a way to do that.

Thanks
-Joe
0 Kudos
4 Replies
NeilClemmons
Regular Contributor III
It depends on the symbol type - for fill symbols use IMultiLayerFillSymbol.
0 Kudos
JoeHershman
MVP Regular Contributor
That was it IMultiLayerMarker in my case.  not sure why I did not see it, does exactly what I expected.

Thanks for the help.

You would not happen to know a way to speed up deleting elements, I delete a lot of elements (probably close to 1000 in some cases) and it takes forever (well almost 10 minutes, which seems like forever when you are watching)

Thanks again
-joe
0 Kudos
NeilClemmons
Regular Contributor III
I've never had to work with that many graphic elements before so these are all untested ideas...

Are you deleting the elements by looping through the graphics container and calling the Reset method after each delete?  If so, it's the call to Reset that is most likely slowing it down.  Instead of deleting the elements within the loop, add them to a collection (and remove the call to Reset).  Then loop through the collection and call DeleteElement.

You might consider creating features on a feature layer instead of graphic elements.  You'd then be able to delete via query by calling ITable.DeleteSearchedRows, which will be about as fast as you're going to get using ArcObjects.

You might also try creating an FdoGraphicsLayer for the elements.  According to the documentation, the FdoGraphicsLayer class also implements ITable, so you should be able to call DeleteSearchedRows on it.  I'm not sure exactly how the query would look since a graphic element doesn't have attributes like a feature does.  I've never done anything like this so you may find out that a lot of the methods on the interfaces the graphics layer implements are just not implemented.  It would be some interesting R&D though.
0 Kudos
JoeHershman
MVP Regular Contributor
My approach is do be looping through the GraphicsContainer and then storing the items to be deleted into a List then looping through that list at the end and deleting each element.  I think because the Graphics Collection is so big that it takes a while to find the element in the collection in order to remove it.  I have put some timers in there and the call to IGraphicsContainer:: DeleteElement is really slow.

The approach I am thinking of trying, which is a bit convoluted but I think may improve performance is to delete everything from the GraphicsContainer and make an ElementCollection of all the things that should be kept.  Then use IGraphicsContainer::AddElements methods and add them back.  I'll see what happens

Thanks again.
-Joe
0 Kudos