ThinkGeo.com    |     Documentation    |     Premium Support

Labeling when name is long

 I am having a hard time figuring out how to properly label a displayed map.   There are a couple of features that would be nice to have:  1) Forcing a label to display in multiple lines instead of a single long line and 2) The ability to specify where a road label should display.  Labeling roads seems to be a hit or miss affair.  Sometimes the label appears, but not where you want them.


I have looked at all the examples in the code community, but unfortunately all labeling projects are for the desktop edition.  But in any case none of them address the problem.


Lastly is there any way of pre-rendering a tile?  If I could somehow manually label each tile, then store the completed tile in cache, this I could get around the dynamic labeling shortcomings.  Is this sort of thing possible?


Thanks for any help,


 


Al Vigil



More on the labeling problem:  1) Setting ForceLineCarriage to true works on long names but only for polygons.  The property seems to be ignored when labeling points.  2) Half of my road labels are upside down.  See attached image.  3)  The labels are cut off at the tile boundary, even though DrawingMarginPercentage is set to 400.  Below is code use to create these labels: 
  
 TextStyle textStyle = TextStyles.Highway2("NAME"); 
         textStyle.TextLineSegmentRatio = 1;  //double.MaxValue
         textStyle.SplineType = SplineType.ForceSplining; 
         textStyle.Font = new GeoFont("Arial", 6); 
         textStyle.XOffsetInPixel = 0; 
         textStyle.YOffsetInPixel = 0; 
         textStyle.FittingPolygon = false; 
         textStyle0.DuplicateRule = LabelDuplicateRule.OneDuplicateLabelPerQuadrant; 
         roadLabelLayer.DrawingMarginPercentage = 400; 
  
 Problem 2, the labels being upside down, is the most serious problem.  Any help in solving this would be greatly appreciated. 
  
 Thanks, 
  
 Al Vigil

 


Hi Al,
The map suite line's labeling is based on LineBaseShape. In other words, one label per one LineShape or MultiLineShape. To render multiple labels for MultiLineShape, we need to make a custom TextStyle and overwrite GetLabelingCandidateCore method. It returns a collection of LabelingCandiate which contains position information where a road label should display. Generally, all the labels are drawn at the center of the lineshape, and you can change the postion using XOffsetInPixel and YOffsetInPixel. Here as following are the sample code about the question 1 and 2. Please pay attention to the “ToDo” comments:

 


        protected override Collection<LabelingCandidate> GetLabelingCandidateCore(Feature feature, GeoCanvas canvas)
        {
            Collection<LabelingCandidate> labelingCandidates = new Collection<LabelingCandidate>();
 
            WellKnownType shapeType = feature.GetWellKnownType();
 
            switch (shapeType)
            {
                default:
                    labelingCandidates = base.GetLabelingCandidateCore(feature, canvas);
                    break;
 
               case WellKnownType.Multiline:
                    // split it into individual lines, solve them independently and then join results.
                    MultilineShape multiLineShape = (MultilineShape)feature.GetShape();
                    foreach (LineShape lineShape in multiLineShape.Lines)
                    {
                        Feature lineFeauture = new Feature(lineShape, feature.ColumnValues);
                        Collection<LabelingCandidate> lineCandidates = GetLabelingCandidateCore(lineFeauture, canvas);
 
                        foreach (LabelingCandidate candidate in lineCandidates)
                            labelingCandidates.Add(candidate);
                    }
                    break;
 
                case WellKnownType.Line:
                    LineShape lineShapeOverall = (LineShape)feature.GetShape();
                    labelingCandidates = base.GetLabelingCandidateCore(feature, canvas);
                    // ToDo: you can change the label position here based on custom senario
                    foreach (LabelingCandidate candidate in labelingCandidates)
                    {
                        foreach (LabelInformation information in candidate.LabelInformation)
                        {
                            PointShape labelPostion = information.PositionInScreenCoordinates;
 
                            // Todo: custom setting........
                        }
                    }
 
                    break;
            }
 
            return labelingCandidates;
        }



Note: Both the WebEdition and DesktopEdition are based on MapSuiteCore.dll, so some of the desktop code community sample also can take effet in WebEdition.
The webEdition also can work on the pre-generated tiles. Here as following is about how to setting the cache for the Overlay:
Map1.StaticOverlay.ServerCache.CacheDirectory = MapPath("~/ImageCache/" + Request.Path);
Thanks,
 
Johnny
 
 
 

Hi AI: 



Here are the answers for your second post: 



1. Yes, the ForceLineCarriage just takes effect to Polygons. 

2. I’m unable to get you attached image, can you post it again? 

3. Regarding the cut off issue, please try SuppressPartialLabels as true. 



Thanks, 



Johnny 

 



 Attached is the image showing the upside-down labels.  This is a critical problem that I must solve.  The labels in question go on to a layer of arterial roads for the capital city of Managua, Nicaragua.  All segments of this network must be labeled.  I have created a shp file joined on road segment name, so there are no discontinuities in the segments.  But as you can see not only are most segments unlabeled, half of the ones that are are upside down.


I initially suspected that the segment direction made a difference, but found out it does not.  Labels are upside down for certain segments regardless of the vector direction.


Please help.


 



MapexsaError.zip (47.4 KB)

 


Hi AI,
Sorry for the delay. I’m unable to get the upside-down labels for roads, below is what I got form the attachment. It seems that the application runs into error. Can you check it? It’s hard for us to imagine the wrong labeling. It seems that there is no problem with your code; is there any other codes for labeling? Hope your further information.
 
Thanks,
Johnny
 
 

I see no such error in our program.  Attached is zipped file containing the arterial road shape file used for the labels (arterialJoined.shp),the one used for displaying the road network (arterial.shp),  an image of the map, where the arterial roads are shown in yellow, and the code used to label the arterial roads.   
  
 Notice right below the label Managua, in the middle of the map, the upside-down label. 
  
 This particular zoom level is 16 (we go from levels 09 to 20).  We would like to label more of the yellow roads, but we see only a few of the less important ones labeled.   
  
 I should mention that the shape file attached is used only to display the labels, not to display the vector.  The vector shape file (arterial.shp) is used to display the roads, the arterialJoined.shp to display the labels.  This latter one is joined on the road name. 
  
 I see a submit button here, but no way of uploading the zipped file.  Perhaps I will be given a chance after clicking on Submit.  If not, let me know how to get this file to you.  As I said before I have got to solve this problem.  One, I need better control of the placement of the labels, and Two, none of them should be upside down.

 


Hi AI,
The upside-down label is caused by the SplineType, please try the StandardPlining, the ForceSplining usually is used for Asian languages, such as Chinese or Japanese. The picture below is what we got:
 
To get more labels rendered, we can try the GridSize property of TextStyle , here as following are the demo codes:
 

Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
Map1.MapUnit = GeographyUnit.DecimalDegree;

ShapeFileFeatureLayer roadLayer = new ShapeFileFeatureLayer(@"D:\LabelingProblems\arterialjoined.shp");
roadLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Highway2;
roadLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

ShapeFileFeatureLayer roadLabelLayer = new ShapeFileFeatureLayer(@"D:\LabelingProblems\arterialjoined.shp");
TextStyle textStyle = TextStyles.Highway2("NAME");
textStyle.TextLineSegmentRatio = 1; //double.MaxValue; 
textStyle.SplineType = SplineType.StandardSplining;
textStyle.Font = new GeoFont("Arial", 6);
textStyle.XOffsetInPixel = 0;
textStyle.YOffsetInPixel = 0;
textStyle.FittingPolygon = false;
textStyle.DuplicateRule = LabelDuplicateRule.OneDuplicateLabelPerQuadrant;
textStyle.GridSize = 8;
roadLabelLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = textStyle;
roadLabelLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
roadLabelLayer.DrawingMarginPercentage = 400;

LayerOverlay overlay = new LayerOverlay("L");

overlay.Layers.Add(roadLayer);
overlay.Layers.Add(roadLabelLayer);


roadLabelLayer.Open();

Map1.CurrentExtent = roadLabelLayer.GetBoundingBox();
Map1.CustomOverlays.Add(overlay);


 
The forum just allows small size file to be uploaded, but we provide several other ways:
1.       Please contact support@thinkgeo.com for a FTP address and then you can upload the file.
2.       You can send the demo file to forumsupport@thinkgeo.com .
 
I’m sorry that I’m unable to open the “arterial.shp”, it seems that it’s broken and throw the exception as following image. I also tried with other viewer, such as Tatuk Viewer. Can you check it?
 
Thanks,
Johnny
 

Thanks Johnny, Changing to StandardSplicing fixed the upside-label problem.  I am left with having too few labels in the zoom level of most interest, which is the one that displays the entire metro area.  I will try your suggestion of increasing the grid size, but have no idea what number to put in there.  What is the default?  What are the units used for the grid size?  Pixels?  Meters? Degrees? Labels/ViewPort? 
  
 I will resend the Arterial shape file to forumsupport@thinkgeo.com, as I still see no way of sending even a small file in this forum.

Johnny, Please disregard my question re GridSize.  I see you suggested a setting in the sample code.  Thanks.  Al Vigil

Glad we could be of assistance! 
 Closing issue with this comment.