WPF - XDL Tutorial

지구 타원체 상의 좌표 및 거리 계산

(piXoneer XDL Tutorial)

 

 

 

 

 

 

 구 타원체 상에서 특정 지점간의 관계를 이용하여 거리나 방향을 구하고

 ECEF좌표계로부터 Geodetic좌표계로의 변환 등에 대해서 설명합니다.

 

 

2019. 04.

 

 

 

 

목차

1    사용 하기... 1

1.1    XDL 엔진... 1

1.2    XDL의 데이터구조를 이용한 예제 프로그램 만들기... 1

1.3    지구상의 특정 위치(Reference Position)로부터 방위각(Azimuth Angle)과 거리(Distance)에 해당하는 위치(Target Position) 구하기 예제... 1

1.4    지구상의 특점 한 위치(Reference Position)와 다른 장소의 한 위치(Target Position)로부터 방위각도와 거리 구하는 예제... 1

1.5    Geographic 좌표계로부터 ECEF좌표계로의 변환 예제... 1

1.6    ECEF좌표계로부터 Geographic좌표계로의 변환 예제... 1

 

 


 

1      사용 하기

1.1    XDL 엔진

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

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

 

1.2    XDL의 데이터구조를 이용한 예제 프로그램 만들기

1.2.1         Visual Studio 2015을 실행한다.

1.2.2         메뉴 [파일]-[새로 만들기]-[프로젝트]를 선택한다.

 

 

1.2.3         [새 프로젝트] 대화상자에서 왼쪽의 템플릿 창에서 “Visual C#”을 선택하고, 대화상자 중간의 목록에서 “WPF 응용 프로그램을 선택한다.

사용자가 원하는 경로를 선택한 다음 프로젝트 이름을 “XDL_GeoPosition” 으로 입력하고 [새 프로젝트] 대화상자의 확인버튼을 클릭한다.

 

 

이 문서에서는 대화상자 오른쪽 아래에 있는 솔루션용 디렉터리 만들기는 선택하지 않겠다. “확인버튼을 누르면 프로젝트가 기본적으로 생성되고, 화면에 Window을 디자인할 수 있는 화면이 뜬다. 만약 아래와 같은 Window 창이 생성되지 않으면, [솔루션 탐색기] 창에서 MainWindow.xaml”를 마우스 더블클릭을 하여 창을 연다.

 

 

1.2.4         참조를 통해 NXDL.dll 항목을 추가한다.

솔루션 탐색기의 프로젝트 아래에 있는 참조 아이템의 마우스 오른쪽 버튼을 클릭하여 생성되는 팝업메뉴에서 참조추가메뉴를 선택한다.

 

 

메뉴를 선택하면 아래와 같이 [참조추가] 대화상자가 나타나며, 대화상자 아래쪽에 있는 찾아보기버튼을 클릭한다.

 

 

 

“C:\Pixoneer\XDL1.2\bin\NXDL.dll” 경로로 이동한 후 파일을 선택한다. “추가를 클릭하고, [참조추가] 대화상자의 확인버튼을 클릭한다. [참조] “NXDL”가 추가된 것을 확인할 수 있다.

 

 

1.2.5         프로그램 종료 시 메모리를 해제를 위한 코드를 Window창이 닫히는 이벤트에 추가한다.

MainWindow.xaml 창에서 Window을 선택한 후 [속성] 창에서 이벤트메뉴를 클릭하고 이벤트 목록 중 “Closed”를 선택한 뒤 마우스 더블클릭을 하여 해당이벤트를 추가한다.

 

 

아래의 굵은 글씨처럼 Window_Closed함수에 코드를 추가한다.

namespace XDL_DataStructrue
{
    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Pixoneer.NXDL.Xfn.Close(); //코드추가
        }
…

 

1.2.6         다음과 같이 NXDL에 대하여 참조를 설정한다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using Pixoneer.NXDL;  //추가

 

1.2.7     다음과 같이 Window에 버튼을 올려 디자인한다.

 

 


1.3    지구상의 특정 위치(Reference Position)로부터 방위각(Azimuth Angle)과 거리(Distance)에 해당하는 위치(Target Position) 구하기 예제

여기에서 거리는 평면상의 거리가 아니고 지구 곡률을 고려한 거리를 의미한다.

 

 

1.3.1         Calc Position By Bearing And Distance버튼을 더블 클릭하여 함수를 자동생성한다.

private void buttonCalcPositionByBearingAndDistance_Click(object sender, RoutedEventArgs e)
{

}

 

1.3.2         buttonCalcPositionByBearingAndDistance_Click 함수에 다음과 같이 코드를 입력한다. 아래 예제는 임의의 기준점(예를 들어 현재 자신의 위치)로부터 방위각과 특정 거리상에 있는 좌표값을 계산한다.

private void buttonCalcPositionByBearingAndDistance_Click(object sender, RoutedEventArgs e)
{
        // 지구의 특저 기준점으로부터 북쪽으로부터 시계방향의 방위각과 임의의
// 거리에 해당하는 지점을 계산

        // 1. 기준점 설정
        XAngle lon1 = XAngle.FromDegree(127);
        XAngle lat1 = XAngle.FromDegree(36);

        // 2. 북쪽으로부터 방위각 설정
        XAngle bearing = XAngle.FromDegree(45);

        // 3. 거리 설정 (unit : meter)
        double dist = 10000;

        // 4. 결과값에 해당하는 위경도 값을 얻을 XAngle생성
        XAngle lon2 = new XAngle();
        XAngle lat2 = new XAngle();

        // 5. CalcPosByBearingAndDist함수를 통해 지점 계산
        XAngle ang = Xfn.CalcPosByBearingAndDist(lon1, lat1, bearing, dist,
ref lon2, ref lat2);

        Console.WriteLine("Position : " + lon2.deg.ToString() + " " + 
lat2.deg.ToString());
        Console.WriteLine("Return Angle : " + ang.deg.ToString());

}

1.3.3         컴파일하고 프로그램을 실행하여 Calc Position By Bearing And Distance버튼을 클릭한다.

 

1.3.4         출력창에 값이 프린트됨을 확인한다.

참조 위경도위치 127, 36인 위치로부터 45도 북방위각이고 거리가 10000meter인 결과를 출력한다.

 

 

1.4    지구상의 특점 한 위치(Reference Position)와 다른 장소의 한 위치(Target Position)로부터 방위각도와 거리 구하는 예제

여기에서 거리는 평면상의 거리가 아니고 지구 곡률을 고려한 거리를 의미한다

.

 

1.4.1         buttonCalcArcDistAndAngle_Click버튼을 더블 클릭하여 함수를 자동생성한다.

private void buttonCalcArcDistAndAngle_Click(object sender, RoutedEventArgs e)
{

}

 

1.4.2         buttonCalcArcDistAndAngle_Click함수에 다음과 같이 코드를 입력한다. 아래 예제는 임의의 2점으로부터 방위각과 특정 거리를 계산한다.

private void buttonCalcArcDistAndAngle_Click(object sender, RoutedEventArgs e)
{
        // 지구의 특정 두지점(기준점과 임의의 지점)을 이용하여 기준점으로부터 임의의
// 지점까지의 방위각(Forward, Backward) 값과 지점간의 거리를 얻는다.
        // 1. 기준점 설정
        XAngle lon1 = XAngle.FromDegree(127);
        XAngle lat1 = XAngle.FromDegree(36);

        // 2. 임의의 지점 설정
        XAngle lon2 = XAngle.FromDegree(128);
        XAngle lat2 = XAngle.FromDegree(37);

        // 3. 두 지점간의 Forward, Backward각도를 얻을 객체 생성
        XAngle fwdAz = new XAngle();
        XAngle revAz = new XAngle();

        double dist = 0;

        // 4. 두지점을 입력하여 CalArcDistAndAngle함수를 이용하여 거리와 각도를 얻는다.
        bool bResult = Xfn.CalArcDistAndAngle(lon1, lat1, lon2, lat2, 
ref dist, ref fwdAz, ref revAz);

        Console.WriteLine("Distance : " + dist.ToString());
        Console.WriteLine("Forward Angle : " + fwdAz.deg.ToString());
        Console.WriteLine("Backward Angle : " + revAz.deg.ToString());

}

1.4.3         컴파일하고 프로그램을 실행하여 Calc Arc Dist and Angle From Two Position버튼을 클릭한다.

 

1.4.4         출력창에 값이 프린트됨을 확인한다.

참조 위치 127, 36(경위도)인 위치로부터 128, 37(경위도)위치로부터 거리가 142618.087미터와 38.6195662318174도인 방위각을 얻을 수 있다.

 

 

1.5    Geographic 좌표계로부터 ECEF좌표계로의 변환 예제

 

1.5.1         buttonGeoToECEF_Click버튼을 더블클릭하여 함수를 자동생성한다.

private void buttonGeoToECEF_Click (object sender, RoutedEventArgs e)
{

}

 

1.5.2         buttonGeoToECEF_Click 함수에 다음과 같이 코드를 입력한다.

private void buttonGeoToECEF_Click (object sender, RoutedEventArgs e)
{
// Lat/Lon(위경도)좌표계로 부터 ECEF좌표계로 변환하기

        // 1. 위경도 좌표값을 설정.
        XGeoPoint geo = new XGeoPoint();
        XVertex3d ecr = new XVertex3d();
        geo.lond = 127;
        geo.latd = 36;
        geo.hgt = 1200;

        // 2. ECEF값을 얻는다.
        Xfn.GeoToEcr(geo, ref ecr);

	// 3. 결과값을 프린트한다.
        Console.WriteLine("X : " + ecr.x.ToString() + "Y : " + ecr.y.ToString() 
+ "Z : " + ecr.z.ToString());
}

1.5.3         컴파일하고 프로그램을 실행하여 Geo To ECEF 버튼을 클릭한다.

 

1.5.4         출력창에 값이 프린트됨을 확인한다.

참조 위치 127, 36(경위도)이고 고도가 1200meter인 위치의 ECEF값은 X : -3109559.92819602 Y : 4126525.40023087 Z : 3728897.01809016임을 확인할 수 있다.

 

 

1.6    ECEF좌표계로부터 Geographic좌표계로의 변환 예제

 

1.6.1         buttonECEFToGeo_Click버튼을 더블클릭하여 함수를 자동생성한다.

private void buttonECEFToGeo_Click (object sender, RoutedEventArgs e)
{

}

 

1.6.2         buttonECEFToGeo_Click 함수에 다음과 같이 코드를 입력한다.

private void buttonECEFToGeo_Click (object sender, RoutedEventArgs e)
{
// ECEF좌표계로부터 Lat/Lon(위경도)좌표계로 변환하기
        //  1. ECEF값을 설정
        XGeoPoint geo = new XGeoPoint();
        XVertex3d ecr = new XVertex3d();
        ecr.x = -3109559.9281960232;
        ecr.y = 4126525.4002308655;
        ecr.z = 3728897.0180901629;

//  2. 위경도값을 얻는다
Xfn.EcrToGeo(ecr, ref geo);

// 3. 결과값을 프린트한다.
Console.WriteLine("Longitude : " + geo.lond.ToString() + 
" Latitude : " + geo.latd.ToString() + " Height : " +
 geo.hgt.ToString());
}

1.6.3         컴파일하고 프로그램을 실행하여 ECEF To Geo버튼을 클릭한다.

 

1.6.4         출력창에 값이 프린트됨을 확인한다.

참조 위치 ECEF값이 X : -3109559.92819602 Y : 4126525.40023087 Z : 3728897.01809016Geographic 좌표계 값은 127, 36(경위도)이고 고도가 1200meter인 위치의 임을 확인할 수 있다.