2012년 3월 20일 화요일

[ArcObjects]INeighborhoodOp.FocalStatistics…

* esriSpatialAnalyst 라이브러리의 INeighborhoodOp 인터페이스는 다양한 집계함수를 제공한다. 해당 인터페이스를 사용하기 위해서는 부가적으로 [Spatial Analyst Extension]이 필요하다.
image
* 다양한 집계 함수들 중에 프로젝트에서는 FocalStatistics 를 사용했다. 집계할 값이 들어 있는 라스터 레이어를 특정 탐색 범위에 맞게 Sum을 수행한 결과 라스터를 필요로 했다.
* FocalStatistics의 기본적인 계산과정은 다음 그림과 같다.
image
* Block과는 다르게 Focal은 탐색영역을 Overlap 하면서 픽셀 하나하나의 값을 계산해 나간다. 그럼으로 분석에 있어서 탐색영역의 크기와 모양을 정하는 것이 키 포인트 였다.
* FocalStatistics의 탐색영역은 esriGeoAnalyst라이브러리의 IRasterNeighborhood 인터페이스를 통해 다양한 모양과 크기로 정의할 수 있다.
* 기본적인 탐색영역의 모양은 다음과 같다.
image
* 이번 프로젝트의 탐색영역과 분석환경에 대한 제약사항은 다음과 같았다.
image
   > 분석 Raster의 CellSize는 10m * 10m 으로 한다.
   > 탐색영역의 모양은 원형으로 하며, 원의 지름은 총 110m로 한다.
   > 원형의 탐색영역에 포함되는 Cell의 갯수는 총 101개가 되어야 한다.
* ArcGIS의 ToolBox를 활용하여 반지름이 55m의 원형으로 탐색했을 경우의 탐색반경에 포함되는 Cell은 다음과 같았다.
image
* Raster 분석에 있어서 반지름이 55m인 원을 그리고 해당 원안에 개별 Cell의 중심점이 포함 된다면 탐색범위에 포함된다고 기술문서에 나와 있었지만 실제 위 그림처럼 이해가 안가는 부분이 있다.
* 결국 해답은 다음과 같았다. 바깥쪽 점선이 반지름이 55m인 원이지만 해당 선상에는 대상 Cell의 중심점이 존재하지 않는다.
image
* Arc에서는 분석 대상 Cell의 중심점에서 X축, 혹은 Y축과 직각이 되는 선상에서 정의된 반지름에 포함되는 Cell까지의 거리를 구하고 해당 거리로 원을 그러 원 안에 중심점이 포함되는 Cell을 탐색영역으로 지정한다.
* 결론적으로 반지름이 50m ~ 59m 까지는 모두 위 그림과 같은 탐색영역으로 지정된다.
* 탐색영역의 제약사항을 만족하기 위해서는 개발자가 직접 탐색영역을 지정해야 한다.
* IRasterNeighborhood2인터페이스의 SetIrregularFile 메서드 사용
image
   > 위 그림과 같이 11 * 11 이라는 것을 지정해주고 (0=탐색영역에서 제외, 1=탐색영역으로 포함) 으로 구분되는 Kernel파일 (별도의 형식이 없는 일반 텍스트 파일) 을 생성하여 해당 파일의 Path로 탐색영역을 설정할 수 있다.
* IRasterNeighborhood2인터페이스의 SetIrregular 메서드 사용
   > 파일을 생성하는 것이 귀찮다면.. Kernel을 2차원 배열로 선언하여 SetIrregular 메서드를 통해 탐색영역을 지정할 수 있다.
   1: public double[,] FocalStatIrregularKernelMatrix
   2: {
   3:     get
   4:     {
   5:         if (this.m_arrKernelMatrix == null)
   6:         {
   7:             double[,] arrMatrix = { {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
   8:                                     {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
   9:                                     {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
  10:                                     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  11:                                     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  12:                                     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  13:                                     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  14:                                     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  15:                                     {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
  16:                                     {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
  17:                                     {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}};
  18:  
  19:             this.m_arrKernelMatrix = arrMatrix;
  20:         }
  21:  
  22:         return this.m_arrKernelMatrix;
  23:     }
  24:     set
  25:     {
  26:         this.m_arrKernelMatrix = value;
  27:     }
  28: }

   > 위 그림과 같이 2차원 배열을 선언하여 탐색영역 지정이 가능하다.
 
* 그 외 IRasterNeighborhood2 에서는 위의 방법과 비슷하게 가중치를 주는 등 다양한 방법으로 개발자가 원하는 탐색영역을 설정하여 집계할 수 있다.

   > 가중치 설정은 위 Kernel 에서 1이 곱해지는 값임으로 +, - 등 다양한 값으로 대체할 수 있으며 데이터 형은 Double 이다.

* Kernel 파일을 이용한 방법은 ArcGIS Desktop의 Toolbox 에서도 옵션설정을 통해 사용 가능한 방법임으로 데이터 작업 시 유용하게 사용할 수 있을것 같다.