How to programatically create a line symbol with a Arrow at the endpoint.

707
4
Jump to solution
09-21-2022 03:01 AM
StephenCochrane
New Contributor III

Hi

I am trying to programmatically construct a simple line symbol using ArcGIS pro sdk for .net. It should show the features with an arrow at the end node of each feature (and only at the end node). I am not sure if need to use line symbol with marker symbols (it seems a bit complicated for a relative simple symbol).

I the old ArcMap application I am migrating i had this code for the symbol

 

 

		private static CartographicLineSymbolClass CreateArrowSymbol(Color c)
		{
			var color = new RgbColorClass() { Red = c.R, Green = c.G, Blue = c.B };
			var de = new SimpleLineDecorationElementClass();
			de.AddPosition(1);
			de.MarkerSymbol = new ArrowMarkerSymbolClass() { Color = color, Size = 8.0, Length = 6.0 };
			var ld = new LineDecorationClass();
			ld.AddElement(de);

			var symbol = new CartographicLineSymbolClass()
			{
				Color = color,
				Width = 1.5,
				LineDecoration = ld
			};
			return symbol;
		}

 

 

 

0 Kudos
2 Solutions

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Stephen, you can also use a pre-defined arrow symbol using this code:

 

if (_lineSymbol == null)
{
  //Get all styles in the project
  var styleProjectItem2D = Project.Current.GetItems<StyleProjectItem>().FirstOrDefault(s => s.Name == "ArcGIS 2D");
  await QueuedTask.Run(() =>
  {
    //Get a specific project style by name
    var arrowLineSymbol = styleProjectItem2D.SearchSymbols(StyleItemType.LineSymbol, "Arrow Line 2 (Mid)")[0];
    if (arrowLineSymbol == null) return;
    _lineSymbol = arrowLineSymbol.Symbol;
  });
}

 

The example symbology will look like this:

Wolf_0-1663789107788.png

I attached a sample tool code snippet that shows the symbology using a graphic overlay.

EDIT: please substitute the SearchSymbol string using the following to get an arrow at the end:

styleProjectItem2D.SearchSymbols(StyleItemType.LineSymbol, "Bold Arrow 2")[0];

 

Wolf_0-1663794606223.png

 

View solution in original post

0 Kudos
StephenCochrane
New Contributor III

Thanks a lot, Wolf.

It worked super. 

View solution in original post

0 Kudos
4 Replies
CharlesMacleod
Esri Regular Contributor

Stephen, i cover symbology in quite some depth here: ArcGIS Pro SDK for .NET: An Introduction to the Use of the CIM with Symbology in Pro (from Dev summit 2021)  and, specifically, arrow heads: 48:30 ish

ppt and code is here: https://esri.github.io/arcgis-pro-sdk/techsessions/2021/PalmSprings/CIMSymbology.zip 

You will need to use something called a CIMMarkerPlacementAtExtremities and apply that to your arrow marker. Along these lines (no pun intended):

 var symbol_layers = new List<CIMSymbolLayer>();
 var stroke = SymbolFactory.Instance.ConstructStroke(
   		ColorFactory.Instance.BlackRGB, 2.0);
 //End arrow
 var arrow = SymbolFactory.Instance.ConstructMarker(
   		63, "ESRI Arrowhead", "Regular", 10) as CIMCharacterMarker;

 //Marker placement on end - Both, JustBegin, JustEnd
 var endMarkerPlacement = new CIMMarkerPlacementAtExtremities() {
   ExtremityPlacement = ExtremityPlacement.JustEnd,
   PlacePerPart = false,
   AngleToLine = true
 };
 arrow.MarkerPlacement = endMarkerPlacement;

 //reverse Z-order
 symbol_layers.Add(arrow);
 symbol_layers.Add(stroke);

 var CIMLineSymbol = new CIMLineSymbol() {
   SymbolLayers = layers.ToArray()
 };
0 Kudos
StephenCochrane
New Contributor III

Hi Charles

Thanks a lot. The links were very use full for my project in general. In regard to your solution, it was working but I could not change the color of the marker (arrowhead).

I think it should be rather simple but setting the color in line 8 below does not seem to work. It got what I wanted using Wolf solution below so this it just my curiosity

 

		private static CIMLineSymbol CreateArrowLineSymbol(System.Drawing.Color color)
		{
			var cimColor = ColorFactory.Instance.CreateColor(color);
			var symbol_layers = new List<CIMSymbolLayer>();
			var stroke = SymbolFactory.Instance.ConstructStroke(cimColor, 2.0);

			//End arrow
			var arrow = SymbolFactory.Instance.ConstructMarker(63, "ESRI Arrowhead", "Regular", 10, cimColor) as CIMCharacterMarker;

			//Marker placement on end - Both, JustBegin, JustEnd
			var endMarkerPlacement = new CIMMarkerPlacementAtExtremities()
			{
				ExtremityPlacement = ExtremityPlacement.JustEnd,
				PlacePerPart = false,
				AngleToLine = true,
			};
			arrow.MarkerPlacement = endMarkerPlacement;

			//reverse Z-order
			symbol_layers.Add(arrow);
			symbol_layers.Add(stroke);
			var CIMLineSymbol = new CIMLineSymbol()
			{
				SymbolLayers = symbol_layers.ToArray()
			};
			return CIMLineSymbol;
		}

 

Wolf
by Esri Regular Contributor
Esri Regular Contributor

Stephen, you can also use a pre-defined arrow symbol using this code:

 

if (_lineSymbol == null)
{
  //Get all styles in the project
  var styleProjectItem2D = Project.Current.GetItems<StyleProjectItem>().FirstOrDefault(s => s.Name == "ArcGIS 2D");
  await QueuedTask.Run(() =>
  {
    //Get a specific project style by name
    var arrowLineSymbol = styleProjectItem2D.SearchSymbols(StyleItemType.LineSymbol, "Arrow Line 2 (Mid)")[0];
    if (arrowLineSymbol == null) return;
    _lineSymbol = arrowLineSymbol.Symbol;
  });
}

 

The example symbology will look like this:

Wolf_0-1663789107788.png

I attached a sample tool code snippet that shows the symbology using a graphic overlay.

EDIT: please substitute the SearchSymbol string using the following to get an arrow at the end:

styleProjectItem2D.SearchSymbols(StyleItemType.LineSymbol, "Bold Arrow 2")[0];

 

Wolf_0-1663794606223.png

 

0 Kudos
StephenCochrane
New Contributor III

Thanks a lot, Wolf.

It worked super. 

0 Kudos