ThinkGeo.com    |     Documentation    |     Premium Support

Displaying labels on the MapShapeLayer (from the MapShapes project)

I am using the MapShapes sample project to define a MapShapeLayer where every feature has its own graphic properties. I have also configured the layer to use labels. However, the labels do not display on the layer when the layer is drawn (the shapes do).


Here's my code:


public class MapShapeLayer : InMemoryFeatureLayer

{

    MapShapeLayer()

    {

        this.Open();

        this.Columns.Add(new FeatureSourceColumn("Label", "String", 30));

        this.Close();



        this.ZoomLevelSet.ZoomLevel101.DefaultTextStyle = TextStyles.City1("Label");

        this.ZoomLevelSet.ZoomLevel101.DefaultTextStyle.PointPlacement - PointPlacement.LowerRight;

        // etc.

    }

}


I use the same DrawCore method as defined in the project.


My BaseMapShape class has a property called "Label" that does the following:


public class BaseMapShape

{

    public string Label

    {

        set { Feature.ColumnValues.Add("Label", value);}

    }

}


This property is executed whenever I add a BaseMapShape object to the MapShapes collection.


Nonetheless (as mentioned above) the labels do not appear on the map when the layer is drawn.


What else do I have to do in order to display labels?


Thanks!



Greg, 
  
   I would really have to see the complete code, for the class at least, to see what is going on.  From the snippets I can’t run it or really do a test.  I am pretty certain we can solve this but too many questions to even offer a guess at this point. 
  
 David

Thanks, David. I am attaching a skinnied-down version of the MapShapes project. I removed the contents of the Data folder in order to meet the maximum file size of the upload attachments tab. If you grab the contents of the Data folder from the actual MapShapes project, you should have a runnable version of the project.


Please let me know if this is not sufficient.



1286-MapShapes.zip (130 KB)

Greg, 
  
  Thanks, looking at it right now.   
  
 David

Greg,


I found the reason and you will need to stay with me here.  I found the cause but I am not sure on your intent.  The reason it is not labeling anything is that in the constructor for your new layer type you are setting the DefaultTextStyle on the ZoomLevelSet of the layer itself.  If you look at the overload for the DrawCore you will see we never refrence the layer itself and instead call the draw on the zoom levels of the map shapes.  Each map shape has its own zoom level set and it needs to be set for each one.  If you add the third line below to the code you sent it now shows the label.  All of the code you placed in the constructor is never used.


 



            MapShape mapShape1 = new MapShape(new Feature(-104, 42));
            mapShape1.Label = "Plane";
            mapShape1.ZoomLevels.ZoomLevel01.DefaultTextStyle = TextStyles.City1("Label");
            mapShape1.ZoomLevels.ZoomLevel01.DefaultPointStyle = new PointStyle(new GeoImage(@"..\..\Data\Cargo Plane.png"));
            mapShape1.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            mapShapeLayer.MapShapes.Add("1", mapShape1);
 

 


If you want the labeling to be automatic because it is kind of inherit in your system them add that code to the constructor of the MapShape class itself.  Below is the new MapShapeConstructor I modified, I just moved the code from the layer to the map shape constructor.


 



        // Let's use this as a handy constructor if you already have
        // a feature or want to create one inline.
        public MapShape(Feature feature)
        {
            this.feature = feature;
            zoomLevelSet = new ZoomLevelSet();
            this.ZoomLevels.ZoomLevel01.DefaultTextStyle = TextStyles.City1("Label");
            this.ZoomLevels.ZoomLevel01.DefaultTextStyle.PointPlacement = PointPlacement.LowerRight;
            this.ZoomLevels.ZoomLevel01.DefaultTextStyle.Mask = new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 1), new GeoSolidBrush(GeoColor.StandardColors.WhiteSmoke));
            this.ZoomLevels.ZoomLevel01.DefaultTextStyle.MaskMargin = 3;
            this.ZoomLevels.ZoomLevel01.DefaultTextStyle.HaloPen = new GeoPen(GeoColor.GeographicColors.Ice, 2);
        }
 

 


If you need more info or want me to send you back the entire solution let me know.  I tried to explain it but sometimes snippets can be confusing.  BTW the first part of code is not necessary if you put in the last snippet of code.  I just wanted to show the labeling is happening on the MapShape itself



David



Greg,


Here is the screenshot showing hwo it labels.  I forgot to include it in the previous post.



David



Thank you so much, David - it works beautifully! For some reason the labels are not showing up for ALL of my shapes, but my starting assumption is that I still have something wrong with my code and need to track it down.  
  
 Thanks again!

Jumping in here… there are settings on the Text style where you indicate your willingness to see duplicate labels, colliding labels, etc.   There will be some combination of those settings that will probably get you every label, but I do have some data where no matter what I do, the last label of the feature source data is not displayed.

Greg, 
  
   Ted is right.  The TextStyle is optimized by default for roads and has many settings tuned that way.  I would use the items below and see what happens.  Their name and setting should say it all. 
  
             this.ZoomLevels.ZoomLevel01.DefaultTextStyle.DuplicateRule = LabelDuplicateRule.UnlimitedDuplicateLabels; 
             this.ZoomLevels.ZoomLevel01.DefaultTextStyle.OverlappingRule = LabelOverlappingRule.AllowOverlapping; 
  
 Let me know how this does. 
  
 David 


Adding those settings to the style has definitely helped so more labels appear on my shapes. However, the labels do not appear on all shapes. For example, if the label is larger than the shape it will not display. What setting can I use to allow labels to display when the label size exceeds the shape size?

Greg, 
  
   Can you send me a screen shot?  Actual if they are lines you can try the TextSegmentRatio or something like that.  Make it really big or small and see if that helps.  That should onl effect lines though. 
  
 David

I set the TextLineSegmentRatio to 1000 and that seems to display ALL my missing labels. Thanks everyone for the advice!

Greg, 
  
   That was the API I was thinking about.  For lines it tries to suppress labels where the label is larget than the line by the ratio of the property.  Again this style was really road optimized and actually I can see how that was a mistake.  Maybe a RoadTextStyle and a PointTextStyle etc. would have been better options and then a general one instead of a single style optimized for roads.  Thanks for the realization! 
  
 David