New to Telerik UI for WinForms? Start a free 30-day trial

How to create a pin with text in RadMap

Updated on Aug 27, 2026

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