DuraMap-Xr을 이용한 좌표 변환 코드 샘플

DuraMap-Xr은 proj.4 기반의 문자열을 토대로 좌표계를 변환할 수 있는데요. 특히 좌표 변환시 10 파라메터에 해당하는 Molodensky-Badekas 모델을 지원합니다.

아래의 코드는 “대한민국 TM 중부원점(Bessel 타원체) – 10.405 보정”의 좌표계의 한 좌표인 (492385.95, 188096.47)를 “대한민국 TM 중부원점(GRS80 타원체)” 좌표계로 변환하는 코드 예입니다.

XrMapLib.Coord Pt;

Pt.X = 492385.95;
Pt.Y = 188096.47;

XrMapLib.Projection proj = new XrMapLib.Projection();

// 대한민국 TM 중부원점(Bessel 타원체) - 10.405 보정
proj.SourceProj4String = "+proj=tmerc +lat_0=38N +lon_0=127.0028902777778E +ellps=bessel +x_0=200000 +y_0=600000 +k=1 +units=m +no_defs";

// 대한민국 TM 중부원점(GRS80 타원체)
proj.TargetProj4String = "+proj=tmerc +lat_0=38N +lon_0=127E +ellps=GRS80 +x_0=200000 +y_0=600000 +k=1 +units=m +no_defs";

// 10 파라메터 적용(towgs84 파라메터)
proj.Set10Parameters(-145.907, 505.034, 685.756, -1.162, 2.347, 1.592, 6.342, -3159521.31, 4068151.32, 3748113.85);

proj.Transform(Pt);

코드를 보면 좌표계 지정을 위해서 사용한 proj.4 문자열에 towgs84에 해당하는 값을 14번째 코드처럼 별도의 매서드(Set10Parameters)로 지정한다는 것입니다. 3개 또는 7개의 파라메터 지정을 위해서는 각각 Set3Parameters, Set7Parameters 매서드를 사용합니다.

최종 좌표변환은 16번 코드의 Transform 매서드로 수행되는데요. 이 매서드는 변환할 입력 좌표 객체를 필요로 하고, 변환된 좌표는 다시 이 입력 좌표 객체에 저장되므로, 입력 좌표를 계속 유지하려면 복사본을 가지고 있어야 합니다.

DuraMap-Xr에서 TMS 레이어 활용하기

C#과 같은 COM을 지원하는 언어에서 GIS 어플리케이션을 개발할 수 있는 GIS 엔진인 DuraMap-Xr에서 TMS 형식의 배경지도를 레이어로 활용할 수 있는 코드를 정리해 봅니다. VWorld에서 제공하는 배경지도를 예시로 하였습니다.

먼저 아래는 듀라맵에서 VWorld의 배경지도를 표시한 화면입니다.

위의 실행 화면에 대한 코드를 살펴보겠습니다. 먼저 TMS 레이어를 추가하는 코드입니다.

XrMapLib.ValueList URLs = new XrMapLib.ValueList();
URLs.AddValueByString(
    "http://xdworld.vworld.kr:8080/2d/Base/201512/${z}/${x}/${y}.png");

XrMapLib.Extent MaxMBR = new XrMapLib.Extent();
MaxMBR.MinX = -20037508.342789244;
MaxMBR.MinY = -20037508.342789244;
MaxMBR.MaxX = 20037508.342789244;
MaxMBR.MaxY = 20037508.342789244;

double[] upps = {
    78000, 39000, 19600, 9800, 4900, 2400, //Dummy
    1222.9924523925781, 611.4962261962891, 305.74811309814453, 
    152.87405654907226, 76.43702827453613, 38.218514137268066, 
    19.109257068634033, 9.554628534317017, 4.777314267158508, 
    2.388657133579254, 1.194328566789627, 0.5971642833948135 };

XrMapLib.ValueList UPPs = new XrMapLib.ValueList();

for (int iUPP = 0; iUPP < upps.Length; ++iUPP)
{
    double UPP = upps[iUPP];
    double MapScale = axXr1.GetMapScaleFromUPP(UPP);

    UPPs.AddValueByFloat(UPP, 14);

    if (iUPP > 5)
    {
        Scales.Add(MapScale);
    }
}

axXr1.Layers.AddTMSLayer("basemap", URLs, MaxMBR, UPPs, true);
axXr1.WaitForAllConnections();

XrMapLib.Coord MapCenter = new XrMapLib.Coord();
MapCenter.X = 14289580.202989;
MapCenter.Y = 4436964.90266281;
axXr1.MapCenter = MapCenter;
axXr1.MapScale = Scales[0];
axXr1.Update();

axXr1.MouseMode = XrMapLib.XrMapViewModeEnum.XrPanMode;

위의 코드 중 2번은 타일맵에 접근하기 위한 URL의 리스트입니다. VWorld는 TMS 이미지에 접근하기 위한 URL을 하나만 제공합니다. 5~9번 코드는 TMS의 전체 MBR 값입니다. 그리고 11번 코드에서 upps 배열에 저장된 값은 Units Per Pixel 값들로써, 1 픽셀당 몇 m인지에 대한 값입니다. 20번 코드의 반복문은 이 upps 배열을 통해 실제 지도 축척값을 계산하여 Scales라는 배열에 저장합니다. 33번 코드가서 TMS 레이어를 추가하는 코드이고, 37~40번 코드에서 첫 실행시 지도의 중심 위치와 지도 축척을 지정합니다. 앞서 UPP값을 지도 축척값으로 계산하여 Scales라는 배열에 저장한다고 하였는데, Scales 변수는 아래와 같습니다.

private List<double> Scales = new List<double>();

TMS를 통한 배경지도는 이미 정해진 축척 레벨이 존재합니다. 이 축척값으로 지도를 확대하고 축소할 경우에 가장 최상의 지도 품질을 사용자에게 제공할 수 있는데요. 듀라맵에서는 이를 위해 아래와 같은 코드가 필요합니다.

private void axXr1_OnBeforeMapDrawing(object sender, EventArgs e)
{
    double NewMapScale = axXr1.MapScale;

    int cntLevels = Scales.Count;
    double Gap = Double.MaxValue;
    int CurrentLevel = -1;
    for (int i = 0; i < cntLevels; i++)
    {
        double ThatGap = Math.Abs(NewMapScale - Scales[i]);
        if (Gap > ThatGap)
        {
            Gap = ThatGap;
            CurrentLevel = i;
        }
    }

    axXr1.MapScale = Scales[CurrentLevel];
}

위는 듀라맵의 OnBeforeMapDrawing 이벤트에 대한 코드로써, TMS에서 제공하는 가장 접합한 지도 축척값을 유지하도록 하고 있습니다. 위의 코드에 대한 Visual Studio 2013 프로젝트를 아래에 첨부합니다.

듀라맵 엔진은 제작사인 지오서비스의 자료실에서 다운로드 받으시기 바라며, 링크는 아래와 같습니다.

지오서비스 자료실

DuraMap-Xr의 SpatialOperator를 이용한 공간연산 응용예

DuraMap-Xr은 Windows 기반의 Desktop GIS Application 개발을 위한 맵 엔진입니다. DuraMap-Xr의 기능 중 SpatialOperator 기능은 벡터 데이터 간의 Intersects나 Intersection과 같은 API와 단일 벡테 데이터의 Buffer 연산자와 같은 API를 제공합니다. 이러한 연산자를 이용하여 다음과 같은 기능에 DuraMap-Xr이 활용되었는데요. 간단히 소개해 봅니다.

위의 그림은 건물 레이어와 홍수범람에 대한 하천 레이어 그리고 행정구역도 레이어로 구성된 간단한 지도입니다. 건물 레이어의 건물 도형 데이터에는 인구수에 대한 속성 데이터가 조인되어 있습니다. 건물 중 홍수범람에 대한 하천 레이어의 도형과 교차(Intersects)되는 건물을 추출하고 추출된 건물에 거주하는 인구수의 총합을 계산해야 합니다. 바로 이 인구수가 홍수에 의한 피해 인구수라고 생각할 수 있습니다.

위의 UI는 위에서 설명한 기능에 대해 실제 구현한 UI입니다. 홍수피해의 결과로 4006명이 산출되었고, 피해를 받은 건물은 result.shp 파일로 저장되도록 하였습니다.

위의 이미지에서 빨간색 도형이 기능에 대한 결과로 생성된 홍수 피해를 받은 건물에 대한 레이어어 입니다. 이미지를 살펴보면, 건물이 하천 경계 도형으로 클리핑(Intersection) 처리 되어 저장된 것을 볼 수 있습니다.

DuraMap-Xr은 우리가 흔히 알고 있는 지도 위에 도형 매쉬업이라는 단순한 기능에서 한발 더 나아가 각 도형들간의 관계와 연산을 통해 더욱 의미 있는 결과를 생성해 내는 GIS 엔진입니다.

[GIS] DuraMap-Xr을 활용한 Windows 기반의 GIS 프로그래밍

듀라맵은 작고 가벼운 GIS 엔진으로 빠르고 풍부한 기능을 제공합니다. 수치지도와 항공영상 기반의 지도 표시, 공간 데이터 편집, 지오메트리와 그리드 기반의 공간분석, 통계 데이터의 차트 표시, 좌표변환, 공간 데이터 생성과 같은 기능을 제공합니다.

사용자 삽입 이미지
듀라맵을 활용한 윈도우즈 기반의 GIS 프로그래밍을 위한 개발자 문서입니다. 문서의 다운로드는 다음 URL을 참고하시기 바랍니다.

[GIS] DuraMap-Xr, 타일맵 레이어

듀라맵은 3.8 버전부터 타일맵 형태의 배경지도를 인터넷을 통해 받아 사용자에게 제공할 수 있습니다. 아래는 듀라맵을 이용해 타일맵 레이어를 추가하여 실행한 화면입니다.

사용자 삽입 이미지
위 화면에 대한 예를 통해 듀라맵에서 타일맵 레이어를 추가하는 API를 살펴보도록 하겠습니다. 저는 여기서 VB를 이용하였습니다. 듀라맵은 COM 기반의 ActiveX 컴포넌트로 ActiveX 개발시 디버깅에 VB가 적합하여 사용하였습니다. 듀라맵은 C#과 델파이와 같은 COM을 지원하는 개발언어에서도 사용할 수 있습니다.

먼저 위의 화면에 보이는 것처럼 4개의 버튼과 듀라맵 컴포넌트를 화면상에 배치합니다. 4개의 버튼에 대한 Caption은 각각 Connect, Zoom In, Zoom Out, Pan Mode로 합니다. Connect 버튼은 인터넷을 통해 타일맵을 서비스 받을 수 있도록 연결하는 기능이며 Zoom In과 Zoom Out은 각각 지도 확대 레벨을 변경하여 지도를 확대하고 축소하는 기능입니다. 끝으로 Pan Mode는 지도를 마우스를 이용해 이동하는 기능입니다.

화면 UI 구성이 끝났으면 다음으로 코드를 작성합니다. 먼저 폼의 크기가 변경되면 듀라맵 컴포넌트의 크기도 폼의 크기에 맞춰 조절되도록 폼의 Resize 이벤트를 다음처럼 작성합니다.

Private Sub Form_Resize()
    Xr1.Height = Me.Height
    Xr1.Width = Me.Width
End Sub

다음으로 Connect 버튼의 Click 이벤트를 다음처럼 작성합니다.

Private Sub Command1_Click()
    Dim OK As Boolean
    OK = Xr1.Layers.AddTileMapLayer("basemap", 
        "XrTileMap://geoservice.co.kr/tilemap")
    If OK Then
        Xr1.WaitForAllConnections
        Xr1.ZoomFullExtent
        Xr1.MapScale = Scales(Current)
        Xr1.MouseMode = XrPanMode
    Else
        MsgBox "Error AddTileMapLayer"
    End If
End Sub

다음으로 Zoom In과 Zoom Out 버튼에 대한 Click 이벤트를 작성해야 하는데요. 그전에 다음과 같은 사용할 전역 변수를 선언해야 합니다.

Dim Scales(1 To 12) As Long
Dim Current As Integer

1번 코드는 타일맵의 12단계 축척을 저장할 배열이고 2번은 현재 화면상에 표시하고 있는 축척 단계를 저장하고 있는 변수입니다. 이 변수에 값을 초기화 하는 코드를 폼의 Load 이벤트에 아래와 같이 작성합니다.

Private Sub Form_Load()
    Scales(1) = 3000000
    Scales(2) = 1800000
    Scales(3) = 800000
    Scales(4) = 460000
    Scales(5) = 250000
    Scales(6) = 110000
    Scales(7) = 50000
    Scales(8) = 25000
    Scales(9) = 14000
    Scales(10) = 7500
    Scales(11) = 3500
    Scales(12) = 2000
    
    Current = 1
End Sub

이제 지도 확대와 축소를 위한 버튼의 기능을 작성합니다. 먼저 지도를 확대하는 Zoom In 버튼의 클릭 이벤트를 아래와 같이 작성합니다.

Private Sub Command2_Click()
    Current = Current + 1
    If Current > 12 Then Current = 12
    Xr1.MapScale = Scales(Current)
    Xr1.Update
End Sub

그리고 지도를 축소하는 Zoom Out 버튼의 클릭 이벤트를 아래와 같이 작성합니다.

Private Sub Command3_Click()
    Current = Current - 1
    If Current < 1 Then Current = 1
    Xr1.MapScale = Scales(Current)
    Xr1.Update
End Sub

마지막으로 지도를 마우스 드레깅을 통해 이동하는 Pan Mode 버튼의 클릭 이벤트를 아래와 같이 작성합니다.

Private Sub Command4_Click()
    Xr1.MouseMode = XrPanMode
End Sub

코드에 대한 설명은 거의 하지 않았으나 코드의 구성이 단순하고 명확하여 이해하기 어렵지 않을것으로 생각합니다.