1

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:

"FC","VALUE_FIELD","VALUE","LABEL"
"Wooded_area","CODE","1240012","Extracted"
"Wooded_area","CODE","1240022","Interpreted"
"Wooded_area","CODE","1240032","FCS-EOSD"
"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.

1

2 Answers 2

3

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']            
        gp.addsubtype(fc,code,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"
2

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)
                continue;
            string[] itm = lines[i].Replace("\"","").Split(",".ToCharArray());
            if(itm.Length < 4)
                continue;

            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()
            };
            outList.Add(uitm);
        }
        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");
    mxDoc.CurrentContentsView.Refresh(null);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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