728x90
반응형
728x170
▶ CityInfo.cs
using System.Text.RegularExpressions;
namespace TestProject
{
/// <summary>
/// 도시 정보
/// </summary>
public class CityInfo
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 명칭
/// </summary>
public string Name;
/// <summary>
/// 위도
/// </summary>
public double Latitude;
/// <summary>
/// 경도
/// </summary>
public double Longitude;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - CityInfo(name, latitudeDegree, latitudeMinute, latitudeSecond, longitudeDegree, longitudeMinute, longitudeSecond)
/// <summary>
/// 생성자
/// </summary>
/// <param name="name">명칭</param>
/// <param name="latitudeDegree">위도 도</param>
/// <param name="latitudeMinute">위도 분</param>
/// <param name="latitudeSecond">위도 초</param>
/// <param name="longitudeDegree">경도 도</param>
/// <param name="longitudeMinute">경도 분</param>
/// <param name="longitudeSecond">경도 초</param>
public CityInfo(string name, int latitudeDegree, int latitudeMinute, int latitudeSecond, int longitudeDegree, int longitudeMinute, int longitudeSecond)
{
Latitude = latitudeDegree + latitudeMinute / 60 + latitudeSecond / 3600;
Longitude = longitudeDegree + longitudeMinute / 60 + longitudeSecond / 3600;
}
#endregion
#region 생성자 - CityInfo(name, latitudeDegree, latitudeMinute, longitudeDegree, longitudeMinute)
/// <summary>
/// 생성자
/// </summary>
/// <param name="name">명칭</param>
/// <param name="latitudeDegree">위도 도</param>
/// <param name="latitudeMinute">위도 분</param>
/// <param name="longitudeDegree">경도 도</param>
/// <param name="longitudeMinute">경도 분</param>
public CityInfo(string name, int latitudeDegree, int latitudeMinute, int longitudeDegree, int longitudeMinute) :
this(name, latitudeDegree, latitudeMinute, 0, longitudeDegree, longitudeMinute, 0)
{
}
#endregion
#region 생성자 - CityInfo(text)
/// <summary>
/// 생성자
/// </summary>
/// <param name="text">텍스트</param>
public CityInfo(string text)
{
Regex regex = new Regex(@"\d");
Match match = regex.Match(text);
int position = match.Index;
Name = text.Substring(0, position - 1).Trim();
text = text.Substring(position);
position = text.IndexOf('°');
double latitudeDegree = double.Parse(text.Substring(0, position));
text = text.Substring(position + 1);
position = text.IndexOf('′');
double latitudeMinute = double.Parse(text.Substring(0, position));
text = text.Substring(position + 1);
Latitude = latitudeDegree + latitudeMinute / 60;
if(text.Substring(0, 1).ToUpper() == "S")
{
Latitude = -Latitude;
}
text = text.Substring(1).Trim();
position = text.IndexOf('°');
double longitudeDegree = double.Parse(text.Substring(0, position));
text = text.Substring(position + 1);
position = text.IndexOf('′');
double longitudeMinute = double.Parse(text.Substring(0, position));
text = text.Substring(position + 1);
Longitude = longitudeDegree + longitudeMinute / 60;
if(text.Substring(0, 1).ToUpper() == "E")
{
Longitude = -Longitude;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 문자열 구하기 - ToString()
/// <summary>
/// 문자열 구하기
/// </summary>
/// <returns>문자열</returns>
public override string ToString()
{
return Name;
}
#endregion
}
}
728x90
▶ MainForm.cs
using System;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 지구 반지름 (단위 : 마일)
/// </summary>
private const double EARTH_RADIUS = 3958.756;
/// <summary>
/// 도시 정보 배열
/// </summary>
private CityInfo[] cityInfoArray =
{
new CityInfo("Beijing 39°55′N 116°26′E"),
new CityInfo("Berlin 52°32′N 13° 25′E"),
new CityInfo("Cairo 30°03′N 31° 15′E"),
new CityInfo("Canberra 35°17′S 149°08′E"),
new CityInfo("London 51°30′N 0° 10′W"),
new CityInfo("Los Angeles 34°03′N 118°15′W"),
new CityInfo("Mexico City 19°24′N 99° 09′W"),
new CityInfo("Moscow 55°45′N 37° 42′E"),
new CityInfo("Mumbai 18°56′N 74° 35′E"),
new CityInfo("New York City 40°43′N 74° 00′W"),
new CityInfo("Rio de Janeiro 22°54′S 43° 14′W"),
new CityInfo("Rome 41°48′N 12° 36′E"),
new CityInfo("San Diego 32°42′N 117°10′W"),
new CityInfo("San Francisco 37°47′N 122°26′W"),
new CityInfo("Tokyo 35°40′N 139°45′E"),
};
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
#region 이벤트를 설정한다.
Load += Form_Load;
this.cityFromComboBox.SelectedIndexChanged += cityFromComboBox_SelectedIndexChanged;
this.cityToComboBox.SelectedIndexChanged += cityToComboBox_SelectedIndexChanged;
this.calculateButton.Click += calculateButton_Click;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 로드시 처리하기 - Form_Load(sender, e)
/// <summary>
/// 폼 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Load(object sender, EventArgs e)
{
foreach(CityInfo cityInfo in this.cityInfoArray)
{
this.cityFromComboBox.Items.Add(cityInfo);
this.cityToComboBox.Items.Add(cityInfo);
}
this.cityFromComboBox.SelectedIndex = 0;
this.cityToComboBox.SelectedIndex = 1;
}
#endregion
#region 도시 FROM 콤보 박스 선택 인덱스 변경시 처리하기 - cityFromComboBox_SelectedIndexChanged(sender, e)
/// <summary>
/// 도시 FROM 콤보 박스 선택 인덱스 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void cityFromComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox comboBox = sender as ComboBox;
if(comboBox.SelectedItem == null)
{
return;
}
CityInfo cityInfo = comboBox.SelectedItem as CityInfo;
this.latitudeFromTextBox.Text = cityInfo.Latitude.ToString("0.0000");
this.longitudeFromTextBox.Text = cityInfo.Longitude.ToString("0.0000");
}
#endregion
#region 도시 TO 콤보 박스 선택 인덱스 변경시 처리하기 - cityToComboBox_SelectedIndexChanged(sender, e)
/// <summary>
/// 도시 TO 콤보 박스 선택 인덱스 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void cityToComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox comboBox = sender as ComboBox;
if(comboBox.SelectedItem == null)
{
return;
}
CityInfo cityInfo = comboBox.SelectedItem as CityInfo;
this.latitudeToTextBox.Text = cityInfo.Latitude.ToString("0.0000");
this.longitudeToTextBox.Text = cityInfo.Longitude.ToString("0.0000");
}
#endregion
#region 계산하기 버튼 클릭시 처리하기 - calculateButton_Click(sender, e)
/// <summary>
/// 계산하기 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void calculateButton_Click(object sender, EventArgs e)
{
double latitudeFrom = double.Parse(this.latitudeFromTextBox.Text);
if(latitudeFrom < 0)
{
latitudeFrom += 360;
}
double longitudeFrom = double.Parse(this.longitudeFromTextBox.Text);
if(longitudeFrom < 0)
{
longitudeFrom += 360;
}
double latitudeTo = double.Parse(this.latitudeToTextBox.Text);
if(latitudeTo < 0)
{
latitudeTo += 360;
}
double longitudeTo = double.Parse(this.longitudeToTextBox.Text);
if(longitudeTo < 0)
{
longitudeTo += 360;
}
double differenceLatitude = Math.Abs(latitudeFrom - latitudeTo);
if(differenceLatitude > 180)
{
differenceLatitude = 360 - differenceLatitude;
}
double differenceLongitude = Math.Abs(longitudeFrom - longitudeTo);
if(differenceLongitude > 180)
{
differenceLongitude = 360 - differenceLongitude;
}
this.flatEarthTextBox.Text = CalculateFlatEarthMethod
(
latitudeFrom,
longitudeFrom,
latitudeTo,
longitudeTo
).ToString("0.0000");
this.haversineTextBox.Text = CalculateHaversineMethod
(
latitudeFrom,
longitudeFrom,
latitudeTo,
longitudeTo
).ToString("0.0000");
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 라디안 구하기 - GetRadian(degree)
/// <summary>
/// 라디안 구하기
/// </summary>
/// <param name="degree">도</param>
/// <returns>라디안</returns>
private double GetRadian(double degree)
{
return degree / 180 * Math.PI;
}
#endregion
#region 플랫 어스 방법으로 계산하기 - CalculateFlatEarthMethod(fromLatitude, fromLongitude, toLatitude, toLongitude)
/// <summary>
/// 플랫 어스 방법으로 계산하기
/// </summary>
/// <param name="fromLatitude">FROM 위도</param>
/// <param name="fromLongitude">FROM 경로</param>
/// <param name="toLatitude">TO 위도</param>
/// <param name="toLongitude">TO 경로</param>
/// <returns>플랫 어스 방법으로 계산한 값</returns>
private double CalculateFlatEarthMethod(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude)
{
double differenceLatitude = Math.Abs(fromLatitude - toLatitude);
if(differenceLatitude > 180)
{
differenceLatitude = 360 - differenceLatitude;
}
double differenceLongitude = Math.Abs(fromLongitude - toLongitude);
if(differenceLongitude > 180)
{
differenceLongitude = 360 - differenceLongitude;
}
double x = 69.1 * differenceLatitude;
double y = 53.0 * differenceLongitude;
return Math.Sqrt(x * x + y * y);
}
#endregion
#region 하버사인 방법으로 계산하기 - CalculateHaversineMethod(fromLatitude, fromLongitude, toLatitude, toLongitude)
/// <summary>
/// 하버사인 방법으로 계산하기
/// </summary>
/// <param name="fromLatitude">FROM 위도</param>
/// <param name="fromLongitude">FROM 경로</param>
/// <param name="toLatitude">TO 위도</param>
/// <param name="toLongitude">TO 경로</param>
/// <returns>하버사인 방법으로 계산한 값</returns>
private double CalculateHaversineMethod(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude)
{
double differenceLatitude = GetRadian(toLatitude - fromLatitude );
double differenceLongitude = GetRadian(toLongitude - fromLongitude);
double a = Math.Sin(differenceLatitude / 2) * Math.Sin(differenceLatitude / 2) +
Math.Cos(GetRadian(fromLatitude)) * Math.Cos(GetRadian(toLatitude)) *
Math.Sin(differenceLongitude / 2) * Math.Sin(differenceLongitude / 2);
return 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)) * EARTH_RADIUS;
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] 파일 잠금 여부 구하기 (0) | 2019.01.12 |
---|---|
[C#/COMMON] Dns 클래스 : GetHostEntry 정적 메소드를 사용해 호스트명으로 IP 주소 구하기 (0) | 2019.01.11 |
[C#/COMMON] 대리자의 BeginInvoke/EndInvoke 메소드를 사용해 비동기 콜백 호출하기 (0) | 2019.01.11 |
[C#/COMMON] 대리자의 BeginInvoke/EndInvoke 메소드를 사용해 비동기 호출하기 (0) | 2019.01.11 |
[C#/COMMON] 컴퓨터 메모리 보여주기 (0) | 2019.01.11 |
[C#/COMMON] 지구상의 위도와 경도를 거리로 변환하기 (0) | 2019.01.09 |
[C#/COMMON] CD 키 확인하기 (0) | 2019.01.09 |
[C#/COMMON] CD 키 생성하기 (0) | 2019.01.09 |
[C#/COMMON] 데스크톱 상의 윈도우 목록 조회하기 (0) | 2019.01.07 |
[C#/COMMON] GeoCoordinateWatcher 클래스 : 컴퓨터 위도/경도 구하기 (0) | 2019.01.06 |
[C#/COMMON] 복소수 사용하기 (0) | 2019.01.05 |
댓글을 달아 주세요