3

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.

4
  • gis.stackexchange.com/questions/6160/…
    – patrick
    Commented Nov 10, 2011 at 23:06
  • @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
    Commented Nov 10, 2011 at 23:14
  • can't you just do: string whatIsValue = leprops.Expression?
    – patrick
    Commented Nov 10, 2011 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
    Commented Nov 11, 2011 at 0:19

2 Answers 2

1

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.
4
  • 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
    Commented Nov 11, 2011 at 0:30
  • It appears the preCode parameter for SetExpression isn't necessarily required to be non-empty.
    – Josh
    Commented Nov 11, 2011 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. Commented Nov 12, 2011 at 5:31
  • It is not real clear to me where to get the pre-code. Please see code in separate answer. Commented Nov 14, 2011 at 15:36
1

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;
}
4
  • 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
    Commented Nov 14, 2011 at 19:56
  • @josh Did you use any PreCode? Commented Nov 16, 2011 at 3:49
  • 1
    PreCode is not used. You don't need it. Commented Nov 16, 2011 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
    Commented Nov 17, 2011 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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