Tech Tip
An Example of using the ILabeler interface for special labeling needs
Have you ever wondered how to draw labels for a polygon at an angle based on the width-to-height ratio of the polygon? For instance, you may want to display the label horizontally if the polygon is wider than it is tall, and vertically if the polygon is taller than it is wide. With the ILabeler interface, you can create your own class implementing that interface and write your own logic to have the labels display accordingly. The following code will show you how.
VB
Public Class CustomLabelerForPolygon : Implements MapSuite.ILabeler
Public Overloads Sub DrawLabels(ByVal g As Graphics, ByVal TextSymbolArrays() As Array, ByVal SymbolArray() As Array, ByVal MultiPoints() As MapSuite.Geometry.MultiPointF, ByRef LabeledAreas() As SimplePolygonF, ByVal CanvasWidth As Integer, ByVal CanvasHeight As Integer) Implements MapSuite.ILabeler.DrawLabels
'-- This routine left blank intentionally
End Sub
Public Overloads Sub DrawLabels(ByVal g As Graphics, ByVal TextSymbols() As Array, ByVal SymbolArray() As Array, ByVal Points() As System.Drawing.PointF, ByRef LabeledAreas() As SimplePolygonF, ByVal CanvasWidth As Integer, ByVal CanvasHeight As Integer) Implements MapSuite.ILabeler.DrawLabels
'-- This routine left blank intentionally
End Sub
Public Overloads Sub DrawLabels(ByVal g As Graphics, ByVal TextSymbolArrays() As Array, ByVal SymbolArray() As Array, ByVal MultiLines() As MapSuite.Geometry.MultiLineF, ByRef LabeledAreas() As SimplePolygonF, ByVal CanvasWidth As Integer, ByVal CanvasHeight As Integer) Implements MapSuite.ILabeler.DrawLabels
'-- This routine left blank intentionally
End Sub
Public Overloads Sub DrawLabels(ByVal g As Graphics, ByVal TextSymbolArrays() As Array, ByVal SymbolArray() As Array, ByVal Polygons() As MapSuite.Geometry.PolygonF, ByRef LabeledAreas() As SimplePolygonF, ByVal CanvasWidth As Integer, ByVal CanvasHeight As Integer) Implements MapSuite.ILabeler.DrawLabels
'-- Drawing labels for polygons
Dim Format As New StringFormat
Format.Alignment = StringAlignment.Center
'Iterate though each polygon
For i As Integer = 0 To Polygons.Length - 1
Dim TextSymbols() As TextSymbol = CType(TextSymbolArrays(i), TextSymbol())
For j As Integer = 0 To Polygons(i).Parts.Length - 1
'If the part of the Polygon is higher than wide, then display the label at a 90 degree angle.
If Polygons(i).Parts(j).Extent.Size.Width >= Polygons(i).Parts(j).Extent.Size.Height Then
For k As Integer = 0 To TextSymbols.Length - 1
g.DrawString(TextSymbols(k).TextValue, TextSymbols(k).Font, TextSymbols(k).Brush, Polygons(i).Parts(j).Centroid.X + TextSymbols(k).XOffset, Polygons(i).Parts(j).Centroid.Y + TextSymbols(k).YOffset, Format)
Next
Else
Dim cx As Single = (Polygons(i).Parts(j).Extent.Left + Polygons(i).Parts(j).Extent.Right) / 2
Dim cy As Single = (Polygons(i).Parts(j).Extent.Top + Polygons(i).Parts(j).Extent.Bottom) / 2
g.TranslateTransform(cx, cy)
g.RotateTransform(-90)
For k As Integer = 0 To TextSymbols.Length - 1
g.DrawString(TextSymbols(k).TextValue, TextSymbols(k).Font, TextSymbols(k).Brush, TextSymbols(k).XOffset, TextSymbols(k).YOffset, Format)
Next
g.RotateTransform(90)
g.TranslateTransform(-cx, -cy)
End If
Next j
Next i
End Sub
End Class
Dim Layer As New Layer("..\MyPolygonLayer.shp")
Dim T As New Threshold(Double.MaxValue, 0)
'Sets the CustomLabelerForPolygon to LabelerPlugin property, so that ‘the DefaultLabeler will no longer be used.
Dim CustomLabelerForPolygon As New CustomLabelerForPolygon
T.LabelerPlugin = CustomLabelerForPolygon
Dim Texts As New TextSymbolCollection
Texts.Add(New TextSymbol(New Font("Arial", 12, FontStyle.Bold), New SolidBrush(Color.Black)))
Texts.Add(New TextSymbol(New Font("Arial", 12, FontStyle.Bold), New SolidBrush(Color.Gainsboro), -2, -2))
T.LabelRenderers.Add(New LabelRenderer("name", Texts))
T.SymbolRenderers.Add(New SymbolRenderer(New AreaSymbol(Pens.Black, Brushes.Red)))
Layer.Thresholds.Add(T)