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…
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.
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.
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!
Multiple Textstyles
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,
- 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
- 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
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