Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

In another area of my application I'd like to display the per-feature label value rendered when Labeling is turned on in ArcMap, i.e. when IGeoFeatureLayer.DisplayAnnotation becomes true.

I have a list of items of type IFeature from say myFeatLayer. I am able to retrieve the layer-level labeling properties, including text formatting, with:

IGeoFeatureLayer geoLayer = (IGeoFeatureLayer)myFeatLayer;
IAnnotateLayerPropertiesCollection anno = pGeoFeatureLayer.AnnotationProperties;
IElementCollection iecp;
IElementCollection iecup;
IAnnotateLayerProperties props;
anno.QueryItem(0, out props, out iecp, out iecup);
ILabelEngineLayerProperties leprops = props as ILabelEngineLayerProperties;
ITextSymbol text = leprops.Symbol;

What I don't know is necessarily how to query an IFeature, and with what (leprops.Expression?), to retrieve the actual value of what will be rendered near each feature by the labeling engine.

Thanks in advance.

share|improve this question
    
    
@iterationx - I did see that. But it's not quite the same question. It seems to me that is programmatically changing the field on which the labeling engine operates, not retrieving the value being rendered. –  Josh Nov 10 '11 at 23:14
    
can't you just do: string whatIsValue = leprops.Expression? –  patrick Nov 10 '11 at 23:52
    
@iterationx - that specifies the field name. As in a basic Name:Value pair, leprops.Expression is the Name. I need the per-feature value. For example, leprops.Expression would return the string "[FID]". So I think I'll need Expression to query the feature. –  Josh Nov 11 '11 at 0:19

2 Answers 2

up vote 2 down vote accepted

The basic workflow for doing this is:

  1. Get the AnnotationExpressionEngine from ILabelEngineLayerProperties via get_ExpressionParser
  2. Set the label expression via SetExpression for simple expressions of SetCode for complex expressions on the parser. This will hand back the actual parser. Simplicity of expression is determined by ILabelEngineLayerProperties::get_IsExpressionSimple.
  3. Use the FindLabel method on the parser to get the label text.
share|improve this answer
    
FindLabel takes an IFeature, thanks! One question, what is the string preCode parameter for the SetExpression method and/or where does it come from? –  Josh Nov 11 '11 at 0:30
    
It appears the preCode parameter for SetExpression isn't necessarily required to be non-empty. –  Josh Nov 11 '11 at 1:31
    
If the expression is simple (a one liner - determined via ILabelEngineLayerProperties::get_IsExpressionSimple) pass in the expression via SetExpression with no pre-code. If the expression is complex (a FindLabel function) then pass the expression itself in as the fullcode parameter and the function name ("FindLabel") as the runFunction. I updated the answer above to reflect this. –  Craig Williams Nov 12 '11 at 5:31
    
It is not real clear to me where to get the pre-code. Please see code in separate answer. –  Kirk Kuykendall Nov 14 '11 at 15:36

This code is a follow-up on Craig's post. It is not real clear to me where the preCode comes from. This should probably be a comment, but we can't put code in a comment.

public static void ListLabels(IGeoFeatureLayer gfLayer)
{
    var parsers = GetParsers(gfLayer);

    IFeature feat;
    var fCur = gfLayer.FeatureClass.Search(null, false);
    while ((feat = fCur.NextFeature()) != null)
    {
        foreach (KeyValuePair<string,IAnnotationExpressionParser> kvp in parsers)
        {
            string label = kvp.Value.FindLabel(feat);
            Debug.Print("class: {0} oid: {1} label: {2}",kvp.Key, feat.OID, label);
        }
    }
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(fCur);
}

public static Dictionary<string,IAnnotationExpressionParser> GetParsers(IGeoFeatureLayer gfLayer)
{
    var parsers = new Dictionary<string,IAnnotationExpressionParser>();
    for (int i = 0; i < gfLayer.AnnotationProperties.Count; i++)
    {
        IElementCollection placedElements;
        IElementCollection unplacedElements;
        IAnnotateLayerProperties alProps;

        gfLayer.AnnotationProperties.QueryItem(
            i, out alProps, out placedElements, out unplacedElements);
        var leProps = alProps as ILabelEngineLayerProperties2;
        string preCode = ""; // where to get this?
        var aeParser = leProps.ExpressionParser.SetExpression(preCode, leProps.Expression);
        parsers.Add(alProps.Class, aeParser);
    }
    return parsers;
}
share|improve this answer
    
Craig's answer with respect to the SetExpression and FindLabel methods were the missing links for me, but many thanks for posting complete code! –  Josh Nov 14 '11 at 19:56
    
@josh Did you use any PreCode? –  Kirk Kuykendall Nov 16 '11 at 3:49
1  
PreCode is not used. You don't need it. –  Craig Williams Nov 16 '11 at 6:38
    
@KirkKuykendall, I didn't use any preCode, just passed in the empty string. As Craig said, doesn't appear to be used. Thanks again. –  Josh Nov 17 '11 at 6:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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