New to Telerik UI for WinFormsStart a free 30-day trial

How to create a pin with text in RadMap

Updated over 6 months ago

Environment

Product VersionProductAuthor
2021.3.1123RadMap for WinFormsHristo Merdjanov

Description

An example demonstrating the MapPin class can be customized to support text.

Solution

We will create a custom MapPin implementation overriding its Paint method. The Paint method will be customized so that the text can be actually painted.

Figure 1: Pin with Text

map-pin-with-text001

Custom Pin Implementation

C#
public class MyMapPin : MapPin
{
    private PointL pixelLocation;

    private RectangleL drawRect;

    public MyMapPin(PointG location) : base(location)
    {
    }

    public override void Paint(IGraphics graphics, IMapViewport viewport)
    {
        object state = graphics.SaveState();
        graphics.ChangeSmoothingMode(SmoothingMode.AntiAlias);
        MapVisualElementInfo info = this.GetVisualElementInfo(viewport);
        GraphicsPath path = info.Path.Clone() as GraphicsPath;
        GraphicsPath dotPath = new GraphicsPath();
        long mapSize = MapTileSystemHelper.MapSize(viewport.ZoomLevel);
        Matrix matrixOffset = new Matrix();
        matrixOffset.Translate(viewport.PanOffset.Width + info.Offset.X, viewport.PanOffset.Height + info.Offset.Y);
        path.Transform(matrixOffset);
        Matrix matrixWraparound = new Matrix();
        matrixWraparound.Translate(mapSize, 0);

        for (int i = 0; i <= viewport.NumberOfWraparounds - 1; i++)
        {
            RectangleF bounds = path.GetBounds();
            float diameter = bounds.Width / 3 ;
            dotPath.AddEllipse(bounds.X + diameter, bounds.Y + diameter, diameter, diameter);
            graphics.FillPath(this.BorderColor, dotPath);
            FillPrimitiveImpl fill = new FillPrimitiveImpl(this, null);
            fill.PaintFill(graphics, path, bounds);
            BorderPrimitiveImpl border = new BorderPrimitiveImpl(this, null);
            border.PaintBorder(graphics, null/* TODO Change to default(_) if this is not a reference type */, path, bounds);

            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = TelerikAlignHelper.TranslateAlignment(ContentAlignment.MiddleLeft);
            stringFormat.LineAlignment = TelerikAlignHelper.TranslateLineAlignment(ContentAlignment.MiddleLeft);
            SizeF size = RadGdiGraphics.MeasurementGraphics.MeasureString(this.Text, this.Font);
            graphics.DrawString(this.Text, new Rectangle((int)bounds.X, (int)bounds.Y, (int)size.Width + 10, 
                (int)size.Height), this.Font, this.ForeColor, stringFormat, Orientation.Horizontal, false);

            path.Transform(matrixWraparound);
        }

        graphics.RestoreState(state);
    }
}

The code snippet below demonstrates how to use the custom map pin no matter which of the above implementations you are using:

Initial Setup

C#

public RadForm1()
{
    InitializeComponent();

    SetupProvider();
   
    MapLayer pinsLayer = new MapLayer("Pins");
    this.radMap1.Layers.Add(pinsLayer);

    MyMapPin element = new MyMapPin(new PointG(34.04302, -118.26725));
    element.Text = "Sample Text"; 
    this.radMap1.Layers["Pins"].Add(element);
}

See Also