2012년 4월 24일 화요일

[ArcObjects]Spatial Grid Index 계산하기..

- ArcCatalog에서 SDE로 FeatureClass(특히 Shapefile)를 업로드 할 때 Spatial Index가 모두 빠져 있는 경우가 있다.

- GDB나 FGDB 라면 그냥 Copy & Paste로 데이터를 복사할 경우엔 Spatial Index가 모두 딸려와 정상적으로 생성이 되지만.. ArcCatalog의 Import나 Export 기능을 사용할 때 (Shapefile의 경우에는 Copy & Paste가 되지 않음) 난감한 경우가 있다.

- ArcCatalog에서 FeatrueClass 속성 창을 보면 Spatial Index를 자동 계산해주는 버튼이 있지만 하나씩 해야 한다. 100개 이상의 레이어를 올리고 하나씩 눌러가며 계산했던 적이 있다. 헐~

- ArcToolBox > Feature Class > Calculate Default Spatial Grid Index 툴을 사용하면 계산이 가능하다. Batch로 해서 하면 되지만 해본 결과 계산은 잘되지만 적용이 잘 되지 않는 듯 하다. 속성창에는 계산된 값이 보여지는데 Preview를 하면 여전히 로드되지 않는다.

- 아래 코드는 ArcObjects를 사용하여 FeatureClass의 Default Spatial Index를 계산해 주는 코드이다.

- 참조된 라이브러리는

> ESRI.ArcGIS.Geoprocessor

> ESRI.ArcGIS.Geoprocessing

- Geoprocessor 인터페이스의  Excute 메서드를 사용하여 직접 ArcToolBox를 사용한다.

- CalculateDefaultGridIndex > RemoveSpatialIndex > AddSpatialIndex   순서로 생성한다.

 

   1: private bool CalculateDefaultSpatialIndex(IFeatureClass pDestFc)
   2: {
   3:     if (pDestFc == null) return false;
   4:  
   5:     try
   6:     {
   7:         bool bSucc = false;
   8:  
   9:         //추가할 FeatureClass Parameter 생성
  10:         IVariantArray pArray = new VarArrayClass();
  11:         pArray.Add(pDestFc);
  12:  
  13:         //Geoprocessor선언
  14:         Geoprocessor pGP = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
  15:  
  16:         //Defualt Spatial Index 계산
  17:         //CalculateDefaultGridIndex_management (in_features)
  18:         IGeoProcessorResult pResult = (IGeoProcessorResult)pGP.Execute
  19:                             ("CalculateDefaultGridIndex", pArray, null);
  20:  
  21:         if (pResult.Status == esriJobStatus.esriJobSucceeded)   //계산성공
  22:         {
  23:             //결과 String은.. "Grid1;Grid2;Grid3" 형태로 반환한다.
  24:             string sGridIdxValue = pResult.ReturnValue.ToString();
  25:  
  26:             string[] arrGridValue = sGridIdxValue.Split(';');
  27:  
  28:             string sGrid1 = arrGridValue[0].Trim();
  29:             string sGrid2 = arrGridValue[1].Trim();
  30:             string sGrid3 = arrGridValue[2].Trim();
  31:  
  32:             //기존 SpatialIndex 삭제
  33:             //RemoveSpatialIndex_management (in_features)
  34:             pResult = (IGeoProcessorResult)pGP.Execute
  35:                       ("RemoveSpatialIndex", pArray, null);
  36:  
  37:             if (pResult.Status == esriJobStatus.esriJobSucceeded)
  38:             {
  39:                 //새롭게 계산된 Spatial Index 추가
  40:                 //AddSpatialIndex_management (in_features, g1, g2, g3) 
  41:                 pArray.Add(sGrid1);
  42:                 pArray.Add(sGrid2);
  43:                 pArray.Add(sGrid3);
  44:  
  45:                 pResult = (IGeoProcessorResult)pGP.Execute
  46:                           ("AddSpatialIndex", pArray, null);
  47:  
  48:                 if (pResult.Status == esriJobStatus.esriJobSucceeded)
  49:                 {
  50:                     bSucc = true;
  51:                 }
  52:             }
  53:         }
  54:  
  55:         System.Runtime.InteropServices.Marshal.ReleaseComObject(pResult);
  56:         System.Runtime.InteropServices.Marshal.ReleaseComObject(pArray);
  57:  
  58:         pResult = null;
  59:         pGP = null;
  60:         pArray = null;
  61:  
  62:         return bSucc;
  63:     }
  64:     catch (Exception Ex)
  65:     {
  66:         return false;
  67:     }
  68: }

2012년 3월 31일 토요일

[PostGIS] Shapefile and DBF Loader 2

  • pgAdmin은 오픈 소스 데이터베이스인 PostgreSQL을 위한 가장 인기있고 기능이 풍부한 오픈소스 관리 및 개발 플랫폼
  • Linux, FreeBSD, Solaris, Mac OSX, Windows 플랫폼에서 모두 사용

pgAdmin III Plug-In Architecture

  • version 1.9+ ~ 1.12.x 까지는 pgAdmin III 인스톨 폴더의 plugins.ini 파일로 관리
  • version 1.13 이후부터는 pgAdmin III 인스톨 폴더 내에 plugins.d 폴더 아래 plugin*.ini 다중 파일들로 관리
  • 만약 PostGIS Shapefile and DBF Loader PostGIS GUI 플러그인을 등록하는 경우
  • 1.12 이하 버전에서는 plugins.ini 파일에, 1.13 버전 부터는 plugins.d 폴더 내에 postgis.shp2pgsql-gui.ini 파일을 생성 또는 편집해서 등록할 수 있음
  • 두 버전 모두 다음의 내용을 등록하면 됨
    ;
    ;PostGIS shp2pgsql-gui (Windows):
    ;
    Title=PostGIS Shapefile and DBF Loader
    Command="$$PGBINDIR\postgisgui\shp2pgsql-gui.exe" -h "$$HOSTNAME" -p $$PORT -U "$$USERNAME" -d "$$DATABASE" -W "$$PASSWORD"
    Description=Open a PostGIS ESRI Shapefile or Plain dbf loader console to the current database.
    KeyFile=$$PGBINDIR\postgisgui\shp2pgsql-gui.exe
    Platform=windows
    ServerType=postgresql
    Database=Yes
    SetPassword=Yes
  • 더 자세한 내용은 다음을 참고

PostGIS Shapefile and DBF Loader2

  • pgAdmin III 플러그인 중 PostGIS Shapefile and DBF Loader(프로그램명 shp2pgsql-gui)라는 플러그인이 있음
  • 이 플러그인은 로컬 shapefile을 PostGIS 레이어로 업로드하는 기능이 있으며 한번에 하나의 shapefile만 변환이 가능함
  • PostGIS 2.0 버전부터는 이 플러그인이 다음과 같이 업데이트 됨
    • PostGIS Shapefile and DBF Loader2 라 함
    • 현재 Windows Experimental Binaries beta2
    • 다중 shapefile을 업로드 할 수 있도록 기능 개선
    • PostGIS 레이어들을 로컬에 shapefile로 변환하는 기능이 새로 탑재됨
  • 설치 요구사항
    • PostgreSQL의 Application Stack Builder 또는 수작업으로 PostGIS를 먼저 설치해야 함.
  • 다음은 윈도우 환경에서 기존 PostgreSQL 8.4.x ~ 9.1.x 버전 및 PostGIS 1.5.x 버전에서 PostGIS Shapefile and DBF Loader2를 설치하고 테스트한 내용임
  • 현재(2012/03/30) postgisgui_pgadmin-2.0.0beta2.zip 버전까지 릴리스되었으며 아래 사이트에서 받을 수 있음
  • 다운로드한 postgisgui_pgadmin-2.0.0beta2.zip 파일을 압축을 푼다.

1. pgAdmin III version 1.9+ ~ 1.12 : PostGIS 1.5.x

  • pgAdmin III 1.12 버전 이하일 경우 설치과정
    • PostgreSQL 설치폴더의 bin 폴더 내 postgisgui 폴더를 postgisgui_bk로 변경
    • 압축해제한 폴더에서 postgisgui 폴더를 복사하여 PostgreSQL 설치폴더의 bin 폴더에 복사한다.
    • PostgreSQL 설치폴더는 pgAdmin III 실행 후 Files -> Options... 메뉴 실행 후 PG bin path 정보를 확인해도 됨
    • 기존 설치한 pgAdmin III 폴더(일반적으로 PostgreSQL 설치 폴더 내 pgAdmin III 폴더)로 이동한다.
    • plugins.ini 파일을 텍스트 편집기에서 불러온다.
    • 다음의 내용을 확인하여 없으면 추가한다. 기존에 PostGIS Shapefile and DBF Loader가 플러그인으로 등록되어 사용하고 있는 경우는 수정할 필요 없음
    ;
    ;PostGIS shp2pgsql-gui (Windows):
    ;
    Title=PostGIS Shapefile and DBF Loader 2.0
    Command="$$PGBINDIR\postgisgui\shp2pgsql-gui.exe" -h "$$HOSTNAME" -p $$PORT -U "$$USERNAME" -d "$$DATABASE" -W "$$PASSWORD"
    Description=Open a PostGIS ESRI Shapefile or Plain dbf loader console to the current database.
    KeyFile=$$PGBINDIR\postgisgui\shp2pgsql-gui.exe
    Platform=windows
    ServerType=postgresql
    Database=Yes
    SetPassword=Yes

2. pgAdmin III version 1.13 ~ : PostGIS 1.5.x ~ PostGIS 2.x

  • pgAdmin III 1.13 버전 이상일 경우 설치과정
    • PostgreSQL 설치폴더의 bin 폴더 내 postgisgui 폴더를 postgisgui_bk로 변경
    • 압축해제한 폴더에서 postgisgui 폴더를 복사하여 PostgreSQL 설치폴더의 bin 폴더에 복사한다.
    • PostgreSQL 설치폴더는 pgAdmin III 실행 후 Files -> Options... 메뉴 실행 후 PG bin path 정보를 확인해도 됨
    • 기존 설치한 pgAdmin III 폴더(일반적으로 PostgreSQL 설치 폴더 내 pgAdmin III 폴더)로 이동한다.
    • plugins.d 폴더를 찾아 그 아래 postgis.shp2pgsql-gui.ini 파일을 텍스트 편집기에서 불러오거나 없으면 생성한다.
    • 다음의 내용을 확인하여 없으면 추가한다. 기존에 PostGIS Shapefile and DBF Loader가 플러그인으로 등록되어 사용하고 있는 경우는 수정할 필요 없음
    • 위 글상자 참조
  • 마지막으로 pgAdmin III이 실행중일 경우 재시작하면 반영됨

3. Version 2.0 사용 후기

  • 1.0에서와 마찬가지로 좌표정보(wkt로 저장된 prj)가 있어도 자동으로 SRID값을 가져오지 않음
  • 1.0에서는 SRID 기본값이 -1(Unknown Coordinate System)값이었으나 2.0에서는 0(2.0에서는 이 값이 기본값인가???)값이 적용.
  • 추후 개선될 것으로 기대되나 SRID값을 자동으로 가져오지 못할 경우 1.0처럼 -1값이 차라리 편함
  • 1.0에서는 GeometryColumn 이름을 the_geom을 기본값으로 사용했으나, 2.0에서는 GeometryColumn 이름을 geom을 기본값으로 사용함. 이 또한 통일이 필요할 듯
  • 다중 파일 선택 후 업로드시 프로그래스 윈도가 표시됨, 테스트 후 오류없이 변환 잘 됨
  • Export 기능이 새로 추가되어 여러 레이어를 shapefile로 내보내기 가능
  • postgresonline 에 나와 있는 UI와는 약간 다름, 정식버전이 나와야 확인이 가능할 듯
Version 1.0 vs Version 2.0
pgAdmin III Plugin
1.0

2.0

2.0 Connection

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 에서도 옵션설정을 통해 사용 가능한 방법임으로 데이터 작업 시 유용하게 사용할 수 있을것 같다.