ThinkGeo.com    |     Documentation    |     Premium Support

Multiple Textstyles

Hello There,
i use TextStyle in my App to show a Label over the features, i have searched if there is a way to change the font or color of a particular word inside this Label,but with TextStyle it was not possible. So i tried to use a second TextStyle for the word i want to be different, witch is drawn over the first Textstyle like this picture where i have placed a red word over the label…
Καταγραφή3
The problem is that when two features are close to each other i need the TextStyle.BestPlacement value to be true so they don’t collide,but it looks like this.
Καταγραφή4
So im looking for a way to move them both together one over the other even if i use the BestPlacement Value. I also tried to don’t use the BestPlacement Value so they would remain static but when i zoomed out and they where to close that happenned.
Καταγραφή2
Concluding i am first of all searching for a way to use the BestPlacement Value and move both of the TextStyles together so they would look as one thing,secondly if that is not possible at least i look for a way to make them not look like the last photo and just place both TextStyles of the first label over the others.
Thank you!

Thanks Marios,
We have the Vehicle Tracking demo project. You can take a look see if it match you requirement. The demo project only allow one callout open at the same time. But you could change that.
Here is the demo project.

Here is the screenshot.

Thanks

Frank

Good Afternoon,

The Popups from the project you sent me were very good,but i actually wanted a way to modify the Textstyle of a feature just a little more,if it is possible,and not make something like this.
After some searching i found a way to place custom text where i wanted inside the label by using every label’s bounding box values from the labelsInThisLayer value of the DrawCore constructor

MyBase.DrawCore(drawn_features, canvas, labelsInThisLayer, labelsInAllLayers)

And after i found the point i wanted inside the Bounding Box i used canvas.DrawTextWithScreenCoordinate to write whatever i wanted inside.
The result was something like this and it fit my needs without them colliding with each other
Καταγραφή

After that i have some questions about other things i can do in this TextStyle,

  1. The outline of the label mask(mask is an AreaStyle type) is a GeoPen type ,and i see that it has customizable values like DashPattern ,DashStyle etc.I’m asking if there is a way to make the outline to be a double color line,even with some more custom GeoCanvas methods
  2. The rounded corners of the label are too round,i’m searching a way to customize how “round” they will be so i can place the mask style somewhere between the rounded corner and rectangle styles that it has already (ThinkGeo.MapSuite.Styles.MaskType.RoundedCorners and ThinkGeo.MapSuite.Styles.MaskType.Rectangle)

Thank you again!!

Thanks Marios,
Could you send us your current existing code/class. We could dig into more detail base on your current code.

Thanks

Frank

1 Like

Hello again!
Here is a part of the code i use.

Imports System.Collections.ObjectModel
Imports System.Threading.Tasks
Imports ThinkGeo.MapSuite.Drawing
Imports ThinkGeo.MapSuite.Layers
Imports ThinkGeo.MapSuite.Shapes
Imports ThinkGeo.MapSuite.Styles
Imports ThinkGeo.MapSuite.Wpf

Public Class Collection
	Public Property CustomLayer As New InMemoryFeatureLayer

	Sub New()
		CustomLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(New CustomTextStyle("Alert", "Labeltext", 0, 10, True, New GeoSolidBrush(GeoColor.FromArgb(255, 0, 0, 0))))
		CustomLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
	End Sub
	
	
Public Class CustomTextStyle
    Inherits TextStyle

    Dim areastyle As Boolean
    Dim Type As String
    Dim p As PointShape
    Public Sub New(type As String, column As String, xoffset As Single, yoffset As Single, areastyle As Boolean, color As GeoSolidBrush, Optional ByVal duplicateRule As LabelDuplicateRule = ThinkGeo.MapSuite.Styles.LabelDuplicateRule.NoDuplicateLabels, Optional ByVal overlapRule As LabelOverlappingRule = ThinkGeo.MapSuite.Styles.LabelOverlappingRule.AllowOverlapping)
        Me.Type = type
        Me.areastyle = areastyle
        Me.TextColumnName = column
        Me.TextSolidBrush = color
        Me.XOffsetInPixel = xoffset
        Me.YOffsetInPixel = yoffset
        Me.Mask = OnCreateMask()
        Me.MaskType = ThinkGeo.MapSuite.Styles.MaskType.RoundedCorners
        Me.DuplicateRule = duplicateRule
        If type = "Alert" Then
            Me.Font = New GeoFont("Bahnschrift", 9, DrawingFontStyles.Regular)
            Me.BestPlacement = True
            Me.PointPlacement = ThinkGeo.MapSuite.Styles.PointPlacement.UpperRight
            Me.OverlappingRule = ThinkGeo.MapSuite.Styles.LabelOverlappingRule.AllowOverlapping
        Else
            Me.Font = New GeoFont("Arial", 7.5, DrawingFontStyles.Bold)
            Me.BestPlacement = False
            Me.PointPlacement = ThinkGeo.MapSuite.Styles.PointPlacement.Center
            Me.OverlappingRule = overlapRule
        End If
    End Sub

    Public Overridable Function OnCreateMask() As AreaStyle
        If areastyle Then
            Dim aStyle As ThinkGeo.MapSuite.Styles.AreaStyle = New ThinkGeo.MapSuite.Styles.AreaStyle
            aStyle.FillSolidBrush = New GeoSolidBrush(GeoColor.FromArgb(255, 255, 255, 255))
            aStyle.PenBrushDrawingOrder = 1
            aStyle.OutlinePen = New GeoPen(GeoColor.StandardColors.Black, 2.5)
            aStyle.DrawingLevel = ThinkGeo.MapSuite.Drawing.DrawingLevel.LabelLevel
            aStyle.YOffsetInPixel = -3
            aStyle.XOffsetInPixel = -1.5
            Return aStyle
        Else
            Return Nothing
        End If
    End Function

    Protected Overrides Sub DrawCore(features As IEnumerable(Of Feature), canvas As GeoCanvas, labelsInThisLayer As Collection(Of SimpleCandidate), labelsInAllLayers As Collection(Of SimpleCandidate))
        Try
            If Type = "Alert" Then

                MyBase.DrawCore(features, canvas, labelsInThisLayer, labelsInAllLayers)

                For Each label In labelsInThisLayer 
                    p = label.SimplePolygonInScreenCoordinate.GetBoundingBox.UpperLeftPoint ''get upperleftpoint of bounding box
                    Dim str = label.OriginalText.Split(vbCrLf) ''splits the text of the label in pieces 
                    If GetObjectByName(str(0)) IsNot Nothing Then ''searches the if there is an object with the name that's inside the first splited string
                        If GetObjectByName(str(0)).AlertBool Then ''checks a boolean value of the object to deside if it shall draw a red text
                            Dim alert As String = GetObjectByName(str(0)).AlertString ''takes the text from the object
							''and draws the red text on canvas,i have used the upperleftpoint of the bounding box and the offsets to place it where i want
                            canvas.DrawTextWithScreenCoordinate(alert, New GeoFont("Segoe UI", 8, DrawingFontStyles.Regular), New GeoSolidBrush(GeoColor.StandardColors.Red), p.X - 1.5 + textSize.Width / 2, p.Y - 10.5, DrawingLevel.LabelLevel)
                        End If
                    End If
                Next

            Else
			    ''if its is not alert it proceses only the Drawcore
                MyBase.DrawCore(features, canvas, labelsInThisLayer, labelsInAllLayers)
            End If
        Catch ex As Exception
            RadMessageBox.Show(ex.Message, projectName & " Information", MessageBoxButtons.OK, RadMessageIcon.Error)
            errLog.WriteLog(ex.Message.ToString, Me.Name, System.Reflection.MethodBase.GetCurrentMethod().Name.ToString())
        End Try
    End Sub
End Class

Thanks Marios,
I looked into the RoundedCorners. We set the cornerRadius = 5. current it not able to modify from out side. For the mask outline. I have not yet find a good way to implement the double colors. You may need try to draw double mask. One with transparent FillSolidBrush.

Thanks

Frank

1 Like