4 votos

¿Hay una manera más rápida de obtener valores únicos para una FeatureClass dada en ArcObject?

Estoy tratando de contar las filas por valores únicos para un determinado FeatureClass. Estoy usando DataStatistics para obtener los valores únicos de una columna específica para un determinado FeatureClass.

Este parece ser (muy) lento con grandes shapefiles (> 200k de características) - ¿hay una manera más rápida de determinar valores únicos?

El segundo paso del proceso (mediante QueryFilter en combinación con FeatureClass.FeatureCount()) parece lo suficientemente rápido a pesar de que estaría contento si estoy apuntado a una mejor solución.

public static Dictionary<string, int> CountUniquesStatistic(ITable table, string fldName)
{
    Dictionary<string, int> uniqueValuesDictionary = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);

    DataStatistics dataStatistics = new DataStatistics();
    dataStatistics.Field = fldName;
    dataStatistics.Cursor = table.Search(null, false);

    IEnumerator uniqueValues = dataStatistics.UniqueValues;

    while (uniqueValues.MoveNext())
    {
        object current = uniqueValues.Current;
        uniqueValuesDictionary[current.ToString()] = 0;
    }

    foreach (string key in uniqueValuesDictionary.Keys.ToList())
    {
        IQueryFilter queryFilter = new QueryFilter();
        queryFilter.WhereClause = string.Format("{0} = '{1}'", fldName, key);

        uniqueValuesDictionary[key] = table.RowCount(queryFilter);
    }

    return uniqueValuesDictionary;
}

2voto

saint_groceon Puntos 2696

No he probado este código, pero estaría muy interesado en cómo se compara el rendimiento con DataStatistics. Tal vez use recycling = true cuando llama a Search para el cursor de datastatistics para una comparación justa. Transmite IFeatureclass a ITable al llamar esto. También tengo curiosidad de cómo se podría comparar esto con Python.

 public static Dictionary<string, int> CountUniques(ITable table, string fldName)
{
    int idx = table.Fields.FindField(fldName);
    if(idx == -1)
    {
        throw new Exception(string.Format(
            "field {0} not found in {1}",
            fldName,((IDataset)table).Name));
    }
    IQueryFilter qf = new QueryFilterClass();
    qf.AddField(fldName);

    var outDict = new Dictionary<string,int>(StringComparer.CurrentCultureIgnoreCase);
    ICursor cur = null;
    IRow row = null;
    try
    {
        cur = table.Search(qf, true);
        while ((row = cur.NextRow()) != null)
        {
            string key = row.get_Value(idx) is DBNull ? "<Null>" :
                row.get_Value(idx).ToString();
            if (!outDict.ContainsKey(key))
                outDict[key] = outDict[key] + 1;
            else
                outDict.Add(key, 1);
        }
    }
    catch(Exception ex)
    {
        string msg = row == null ? "error getting value" :
            "error getting value for row " + row.OID.ToString();
        throw new Exception(msg, ex);
    }
    finally
    {
        if(cur != null)
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cur);
    }

    return outDict;
}
 

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X