Hi...
Though I've done a lot of Typescript programing for ArcGIS WebApplications, I am very now to ArcGIS Pro SDK for .net development.
We are porting an arcGIS Map 10.X addon to ArcGIS Pro 3.6. A lot of things ave been quite straight forward, but I have run into a block, and hope for some help.
We have application configurations from System ENV, .json, .dat, and .ini files and have loaded all of it into a few Generic Dictionaries.
In on place within a file called LayerUtils, we load a list of FeatureLayers from a ThemeSet File and then send this list of layers to be added to the Map.
The method that adds the list of layers to the map calls SetLayerDisplayProperties(featureLayer) for preprocessing. This method eventually sends the layer to SetLayerLabel(featureLayer).
This is how the old code looks and I am trying to figure out why this small amount of code must be so ginormous (according to Google AI) when asked about labeling FeatureLayers.
I deduced the featureLayer.DisplayAnnotation = true, should be featureLayer.SetLabelVisibility(true).
I have the LabelSymbol defined in my version of SymbolUtils.
If someone can point me to or provide a succinct example of
Here is the code:
Yes.. It is old!!!
/// <summary>
/// Sets the label for a layer
/// </summary>
/// <param name="featureLayer">An GeoFeatureLayer interface</param>
private static void SetLayerLabel(IGeoFeatureLayer featureLayer)
{
try
{
if (featureLayer != null)
{
int labelField = featureLayer.FeatureClass.Fields.FindField("Label");
if (labelField > -1)
{
featureLayer.DisplayAnnotation = true;
IAnnotateLayerProperties annotateLayerProps = null;
IElementCollection placedElements;
IElementCollection unplacedElements;
featureLayer.AnnotationProperties.QueryItem(0, out annotateLayerProps, out placedElements, out unplacedElements);
ILabelEngineLayerProperties labelEngineLayerProps = annotateLayerProps as ILabelEngineLayerProperties;
labelEngineLayerProps.Expression = "[Label]";
labelEngineLayerProps.Symbol = SymbolUtils.LabelSymbol;
}
}
}
catch (Exception ex)
{
ErrorHandling.ErrorMessage(ex);
}
}
It will be a while before I can test and debug this, but I just want to know If this is ideal, or if I should create an AnnotationLayer and do a who lot of stuff I don't want to do, if it isn't necessary.
This is what I came up with:
private void SetLayerLabel(FeatureLayer featureLayer)
{
//This is a continuation from the calling method and is already running inside of QueuedTask.Run()
try
{
if (featureLayer != null)
{
int labelField = featureLayer.GetFeatureClass().GetDefinition().FindField("Label");
if (labelField > -1)
{
CIMFeatureLayer cimFeatureLayer = featureLayer.GetDefinition() as CIMFeatureLayer;
if (cimFeatureLayer != null)
{
CIMLabelClass newLabelClass = new CIMLabelClass()
{
Name = featureLayer.Name,
Visibility = true,
Expression = $"return {SymbolUtils.LabelSymbolTextFormat}",
TextSymbol = new CIMSymbolReference
{
Symbol = SymbolUtils.LabelSymbol
},
MaplexLabelPlacementProperties = new CIMMaplexLabelPlacementProperties
{
PreferHorizontalPlacement = true
}
};
List<CIMLabelClass> labelClasses = cimFeatureLayer.LabelClasses.ToList();
labelClasses.Add(newLabelClass);
cimFeatureLayer.LabelClasses = labelClasses.ToArray();
cimFeatureLayer.LabelVisibility = true;
featureLayer.SetDefinition(cimFeatureLayer);
}
}
}
}
catch (Exception ex)
{
ErrorHandling.ErrorMessage(ex);
}
}
Thanks for any input!!!
Solved! Go to Solution.
You’re on the right track, and no—you don’t need an AnnotationLayer unless you need stored, editable annotation. For simple dynamic labeling, stick with CIM label classes on the FeatureLayer.
A few key corrections:
Expression
In Pro SDK, CIMLabelClass.Expression expects an Arcade label expression (string). For your case it can be as simple as:
"return $feature.Label"
or
"$feature.Label" depending on Arcade profile support, but safest is the return form.
Don’t “add” label classes repeatedly
If you run this multiple times, you’ll keep appending classes. Better: replace the existing label class (or clear first).
Enable labeling
Setting both cimFeatureLayer.LabelVisibility = true and the label class Visibility=true is correct.
Minimal pattern (inside QueuedTask.Run):
var cim = (CIMFeatureLayer)featureLayer.GetDefinition();
cim.LabelClasses = new[]
{
new CIMLabelClass
{
Name = "Default",
Visibility = true,
Expression = "return $feature.Label",
TextSymbol = new CIMSymbolReference { Symbol = SymbolUtils.LabelSymbol },
MaplexLabelPlacementProperties = new CIMMaplexLabelPlacementProperties()
}
};
cim.LabelVisibility = true;
featureLayer.SetDefinition(cim);
Bottom line: your approach is ideal for Pro 3.x. Only go AnnotationFeatureClass/AnnotationLayer if you need cartographic editing, conflict resolution stored in the DB, or performance for massive static maps.
– Venkat
You’re on the right track, and no—you don’t need an AnnotationLayer unless you need stored, editable annotation. For simple dynamic labeling, stick with CIM label classes on the FeatureLayer.
A few key corrections:
Expression
In Pro SDK, CIMLabelClass.Expression expects an Arcade label expression (string). For your case it can be as simple as:
"return $feature.Label"
or
"$feature.Label" depending on Arcade profile support, but safest is the return form.
Don’t “add” label classes repeatedly
If you run this multiple times, you’ll keep appending classes. Better: replace the existing label class (or clear first).
Enable labeling
Setting both cimFeatureLayer.LabelVisibility = true and the label class Visibility=true is correct.
Minimal pattern (inside QueuedTask.Run):
var cim = (CIMFeatureLayer)featureLayer.GetDefinition();
cim.LabelClasses = new[]
{
new CIMLabelClass
{
Name = "Default",
Visibility = true,
Expression = "return $feature.Label",
TextSymbol = new CIMSymbolReference { Symbol = SymbolUtils.LabelSymbol },
MaplexLabelPlacementProperties = new CIMMaplexLabelPlacementProperties()
}
};
cim.LabelVisibility = true;
featureLayer.SetDefinition(cim);
Bottom line: your approach is ideal for Pro 3.x. Only go AnnotationFeatureClass/AnnotationLayer if you need cartographic editing, conflict resolution stored in the DB, or performance for massive static maps.
– Venkat
Thank you Venkata,
This is much better than I thought it would be 😊