Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Let's say I have 10 police cars using the same image, and I want each one to be numbered 1 - 10, but the number 1 is dynamically drawn on top of the police car image. What is the class / interface I use for that with C# and ArcEngine 10.

share|improve this question
up vote 7 down vote accepted

I'd use a multilayer markersymbol with two symbol layers. The bottom symbol would be a picturemarkersymbol of a police car. On top of that would be one or more charactermarkersymbols, with the car number set via ICharactermarkersymbol.CharacterIndex.

As I've said before, you really need to get Arcview arcmap if you haven't already done so. It has interactive symbol editing that would allow you to create symbols interactively, save them to a file that your arcengine app could then load. Defining these symbols without arcview (or desktop) arcmap will be quite tedious.

share|improve this answer
Wouldn't you recommend ArcInfo over ArcView in this case since it has greater functionality, or do you really think ArcView will suffice? – patrick Oct 19 '10 at 16:56
At the current version of ArcGIS, ArcInfo is a license level, not a product. An ArcInfo license can be checked out when using ArcMap (or ArcCatalog) to do certain types of editing. I think Kirk is referring to the entire ArcGIS suite when he mentions ArcView (and, if not, I'd appreciate a little enlightenment from him as well). See here for details regarding what you get with a specific license level. – Michael Todd Oct 19 '10 at 20:44
To use an interactive symbol editor, as found in arcmap, at minimum you would need ArcView. I think 90 day eval licenses are available. – Kirk Kuykendall Oct 20 '10 at 2:20

Kirk was right. Here's the code if anyone wants it.

  IDynamicGlyph createMultiGlyph(String imagePathName, String text, int fontSize, System.Drawing.FontStyle fontstyle = System.Drawing.FontStyle.Bold, String fontType = "Arial")
        IMultiLayerMarkerSymbol multiLayerMarkerSymbol = new MultiLayerMarkerSymbolClass();
        pictureMarkerSymbol = new PictureMarkerSymbolClass();
        pictureMarkerSymbol.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, imagePathName);
        pictureMarkerSymbol.Size = 100;
        IColor whiteTransparencyColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.ToRGBColor(Color.FromArgb(255, 255, 255)) as IColor;
        pictureMarkerSymbol.BitmapTransparencyColor = whiteTransparencyColor;

        List<int> asciiList = stringToAscii(text);

        int pixelsBetweenLetters = 2;
        int numLetters = text.Length;
        int widthOfAllSpaces = (numLetters -1) * pixelsBetweenLetters;
        int adjustmentMultiplier = 3; //TextRenderer.MeasureText is not perfect

        int width = 0; 
        for (int i = 0; i < text.Length; i++)
            SizeF size = TextRenderer.MeasureText(text[i].ToString(), new Font(fontType, fontSize, fontstyle));
            width = ((width + Convert.ToInt32(size.Width)) / adjustmentMultiplier); 
        int negativeXoffset = -1 * ((width + widthOfAllSpaces) / 2);
        int currentOffset = negativeXoffset; 

        for (int i = 0; i < asciiList.Count; i++)
            ICharacterMarkerSymbol characterMarkerSymbol = new CharacterMarkerSymbolClass();
            Font arialFont = new Font(fontType, fontSize, fontstyle);
            characterMarkerSymbol.Font = ESRI.ArcGIS.ADF.Connection.Local.Converter.ToStdFont(arialFont);
            characterMarkerSymbol.Size = fontSize;
            characterMarkerSymbol.Color = SymbolCreator.getColor(255, 0, 0) as IColor;
            characterMarkerSymbol.XOffset = currentOffset;
            characterMarkerSymbol.CharacterIndex = asciiList[i];

            SizeF size = TextRenderer.MeasureText(text[i].ToString(), new Font(fontType, fontSize));
            currentOffset += Convert.ToInt32(size.Width / adjustmentMultiplier) + pixelsBetweenLetters; 

        IDynamicGlyph returnGlyph = dynamicGlyphFactory.CreateDynamicGlyph((ISymbol)multiLayerMarkerSymbol);
        return returnGlyph; 

       public List<int> stringToAscii(String stringToConvert)
                List<int> asciiList = new List<int>(); 
                for (int i = 0; i < stringToConvert.Length; i++)
                    char c = stringToConvert[i];
                    byte b = (byte)c;
                return asciiList; 
share|improve this answer

First I would consider using standard labeling mechanisms. If this approach is insufficient, I suggest looking into custom renderers (IFeatureRenderer). You could also employ custom layers but I guess that is unnecessary in your case.

But, if your objects (cars) change position very often, you will want to work with dynamic display.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.