VWorld에서 제공하는 지적도를 WFS로 사용하기

VWorld는 다양한 주제도를 전국 단위로 OpenAPI로 제공합니다. WMS와 WFS 등의 방식으로 제공하는데요. VWorld의 지적도를 WFS 방식으로 사용하는 내용을 정리해 봅니다. 먼저 최종 결과는 다음과 같습니다.

VWorld에서 제공하는 지적도에 대한 WFS 방식으로 레이어를 추가하는 코드는 다음과 같습니다.

let parcLyr = new Xr.layers.WFSLayer(
    "wfs_parc",
    {
        proxy: "http://www.gisdeveloper.co.kr:8080/Xr",
        url: "http://api.vworld.kr/req/wfs",
        typename: "lp_pa_cbnd_bubun",
        key: "##09##85-1##3-3##5-A##6-####6##C####",
        domain: "http://localhost:56612"
    }
);
lm.add(parcLyr);

WFS 방식의 장점은 공간 데이터를 좌표값으로 받아와 클라이언트에서 직접 그릴 수 있다는 점입니다. 즉, 다양한 심벌을 자유롭게 지정할 수 있습니다. 그에 대한 코드는 아래와 같습니다.

let parcTheme = parcLyr.theme();
let parcPen = parcTheme.penSymbol();
let parcBrush = parcTheme.brushSymbol();

parcPen.color('#ffff00').width(1);
parcBrush.opacity(0);

WFS 방식의 또 다른 장점은 속성 데이터를 함께 제공한다는 것인데요. 이 속성 데이터를 이용하여 원하는 텍스트 심벌을 사용하여 레벨을 표현할 수 있습니다. 해당하는 코드는 이래와 같습니다.

let label = parcLyr.label();
label.enable(true);
label.formatter().fieldName("jibun");

let labelTheme = label.theme();
labelTheme.symbol().strokeColor("#000000").strokeWidth(2).size(12).fontFamily('맑은 고딕').color("#ffffff");

VWorld에서 제공하는 WFS 방식을 통한 지도 레이어는 매우 활용도가 높습니다. 즉, 전국범위의 공간 데이터를 좌표와 속성 데이터를 그대로 받아 원하는 형태로 자유롭고 다양하게 사용할 수 있기 때문입니다. 하지만 VWorld에서 제공하는 WFS 방식은 WMS 방식 보다 제공되는 지도의 종류 수가 적습니다. 예를 들어 건물 레이어의 경우 WMS로는 제공하지만 WFS로는 제공하지 않습니다. VWorld의 OpenAPI를 통해 지적도처럼 건물도 WFS 방식으로 제공되어 활용할 수 있었으면 좋겠습니다.

모바일 NexGen 관리자

모바일 NexGen 관리자는 단말기를 통해 편집한 공간 데이터와 수집한 현장 데이터를 사용자 PC에 내려 받을 수 있는 프로그램입니다. 아래는 모바일 넥스젠과 관리자 프로그램 간의 업무 흐름에 대한 도식도입니다.

단말기를 사용자 PC의 USB에 연결하여 바로 데이터를 내려받을 수 있으며, 편집된 공간 데이터는 SHP 파일 형식으로 저장할 수 있으며, 수집한 위치 기반 현장 데이터에 대해서는 그 목적에 맞게 SHP, CSV, 이미지, 동영상 파일들로 저장됩니다.

모바일 넥스젠 앱이 설치된 단말기에서 공간 데이터를 편집하는 기능에 대한 소개는 다음 URL을 통해 살펴볼 수 있습니다.

모바일 넥스젠의 공간 데이터 편집

또한 현장에서 다양한 데이터를 수집하는 기능에 대한 소개는 다음 URL을 통해 살펴볼 수 있습니다.

모바일 넥스젠의 현장 데이터 수집

C#에서 Spatialite 사용하기

Spatialite는 SQLite를 기반으로 하므로 먼저 SQLite를 설치해야 합니다. SQLite 사이트에서 Precompiled Binaries for 32-bit Windows (.NET Framework 4.6) 중 두번째인 sqlite-netFx46-binary-Win32-2015-1.0.113.0.zip 다운로드 받습니다. (Visual Studio에서 .NET WinForm 프로젝트에서 사용할 것인데 .NET 버전은 4.6으로 하고 32Bits로 설정함). 압축을 풀고 System.Data.SQLite.dll 파일 프로젝트 참조에 추가하고, SQLite.Interop.dll 파일은 프로젝트의 실행 파일이 생성되는 Debug 및 Release에 복사하면 SQLite의 기본 기능은 사용할 수 있게 됩니다.

이제 Spatialite를 사용하기 위해서는 이 파일을 다운로드 받아 압축을 풀고 전체 파일을 프로젝트의 실행 파일이 생성되는 Debug 및 Release 폴더에 복사합니다. 최종적으로 아래처럼 파일이 구성될 것입니다. (복사되어진 파일은 선택 상태로 둠)

이제 다음 코드를 테스트하면 정상 작동됩니다.

conn = new SQLiteConnection("Data Source=d:/db.sqlite;Version=3;");
conn.Open();

conn.LoadExtension("mod_spatialite");

String sql = "select sig_cd, ST_AsText(geometry) from TL_SCCO_SIG";
//String sql = "select sig_cd, geometry from TL_SCCO_SIG";
SQLiteCommand cmd = new SQLiteCommand(sql, conn);
SQLiteDataReader rdr = cmd.ExecuteReader();
            
while (rdr.Read())
{
    MessageBox.Show(rdr["sig_cd"] + " " + rdr.GetString(1));
    break;
}

rdr.Close();
conn.Close();
conn.Dispose();

위의 코드 중 4번 코드가 Spatialite 모듈을 확장 기능으로 적재합니다.

Spatialite에서 공간 데이터를 가지는 Table 생성하기

Spatialite에서는 테이블 생성시 바로 공간 데이터 필드를 추가할 수 없다. 먼저 공간 데이터 필드를 제외하고 테이블을 생성한다.

CREATE TABLE  main_item (
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    layer TEXT,
    title TEXT,
    feature_id INTEGER
);

이제 공간 데이터 필드를 추가한다.

SELECT AddGeometryColumn('main_item', 'geometry', -1, 'GEOMETRY', 'XY');

AddGeometryColumn 함수의 3번째는 EPSG 코드값이며, 4번째는 POINT, LINESTRING, POLYGON, MULTIPOINT 등이 올 수 있다. GEOMETRY는 모든 타입의 공간 데이터를 받을 수 있다.

공간 데이터 필드에 공간 인덱스를 건다.

SELECT CreateSpatialIndex('main_item', 'geometry');

끝으로 Row를 추가하는 SQL문은 다음과 같다.

INSERT INTO main_item (layer, title, feature_id, geometry) 
VALUES ('layer1', 'title1', 100, ST_GEOMFROMTEXT('POINT(128.32132 37.34322)', -1));

잘못된 Geometry를 수정하기

PostGIS의 공간 함수 중 ST_MakeValid는 이미 저장된 올바르지 못한 Geometry를 수정해 준다. 아래의 쿼리는 이에 대한 내용이다.

select ST_IsValid(the_geom) from sify_li;
update sify_li set the_geom = ST_MakeValid(the_geom);

위의 SQL 구문 중 sify_li는 Table 이름이며 the_geom은 Geometry 타입에 대한 필드명에 대한 예시이다.

멀티 폴리곤의 경우 실패하는 경우가 있는데 아래의 SQL문을 사용하면 해결되는 경우가 있음

update sig set the_geom = st_multi(st_collectionextract(st_makevalid(the_geom),3)) where not st_isvalid(the_geom);