Select to view content in your preferred language

how to add leader lines to the labels i have created in arcgis pro sdk?

1242
3
Jump to solution
11-17-2023 06:42 PM
RishabhRaj29
Occasional Contributor

Hi all,

I have a feature layer which has single part and multi part features. I have created labels for each multi part and single part features using mapleslabelengine in sdk and these are coming fine.

 

I want to add leader lines to each label so that it seems easier to understand where is the feature (even if it’s really small) in the layout pdf that i am exporting.

I am lost as to where to start and how to achieve this.

 

Any help is appreciated. I am working with Pro 2.9.8.

 

0 Kudos
1 Solution

Accepted Solutions
RishabhRaj29
Occasional Contributor

Here is the updated response with the code snippet:

QueuedTask.Run(() =>
{
var lyrDefn = featureLayer.GetDefinition() as CIMFeatureLayer;
var textSymbol = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.BlackRGB, 12, "Arial", "Regular");
textSymbol.OffsetY = 45.0;
var maplexLabelPlacementProps = new CIMMaplexLabelPlacementProperties
{
FeatureType = LabelFeatureType.Polygon,
LabelLargestPolygon = false,
CanRemoveOverlappingLabel = false,
PolygonPlacementMethod = MaplexPolygonPlacementMethod.HorizontalInPolygon,
CanPlaceLabelOutsidePolygon = true,
PolygonAnchorPointType = MaplexAnchorPointType.ErodedCenter,
IsOffsetFromFeatureGeometry = true,
MultiPartOption = MaplexMultiPartOption.OneLabelPerPart,
PrimaryOffset = 10.0
};
//End arrow
var arrow = SymbolFactory.Instance.ConstructMarker(63, "ESRI Arrowhead", "Regular", 10, ColorFactory.Instance.BlackRGB) as CIMCharacterMarker;
//Marker placement on end - Both, JustBegin, JustEnd
var endMarkerPlacement = new CIMMarkerPlacementAtExtremities()
{
ExtremityPlacement = ExtremityPlacement.JustEnd,
PlacePerPart = true,
AngleToLine = true
};
arrow.MarkerPlacement = endMarkerPlacement;
var symbol_layers = new List<CIMSymbolLayer>();
symbol_layers.Add(arrow);
var stroke = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid);

// Create a callout
//CIMLineSymbol lineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid);
symbol_layers.Add(stroke);
var CIMLineSymbol = new CIMLineSymbol()
{
SymbolLayers = symbol_layers.ToArray()
};
ArcGIS.Core.CIM.CIMSimpleLineCallout callout = new ArcGIS.Core.CIM.CIMSimpleLineCallout
{
LeaderTolerance = 1.0,
LeaderOffset = 4.0,
//LineSymbol = lineSymbol,
LineSymbol = CIMLineSymbol,
AutoSnap = true

};
textSymbol.Callout = callout;

var lyrsLabelsClasses = lyrDefn.LabelClasses.ToList();
var theLabelClass = lyrsLabelsClasses.FirstOrDefault();
theLabelClass.ExpressionEngine = LabelExpressionEngine.Arcade;
//theLabelClass.Expression = "return $feature.name;";
theLabelClass.Expression = "'Test'";
theLabelClass.TextSymbol = textSymbol.MakeSymbolReference();
theLabelClass.MaplexLabelPlacementProperties = maplexLabelPlacementProps;
lyrDefn.LabelClasses = lyrsLabelsClasses.ToArray(); //Set Label Class back to definition
featureLayer.SetDefinition(lyrDefn); //set the layer's definition;
featureLayer.SetLabelVisibility(true);
});

View solution in original post

0 Kudos
3 Replies
GKmieliauskas
Esri Regular Contributor

Hi,

There is ArcGIS Pro sdk community sample which shows how to add balloon/line callout with a leader line to an annotation feature. Maybe it could help you

0 Kudos
RishabhRaj29
Occasional Contributor

I was able to make it work. 

I created one Stroke symbol, Arrow symbol. Set marker placement properties to place it at the end. Then added both the stroke and arrow to symbol layers. 

 

Created a new line symbol and added the symbol layers as the symbol, then created a simple line callout on this line symbol. 

After that added this callout to the Text symbol which contains the style and symbol for the label.

Then it was simple labelling code to include the text symbol in the label class. 

0 Kudos
RishabhRaj29
Occasional Contributor

Here is the updated response with the code snippet:

QueuedTask.Run(() =>
{
var lyrDefn = featureLayer.GetDefinition() as CIMFeatureLayer;
var textSymbol = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.BlackRGB, 12, "Arial", "Regular");
textSymbol.OffsetY = 45.0;
var maplexLabelPlacementProps = new CIMMaplexLabelPlacementProperties
{
FeatureType = LabelFeatureType.Polygon,
LabelLargestPolygon = false,
CanRemoveOverlappingLabel = false,
PolygonPlacementMethod = MaplexPolygonPlacementMethod.HorizontalInPolygon,
CanPlaceLabelOutsidePolygon = true,
PolygonAnchorPointType = MaplexAnchorPointType.ErodedCenter,
IsOffsetFromFeatureGeometry = true,
MultiPartOption = MaplexMultiPartOption.OneLabelPerPart,
PrimaryOffset = 10.0
};
//End arrow
var arrow = SymbolFactory.Instance.ConstructMarker(63, "ESRI Arrowhead", "Regular", 10, ColorFactory.Instance.BlackRGB) as CIMCharacterMarker;
//Marker placement on end - Both, JustBegin, JustEnd
var endMarkerPlacement = new CIMMarkerPlacementAtExtremities()
{
ExtremityPlacement = ExtremityPlacement.JustEnd,
PlacePerPart = true,
AngleToLine = true
};
arrow.MarkerPlacement = endMarkerPlacement;
var symbol_layers = new List<CIMSymbolLayer>();
symbol_layers.Add(arrow);
var stroke = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid);

// Create a callout
//CIMLineSymbol lineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid);
symbol_layers.Add(stroke);
var CIMLineSymbol = new CIMLineSymbol()
{
SymbolLayers = symbol_layers.ToArray()
};
ArcGIS.Core.CIM.CIMSimpleLineCallout callout = new ArcGIS.Core.CIM.CIMSimpleLineCallout
{
LeaderTolerance = 1.0,
LeaderOffset = 4.0,
//LineSymbol = lineSymbol,
LineSymbol = CIMLineSymbol,
AutoSnap = true

};
textSymbol.Callout = callout;

var lyrsLabelsClasses = lyrDefn.LabelClasses.ToList();
var theLabelClass = lyrsLabelsClasses.FirstOrDefault();
theLabelClass.ExpressionEngine = LabelExpressionEngine.Arcade;
//theLabelClass.Expression = "return $feature.name;";
theLabelClass.Expression = "'Test'";
theLabelClass.TextSymbol = textSymbol.MakeSymbolReference();
theLabelClass.MaplexLabelPlacementProperties = maplexLabelPlacementProps;
lyrDefn.LabelClasses = lyrsLabelsClasses.ToArray(); //Set Label Class back to definition
featureLayer.SetDefinition(lyrDefn); //set the layer's definition;
featureLayer.SetLabelVisibility(true);
});

0 Kudos