XDL Manual

XDL MilmapView 활용 두번째

(piXoneer XDL Tutorial)

 

 

 

 

 

 

이 문서는 XDL Development Library

 설치 및 사용하기 위한 문서입니다.

 

2017. 01.

 

 

목차

XDL MilmapView 활용 두번째... 1

1    사용하기... 3

1.1    XDL 엔진... 3

2    NXMilmapView 이용한 예제 프로그램 만들기... 3

2.1    기본 프로그램 작성... 3

2.2    프로그램 디자인... 3

2.3    기능 이벤트 추가... 5

 

 

 

 

1     사용하기

 

1.1    XDL 엔진

설치 프로그램으로 배포되는 XDL 엔진은 Visual Studio 2010 x86 Release 버전으로, Visual Studio 2010 이상의 버전에서 사용가능하다.

아래의 설명은 Visual Studio 2010을 기준으로 하겠다.

2     NXMilmapView를 이용한 예제 프로그램 만들기

l  본 예제 프로그램은 NXMilmapView의 기본 측정 모드를 설정하여 길이, 면적 등을 측정해 보고, 세 점을 이용한 거리 및 각도를 사용자 코드를 이용하여 도시하고 측정해 보도록 한다.

2.1    기본 프로그램 작성

2.1.1     Visual Studio 2010을 이용하여 예제 “XDL_MilmapView1”“Config 파일 설정하기기본 프로그램 작성방법을 참고로 기본 프로젝트를 생성한다.

 

2.2    프로그램 디자인

 

번호

Name

Control type

menuStrip1

MenuStrip

nxMilmapView1

NXMilmapView

nxMilmapLayer1

NXMilmapLayer

2.2.1     [도구 상자]“MenuStrip”를 선택하고 Form1에 끌어다가 놓는다.

Form1 menuStrip1이 추가된다. Form의 상단을 클릭하면 아래와 같이 메뉴를 추가할 수 있도록 바뀐다.

기능을 위한 메뉴를 입력하고 이에 대한 Name도 설정한다. 예제의 메뉴 구성은 아래와 같다.

Text

Name

거리(단선) 측정

MeasureLineToolStripMenuItem

거리(폴리라인) 측정

MeasurePolyLineToolStripMenuItem

면적 측정

MeasureAreaToolStripMenuItem

각도 측정(진북방향)

MeasureAngleToolStripMenuItem

원형 측정

MeasureCircleToolStripMenuItem

 

Text

Name

거리 및 각도 측정

UserDefinedMeasureToolStripMenuItem

2.2.2     NXMilmapView 컨트롤은 “XDL_MilmapView1”을 참고하여 추가한다.

2.2.3     [도구 상지]에서 NXMilmapLayer를 선택한 뒤 드래그하여 nxMilmapView1 위에 놓는다.

NXMilmapLayerMilmapView에 추가되어 XDL 엔진에서 발생하는 이벤트를 외부 어플리케이션에서 처리할 수 있다. Form1.Designer.cs에서 보면 다음과 같이 컨트롤 nxMilmapLayer1 멤버변수가 추가됨을 확인할 수 있다.

 

2.3    기능 및 이벤트 추가

2.3.1     Form1을 선택하고 [속성] - [이벤트 ] 메뉴를 선택한 뒤 “Load” 이벤트를 더블클릭한다.

Form1_Load 함수와 함께 아래와 같이 코드를 추가한다.

using Pixoneer.NXDL;            // 기본 기능
using Pixoneer.NXDL.NGR;        // 그래픽 관련 기능
using Pixoneer.NXDL.NXMilmap;   // 군사 지도 도시 관련 기능
using Pixoneer.NXDL.NCC;        // 좌표 관련 기능

namespace XDL_MilmapView2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // XMilmapConfig.xml을 이용하여 군사지도를 위한 NXMilmapView 및 NXMilmapEngine을 초기화한다.
            if (!NXMilmapView.m_MapEngine.InitFromXML("c:\\Pixoneer\\Xdl1.2\\Config\\XMilmapConfig.xml"))
            {
                return;
            }

            nxMilmapView1.AddRenderLayer(ref nxMilmapLayer1);

            // 마우스 휠을 끌고 당기는 것을 확대/축소 요인으로 계산하여 화면을 확대/축소한다.
            // 이 때, 계산된 공간 해상도와 가까운 축척(scale)이 있는 경우 자동적으로 해당 축척으로 바뀌면서 도시된다.
            // 마우스 휠을 끌고 당기는 것으로 화면의 축척을 변경하려면, NXMilmapView.eWheelZoomAction.ByScaleIndex으로 설정
            nxMilmapView1.WheelZoomAction = NXMilmapView.eWheelZoomAction.ByZoomFactor;
            nxMilmapView1.SetGeoToCenter(0, new XVertex2d(127.0, 36.0));

            // MilmapView의 측정 단위 설정
            // 거리 측정 단위
            nxMilmapView1.ToolboxDistUnit = NXMilmapView.eToolboxDistUnit.KiloMeter;
            // 면적 측정 단위
            nxMilmapView1.ToolboxAreaUnit = NXMilmapView.eToolboxAreaUnit.SquareKiloMeter;
        }
    }
}

측정 결과를 표시하는 데에 측정 단위를 설정하려면, 면적에 대해서는 NXMilmapView ToolboxAreaUnit 속성을 NXMilmapView.eToolboxAreaUnit 값으로 설정하면 되고, 거리에 대해서는 NXMilmapView ToolboxDistUnit 속성을 NXMilmapView.eToolboxDistUnit 값으로 설정한다.

Form1_Load 함수에서는 면적 측정 단위는 ㎢로, 길이 측정 단위는 ㎞로 한다.

 

2.3.2     “Measurement/사용자 정의의 하위 메뉴를 선택한 후 더블클릭한다.

메뉴에서 마우스로 더블클릭하면 “Click”에 대한 이벤트 함수가 자동 추가된다.

 

2.3.3     각 메뉴에 따른 MilmapViewToolboxMode를 설정한다.

NXMilmapView의 측정모드로는 2점을 이용한 거리 측정(NXMilmapView.eToolboxMode. DistanceMeasurer), 다중 점을 이용한 거리 측정(eToolboxMode.PathMeasurer), 다중 점을 이용한 면적 측정(eToolboxMode.AreaMeasurer), 점의 거리를 반지름으로 원형 측정(eToolboxMode.CircleMeasurer), 점으로 이루어진 벡터와 진북방향과의 각도 측정(eToolboxMode.AngleMeasurer) 있다.

코드는 아래와 같다.

private void MeasureLineToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxMilmapView1.ToolboxMode = NXMilmapView.eToolboxMode.DistanceMeasurer;

}

 

private void MeasurePolyLineToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxMilmapView1.ToolboxMode = NXMilmapView.eToolboxMode.PathMeasurer;

}

 

private void MeasureAreaToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxMilmapView1.ToolboxMode = NXMilmapView.eToolboxMode.AreaMeasurer;

}

 

private void MeasureAngleToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxMilmapView1.ToolboxMode = NXMilmapView.eToolboxMode.AngleMeasurer;

}

 

private void MeasureCircleToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxMilmapView1.ToolboxMode = NXMilmapView.eToolboxMode.CircleMeasurer;

}

2.3.4     사용자 정의 측정을 위한 변수를 추가하고 UserDefinedMeasureToolStripMenuItem 이벤트 함수에서 초기화한다.

사용자 정의 측정 여부를 설정하는 “bool userMeasure”와 각도 측정을 위한 세 변수 “XVertex2d posMeasure0, posMeasure1, posMeasure2”를 생성하고 초기화한다.

public partial class Form1 : Form

{

    bool userMeasure = false;

    int countPos = 0;

    XVertex2d posAngle0, posAngle1, posAngle2;    // index 0 : start, index 1 : center, index 2 : end

    public Form1()

    {

        InitializeComponent();

}

 

private void Form1_Load(object sender, EventArgs e)

    {

        // XMilmapConfig.xml 이용하여 군사지도를 위한 NXMilmapView NXMilmapEngine 초기화한다.

        if (!NXMilmapView.m_MapEngine.InitFromXML("c:\\Pixoneer\\Xdl1.2\\Config\\XMilmapConfig.xml"))

        {

            return;

        }

 

        nxMilmapView1.AddRenderLayer(ref nxMilmapLayer1);

 

        // 마우스 휠을 끌고 당기는 것을 확대/축소 요인으로 계산하여 화면을 확대/축소한다.

        // , 계산된 공간 해상도와 가까운 축척(scale) 있는 경우 자동적으로 해당 축척으로 바뀌면서 도시된다.

        // 마우스 휠을 끌고 당기는 것으로 화면의 축척을 변경하려면, NXMilmapView.eWheelZoomAction.ByScaleIndex으로 설정

        nxMilmapView1.WheelZoomAction = NXMilmapView.eWheelZoomAction.ByZoomFactor;

        nxMilmapView1.SetGeoToCenter(0, new XVertex2d(127.0, 36.0));

 

        // MilmapView 측정 단위 설정

        // 거리 측정 단위

        nxMilmapView1.ToolboxDistUnit = NXMilmapView.eToolboxDistUnit.KiloMeter;

        // 면적 측정 단위

        nxMilmapView1.ToolboxAreaUnit = NXMilmapView.eToolboxAreaUnit.SquareKiloMeter;

 

        // 사용자 정의 측정을 위한 변수 초기화

        userMeasure = false;

        countPos = 0;

    }

 

private void UserDefinedMeasureToolStripMenuItem_Click(object sender, EventArgs e)

    {

        userMeasure = !userMeasure;

        countPos = 0;

    }

2.3.5     각도 및 거리를 측정하는 함수를 이용하기 위해서 “NXDLcc.dll”을 참조에 추가한다.

WGS84체를 반영한 거리를 측정하는 함수는 Xcc.CalcGeodeticDistance이며, 각도를 측정하는 함수는 Xcc.CalcGeodeticAngle이다. 이를 위해 NXDLcc.dll을 참조에 추가하고, “using Pixoneer.NXDL.NCC;” 구문 또한 추가한다.

2.3.6     nxMilmapLayer1을 선택하여 “OnWndProc” 이벤트와 “OnRender” 이벤트 함수를 추가하여 코드를 작성한다.

OnWndProc 이벤트는 NXMilmapLayer가 추가되어 있는 View의 윈도우 이벤트를 외부에서 받아서 사용할 수 있도록 한다. OnRenderNXMilmapLayer가 추가되어 있는 ViewRendering이 완료된 후 어플리케이션에서 추가적인 작업을 구현해야 할 필요가 있을 때 사용하면 된다.

왼쪽 버튼이 클릭할 때마다 각도 측정을 위한 점을 차례대로 설정하고 3점이 모두 설정되면 계산결과를 Visual Studio 2010 출력창에 출력하도록 한다. 또한 2점 이상인 경우 화면에 붉은 선으로 도시한다.

코드는 아래와 같다.

private bool nxMilmapLayer1_OnWndProc(object sender, Pixoneer.NXDL.NXMilmap.NXMilmapDrawArgs e, ref Message m)

{

    if (m.Msg == Pixoneer.NXDL.XWndMsg.XWM_LBUTTONDOWN)

    {

        if (userMeasure)

        {

            double x = Pixoneer.NXDL.XWndMsg.GetLowValue(m.LParam);

            double y = Pixoneer.NXDL.XWndMsg.GetHighValue(m.LParam);

 

            NXMilmapDrawArgs drawArgs = nxMilmapView1.GetDrawArgs();

            XVertex2d gpPos = drawArgs.ScreenToGeographic(new XVertex2d(x, y));

            if (countPos == 0)

            {

                posAngle0 = gpPos;

            }

            else if (countPos == 1)

            {

                posAngle1 = gpPos;

            }

            else if (countPos == 2)

            {

                posAngle2 = gpPos;

 

                // 선분의 길이와 3 점으로 이루어지는 각도 계산

                double distance = 0.0;

                distance += Xcc.CalcGeodeticDistance(XAngle.FromDegree(posAngle0.x), XAngle.FromDegree(posAngle0.y),

                    XAngle.FromDegree(posAngle1.x), XAngle.FromDegree(posAngle1.y));

                distance += Xcc.CalcGeodeticDistance(XAngle.FromDegree(posAngle1.x), XAngle.FromDegree(posAngle1.y),

                    XAngle.FromDegree(posAngle2.x), XAngle.FromDegree(posAngle2.y));

 

                double angle = 0.0;

                angle = Xcc.CalcGeodeticAngle(XAngle.FromDegree(posAngle1.x), XAngle.FromDegree(posAngle1.y),

                    XAngle.FromDegree(posAngle0.x), XAngle.FromDegree(posAngle0.y),

                    XAngle.FromDegree(posAngle2.x), XAngle.FromDegree(posAngle2.y));

 

                System.Diagnostics.Debug.WriteLine("Distance : " + distance.ToString());

                System.Diagnostics.Debug.WriteLine("Angle    : " + angle.ToString());

            }

 

            countPos++;

 

            nxMilmapView1.RefreshScreen();

        }

    }

 

    return default(bool);

}

 

private bool nxMilmapLayer1_OnRender(object sender, NXMilmapDrawArgs e)

{

    if (!userMeasure) return false;

 

    if (countPos > 1)

    {

        e.Graphics.glDisable(XGraphics.GL_DEPTH_TEST);

        e.Graphics.glEnable(XGraphics.GL_BLEND);

        e.Graphics.glBlendFunc(XGraphics.GL_SRC_ALPHA, XGraphics.GL_ONE_MINUS_SRC_ALPHA);

 

        e.Graphics.glPushMatrix();

 

        e.Graphics.glColor3f(1.0f, 0.0f, 0.0f);

        e.Graphics.glLineWidth(3);

        e.Graphics.glBegin(XGraphics.GL_LINE_STRIP);

 

        NXMilmapDrawArgs drawArgs = nxMilmapView1.GetDrawArgs();

        XVertex3d posWorld = drawArgs.GeographicToWorld(posAngle0);

        e.Graphics.glVertex3d(posWorld);

 

        posWorld = drawArgs.GeographicToWorld(posAngle1);

        e.Graphics.glVertex3d(posWorld);

 

        if (countPos >= 3)

        {

            posWorld = drawArgs.GeographicToWorld(posAngle2);

            e.Graphics.glVertex3d(posWorld);

        }

 

        e.Graphics.glEnd();

        e.Graphics.glColor3f(1.0f, 1.0f, 1.0f);

        e.Graphics.glPopMatrix();

        e.Graphics.glEnable(XGraphics.GL_DEPTH_TEST);

    }

 

    return default(bool);

}

2.3.7     솔루션을 빌드하고 실행한다.

Measurement거리(폴리라인) 측정메뉴를 선택한 뒤 nxMilmapView1 위에서 마우스 왼쪽 버튼을 클릭하면서 측정하고자 하는 정점을 설정한다. 아래 그림과 같이 측정 결과가 각 선분 요소에 도시된다.

 

사용자 정의 메뉴의 거리 및 각도 측정을 선택한 뒤 nxMilmapView1 위에서 마우스 왼쪽 버튼을 클릭하면 2점 이상부터 화면에 붉은 실선이 도시되고, 3점이 선택되면 Visual Studio 2010의 출력창에 측정결과가 나타난다.

 

Xcc.CalcGeodeticAngle 측정결과의 단위는 거리의 경우 meter, 각도의 경우 ˚이다.