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();
        }
    }
}

▣ 결과
펼쳐두기..