AnsweredAssumed Answered

How to draw markers and text on a ArcGIS map, at a fixed size, independent of zoom?

Question asked by jcdege on Jul 8, 2016

I'm writing a WPF application, in C#, using ArcObjects.


I have an ESRI.ArcGIS.Controls.AxMapControl on my form, and I'm trying to draw some graphics elements on top of it.


The map I'm developing with is a customer-provided mdf of the state of Georgia.


Over the top of this, I need to display some markers and some text. It's taken a while, but I've figured out how to do this, except that the image and the text scales with the map. If it looks good at one zoom, it's way too big or way too small at others.


What I'd like is for the marker and text to be placed at a lat/long, so that it moves as the map is panned, but at a fix size that doesn't change as the map is zoomed in and out.


I'd thought that setting ScaleText = false would solve this for the text, but it doesn't seem to, and I'm not seeing any method for doing this with markers.


My current attempt:


    public void addMarker(IMap map, double x, double y, string text, string imagePath)
        var point = new PointClass() {X = x, Y = y};

        var pictureMarkerSymbol = new PictureMarkerSymbolClass
            Size = 15,
            BitmapTransparencyColor = new RgbColorClass
                Red = 0,
                Green = 0,
                Blue = 0

        pictureMarkerSymbol.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, imagePath);

        var markerElement = new MarkerElementClass
            Symbol = pictureMarkerSymbol,
            Geometry = point

        var textElement = new TextElementClass
            Text = text,
            ScaleText = false,
            Symbol = new TextSymbolClass
                XOffset = 40,
                Size = 10

        ((IElement) textElement).Geometry = point;

        (map as IGraphicsContainer)?.AddElement(((IElement)textElement), -1);
        (map as IGraphicsContainer)?.AddElement(((IElement)markerElement), 0);

        (map as IActiveView)?.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);


I recognize that the above is stylistically very different from the usual ESRI examples. I find the typical ESRI example almost unreadable. If you strip the more recent C# syntactic sugar from the above, you get the following, which should (and does, in my testing), behave identically:


    public void addMarker(IMap map, double x, double y, string text, string imagePath)
        IPoint point = new PointClass();
        point.X = x;
        point.Y = y;

        IRgbColor rgbColorClass = new RgbColorClass();
        rgbColorClass.Red = 0;
        rgbColorClass.Green = 0;
        rgbColorClass.Blue = 0;

        IPictureMarkerSymbol pictureMarkerSymbol = new PictureMarkerSymbolClass();
        pictureMarkerSymbol.Size = 15;
        pictureMarkerSymbol.BitmapTransparencyColor = rgbColorClass;

        pictureMarkerSymbol.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, imagePath);

        IMarkerElement markerElement = new MarkerElementClass();
        markerElement.Symbol = pictureMarkerSymbol;

        IElement eMarkerElement = (IElement) markerElement;
        eMarkerElement.Geometry = point;

        var textSymbol = new TextSymbolClass();
        textSymbol.XOffset = 40;
        textSymbol.Size = 10;

        var textElement = new TextElementClass();
        textElement.Text = text;
        textElement.ScaleText = false;
        textElement.Symbol = textSymbol;

        IElement eTextElement = (IElement) textElement;
        eTextElement.Geometry = point;

        IGraphicsContainer gcMap = (IGraphicsContainer) map;
        gcMap.AddElement(eTextElement, -1);
        gcMap.AddElement(eMarkerElement, 0);

        IActiveView avMap = (IActiveView) map;
        avMap.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);


Anyone have any ideas how I can make this marker and text draw at a fixed size independent of zoom?