2010년 1월 21일 목요일

[ArcObjects]Get Sorted Cursor

ArcObjects를 사용하면서 소팅된 Cursor가 필요한 경우가 종종 있습니다.
다음은 소팅된 커서를 받아오는 예이며, ITableSort 인터페이스와 IQueryFilterDefinition 인터페이스를 사용할 수 있습니다.

ITableSort 인터페이스는 8.0버전에서부터 지원하는 인터페이스이고, 특히,  IQueryFilterDefinition 인터페이스는 9.2 버전에서 추가된 인터페이스입니다.

IQueryFilterDefinition  인터페이스는 SDE 및 Access GeoDatabase에서만 사용이 가능하며 File GeoDatabse 및 File 기반 데이터 소스(Shapefile 등)에서는 현재 지원하지 않습니다.

① ITableSort 인터페이스 활용

[code c#]
public static ICursor GetSortedCursor91(ITable ipTable, IQueryFilter ipFilter, string[] fieldList, bool ascending)
{
    ICursor ipCursor = null;

    ITableSort ipTableSort = new TableSortClass();

    ipTableSort.Table = ipTable;
    ipTableSort.QueryFilter = ipFilter;
    ipTableSort.Fields = string.Join(", ", fieldList);

    foreach (string fieldName in fieldList)
    {
        ipTableSort.set_Ascending(fieldName, ascending);

        int idxField = ipTable.FindField(fieldName);
        IField ipField = ipTable.Fields.get_Field(idxField);

        if (ipField.Type == esriFieldType.esriFieldTypeString)
        {
            ipTableSort.set_CaseSensitive(fieldName, true);
        }
    }

    try
    {
        ipTableSort.Sort(null);

        ipCursor = ipTableSort.Rows;
    }
    catch (Exception Ex)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("GetSortedCursor Failed : {0}", Ex.Message));
    }

    return ipCursor;
}
[/code]
② IQueryFilterDefinition 인터페이스 활용
[code c#]
public static ICursor GetSortedCursor92(ITable ipTable, IQueryFilter ipFilter, string[] fieldList, bool ascending)
{
    ICursor ipCursor = null;
  
    IWorkspace ipWs = ((IDataset)ipTable).Workspace;

    if (ipWs.Type == esriWorkspaceType.esriRemoteDatabaseWorkspace)
    {
        string order = ascending ? " ASC" : " DESC";

        if (ipFilter == null) ipFilter = new QueryFilterClass();

        IQueryFilterDefinition ipFDef = (IQueryFilterDefinition)ipFilter;
        ipFDef.PostfixClause = "ORDER BY " + string.Join(", ", fieldList) + order;

        ipCursor = ipTable.Search(ipFilter, false);
    }
    else
    {
        ipCursor = GetSortedCursor91(ipTable, ipFilter, fieldList, ascending);
    }

    return ipCursor;
}
[/code]

③ 활용 예

[code c#]
IWorkspace  ipSourcewS = OpenShapefileWs("폴더경로");
IFeatureClass  ipInputFc = OpenFeatureClass(ipSourcewS, "클래스이름");

string[] fieldList = new string[] {"필드이름1", "필드이름2"};

ICursor ipCursor = GetSortedCursor91((ITable)ipInputFc, null, fieldList, true);

IRow ipRow = ipCursor.NextRow();

int idxField = ipInputFc.FindField("필드이름1");
while (ipRow != null)
{
    System.Diagnostics.Debug.WriteLine(ipRow.get_Value(idxField).ToString());

    ipRow = ipCursor.NextRow();
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(ipCursor);
[/code]