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

2012년 3월 15일 목요일

[ArcObjects]레이어 라벨 Expression 적용하기..

- 시군구별 데이터 매칭률을 계산하고 결과를 도면에 표시하는 기능을 추가하기 위해서 개발 하던중 도면에 표시할때 시군구 명칭과 매칭률을 동시에 라벨로 표현해야 했다.

- ArcMap 에서는 아래 그림과 같이 Label 속성에서 Expression을 사용해 VBScript 를 통해 다양한 라벨을 만들어 표현할 수 있다.

image

- 이런 형식으로 라벨을 만들어 표현하기 위해서 ArcObjects에서는 아래의 방법으로 구현이 가능하다.

- 주요 인터페이스

    > ESRI.ArcGIS.Carto.IAnnotateLayerPropertiesCollection

    > ESRI.ArcGIS.Carto.IAnnotateLayerProperties

    > ESRI.ArcGIS.Carto.IAnnotationExpressionEngine

    > ESRI.ArcGIS.Carto.IAnnotationExpressionParser

- VBScript 라벨 생성 함수 소스

   1: /// <summary>
   2: /// VBScript 형식의 라벨 표현
   3: /// </summary>
   4: /// <param name="pFeatureLayer"></param>
   5: /// <param name="sExpression"></param>
   6: /// <param name="pTextSym"></param>
   7: public static void SetLayerLabelByVBScriptEngine(IFeatureLayer pFeatureLayer, string sExpression, ITextSymbol pTextSym)
   8: {
   9:     IGeoFeatureLayer pGeoFLayer = (IGeoFeatureLayer)pFeatureLayer;
  10:     pGeoFLayer.DisplayAnnotation = true;    //라벨 ON
  11:  
  12:     //기존 라벨형식 Clear
  13:     IAnnotateLayerPropertiesCollection pAnnoLyrPropCol = pGeoFLayer.AnnotationProperties;
  14:     pAnnoLyrPropCol.Clear();    
  15:  
  16:     //VBScript 생성
  17:     IAnnotationExpressionEngine pAnnoExpEngine = new AnnotationVBScriptEngineClass();
  18:     IAnnotationExpressionParser pAnnoExpParser = pAnnoExpEngine.SetExpression(string.Empty, sExpression);
  19:  
  20:     //sExpression 에러체크
  21:     int nNumber = -1;
  22:     int nLine = -1;
  23:     string sDesc = string.Empty;
  24:  
  25:     pAnnoExpParser.LastError(ref nNumber, ref nLine, ref sDesc);
  26:  
  27:     if (nNumber != 0)
  28:     {
  29:         System.Diagnostics.Debug.Print(sDesc);
  30:         return;
  31:     }
  32:  
  33:     //Simple방식으로 Expression 적용
  34:     ILabelEngineLayerProperties pLabelEngLyrProp = new LabelEngineLayerPropertiesClass();
  35:     pLabelEngLyrProp.IsExpressionSimple = true;
  36:     pLabelEngLyrProp.ExpressionParser = pAnnoExpEngine;
  37:     pLabelEngLyrProp.Expression = sExpression;
  38:     pLabelEngLyrProp.Symbol = pTextSym;
  39:     
  40:     //라벨의 특성(위치, Conflict 등등)
  41:     IBasicOverposterLayerProperties pBasicProp = pLabelEngLyrProp.BasicOverposterLayerProperties;
  42:     pBasicProp.NumLabelsOption = esriBasicNumLabelsOption.esriOneLabelPerShape;
  43:     pBasicProp.GenerateUnplacedLabels = true;
  44:  
  45:     //라벨 스케일 설정
  46:     IAnnotateLayerProperties pAnnoLyrProp = (IAnnotateLayerProperties)pLabelEngLyrProp;
  47:     pAnnoLyrProp.AnnotationMaximumScale = 0;
  48:     pAnnoLyrProp.AnnotationMinimumScale = 0;
  49:  
  50:     //추가
  51:     pAnnoLyrPropCol.Add(pAnnoLyrProp);
  52: }

    > IAnnotateLayerPropertiesCollection 에는 여러 개의 IAnnotateLayerProperties가 생성될 수 있는데 IAnnotateLayerProperties.WhereClause 속성에서 쿼리 되는 Feature별로 다르게 라벨을 정할 수 있기 때문이다.


    > IAnnotationExpressionEngine.SetExpression 으로 사용자가 정의한 Expression을 적용하고 난 뒤 IAnnotationExpressionParser.LastError를 통해 사용자의 Expression을 검증할 수 있다.


    > 위 소스에서 적용된 Expression은 sExpression = “[SGG_NM] & vbcrlf & Round( [J_RATIO] , 2) & \"%\"” 이다.


    > ILabelEngineLayerProperties.IsExpressionSimple 속성에 따라 ArcMap에서 [Advanced]의 구분과 같은 역할을 한다.


    > IsExpressionSimple = true : 단순 VBScript를 통한 라벨 표현


    > IsExpressionSimple = False : Function을 통한 보다 강력한 라벨을 표현