2010년 2월 6일 토요일

[Tips]Storing FindField results

이 문서는 ArcGIS 9.3. 버전을 기준으로 작성되었으며, .NET C#(3.0) 샘플 코드 실행을 위해서는 다음의 어셈블리를 참조해야 한다.
- ESRI.ArcGIS.ADF
- ESRI.ArcGIS.Geodatabase
- ESRI.ArcGIS.System (ESRI.ArcGIS.esriSystem)

이 문서는 Geodatabase API를 사용하는 개발자들에게 CheatSheet(커닝페이퍼?)을 제공할 목적으로 작성되었으며 주요 내용은 성능향상, 범하기 쉬운 실수 등을 제공한다.
예제 코드는 특정 상황에 대한 샘플 코드로서 패턴을 제공하고, 상황에 따라 오류를 비교하기 위해 임의의 오류를 포함하고 있으므로 이 코드를 재활용해서는 안된다.


③ Storing FindField results
IClass.FindField 와 IFields.FindField 메쏘드는 데이터셋이나 필드 컬렉션에서 필드이름을 사용하여 필드의 위치를 검색하는데 사용한다.

하드코딩된 필드 위치를 사용하는 것보다 FindField를 사용하는 것이 좋지만, FindField의 과다 사용은 성능에 영향을 미친다.

Cursor의 피쳐로부터 NAME 필드의 값을 추출하는 다음 예를 살펴보자.

[code c#]
public static void ExcessiveFindFieldCalls(IFeatureClass featureClass)
{
  using(ComReleaser comReleaser = new ComReleaser())
  {
    // Open a cursor on the feature class.
    IFeatureCursor featureCursor = featureClass.Search(null, true);
    comReleaser.ManageLifetime(featureCursor);

    // Display the NAME value from each feature.
    IFeature feature = null;
    while ((feature = featureCursor.NextFeature()) != null)
    {
      Console.WriteLine(feature.get_Value(featureClass.FindField("NAME")));
    }
  }
}
[/code]
비록 FindField 호출이 소모적인 작업은 아니지만, 대용량의 피쳐를 사용할 경우 처리시간이 증가한다.

위의 코드를 바꿔서 FindField 결과를 재사용할 경우 약 3 ~ 10%(어떤 경우에는 그 이상)의 성능향상을 가져올 수 있으며, 코드 변경도 간단하다.
 
다음 코드는 FindField 메쏘드 사용의 좋은 예이며 만약 필드가 없을 경우 -1값을 반환한다. FindField를 사용할 때 필드가 없더라도 오류를 반환하지 않으므로 이에 대한 처리는 클라이언트의 몫이다. 아래 코드처럼 -1값이 리턴되었을 경우는 해당 테이블에 필드가 없다는 얘기다.
[code c#]
public static void SingleFindFieldCall(IFeatureClass featureClass)
{
  using(ComReleaser comReleaser = new ComReleaser())
  {
    // Open a cursor on the feature class.
    IFeatureCursor featureCursor = featureClass.Search(null, true);
    comReleaser.ManageLifetime(featureCursor);

    // Display the NAME value from each feature.
    IFeature feature = null;
    int nameIndex = featureClass.FindField("NAME");

    // Make sure the FindField result is valid.
    if (nameIndex ==  - 1)
    {
      throw new ArgumentException("The NAME field could not be found.");
    }

    while ((feature = featureCursor.NextFeature()) != null)
    {
      Console.WriteLine(feature.get_Value(nameIndex));
    }
  }
}
[/code]
출처 : ArcGIS Resource Center