ThinkGeo.com    |     Documentation    |     Premium Support

Multiple Labels per line of road

I have been digging through the forums for the upwards of an hour now, and I need this solved in a more timely manner. The map I am dealing with has many long stretches of road of a single long line. We cannot split the road unless at an intersection, thus it has to remain a single long stretch of road… the problem is that the label for it sits in the middle of this stretch and when we look up addresses along the line not close to the middle we cannot see a road label. Is there a textstyle setting that allows the label to replicate along the road like Google Maps does for their roads or something similar?

I have attached an image with a find example. Greenbrier Dr is long, and if I am zoomed in on houses north of it, I cannot tell what road I am on… my current code for the textstyle is…



 Dim textStyle2 As TextStyle = TextStyles.CreateSimpleTextStyle(loLabelField, "Arial", LineLabelSize, DrawingFontStyles.Bold, GeoColor.StandardColors.Black)
        With textStyle2
            .TextLineSegmentRatio = 1
            .DuplicateRule = LabelDuplicateRule.UnlimitedDuplicateLabels
            .SplineType = SplineType.None
            .SuppressPartialLabels = True
            .BestPlacement = False
            .GridSize = 10
        End With

Image…

Hi Jayce,



Got your questions and sorry to say our text style can’t do this with current APIs. But I have a workaround: In drawing event, we can split the long line shape into multi short lines, then we can make the labels display more. I wrote some codes for you:




austinStreetsLabelLayer.DrawingFeatures += austinStreetsLabelLayer_DrawingFeatures;
 
void austinStreetsLabelLayer_DrawingFeatures(object sender, DrawingFeaturesEventArgs e)
        {
            for (int i = 0; i < e.FeaturesToDraw.Count; i++)
            {
                Feature currentFeature = e.FeaturesToDraw<i>;
                Feature newFeature null;
                if (currentFeature.GetShape() is MultilineShape)
                {
                    newFeature = new Feature(ConvertLongMultiLineToShort(currentFeature.GetShape() as MultilineShape));
                }
                if (currentFeature.GetShape() is LineShape)
                {
                    newFeature = new Feature(ConvertLongLineToShort(currentFeature.GetShape() as LineShape));
                }
                if (newFeature != null)
                {
                    newFeature.Id currentFeature.Id;
                    foreach (var keyvalue in currentFeature.ColumnValues)
                    {
                        newFeature.ColumnValues.Add(keyvalue.Key, keyvalue.Value);
                    }
                    e.FeaturesToDraw<i> = newFeature;
                }
            }
        }
 
        const int displayLabelDistanceInMeter 30;
        const int splitCountBtweenTwoVertexes 3;
 
        private MultilineShape ConvertLongMultiLineToShort(MultilineShape multiLineShape)
        {
            MultilineShape returnShapes new MultilineShape();
            foreach (var item in multiLineShape.Lines)
            {
                if (item.GetLength(winformsMap1.MapUnit, DistanceUnit.Meter) > displayLabelDistanceInMeter)
                {
                    MultilineShape tempLineShapes = ConvertLongLineToShort(item);
                    foreach (LineShape lineShape in tempLineShapes.Lines)
                    {
                        returnShapes.Lines.Add(lineShape);
                    }
                }
                else
                {
                    returnShapes.Lines.Add(item);
                }
            }
            return returnShapes;
        }
 
        private MultilineShape ConvertLongLineToShort(LineShape lineShape)
        {
            MultilineShape multiLineShape = new MultilineShape();
 
            for (int i = 1; i < lineShape.Vertices.Count; i++)
            {
                LineShape newline = new LineShape();
                newline.Vertices.Add(lineShape.Vertices[i - 1]);
                newline.Vertices.Add(lineShape.Vertices<i>);
                if (newline.GetLength(winformsMap1.MapUnit, DistanceUnit.Meter) > displayLabelDistanceInMeter)
                {
                    newline.Vertices.Clear();
                    Collection<Vertex> vertexes = SplitTwoVertex(lineShape.Vertices[i - 1], lineShape.Vertices<i>);
                    for (int j = 1; j < vertexes.Count; j++)
                    {
                        LineShape newTempline = new LineShape();
                        newTempline.Vertices.Add(vertexes[j - 1]);
                        newTempline.Vertices.Add(vertexes[j]);
                        multiLineShape.Lines.Add(newTempline);
                    }
 
                }
                else
                {
                    multiLineShape.Lines.Add(newline);
                }
            }
            return multiLineShape;
        }
 
        private Collection<Vertex> SplitTwoVertex(Vertex vertex1, Vertex vertex2)
        {
            Collection<Vertex> returnVertexes = new Collection<Vertex>();
            returnVertexes.Add(vertex1);
 
            double deltaX = (vertex2.X - vertex1.X) / splitCountBtweenTwoVertexes;
            double deltaY = (vertex2.Y - vertex1.Y) / splitCountBtweenTwoVertexes;
            for (int i = 1; i <= splitCountBtweenTwoVertexes; i++)
            {
                Vertex newVertex = new Vertex(vertex1.X + deltaX * i, vertex1.Y + deltaY * i);
                returnVertexes.Add(newVertex);
            }
 
            returnVertexes.Add(vertex2);
            return returnVertexes;
        }

Any questions, please feel free to let us know.



Thanks,



Troy

Thank you! I will try this out, and see how it looks with the result! :D

Our pleasures, Please let us know if any questions. 



Thanks, 

Troy