2010년 12월 14일 화요일

블로거로 이사왔습니다.

불편한 점이 몇가지 있지만 일단 블로거로 자리를 잡았습니다. ^^

2010년 11월 4일 목요일

[ArcObjects]Workspace의 모든 FeatureClass를 지도에 추가하기

다음은 ArcObjects에서 IWorkspace에 포함된 모든 레이어(일반적으로 IFeatureClass)를 지도에 추가하는 코드 샘플입니다. C#으로 작성되었으며, 개념만 확인하세요...

핵심 코드는
IEnumDataset  enumDataSet = srcWorkspace.get_Datasets(esriDatasetType.esriDTAny); 입니다.


▣ IFeatureClass로부터 IFeatureLayer를 생성하는 함수


private IFeatureLayer CreateFeatureLayer(IFeatureClass srcFc, string layerName, bool isVisible)
{
    IFeatureLayer featureLayer = new FeatureLayerClass();
    featureLayer.FeatureClass = srcFc;
    featureLayer.Visible = isVisible;

    if (string.IsNullOrEmpty(layerName))
    {
        featureLayer.Name = srcFc.AliasName;
    }
    else
    {
        featureLayer.Name = layerName;
    }

    return featureLayer;
}


▣ IWorkspace의 모든 FeatureClass를 IMap(지도)에 추가하기
여기에서 IWorkspace는 SDE Workspace뿐만 아니라 Shapefile, File GeoDatabase 등의 FeatureWorkspace를 모두 포함합니다.


private void AddAllFeatuerClassToMap(IMap srcMap, bool layerVisible, IWorkspace srcWorkspace)
{
    IFeatureLayer featureLayer = null;
    IFeatureClass featureClass = null;

    IEnumDataset enumDataSet = srcWorkspace.get_Datasets(esriDatasetType.esriDTAny);
    enumDataSet.Reset();
    IDataset dataSet = enumDataSet.Next();
    while (dataSet != null)
    {
        switch (dataSet.Type)
        {
            case esriDatasetType.esriDTFeatureClass:
                featureClass = (IFeatureClass)dataSet;

                // create feature layer
                featureLayer = CreateFeatureLayer(featureClass, featureClass.AliasName, layerVisible);

                // add layer to map
                srcMap.AddLayer(featureLayer);
                break;
            case esriDatasetType.esriDTFeatureDataset:
                IFeatureDataset featureDataset = (IFeatureDataset)dataSet;

                // create group layer
                IGroupLayer groupLayer = new GroupLayerClass();
                groupLayer.Name = featureDataset.Name;

                IEnumDataset enumSubSet = featureDataset.Subsets;
                enumSubSet.Reset();
                IDataset subDataSet = enumSubSet.Next();
                while (subDataSet != null)
                {
                    if (subDataSet.Type == esriDatasetType.esriDTFeatureClass)
                    {
                        featureClass = (IFeatureClass)subDataSet;

                        // create feature layer
                        featureLayer = CreateFeatureLayer(featureClass, featureClass.AliasName, layerVisible);

                        // add layer to group layer
                        groupLayer.Add(featureLayer);

                    }
                    subDataSet = enumSubSet.Next();
                }

                // add group layer to map
                srcMap.AddLayer(groupLayer);
                break;
        }
        dataSet = enumDataSet.Next();
    }
}

▣ 함수 사용하기
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Carto;

private void AddLayers()
{
    IWorkspace srcWorkspace = OpenSdeWorkspace();

    IMap srcMap = GetMap();

    AddAllFeatuerClassToMap(srcMap, true, srcWorkspace);

   // refresh map
   IActiveView activeView = (IActiveView)srcMap;
   activeView.Refresh();
}

▣ 기타 참고하기
위 예제(불러와서 바로 지도에 추가하는 경우, 즉 FeatureClass를 직접 사용해야 하는 상황) 와는 달리 SDE Workspace나 기타 File GeoDatabase 등의 Feature Class가 많을 경우 Feature Class를 직접 사용하지 않고 모든 레이어 목록을 불러와야 하는 경우가 있습니다. 이럴때 아래 코드를 참고해 보세요. 속도 개선에 도움이 됩니다.

IEnumDatasetName enumDataSet = srcWorkspace.get_DatasetNames(esriDatasetType.esriDTAny);

2010년 10월 18일 월요일

[foursquare]100일째 기념

요즘 foursquare 를 즐기고 있습니다. ^^
오늘이 제 셋째 딸 100일임과 동시에 foursqure 사용일도 100일째 되는 날입니다.
하루하루 빠뜨리지 않고 사용해서 언젠가 제 딸에게 계정을 승계(?)할 생각입니다. ㅎㅎ

어제는 주간 서울 순위(편집왕 님의 [2010.10.01~10.17] 포스퀘어 Seoul 지역 순위표 (Leaderboard))에서 12위에 올랐네요

foursquare가 궁금하신 분은 여기에 들러 보세요.
어라님의 포스퀘어 한국 사용자그룹
편집왕의 포스퀘어 따라잡기 (Seize the Foursquare)

▣ 제 포스퀘어 웹 : http://foursquare.com/user/mapplus

▣ 기념 스크린샷


2010년 9월 4일 토요일

세종대학교 도시공간정보사업단에 다녀와서

금요일 세종대학교 도시공간정보사업단에서 OGC 공간정보 표준 웹 프로세싱 서비스(WPS)에 관한 최신동향 및 질의응답 시간을 가졌습니다.

WPS 분야의 선구자 역할을 담당하고 있는 52°North의 Bastian Schaffer(OGC WPS Standard Working Group Chairman)님 및 염재홍 교수님께서 다양한 조언을 해 주셨습니다.
 
기술적인 문제는 제외하고 "문화적 차이"에 대한 일화 2가지만 소개할까 합니다.
Open Source 사용에 대해 얘기 나누다가 질의에 대한 답이 참 와 닿았습니다.
 
다음은 "속도"문제에 대한 Bastian Schaffer 답변입니다.
  1. 혹시 응급 시스템인가요?
  2. 처리 시간이 길어 지면 그 사이 다른 일도 할 수 있고...
 
빨리빨리만 외치는 우리 나라에서 이런 생각을 가질 수 있을까요?
 
혹시 GIS 업계에 계신분들 OGC WPS 및 52°North에 관심 있으신 분들은 다음 메일링 리스트에 가입해 보세요... Geoprocessing mailing list
 
끝으로, 뜻깊은 자리 마련해 주신 염재홍 교수님, 김승용 소장님! 초청해 주셔서 정말 감사합니다.

2010년 8월 25일 수요일

ArcSDE 관련 문제해결


문제발생 : 기존 사용자(아래 예에서는 BASEMAP)의 테이블스페이스, 데이터 파일, 사용자를 오라클에서 물리적으로 삭제 후 새로 BASEMAP 사용자를 생성한 상태에서 ArcCatalog 등에서 피쳐클래스 및 테이블을 업로드 할 경우 이미 테이블이 있다고 나오는 경우

 : 이는 SDE 시스템 테이블에 기존 데이터 정보가 남아 있어서 발생하는 오류이며 아래 순서대로 관련 테이블의 BASEMAP 사용자 관련 테이블 정보를 삭제하면 됨

 
1. SQL/PLUS 등에서 SDE 유저로 접속

2. SDE 시스템 테이블은 지오데이터베이스로 관리하는 GDB_*로 시작하는 테이블 및 SDE 관리테이블(LAYERS, SPATIAL_REFERENCES 등)이 있습니다.

 : 수정 대상 테이블은 다음과 같으며 하나씩 확인해 가면서 수정하세요.

 : UI 도구를 사용한다면 되도록이면 수정 전에 테이블에 어떤 내용이 들어 있는지 확인해 보세요. ArcSDE 테이블 이해에 도움이 됩니다.

: 만약 버저닝을 사용하면 더 많은 테이블이 관련되어 있습니다. 자세한 내용은 다음을 참고하세요

3. 테이블 수정 내용
▣ LAYERS
 : SELECT COUNT(*) FROM LAYERS WHERE OWNER = 'BASEMAP';
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM LAYERS WHERE OWNER = 'BASEMAP';
 
▣ GEOMETRY_COLUMNS
 : SELECT COUNT(*) FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = 'BASEMAP';
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = 'BASEMAP';

▣ COLUMN_REGISTRY
 : SELECT COUNT(*) FROM COLUMN_REGISTRY WHERE OWNER = 'BASEMAP';
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM COLUMN_REGISTRY WHERE OWNER = 'BASEMAP';

▣ TABLE_REGISTRY
 : SELECT COUNT(*) FROM TABLE_REGISTRY WHERE OWNER = 'BASEMAP';
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM TABLE_REGISTRY WHERE OWNER = 'BASEMAP';
 
▣ GDB_USERMETADATA
 : SELECT COUNT(*) FROM GDB_USERMETADATA WHERE OWNER = 'BASEMAP';
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM GDB_USERMETADATA WHERE OWNER = 'BASEMAP';
 
▣ GDB_FIELDINFO
 : SELECT COUNT(*) FROM GDB_FIELDINFO WHERE CLASSID IN (SELECT ID FROM GDB_OBJECTCLASSES WHERE OWNER = 'BASEMAP');
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM GDB_FIELDINFO WHERE CLASSID IN (SELECT ID FROM GDB_OBJECTCLASSES WHERE OWNER = 'BASEMAP');

▣ GDB_FEATUREDATASET
 : SELECT COUNT(*) FROM GDB_FEATUREDATASET WHERE OWNER = 'BASEMAP';
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM GDB_FEATUREDATASET WHERE OWNER = 'BASEMAP';

▣ GDB_FEATURECLASSES
 : SELECT COUNT(*) FROM GDB_FEATURECLASSES WHERE OBJECTCLASSID IN (SELECT ID FROM GDB_OBJECTCLASSES WHERE OWNER = 'BASEMAP');
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM GDB_FEATURECLASSES WHERE OBJECTCLASSID IN (SELECT ID FROM GDB_OBJECTCLASSES WHERE OWNER = 'BASEMAP');
 
▣ GDB_OBJECTCLASSES
 : 마지막 수정해야 할 테이블입니다.
 : SELECT COUNT(*) FROM GDB_OBJECTCLASSES WHERE OWNER = 'BASEMAP';
 : 갯수가 0개 이상이면 다음을 수행
 : DELETE FROM GDB_OBJECTCLASSES WHERE OWNER = 'BASEMAP';

마지막으로 커밋 하시면 됩니다.

2010년 8월 19일 목요일

수치지도 Ver.2.0(NGI 포맷)의 변환 및 활용 2

지난 시간에 수치지도 Ver 2.0(NGI 포맷, 국토지리정보원 내부포맷)에 대해서 간략히 살펴보았습니다. 앞서 살펴보았듯이 NGI 포맷의 변환 도구들을 쉽게 구할 수 없습니다.

여기에서는 ArcObject를 활용하여 Custom Plug-in Data Source를 구현했습니다. 일반적으로 ArcObject에서 Custom Data Source를 구현하는 방법은 3가지로 알려져 있으니 한번 확인해 보시기 바랍니다.

1. 구현 환경
- Microsoft Visual Studio 2008 Visual C# 및 .NET Framework 3.5
- ArcGIS Engine Developer Kit 9.3

2. 제약사항
- NGI 및 NDA, 즉 ASCII 포맷만 지원
- NGI 데이터에 읽기전용만 지원
- ArcGIS Desktop이나 ArcGIS Engine 9.3 이상에서 지원하며 반드시 .NET Support 옵션을 설치해야 함
- 국토지리정보원에서 제공하는 샘플 데이터 및 기타 샘플 데이터에서만 테스트 했으므로 다양한 환경에서의 테스트를 못함
- NGI 포맷에서 TEXT(주기) 유형은 포인트(Point)로 인식하도록 설정
- 만약 NGI(공간데이터)만 포함되어 있고 NDA(속성데이터)가 없을 경우에도 확인 및 불러오기 등이 가능하나 변환시 속성정보는 포함하지 않음

3. 향후 일정
- 내보내기 일괄작업을 위한 도구 제공
 : 대량의 NGI 파일 레이어 분류 후 Merge 등
 : 내보내기 일괄작업을 위한 UI
- 속도 개선
 : 현재 그리기할 때 마다 파일 읽기 --> 캐쉬적용
- 기타 버그 수정

4. 프로그램 다운로드 및 라이센스
▣ 라이센스 공지
- 상업적 이용을 제외한 아무나 사용 가능하며, 사용상 오류에 대한 어떤 책임도 없음을 밝혀둡니다.
- 이 프로그램은 이 블로그에서만 배포될 수 있으며, 업데이트 역시 이 블로그를 통해서 이루어집니다.

▣ 프로그램 다운로드

5. 플러그인 데이터소스 설치 및 제거
▣ 설치
위 다운로드 받은 파일을 압축 해제 후 setup.exe 파일을 더블클릭하여 설치합니다.

▣ 제거
[제어판] -> [프로그램 추가/제거] -> [NGI Plugin for ArcGIS] 선택 후 제거 버튼을 눌러 프로그램을 제거합니다.

6. 활용 예
▣ ArcMap에서의 활용
 ◎ 레이어 불러오기
NGI 포맷은 Cad Dataset과 같이 Feature Dataset으로 인식하도록 구현하였으며, NGI 파일 하나를 Feature Dataset으로 인식한다. 다음 그림과 같이 [Add Data]버튼을 이용하여 레이어 불러오기가 가능하며 Feature Dataset을 불러오면 NGI 파일에 포함된 모든 레이어(Feaure Class)를 한번에 불러온다. Feature Dataset을 더블클릭하여 개별 레이어를 하나씩 불러올 수 있다.

 ◎ 레이어 등록정보
NGI 레이어 역시 Feature Layer이므로 레이어 등록정보의 모든 기능을 사용할 수 있음.

 ◎ 속성 확인
NGI 레이어 중 건물 레이어의 속성을 확인하는 예

 ◎ 레이어 내보내기 1
TOC(Table Of Contents) -> 레이어 선택 -> 팝업메뉴 -> Data -> Export Data... 메뉴를 실행하여 다양한 포맷으로 내보내기 실행

 ◎ 여러 레이어 한번에 Shapefile로 내보내기
ArcToolbox -> Conversion Tools -> To Shapefile -> Feature Class To Shapefile (multiple) 도구 실행 후 TOC에서 레이어를 한번에 선택 후 드래그 & 드랍하여 도구에 레이어 추가 후 변환.
현재까지는 반드시 Drag&Drop만 이용가능하며, 직접 불러왔을 경우 오류가 발생하며, 추후 수정 후 공지 예정


 ◎ 기타 기능
편집기능을 제외한 TIN, Raster 변환 등 레이어를 Source로 활용하는 분석 등 가능

▣ ArcCatalog에서의 활용

2010년 8월 7일 토요일

[foursquare]Where Do You Go

foursquare에서 내가 체크인한 장소를 활용한 heatmap 서비스입니다.

foursquare 사용자라면 홈에 가서 다양한 App들을 활용해 보실 수 있습니다.

전 조만간 월별/시간대별로 SpiderMap 같은 지도를 만들어 보려고 합니다.

아마 이미 App들이 있을 지도 모르겠네요...

1. URL

2. 활동반경

2010년 7월 27일 화요일

KLIS 지적 및 주제도 코드 설명

KLIS(한국토지정보시스템)에서 제공하는 지적도 및 주제도의 Primary Key에 대한 설명입니다.

▣ 토지코드(19자리)
 - 지적도 및 개별공시지가(토지특성) 테이블 등 필지의 Unique ID
 - 지적도(연속/편집)에서는 PNU, 개별공시지가(토지특성)에서는 LAND_CD 등의 필드 이름으로 사용
 - 필드 구성
  : 시도(2)+시군구(3)+읍면동(3)+리(2)+필지구분(1)+본번(4)+부번(4)

- 참고설명 :  필지구분: 1(일반), 2(산)

▣ 용도지역지구관리코드(33자리)
 - 각종 용도지역지구(KLIS에서 LT_*로 시작하는 주제도)주제도의 Unique ID
 - MNUM이라는 19자리의 필드로 사용
 - 필드 구성
  : 지정권자(7) + 시도코드(2) + 시군구코드(3) + 고시년도(4) + 고시번호(4) + 용도지역지구코드(6) + 도면표시번호본번(4) + 도면표시번호부번(3)

▣ 참고: KLIS 레이어의 일반적인 구성
 - KLIS의 GIS 레이어는 크게 지적도(LP*), 주제도(LT*), 지형도(LB*)로 구성
 - LP = LMIS Parcel, LT = LMIS Thematic, LB = LMIS Base Layer를 의미
 - Geometry 유형은 폴리곤(A-Area), 라인(L-Line), 포인트(P-Point), 주기(T-Text)로 구분

 - 지형도 관련 레이어 : LB10_*, LB50_*로 시작하는 레이어
 : LB10_BT_NAME(1:1,000 지형도의 건물레이어 중 주기, BT = Building Text)
 : LB50_RL_ROAD(1:5,000 지형도의 도로레이어 중 도로경계, RL = Road Line)
 : LB50_BA_BLDG(1:5,000 지형도의 건물레이어 중 건물경계, BA = Building Area)

 - 지적도 관련 레이어 : LP_*로 시작하는 레이어
 : LP_AA_SGG(연속지적 행정구역 시군구 폴리곤, AA = Administrative Area)
 : LP_PA_CBND(연속지적 폴리곤, PA = Parcel Area)
 : LP_PA_BBND(편집지적 폴리곤, PA = Parcel Area)

 - 주제도 관련 레이어
 : LT_*로 시작하는 레이어로 모두 폴리곤으로 구성
 : LT_B_UQ111(국토계획/도시지역 편집주제도)
 : LT_C_UQ111(국토계획/도시지역 연속주제도)

==> 어떻습니까? 레이어 이름만 봐도 딱~ 어떤 유형의 어떤 레이어인지 감이 오시지요?

OWS Search Engine

OWS Search Engine is an engine specialised in the search for web services implementing standards published by OGC(Open Geospatial Consortium).


2010년 7월 26일 월요일

List of Public OGC Web Services

전세계의 OGC Web Service(OWS) 현황을 다루고 있는 사이트입니다.


주로 WMS(Web Map Service) 목록만을 대상으로 하지만 아래 서비스 현황을 보면 놀라울 따름입니다. 울 나라는 하나도 없어요...

Total Number of Servers: 994
Total Number of Layers: 339,254

목록을 선택하면 다음과 같이 service capabilities를 확인할 수 있습니다. 연결이 안되는 사이트들도 많네요...
Capabilities: http://wms.telascience.org/cgi-bin/hurricane_ows?Version=1.1.1&Service=WMS&Request=GetCapabilities
Date added: Tue Oct 31 09:11:12 UTC 2006
Number of Layers: 3
Abstract: This OWS has imagery and outlines related to hurricanes

제가 시간이 된다면 GeoNetwork를 활용해서 관리해 보고 싶네요...

[ArcObjects]WMS Layer

ArcObjects에서 OGC WMS(Web Map Service) 레이어를 추가하는 코드입니다.

아래 코드의 ServiceURL에 http://gnis.lbsplus.com/gnis/wms?GDX=tilo.xml&를 입력한 결과는 아래 이미지...


▣ Sample Code
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.GISClient;

public static void AddWMSLayer(IMap targetMap, String serviceURL)
{
    ILayer wmsLayer = OpenWMSLayer(serviceURL, string.Empty);

    if (wmsLayer != null)
    {
        targetMap.AddLayer(wmsLayer);

        IActiveView activeView = (IActiveView)targetMap;
        activeView.Refresh();
    }
}

public static ILayer OpenWMSLayer(string serviceURL, string layerName)
{
    IPropertySet propSet = new PropertySetClass();
    propSet.SetProperty("URL", serviceURL);

    IWMSConnectionName connName = new WMSConnectionNameClass();
    connName.ConnectionProperties = propSet;

    IWMSGroupLayer wmsMapLayer = new WMSMapLayerClass();
   
    IDataLayer dataLayer = (IDataLayer)wmsMapLayer;
    dataLayer.Connect((IName)connName);

    IWMSServiceDescription serviceDesc = wmsMapLayer.WMSServiceDescription;

    for (int k = 0; k < serviceDesc.LayerDescriptionCount; k++)
    {
        IWMSLayerDescription layerDesc = serviceDesc.get_LayerDescription(k);

        ILayer newLayer = null;
        if (layerDesc.LayerDescriptionCount == 0)
        {
            try
            {
                IWMSLayer newWMSLayer = wmsMapLayer.CreateWMSLayer(layerDesc);
                newLayer = (ILayer)newWMSLayer;
            }
            catch (Exception Ex)
            {
                System.Diagnostics.Debug.WriteLine(Ex.Message);
            }

            if (newLayer == null)
            {
                IWMSGroupLayer grpLayer = wmsMapLayer.CreateWMSGroupLayers(layerDesc);
                newLayer = (ILayer)grpLayer;
            }
        }
        else
        {
            IWMSGroupLayer grpLayer = wmsMapLayer.CreateWMSGroupLayers(layerDesc);
            newLayer = (ILayer)grpLayer;
        }

        newLayer.Visible = true;
        wmsMapLayer.InsertLayer(newLayer, 0);
    }

    if (wmsMapLayer == null || wmsMapLayer.Count == 0)
        return null;

    ILayer wmsLayer = (ILayer)wmsMapLayer;
    wmsLayer.Visible = true;

    if (string.IsNullOrEmpty(layerName))
    {
        wmsLayer.Name = serviceDesc.WMSTitle;
    }
    else
    {
        wmsLayer.Name = layerName;
    }

    return wmsLayer;
}


▣ 결과
WMS UI
ArcMap WMS Layer

2010년 7월 18일 일요일

대한민국 공항 및 항구(국가항) 위치

2010년 5월 기준 대한민국의 공항 및 항구(국가항) 현황입니다.

첨부된 파일에 포함된 X, Y좌표는 WGS84 경위도 좌표값입니다.

공항
항구
▣ 위치

대한민국 읍면동 기반 인구밀도

대한민국 읍면동 기반의 인구밀도(단위:명/㎢, 기준 : 2008년)

읍면동별 인구 자료출처: 통계청
국가통계포털


2010년 1월 기준 서울시 표준지공시지가현황

서울시 지가현황(㎡당 지가)입니다. 간단한 제작과정을 살펴보면 다음과 같습니다.

지도제작 과정
 - 국토해양부한국감정평가협회에서 제공하는 부동산공시가격알리미 서비스의  2010/1/1일 기준 표준지공시지가
 - 주소 기반 지오코딩 후 포인트화
 - Interpolation(IDW)
 - Classification(Quantile) 지도화



2010년 7월 15일 목요일

SpatiaLite and Java


오늘은 SQLite 및 SpatiaLite 3번째로 초간단 SpatiaLite 사용법 및 이를 Java 클래스에서 사용하는 방법을 알아보도록 합니다. 우선 아래 두 링크를 확인/설치 후 진행하도록 하세요. 그리고 아래 샘플데이터 받아서 테스트하시면 됩니다.


3. SpatiaLite and Java
3.1 SpatiaLite 사용법

▣ SQLite Command
SpatiaLite Extension을 사용하기 위해서는 다음 command나 query를 이용하면 된다.

만약 라이브러리를 찾을 수 없다고 나오면 해당 파일이 설치되어 있는지 확인 또는 환경변수에 설치된 폴더를 Path에 등록, 이것도 귀찮으면 SQLite 및 SpatiaLite 관련 라이브러리를 윈도우즈 시스템 폴더에 복사하면 된다.

.load 'libspatialite-2.dll'  또는 SELECT load_extension('libspatialite-2.dll')


▣ SpatiaLite Command
SQLite Command와 같은 환경이면서 extension 을 따로 load할 필요 없다. 아래 그림 참조...

SpatiaLite Quick Tutorial은 여기(A quick tutorial to SpatiaLite)서 참고
▣ SpatiaLite GUI 및 GIS
SpatiaLite GUI 에서 Shapefile을 Load하는 방법은 다음과 같다.

[Files] - [Advanced] - [Load Shapefile] 메뉴 실행 후 Shapefile 선택하면 아래 등록 창 표시
SRID(좌표체계, 아래 4326은 WGS84 경위도좌표체계) 및 Charset Encoding(아래처럼 CP949 선택하면 됨) 선택 후 OK 눌러 Load.

※ 샘플 데이터
 - continent polygon 및 earthquake point dataset

▣ Java Class에서 사용하기
SQLite 사용법과 동일하며 다음 Query를 이용하여 Extension을 load한 후 공간관련 함수를 사용할 수 있다.


SELECT load_extension('libspatialite-2.dll')

다음 코드와 결과를 보면서 각 공간함수가 뭘 하는 기능인지 생각해 볼 것!

더 많은 공간관련 함수는 여기(SQL spatial functions)서 참고!

▣ Java Sample Code
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import org.sqlite.SQLiteConfig;

public class SpatiaLite {

    public static void connect() {

        try {
            String dbPath = "C:/DBMS/SpatiaLite/db/db.sqlite";

            Class.forName("org.sqlite.JDBC");

            SQLiteConfig config = new SQLiteConfig();
            config.enableLoadExtension(true);

            Connection dbCon = DriverManager.getConnection("jdbc:sqlite:" + dbPath, config.toProperties());

            Statement dbStmt = dbCon.createStatement();   

            // load_extension SQLite 3.3.6 or higher
            dbStmt.execute("SELECT load_extension('libspatialite-2.dll')");

            // Polygon
            ResultSet rs2 = dbStmt.executeQuery("SELECT PK_UID, ST_Area(Geometry), ST_AsText(Centroid(Geometry)), " + "ST_Dimension(Geometry), ST_GeometryType(Geometry) FROM continent ORDER BY ST_Area(Geometry) DESC LIMIT 5;");   

            printResultSet(rs2);           
            rs2.close();

            // Point
            ResultSet rsSgg = dbStmt.executeQuery("SELECT LOC, ST_AsText(Geometry) as WKT FROM earthquake DESC LIMIT 5;");
            printResultSet(rsSgg);           
            rsSgg.close();   

            dbStmt.close();
            dbCon.close();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static void printResultSet(ResultSet rs) {
        if (rs == null) {
            System.out.println("Error : ResultSet is null!");
            return;
        }

        try {
            ResultSetMetaData rsMetaData = rs.getMetaData();

            if (rsMetaData == null)
                return;

            int columnCount = rsMetaData.getColumnCount();       

            System.out.println("\r\n=========== " + rsMetaData.getTableName(1) + " ==========");

            StringBuilder sb = new StringBuilder();
            for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
                String colName = rsMetaData.getColumnName(columnIndex);
                String colType = rsMetaData.getColumnTypeName(columnIndex);
                int colLen = rsMetaData.getColumnDisplaySize(columnIndex);

                if (columnIndex == columnCount) {
                    sb.append(String.format("%s(%s, %d)", colName, colType, colLen));
                } else {
                    sb.append(String.format("%s(%s, %d) | ", colName, colType, colLen));                   
                }
            }
            System.out.println(sb.toString());           

            while(rs.next()) {
                sb = new StringBuilder();

                for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
                    String colVal = rs.getObject(columnIndex).toString();
                    if (columnIndex == columnCount) {
                        sb.append(colVal);
                    } else {
                        sb.append(colVal + " | ");                   
                    }
                }

                System.out.println(sb.toString());
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

▣ 결과
펼쳐두기..