XDL Manual

XDL PlanetView 활용 두번째

(piXoneer XDL Tutorial)

 

 

 

 

 

 

이 문서는 XDL Development Library

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

 

2017. 01.

 

 

목차

XDL PlanetView 활용 두번째... 1

1    사용하기... 3

1.1    XDL 엔진... 3

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

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

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

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

 

 

 

 

1     사용하기

 

1.1    XDL 엔진

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

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

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

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

2.1    기본 프로그램 작성

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

 

2.2    프로그램 디자인

 

번호

Name

Control type

menuStrip1

MenuStrip

splitContainter1

SplitContainer

nxPlanetView2D

NXPlanetView

nxPlanetView3D

NXPlanetView

nxPlanetLayer2D

NXPlanetLayer

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

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

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

Text

Name

거리(단선) 측정

Measure2DLineToolStripMenuItem

거리(폴리라인) 측정

Measure2DPolyLineToolStripMenuItem

면적 측정

Measure2DAreaToolStripMenuItem

각도 측정(진북방향)

Measure2DAngleToolStripMenuItem

각도 측정(3점 이용)

Measure2DAngle3PtToolStripMenuItem

원형 측정

Measure2DCircleToolStripMenuItem

 

Text

Name

거리(단선) 측정

Measure3DLineToolStripMenuItem

거리(폴리라인) 측정

Measure3DPolyLineToolStripMenuItem

면적 측정

Measure3DAreaToolStripMenuItem

각도 측정(진북방향)

Measure3DAngleToolStripMenuItem

각도 측정(3점 이용)

Measure3DAngle3PtToolStripMenuItem

원형 측정

Measure3DCircleToolStripMenuItem

 

Text

Name

거리 및 각도 측정

UserDefinedMeasureToolStripMenuItem

2.2.2     나머지 컨트롤은 “XDL_PlanetView1”을 참고하여 추가한다.

2.2.3     nxPlanetView3D 컨트롤을 선택하고 [속성] 창의 “EarthMode”“Planet3D”로 설정한다.

NXPlanetViewEarthMode“Planet2D”이다. Earth모드를 “Planet3D”로 설정하면 PlanetView 3차원 도시 모드로 변경된다.

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

 

2.3    기능 및 이벤트 추가

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

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

using Pixoneer.NXDL;
using Pixoneer.NXDL.NGR;
using Pixoneer.NXDL.NXPlanet;

namespace XDL_PlanetView2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            nxPlanetView2D.BackColor = Color.Black;
            nxPlanetView3D.BackColor = Color.Black;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            XGeoPoint gpEye = XGeoPoint.FromDegree(127.4, 38.0, 1500000);
            // Planet2D 모드의 camera 위치 설정
            nxPlanetView2D.SetCameraPosition(gpEye, XAngle.FromDegree(0.0));
            // Planet3D 모드의 camera 위치 설정
            nxPlanetView3D.SetCameraPosition(gpEye, XAngle.FromDegree(0.0), XAngle.FromDegree(-90.0), XAngle.FromDegree(0.0));

            // PlanetView의 측정 단위 설정
            // 거리 측정 단위
            nxPlanetView3D.ToolboxDistUnit = NXPlanetView.eToolboxDistUnit.Mile;
            // 면적 측정 단위
            nxPlanetView3D.ToolboxAreaUnit = NXPlanetView.eToolboxAreaUnit.SquareKiloMeter;
         
            nxPlanetView2D.RefreshScreen();
            nxPlanetView3D.RefreshScreen();
        }
    }
}

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

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

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

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

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

코드는 아래와 같다.

private void Measure2DLineToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView2D.ToolboxMode = NXPlanetView.eToolboxMode.DistanceMeasurer;

}

 

private void Measure2DPolyLineToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView2D.ToolboxMode = NXPlanetView.eToolboxMode.PathMeasurer;

}

 

private void Measure2DAreaToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView2D.ToolboxMode = NXPlanetView.eToolboxMode.AreaMeasurer;

}

 

private void Measure2DAngleToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView2D.ToolboxMode = NXPlanetView.eToolboxMode.AngleMeasurer;

}

 

private void Measure2DAngle3PtToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView2D.ToolboxMode = NXPlanetView.eToolboxMode.AngleMeasurer2;

}

 

private void Measure2DCircleToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView2D.ToolboxMode = NXPlanetView.eToolboxMode.CircleMeasurer;

}

 

private void Measure3DLineToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView3D.ToolboxMode = NXPlanetView.eToolboxMode.DistanceMeasurer;

}

 

private void Measure3DPolyLineToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView3D.ToolboxMode = NXPlanetView.eToolboxMode.PathMeasurer;

}

 

private void Measure3DAreaToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView3D.ToolboxMode = NXPlanetView.eToolboxMode.AreaMeasurer;

}

 

private void Measure3DAngleToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView3D.ToolboxMode = NXPlanetView.eToolboxMode.AngleMeasurer;

}

 

private void Measure3DAngle3PtToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView3D.ToolboxMode = NXPlanetView.eToolboxMode.AngleMeasurer2;

}

 

private void Measure3DCircleToolStripMenuItem_Click(object sender, EventArgs e)

{

    nxPlanetView3D.ToolboxMode = NXPlanetView.eToolboxMode.CircleMeasurer;

}

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

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

public partial class Form1 : Form

{

    bool userMeasure = false;

    int countPos = 0;

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

    public Form1()

    {

        InitializeComponent();

        nxPlanetView2D.BackColor = Color.Black;

        nxPlanetView3D.BackColor = Color.Black;

    }

 

    private void Form1_Load(object sender, EventArgs e)

    {

        XGeoPoint gpEye = XGeoPoint.FromDegree(127.4, 38.0, 1500000);

        // Planet2D 모드의 camera 위치 설정

        nxPlanetView2D.SetCameraPosition(gpEye, XAngle.FromDegree(0.0));

        // Planet3D 모드의 camera 위치 설정

        nxPlanetView3D.SetCameraPosition(gpEye, XAngle.FromDegree(0.0), XAngle.FromDegree(-90.0), XAngle.FromDegree(0.0));

 

        // PlanetView 측정 단위 설정

        // 거리 측정 단위

        nxPlanetView3D.ToolboxDistUnit = NXPlanetView.eToolboxDistUnit.Mile;

        // 면적 측정 단위

        nxPlanetView3D.ToolboxAreaUnit = NXPlanetView.eToolboxAreaUnit.SquareKiloMeter;

        

        nxPlanetView2D.RefreshScreen();

        nxPlanetView3D.RefreshScreen();

 

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

        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     nxPlanetLayer2D을 선택하여 “OnWndProc” 이벤트와 “OnRender” 이벤트 함수를 추가하여 코드를 작성한다.

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

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

코드는 아래와 같다.

private bool nxPlanetLayer2D_OnWndProc(object sender, NXPlanetDrawArgs 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);

 

            XGeoPoint gpPos = nxPlanetView2D.ScreenToGeographic(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.lond), XAngle.FromDegree(posAngle0.latd),

                    XAngle.FromDegree(posAngle1.lond), XAngle.FromDegree(posAngle1.latd));

                distance += Xcc.CalcGeodeticDistance(XAngle.FromDegree(posAngle1.lond), XAngle.FromDegree(posAngle1.latd),

                    XAngle.FromDegree(posAngle2.lond), XAngle.FromDegree(posAngle2.latd));

 

                double angle = 0.0;

                angle = Xcc.CalcGeodeticAngle(XAngle.FromDegree(posAngle1.lond), XAngle.FromDegree(posAngle1.latd),

                    XAngle.FromDegree(posAngle0.lond), XAngle.FromDegree(posAngle0.latd),

                    XAngle.FromDegree(posAngle2.lond), XAngle.FromDegree(posAngle2.latd));

 

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

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

            }

 

            countPos++;

 

            nxPlanetView2D.RefreshScreen();

        }

    }

    return default(bool);

}

 

private bool nxPlanetLayer2D_OnRender(object sender, NXPlanetDrawArgs 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);

 

        XVertex3d posWorld = nxPlanetView2D.GeographicToWorld(posAngle0);

        e.Graphics.glVertex3d(posWorld - e.WOS);

 

        posWorld = nxPlanetView2D.GeographicToWorld(posAngle1);

        e.Graphics.glVertex3d(posWorld - e.WOS);

 

        if (countPos >= 3)

        {

            posWorld = nxPlanetView2D.GeographicToWorld(posAngle2);

            e.Graphics.glVertex3d(posWorld - e.WOS);

        }

 

        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     솔루션을 빌드하고 실행한다.

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

 

3D Measurement각도 측정(진북방향)” 메뉴를 선택한 뒤 nxPlanetView3D 위에서 마우스 왼쪽 버튼을 클릭하고 마우스를 움직이면 진북방향과 이루는 각도가 화면에 도시되며 마우스 왼쪽 버튼을 더블 클릭하여 측정을 종료한다.

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

 

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