Create line element with arrow symbol at end

7418
2
03-03-2013 01:07 PM
DavidHowes
New Contributor III
I found this archived thread very helpful for creating a line with an arrow: http://forums.esri.com/Thread.asp?t=248367&c=93&f=1154&ESRISessionID=VVH6mNCepIZNJVUggkPd2w9AhfkhhyV...

So, for anyone who wants to do the same thing in C#, here's some equivalent code with a few extras. All it does is create a line element named "ArrowTest" which is a simple line with an arrow at one end.

The initial code looks for any existing elements with that name and deletes them so you can run this repeatedly and tweak it until you're ready to use it in production. Note that at the start I build a list of elements to delete and then delete them in a separate loop. DeleteElement isn't guaranteed to work properly if you try calling it within the while loop because you're altering the list over which you're looping.

I'm using ArcObjects 10.1, but it should work in earlier versions.

//Set the element name
string elementName = "ArrowTest";

//Get the graphics container from the page layout (set elsewhere)
IActiveView activeView = (IActiveView)pageLayout;
IGraphicsContainer graphicsContainer = (IGraphicsContainer)pageLayout;

//Find all existing elements with specified name
//Build a list of elements and then loop over the list to delete them
List<IElement> elementsToDelete = new List<IElement>();
graphicsContainer.Reset();
IElementProperties3 elementProperties3 = null;
IElement element = null;
while ((element = graphicsContainer.Next()) != null)
{
    elementProperties3 = (IElementProperties3)element;
    if (elementProperties3.Name == elementName)
    {
 elementsToDelete.Add(element);
    }
}

foreach (IElement elementToDelete in elementsToDelete)
{
    graphicsContainer.DeleteElement(elementToDelete);
}

//Define color
IRgbColor rgbColor = new RgbColorClass();
rgbColor.RGB = Color.Black.ToArgb();

//Define an arrow marker
IArrowMarkerSymbol arrowMarkerSymbol = new ArrowMarkerSymbolClass();
arrowMarkerSymbol.Color = rgbColor;
arrowMarkerSymbol.Size = 6;
arrowMarkerSymbol.Length = 8;
arrowMarkerSymbol.Width = 6;
//Add an offset to make sure the square end of the line is hidden
arrowMarkerSymbol.XOffset = 0.8;

//Create cartographic line symbol
ICartographicLineSymbol cartographicLineSymbol = new CartographicLineSymbolClass();
cartographicLineSymbol.Color = rgbColor;
cartographicLineSymbol.Width = 1;

//Define simple line decoration
ISimpleLineDecorationElement simpleLineDecorationElement = new SimpleLineDecorationElementClass();
//Place the arrow at the end of the line (the "To" point in the geometry below)
simpleLineDecorationElement.AddPosition(1);
simpleLineDecorationElement.MarkerSymbol = arrowMarkerSymbol;

//Define line decoration
ILineDecoration lineDecoration = new LineDecorationClass();
lineDecoration.AddElement(simpleLineDecorationElement);

//Set line properties
ILineProperties lineProperties = (ILineProperties)cartographicLineSymbol;
lineProperties.LineDecoration = lineDecoration;

//Define line element
ILineElement lineElement = new LineElementClass();
lineElement.Symbol = (ILineSymbol)cartographicLineSymbol;

//Create the line geometry
IPoint fromPoint = new PointClass();
fromPoint.X = 4.0;
fromPoint.Y = 0.8;

IPoint toPoint = new PointClass();
toPoint.X = 5.0;
toPoint.Y = 0.8;

IPolyline polyline = new PolylineClass();
polyline.FromPoint = fromPoint;
polyline.ToPoint = toPoint;

//Cast to Element and set geometry
element = (IElement)lineElement;
element.Geometry = polyline;

//Set the name
elementProperties3.Name = elementName;

//Add element to graphics container
graphicsContainer.AddElement(element, 0);

//Clear the graphics selection (graphics are selected when added)
IGraphicsContainerSelect graphicsContainerSelect = (IGraphicsContainerSelect)graphicsContainer;
graphicsContainerSelect.UnselectAllElements();

activeView.Refresh();
0 Kudos
2 Replies
ZLIU
by
New Contributor II

Thanks!It helps!

0 Kudos
RavindraSingh
Occasional Contributor

Putting Code for creating two sided arrow symbol in a line.

hope this shall help some one.

/// <summary>
/// Crates MultiLayerLineSymbol with Two Sided arrow.
/// </summary>
/// <returns></returns>
private ISymbol Create_MultiLayerLineSymbol()
{
// Create Arrow Marker Symbol
IArrowMarkerSymbol pAMS = new ArrowMarkerSymbolClass();
pAMS.Style = esriArrowMarkerStyle.esriAMSPlain;
pAMS.Length = Constants.AMS_LENGTH;
pAMS.Width = Constants.AMS_WIDTH;

// Line Decoration Element
SimpleLineDecorationElementClass sldElement = new SimpleLineDecorationElementClass();
sldElement.AddPosition(1);
sldElement.FlipFirst = true;
sldElement.FlipAll = false;
sldElement.Rotate = true;
sldElement.MarkerSymbol = (IMarkerSymbol)pAMS;
sldElement.PositionAsRatio = true;

// Line Decoration
LineDecoration ld = new LineDecorationClass();
ld.AddElement(sldElement);

// Cartographic Line Symbol
CartographicLineSymbolClass cls = new CartographicLineSymbolClass();

// Line Properties. In order to set additional properties like offsets and dash patterns we must create an ILineProperties object
ILineProperties lp = cls as ILineProperties; //QI
lp.Offset = Constants.CLS_LINE_PROP_OFFSET;
//lp.Flip = true;
lp.LineDecoration = ld;

cls.Cap = esriLineCapStyle.esriLCSButt;
cls.Join = esriLineJoinStyle.esriLJSRound;
cls.Width =Constants.CLS_WIDTH;


//---[START]--------------------------- 2nd CartographicLineSymbolClass ----------------------------
// for putting the arrow marker at opposite end of the line.

// Line Decoration Element
SimpleLineDecorationElementClass sldElement1 = new SimpleLineDecorationElementClass();
sldElement1.AddPosition(0);
sldElement1.FlipFirst = true;
sldElement1.FlipAll = false;
sldElement1.Rotate = true;
sldElement1.MarkerSymbol = (IMarkerSymbol)pAMS;
sldElement1.PositionAsRatio = true;

// Line Decoration
LineDecoration ld1 = new LineDecorationClass();
ld1.AddElement(sldElement1);

// Cartographic Line Symbol
CartographicLineSymbolClass cls1 = new CartographicLineSymbolClass();

// Line Properties. In order to set additional properties like offsets and dash patterns we must create an ILineProperties object
ILineProperties lp1 = cls1 as ILineProperties; //QI
lp1.Offset =Constants.CLS_LINE_PROP_OFFSET;
//lp.Flip = true;
lp1.LineDecoration = ld1;

cls1.Cap = esriLineCapStyle.esriLCSButt;
cls1.Join = esriLineJoinStyle.esriLJSRound;
cls1.Width = Constants.CLS_WIDTH;

//---[END]--------------------------- 2nd CartographicLineSymbolClass ------------------------------


IMultiLayerLineSymbol multiLayerLineSymbol = new MultiLayerLineSymbolClass();
multiLayerLineSymbol.AddLayer((ILineSymbol)cls);
multiLayerLineSymbol.AddLayer((ILineSymbol)cls1);

return multiLayerLineSymbol as ISymbol;
}

0 Kudos