I'm looking for a way to programmatically edit the symbol labels of my feature layer (the labels that appear in the table of contents / legend):
For example, let's say I'm assigning a simple unique value renderer to my layer based on a single field:
var fields = new[] {"RENDITION"}; var rendererDef = new UniqueValueRendererDefinition(fields); var renderer = layer.CreateRenderer(rendererDef); layer.SetRenderer(renderer);
Is there a way I can then define the labels for these unique symbols?
Solved! Go to Solution.
Hi Luke,
We have to edit the unique value renderer itself, once it has been made. I have provided some code below. Note: I encourage you to look at the samples for the CIM at https://github.com/esri/arcgis-pro-sdk-community-samples/tree/master/Map-Authoring/CIMExamples. I based the code snippet below on the source code in 'CreateCIMRendererFromScratch.cs'. It uses the U.S. States dataset available with the samples.
internal class SetLabelsOnUniqueValueRenderer : Button {
protected async override void OnClick() {
var usStatesLayer =
MapView.Active.Map.GetLayersAsFlattenedList().FirstOrDefault((fl) => fl.Name == "States") as
FeatureLayer;
if (usStatesLayer == null) {
MessageBox.Show("Please add the 'States' layer to the TOC - with a 'STATE_NAME' field containing state names.", "Cannot find US States");
return;
}
//make a unique value renderer
await CreateUniqueValueRendererOnStatesAsync(usStatesLayer);
SetLabelsOnStatesRendererAsync(usStatesLayer);
}
private Task CreateUniqueValueRendererOnStatesAsync(FeatureLayer fl) {
return QueuedTask.Run(() => {
var uvrDef = new UniqueValueRendererDefinition() {
ValueFields = new string[] {"STATE_ABBR"},
SymbolTemplate = SymbolFactory.DefaultPolygonSymbol.MakeSymbolReference(),
//Simple ramp
ColorRamp = new CIMLinearContinuousColorRamp() {
FromColor = CIMColor.CreateRGBColor(0, 255, 0, 60),//Green, partially transparent
ToColor = CIMColor.CreateRGBColor(255, 0, 0, 60),//Red, partially transparent
ColorSpace = new CIMICCColorSpace() {
URL = "Default RGB"
}
}
};
fl.SetRenderer(fl.CreateRenderer(uvrDef));
});
}
private Task SetLabelsOnStatesRendererAsync(FeatureLayer fl) {
return QueuedTask.Run(() => {
var renderer = fl.GetRenderer() as CIMUniqueValueRenderer;
//A UniqueValue renderer has one or more CIMUniqueValueGroups. In this example
//there is only one CIMUniqueValueGroup (otherwise use a 'foreach(var group in ....)'
var group = renderer.Groups[0];
//Each group has one or more CIMUniqueValueClasses - in this case we have one class per
//STATE_ABBR value. Note: The default value and label are on the renderer itself
//(renderer.DefaultLabel, renderer.DefaultSymbol) and are NOT in a class.
foreach (var valClass in group.Classes) {
//Each CIMUniqueValueClass has a Label (what you are after 😉 and an array of CIMUniqueValues
//As our values are unique, we have one CIMUniqueValue per class.
//Get its field value (read from STATE_ABBR) and change the label to be the state name
if (valClass.Values[0].FieldValues[0] == "AK")
valClass.Label = "Alaska";
else if (valClass.Values[0].FieldValues[0] == "AL")
valClass.Label = "Alabama";
else if (valClass.Values[0].FieldValues[0] == "AR")
valClass.Label = "Arkansas";
else if (valClass.Values[0].FieldValues[0] == "AZ")
valClass.Label = "Arizona";
//etc,etc
}
fl.SetRenderer(renderer);
});
}
}
Hi Luke,
We have to edit the unique value renderer itself, once it has been made. I have provided some code below. Note: I encourage you to look at the samples for the CIM at https://github.com/esri/arcgis-pro-sdk-community-samples/tree/master/Map-Authoring/CIMExamples. I based the code snippet below on the source code in 'CreateCIMRendererFromScratch.cs'. It uses the U.S. States dataset available with the samples.
internal class SetLabelsOnUniqueValueRenderer : Button {
protected async override void OnClick() {
var usStatesLayer =
MapView.Active.Map.GetLayersAsFlattenedList().FirstOrDefault((fl) => fl.Name == "States") as
FeatureLayer;
if (usStatesLayer == null) {
MessageBox.Show("Please add the 'States' layer to the TOC - with a 'STATE_NAME' field containing state names.", "Cannot find US States");
return;
}
//make a unique value renderer
await CreateUniqueValueRendererOnStatesAsync(usStatesLayer);
SetLabelsOnStatesRendererAsync(usStatesLayer);
}
private Task CreateUniqueValueRendererOnStatesAsync(FeatureLayer fl) {
return QueuedTask.Run(() => {
var uvrDef = new UniqueValueRendererDefinition() {
ValueFields = new string[] {"STATE_ABBR"},
SymbolTemplate = SymbolFactory.DefaultPolygonSymbol.MakeSymbolReference(),
//Simple ramp
ColorRamp = new CIMLinearContinuousColorRamp() {
FromColor = CIMColor.CreateRGBColor(0, 255, 0, 60),//Green, partially transparent
ToColor = CIMColor.CreateRGBColor(255, 0, 0, 60),//Red, partially transparent
ColorSpace = new CIMICCColorSpace() {
URL = "Default RGB"
}
}
};
fl.SetRenderer(fl.CreateRenderer(uvrDef));
});
}
private Task SetLabelsOnStatesRendererAsync(FeatureLayer fl) {
return QueuedTask.Run(() => {
var renderer = fl.GetRenderer() as CIMUniqueValueRenderer;
//A UniqueValue renderer has one or more CIMUniqueValueGroups. In this example
//there is only one CIMUniqueValueGroup (otherwise use a 'foreach(var group in ....)'
var group = renderer.Groups[0];
//Each group has one or more CIMUniqueValueClasses - in this case we have one class per
//STATE_ABBR value. Note: The default value and label are on the renderer itself
//(renderer.DefaultLabel, renderer.DefaultSymbol) and are NOT in a class.
foreach (var valClass in group.Classes) {
//Each CIMUniqueValueClass has a Label (what you are after 😉 and an array of CIMUniqueValues
//As our values are unique, we have one CIMUniqueValue per class.
//Get its field value (read from STATE_ABBR) and change the label to be the state name
if (valClass.Values[0].FieldValues[0] == "AK")
valClass.Label = "Alaska";
else if (valClass.Values[0].FieldValues[0] == "AL")
valClass.Label = "Alabama";
else if (valClass.Values[0].FieldValues[0] == "AR")
valClass.Label = "Arkansas";
else if (valClass.Values[0].FieldValues[0] == "AZ")
valClass.Label = "Arizona";
//etc,etc
}
fl.SetRenderer(renderer);
});
}
}
Just what I was looking for. Thanks Charles.