728x90
728x170
▶ HammerAitoffProjection.cs
using System;
using DevExpress.XtraMap;
namespace TestProject
{
/// <summary>
/// HAMMER-AITOFF 투영
/// </summary>
public class HammerAitoffProjection : ProjectionBase
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 최소 위도
/// </summary>
private const double MINIMUM_LATITUDE = -90.0;
/// <summary>
/// 최대 위도
/// </summary>
private const double MAXIMUM_LATITUDE = 90.0;
/// <summary>
/// 최소 경도
/// </summary>
private const double MINIMUM_LONGITUDE = -180.0;
/// <summary>
/// 최대 경도
/// </summary>
private const double MAXIMUM_LONGITUDE = 180.0;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 오프셋 X - OffsetX
/// <summary>
/// 오프셋 X
/// </summary>
[Obsolete]
public override double OffsetX
{
get
{
return 0.5;
}
}
#endregion
#region 오프셋 Y - OffsetY
/// <summary>
/// 오프셋 Y
/// </summary>
[Obsolete]
public override double OffsetY
{
get
{
return 0.5;
}
}
#endregion
#region 스케일 X - ScaleX
/// <summary>
/// 스케일 X
/// </summary>
[Obsolete]
public override double ScaleX
{
get
{
return 0.5;
}
}
#endregion
#region 스케일 Y - ScaleY
/// <summary>
/// 스케일 Y
/// </summary>
[Obsolete]
public override double ScaleY
{
get
{
return -0.25;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 도 구하기 - GetDegree(value)
/// <summary>
/// 도 구하기
/// </summary>
/// <param name="value">값</param>
/// <returns>도</returns>
private static double GetDegree(double value)
{
return value * 180.0 / Math.PI;
}
#endregion
#region 라디안 구하기 - GetRadian(value)
/// <summary>
/// 라디안 구하기
/// </summary>
/// <param name="value">값</param>
/// <returns>라디안</returns>
private static double GetRadian(double value)
{
return value * Math.PI / 180.0;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Public
#region 지도 단위 구하기 - GeoPointToMapUnit(geoPoint)
/// <summary>
/// 지도 단위 구하기
/// </summary>
/// <param name="geoPoint">지리 포인트</param>
/// <returns>지도 단위</returns>
public override MapUnit GeoPointToMapUnit(GeoPoint geoPoint)
{
double longitude = GetRadian(Math.Min(MAXIMUM_LONGITUDE, Math.Max(MINIMUM_LONGITUDE, geoPoint.Longitude)));
double latitude = GetRadian(Math.Min(MAXIMUM_LATITUDE , Math.Max(MINIMUM_LATITUDE , geoPoint.Latitude )));
double z = Math.Sqrt(1 + Math.Cos(latitude) * Math.Cos(longitude / 2));
double x = Math.Cos(latitude) * Math.Sin(longitude / 2) / z;
double y = Math.Sin(latitude) / z;
return new MapUnit(x * ScaleX + OffsetX, y * ScaleY + OffsetY);
}
#endregion
#region 지리 포인트 구하기 - MapUnitToGeoPoint(mapUnit)
/// <summary>
/// 지리 포인트 구하기
/// </summary>
/// <param name="mapUnit">지도 단위</param>
/// <returns>지리 포인트</returns>
public override GeoPoint MapUnitToGeoPoint(MapUnit mapUnit)
{
double x = (mapUnit.X - OffsetX) / ScaleX;
double y = Math.Min(1, Math.Max(-1, (mapUnit.Y - OffsetY) / ScaleY));
if(IsValidPoint(x, y))
{
double z = Math.Sqrt(1 - 0.5 * Math.Pow(x, 2) - 0.5 * Math.Pow(y, 2));
double c = Math.Sqrt(2) * z * x / (2 * Math.Pow(z, 2) - 1);
double longitude = 2 * Math.Atan(c);
double latitude = Math.Asin(Math.Min(Math.Max(Math.Sqrt(2) * z * y, -1), 1));
double latitudeDegree = latitude * 180.0 / Math.PI;
double longitudeDegree = longitude * 180.0 / Math.PI;
return new GeoPoint
(
Math.Min(MAXIMUM_LATITUDE , Math.Max(MINIMUM_LATITUDE , GetDegree(latitude ))),
Math.Min(MAXIMUM_LONGITUDE, Math.Max(MINIMUM_LONGITUDE, GetDegree(longitude)))
);
}
else
{
int signX = (x < 0) ? -1 : 1;
int signY = (y < 0) ? -1 : 1;
return new GeoPoint(MAXIMUM_LATITUDE * signY, MAXIMUM_LONGITUDE * signX);
}
}
#endregion
#region 킬로미터 크기 구하기 - GeoToKilometersSize(anchorPoint, mapSize)
/// <summary>
/// 킬로미터 크기 구하기
/// </summary>
/// <param name="anchorPoint">앵커 포인트</param>
/// <param name="mapSize">맵 크기</param>
/// <returns>킬로미터 크기</returns>
public override MapSize GeoToKilometersSize(GeoPoint anchorPoint, MapSize mapSize)
{
return new MapSize
(
mapSize.Width * LonToKilometersRatio * Math.Cos(GetRadian(anchorPoint.Latitude)),
mapSize.Height * LatToKilometersRatio
);
}
#endregion
#region 지리 크기 구하기 - KilometersToGeoSize(anchorPoint, mapSize)
/// <summary>
/// 지리 크기 구하기
/// </summary>
/// <param name="anchorPoint">앵커 포인트</param>
/// <param name="mapSize">맵 크기</param>
/// <returns>지리 크기</returns>
public override MapSize KilometersToGeoSize(GeoPoint anchorPoint, MapSize mapSize)
{
return new MapSize
(
mapSize.Width / LonToKilometersRatio / Math.Cos(GetRadian(anchorPoint.Latitude)),
mapSize.Height / LatToKilometersRatio
);
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region 포인트 검증 여부 구하기 - IsValidPoint(x, y)
/// <summary>
/// 포인트 검증 여부 구하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <returns>포인트 검증 여부</returns>
private bool IsValidPoint(double x, double y)
{
if(Math.Pow(x, 2) + Math.Pow(y, 2) > 1)
{
return false;
}
else
{
return true;
}
}
#endregion
}
}
728x90
▶ MainForm.cs
using System;
using System.Reflection;
using DevExpress.XtraEditors;
using DevExpress.XtraMap;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : XtraForm
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
GeoMapCoordinateSystem geoMapCoordinateSystem = this.mapControl.CoordinateSystem as GeoMapCoordinateSystem;
geoMapCoordinateSystem.Projection = new HammerAitoffProjection();
Uri baseURI = new Uri(Assembly.GetEntryAssembly().Location);
this.shapefileDataAdapter.FileUri = new Uri(baseURI, "Data/Countries.shp");
}
#endregion
}
}
728x90
그리드형(광고전용)