ThinkGeo.com    |     Documentation    |     Premium Support

Determining which feature labels did not display

I load some layers and set the properities such that overlapping labels will not display.


However, I have a need to find out which features did not display their labels due to the overlapping algorithms.


1. Is there a way I can find this out?


2. Is there a way I could determine (in advance) which labels would not display and then change their label to something smaller that might display because of less overlap likeliness.  For instance, if the label would have been "Bob Smith", I could change the label to "1" - this would then be used as an index to look up on a seperate list of features that could not display their full labels.


Your help is appreciated.


Jim



Does anyone have any advice on this topic?

Jim, 
  
   Sorry to make you wait on this.  We are launching 4 products to production today and it was quite busy last week as we pulled some support resource to help with the testing.   
  
   On to your question…  I think there is a way to do what you are talking about.  In our labeling system we have setup a series of protected virtual methods that get called in order to do the labeling.  Like for example the first method gets the labels in view, the second step eliminated duplicates, the third step does something etc.  What you could do is inherit from our text style, override the proper step and then in your code call the base code.  You can look at the results and then if you don’t like them do something to modify the stuff coming in and then resend them.  You will see the features going in and the results going out.  You will control if the results are accepted.  At the moment I need to run but when I get back in the office I will find that method, do a quick test and let you know my results. 
  
 David

I will be anxiously standing by… thanks.

Jim,


I am sorry for the delay for your questions.
 
Hope my following sample code can show you what is going on the labeling stuff. Of course, you can change the logic to anything you want.

    public class MyTextStyle
        : TextStyle
    {
        public MyTextStyle()
            : base()
        { }
 
        public MyTextStyle(string textColumnName, GeoFont textFont, GeoSolidBrush textSolidBrush)
            : base(textColumnName, textFont, textSolidBrush)
        {
        }
 
        public Collection<Feature> GetLabeledFeatures(Collection<Feature> allFeatures, GeoCanvas drawingCanvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
        {
            Collection<Feature> unfilteredFeatures = base.FilterFeatures(allFeatures, drawingCanvas);
 
            Collection<Feature> returnFeatures = new Collection<Feature>(); 
            RectangleShape canvasScreenExtent = null;
            if (SuppressPartialLabels)
            {
                canvasScreenExtent = ConvertToScreenShape(new Feature(drawingCanvas.CurrentWorldExtent), drawingCanvas).GetBoundingBox();
            }
 
            foreach (Feature feature in unfilteredFeatures)
            {
                Collection<LabelingCandidate> labelingCandidates = GetLabelingCandidates(feature, drawingCanvas);
                foreach (LabelingCandidate labelingCandidate in labelingCandidates)
                {
                    if (CheckDuplicate(labelingCandidate, drawingCanvas, labelsInThisLayer, labelsInAllLayers)) { continue; }
                    if (CheckOverlapping(labelingCandidate, drawingCanvas, labelsInThisLayer, labelsInAllLayers)) { continue; }
 
                    SimpleCandidate simpleCandidate = new SimpleCandidate(labelingCandidate.OriginalText, labelingCandidate.ScreenArea);
                    if (labelsInAllLayers != null) { labelsInAllLayers.Add(simpleCandidate); }
                    if (labelsInThisLayer != null) { labelsInThisLayer.Add(simpleCandidate); }
 
                    if (SuppressPartialLabels)
                    {
                        if (!canvasScreenExtent.Contains(labelingCandidate.ScreenArea))
                        {
                            returnFeatures.Add(feature);
                        }
                    }
                    else
                    {
                        returnFeatures.Add(feature);
                    }
                }
            }
 
            return returnFeatures;
        }
 
        public Collection<Feature> GetUnLabeledFeaturesForOverlayping(Collection<Feature> allFeatures, GeoCanvas drawingCanvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
        {
            Collection<Feature> unfilteredFeatures = base.FilterFeatures(allFeatures, drawingCanvas);
 
            Collection<Feature> returnFeatures = new Collection<Feature>();
 
            foreach (Feature feature in unfilteredFeatures)
            {
                Collection<LabelingCandidate> labelingCandidates = GetLabelingCandidates(feature, drawingCanvas);
                foreach (LabelingCandidate labelingCandidate in labelingCandidates)
                {
                    if (CheckDuplicate(labelingCandidate, drawingCanvas, labelsInThisLayer, labelsInAllLayers))
                    {
                        continue;
                    }
                    if (CheckOverlapping(labelingCandidate, drawingCanvas, labelsInThisLayer, labelsInAllLayers))
                    {
                        returnFeatures.Add(feature);
                    }
 
                    SimpleCandidate simpleCandidate = new SimpleCandidate(labelingCandidate.OriginalText, labelingCandidate.ScreenArea);
                    if (labelsInAllLayers != null) { labelsInAllLayers.Add(simpleCandidate); }
                    if (labelsInThisLayer != null) { labelsInThisLayer.Add(simpleCandidate); }
                   
                }
            }
 
            return returnFeatures;
        }
 
        public Collection<Feature> GetUnLabeledFeaturesForDupulicating(Collection<Feature> allFeatures, GeoCanvas drawingCanvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
        {
            Collection<Feature> unfilteredFeatures = base.FilterFeatures(allFeatures, drawingCanvas);
 
            Collection<Feature> returnFeatures = new Collection<Feature>();
 
            foreach (Feature feature in unfilteredFeatures)
            {
                Collection<LabelingCandidate> labelingCandidates = GetLabelingCandidates(feature, drawingCanvas);
                foreach (LabelingCandidate labelingCandidate in labelingCandidates)
                {
                    if (CheckDuplicate(labelingCandidate, drawingCanvas, labelsInThisLayer, labelsInAllLayers))
                    {
                        returnFeatures.Add(feature);
                    }
                    if (CheckOverlapping(labelingCandidate, drawingCanvas, labelsInThisLayer, labelsInAllLayers))
                    {
                        continue;
                        //returnFeatures.Add(feature);
                    }
 
                    SimpleCandidate simpleCandidate = new SimpleCandidate(labelingCandidate.OriginalText, labelingCandidate.ScreenArea);
                    if (labelsInAllLayers != null) { labelsInAllLayers.Add(simpleCandidate); }
                    if (labelsInThisLayer != null) { labelsInThisLayer.Add(simpleCandidate); }
 
                }
            }
 
            return returnFeatures;
        }
}

 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

I’m trying to work out how to call these methods.  A sample of calling the GetUnLabeledFeaturesForOverlayping method would be helpful. 
  
 Jim

Ok.  I have overriden the DrawCore of my TextStyle and in that method I have this call: 
  
             Collection<Feature> unlabled = GetUnLabeledFeaturesForOverlapping((Collection<Feature>)features, canvas, labelsInThisLayer, labelsInAllLayers); 
  
 this returns to me a list of features that did not print their labels - however, the features do not have anything but the label column in their columnvalues.  I would like to get the identity column that I include with the feature so that I can reference back to the methods that will do something with this list. 
  
 Any ideas?

Ok.  So I grab the id of each feature that is returned by GetUnLabeledFeaturesForOverlapping() and then use the correct featureLayer to grab all features in that list - retreiving the column that I need for identification. 
  
 Is this the best way?  It does seem to be working. 
  
 Jim

Jim,


This is way should work as David describled above. I hope it is the best way:).
 
Thanks very much for updating your status and let us know the result.
 
Any more quesitons just feel free to let me know.
 
Thanks.
 
Yale