I have a geology layer with a very large legend that was painstakingly created based on a geological code. I now have a new attribute which is a friendly description for each code and I would like the legend to use (or simply display) the description instead of the geological code. How can I do this without recreating the legend by hand?

  • Would you be willing to do this by Code? I did something just like this, for an LULC rater – Devdatta Tengshe Feb 4 '11 at 4:06
  • @Devdatta, It may be that 'do it by hand' and 'do it by code' are the only answers, so if you have a code solution to share it may be worth posting. I my case I'll probably suck it up and bribe an intern into doing it for me. – Regan Sarwas Feb 4 '11 at 16:30
  • Sounds like something that ArcPy.mapping should be able to do - perhaps start by looking at the LegendElement object: help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… I'm not certain that ArcPy.mapping has the functionality to be able to swap the field being used by a legend item so please just treat as a suggestion. – PolyGeo Feb 13 '11 at 22:28
  • @PolyGeo, I agree it should, but it looks like it doesn't. Neither the Layer object, nor the LegendElement object provide any access to the renderer. The closest the LegendElement object gets is providing a readonly list of item names. Thanks for the idea, it was worth checking on. – Regan Sarwas Feb 14 '11 at 17:11

The following C# snippet did the trick (in the OnClick() method of a Button AddIn):

const string CodeField = "SMUcode";
const string DescriptionField = "SMUdetails";

IGeoFeatureLayer layer = ArcMap.Document.SelectedLayer as IGeoFeatureLayer;
IUniqueValueRenderer renderer = layer.Renderer as IUniqueValueRenderer;
IDisplayTable table = layer as IDisplayTable;
IFeatureCursor cursor = table.SearchDisplayTable(null, false) as IFeatureCursor;
int indexCodeField = cursor.Fields.FindField(CodeField);
int indexDescriptionField = cursor.Fields.FindField(DescriptionField);
//loop through each feature creating a dictionary mapping codes to descriptions
//code and descriptions should match 1 for 1, but if not, the last description
//for a code value will be used.
var descriptions = new Dictionary<string, string>();
IFeature feature = cursor.NextFeature();
while (feature != null)
    string code = feature.Value[indexCodeField] as string;
    string description = feature.Value[indexDescriptionField] as string;
    descriptions[code] = description;
    feature = cursor.NextFeature();

//loop through the renderer changing each value
//Assumes descriptions are unique
renderer.Field[0] = DescriptionField;
for (int i = 0; i < renderer.ValueCount; i++)
    string code = renderer.Value[i];
    // change the label
    renderer.Label[code] = descriptions[code];
    //Change the value of the renderer item.  
    renderer.Value[i] = descriptions[code];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.