Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have a polyline feature layer. After doing some computation, I update a field of that layer and want to set unique color for different value of that field. We can do this from symbology using unique values. But I want to do it programmatically.

I know there should be a very easy way to do this thing with arcObjects. But I couldn't find the way.

enter image description here

I go through How to define a renderer for your layer document. But I did not find the way to set "Value Field" and "Add All Values" options here. And of course I have tried to use IUniqueValueRenderer.AddReferenceValue Method. But the document is not giving me all necessary information.

Question : How to set unique color value for different value of a specific field using c#? It will be vary helpful if anyone can give me some pointer about this.

Thanks.

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

First, to set UniqueValueRenderer in programmably, "Value Field" is set as,

pUniqueValueRenderer.FieldCount = 1;
pUniqueValueRenderer.set_Field(0, fieldName);

Next, RandomColorRamp does not guarantee unique colors. So you need to implement color creation part by your own self. One approach, create existed color list and check if the color is already used. I wrote the sample code referenced from How to define a renderer for your layer . And also specialized to SimpleLineSymbol. But you must consider about maximum number of values. Theoretically, you can use only up to 65535 colors.

private void DefineUniqueValueRendererWithUniqueColors(IGeoFeatureLayer pGeoFeatureLayer, string
    fieldName) {

    //Create the renderer.
    IUniqueValueRenderer pUniqueValueRenderer = new UniqueValueRendererClass();

    ISimpleLineSymbol pDefaultSimpleLineSymbol = new SimpleLineSymbolClass();
    pDefaultSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
    pDefaultSimpleLineSymbol.Width = 0.4;

    //These properties should be set prior to adding values.
    pUniqueValueRenderer.FieldCount = 1;
    pUniqueValueRenderer.set_Field(0, fieldName);
    pUniqueValueRenderer.DefaultSymbol = pDefaultSimpleLineSymbol as ISymbol;
    pUniqueValueRenderer.UseDefaultSymbol = true;

    IDisplayTable pDisplayTable = pGeoFeatureLayer as IDisplayTable;
    IFeatureCursor pFeatureCursor = pDisplayTable.SearchDisplayTable(null, false) as
        IFeatureCursor;
    IFeature pFeature = pFeatureCursor.NextFeature();


    bool ValFound;
    int fieldIndex;

    IFields pFields = pFeatureCursor.Fields;
    fieldIndex = pFields.FindField(fieldName);
    while (pFeature != null) {
        ISimpleLineSymbol pClassSymbol = new SimpleLineSymbolClass();
        pClassSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
        pClassSymbol.Width = 0.4;

        string classValue;
        classValue = pFeature.get_Value(fieldIndex) as string;

        //Test to see if this value was added to the renderer. If not, add it.
        ValFound = false;
        for (int i = 0; i <= pUniqueValueRenderer.ValueCount - 1; i++) {
            if (pUniqueValueRenderer.get_Value(i) == classValue) {
                ValFound = true;
                break; //Exit the loop if the value was found.
            }
        }
        //If the value was not found, it's new and will be added.
        if (ValFound == false) {
            pUniqueValueRenderer.AddValue(classValue, fieldName, pClassSymbol as
                ISymbol);
            pUniqueValueRenderer.set_Label(classValue, classValue);
            pUniqueValueRenderer.set_Symbol(classValue, pClassSymbol as ISymbol);
        }
        pFeature = pFeatureCursor.NextFeature();
    }
    //Since the number of unique values is known, the color ramp can be sized and the colors assigned.

    int seed = 0;
    List<int> colorList = new List<int>();
    IColor pColor = new RgbColorClass();

    for (int j = 0; j <= pUniqueValueRenderer.ValueCount - 1; j++) {
        string xv;
        xv = pUniqueValueRenderer.get_Value(j);
        if (xv != "") {
            ISimpleLineSymbol pSimpleLineSymbol = pUniqueValueRenderer.get_Symbol(xv)
                as ISimpleLineSymbol;

            //EDITED: Create unique color from random value.
            int colorValue = 0;
            while (true) {

                Random rnd = new Random(seed);
                seed++;

                colorValue = rnd.Next(0x00000000, 0x00FFFFFF);
                if (colorList.Contains(colorValue) == false) {

                    colorList.Add(colorValue);
                    break;
                }
                else {

                    double a = 0;
                }
            }

            pColor.RGB = colorValue;

            pSimpleLineSymbol.Color = pColor;
            pUniqueValueRenderer.set_Symbol(xv, pSimpleLineSymbol as ISymbol);

        }
    }

    //'** If you didn't use a predefined color ramp in a style, use "Custom" here. 
    //'** Otherwise, use the name of the color ramp you selected.
    pUniqueValueRenderer.ColorScheme = "Custom";
    ITable pTable = pDisplayTable as ITable;
    bool isString = pTable.Fields.get_Field(fieldIndex).Type ==
        esriFieldType.esriFieldTypeString;
    pUniqueValueRenderer.set_FieldType(0, isString);
    pGeoFeatureLayer.Renderer = pUniqueValueRenderer as IFeatureRenderer;

    //This makes the layer properties symbology tab show the correct interface.
    IUID pUID = new UIDClass();
    pUID.Value = "{683C994E-A17B-11D1-8816-080009EC732A}";
    pGeoFeatureLayer.RendererPropertyPageClassID = pUID as UIDClass;
}
share|improve this answer
add comment

Your Answer

 
discard

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.