Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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

I need to create a large number of Arcmap layer files (v9.3 or 10), perhaps a hundred, from lookup tables. I don't have to set the symbol patch itself, that can be random, but I do need the value and label attributes filled out. The lookup tables look like:

"Wooded_area","CODE","1240042","Land Cover, Circa 2000 - Vector"

And the result would resemble (except the symbols themselves):

screen shot of layer properties

I'd prefer a python based solution, via arcobjects+python if required, C# next, but anything that works, even partially or only conceptually, is welcome.

share|improve this question
related (v10 specific):… – matt wilkie Aug 31 '10 at 22:02

A class like this can be used:

public class UvrItem
    public string m_fc;
    public string m_value_field;
    public string m_value;
    public string m_label;
    public ISymbol m_Symbol;
    public static IUniqueValueRenderer MakeUVR(string filePath)
        List<UvrItem> list = Load(filePath);
        IUniqueValueRenderer uvr = new UniqueValueRendererClass();
        uvr.FieldCount = 1;
        // assume all items in list have same field
        uvr.set_Field(0, list[0].m_value_field);
        uvr.DefaultLabel = "other";
        uvr.DefaultSymbol = new SimpleFillSymbolClass();
        uvr.UseDefaultSymbol = true;
        foreach (UvrItem itm in list)
            uvr.AddValue(itm.m_value, "", itm.m_Symbol);
            uvr.set_Label(itm.m_value, itm.m_label);
        return uvr;
    private static List<UvrItem> Load(string filePath)
        string[] lines = System.IO.File.ReadAllLines(filePath);
        List<UvrItem> outList = new List<UvrItem>();
        for (int i = 1; i < lines.Length; i++)
            if (lines[i].Trim().Length == 0)
            string[] itm = lines[i].Replace("\"","").Split(",".ToCharArray());
            if(itm.Length < 4)

            UvrItem uitm = new UvrItem()
                m_fc = itm[0],
                m_value_field = itm[1],
                m_value = itm[2],
                m_label = itm[3],
                m_Symbol = new SimpleFillSymbolClass()
        return outList;


Call it from an ICommand with code like this:

public static void ApplyUVR(IApplication app)
    IMxDocument mxDoc = (IMxDocument)app.Document;
    IGeoFeatureLayer gfLayer = mxDoc.FocusMap.get_Layer(0) as IGeoFeatureLayer;
    gfLayer.Renderer = (IFeatureRenderer)UvrItem.MakeUVR(@"D:\Projects\AmberGIS\Forums\uvr1.csv");
share|improve this answer
up vote 2 down vote accepted

I was going about this the wrong way, and have since found a better approach: use coded attribute domains, added to the feature classes using gp.addsubtype. Then when the fc is dropped into a map it automatically uses a random symbol pallette with the appropiate labels spelled out. This is better than layer files because a) it will never get out of sync with the real data, and b) the friendly names (labels) are also visible in other places like Select by attributes.

Relevent code snippet (from full script).

reader = csv.DictReader(f)
for row in reader:
    if row.get('fc_point'):
        fc = row ['fc_point']
        code = row ['fc_point_code']
        name = row ['code_friendly_name']            

The csv table looks like:

"fc_point", "fc_point_code", "fc_line", "fc_line_code", "fc_poly", "fc_poly_code", "code_friendly_name"
,,,, "LX_2260009_2", "2260012", "Amusement park"
,,,, "IC_2360009_2", "2360012", "Auto wrecker"
"TR_1780009_0", "1780010",,,,, "Blocked passage"
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.