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.
Solved! Go to Solution.
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);
});
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
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.
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);
});