经纬度帮助类
核心代码
/// <summary>
/// 点位信息
/// </summary>
[DataContract]
public class DPoint
{
/// <summary>
/// x坐标,对应经度
/// </summary>
public double x;
/// <summary>
/// y坐标,对应纬度
/// </summary>
public double y;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="lng">经度</param>
/// <param name="lat">纬度</param>
public DPoint(double lng, double lat)
{
x = lng;
y = lat;
}
public DPoint()
{ }
#region 已知两点计算距离
private const double EARTH_RADIUS = 6378.137; //地球半径
//private static double rad(double d)
//{
// return d * Math.PI / 180.0;
//}
/// <summary>
/// 将弧度转换为度
/// </summary>
/// <param name="radians">弧度</param>
/// <returns>度</returns>
private static double RadToDeg(double radians)
{
return radians * (180 / Math.PI);
}
/// <summary>
/// 将度转换为弧度
/// </summary>
/// <param name="degrees">度</param>
/// <returns>弧度</returns>
private static double DegToRad(double degrees)
{
return degrees * (Math.PI / 180);
}
/// <summary>
/// Calculates the middle point coordinate.
/// </summary>
/// <param name="firstCoordinate">The first coordinate.</param>
/// <param name="secondCoordinate">The second coordinate.</param>
/// <returns>Middle point coordinate</returns>
public static DPoint GetMidPoint(DPoint firstCoordinate, DPoint secondCoordinate)
{
double lon1 = DegToRad(firstCoordinate.x);
double lat1 = DegToRad(firstCoordinate.y);
double lon2 = DegToRad(secondCoordinate.x);
double lat2 = DegToRad(secondCoordinate.y);
double deltaLong = lon2 - lon1;
double Bx = Math.Cos(lat2) * Math.Cos(deltaLong);
double By = Math.Cos(lat2) * Math.Sin(deltaLong);
double lat3 = RadToDeg(Math.Atan2(Math.Sin(lat1) + Math.Sin(lat2), Math.Sqrt((Math.Cos(lat1) + Bx) * (Math.Cos(lat1) + Bx) + By * By)));
double lon3 = RadToDeg(lon1 + Math.Atan2(By, Math.Cos(lat1) + Bx));
return new DPoint(lon3, lat3);
}
/// <summary>
/// 计算指定两点间的距离(单位KM)
/// </summary>
/// <param name="p1">起始点</param>
/// <param name="p2">终止点</param>
/// <returns>两点间的公里数</returns>
public static double GetDistance(DPoint p1, DPoint p2)
{
return GetDistance(p1.y, p1.x, p2.y, p2.x);
}
/// <summary>
/// 计算指定两点间的距离(单位KM)
/// </summary>
/// <param name="lat1">纬度1</param>
/// <param name="lng1">经度1</param>
/// <param name="lat2">纬度2</param>
/// <param name="lng2">经度2</param>
/// <returns>两点间距离公里数</returns>
public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = DegToRad(lat1);
double radLat2 = DegToRad(lat2);
double a = radLat1 - radLat2;
double b = DegToRad(lng1) - DegToRad(lng2);
double dst = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
dst = dst * EARTH_RADIUS;
dst = Math.Round(dst * 10000) / 10000;
return dst;
}
/// <summary>
/// 计算指定两点间的距离(单位M)
/// </summary>
/// <param name="lat1">纬度1</param>
/// <param name="lng1">经度1</param>
/// <param name="lat2">纬度2</param>
/// <param name="lng2">经度2</param>
/// <returns>两点间距离公里数</returns>
public static double GetDistanceMeter(double lat1, double lng1, double lat2, double lng2)
{
return GetDistance(lat1, lng1, lat2, lng2) * 1000;
}
/// <summary>
/// 计算指定两点间的距离(单位M)
/// </summary>
/// <param name="lat1">纬度1</param>
/// <param name="lng1">经度1</param>
/// <param name="lat2">纬度2</param>
/// <param name="lng2">经度2</param>
/// <returns>两点间距离公里数</returns>
public static double GetDistanceMeter(DPoint p1, DPoint p2)
{
return GetDistance(p1.y, p1.x, p2.y, p2.x) * 1000;
}
/// <summary>
/// 判断点是否在多边形内或多边形上
/// </summary>
/// <param name="point">当前点</param>
/// <param name="Points">多边形边界点集合</param>
/// <returns></returns>
public static bool IsPtInPoly(DPoint point, DPoint[] Points)
{
int iIndex;
double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon;
if (Points.Length < 3)
{
return false;
}
var iSum = 0;
var iCount = Points.Length;
for (iIndex = 0; iIndex < iCount; iIndex++)
{
if (point.x == Points[iIndex].x && point.y == Points[iIndex].y) //A点在多边形上
return true;
if (iIndex == iCount - 1)
{
dLon1 = Points[iIndex].x;
dLat1 = Points[iIndex].y;
dLon2 = Points[0].x;
dLat2 = Points[0].y;
}
else
{
dLon1 = Points[iIndex].x;
dLat1 = Points[iIndex].y;
dLon2 = Points[iIndex + 1].x;
dLat2 = Points[iIndex + 1].y;
}
//以下语句判断A点是否在边的两端点的纬度之间,在则可能有交点
if (((point.y > dLat1) && (point.y < dLat2)) || ((point.y > dLat2) && (point.y < dLat1)))
{
if (Math.Abs(dLat1 - dLat2) > 0)
{
//获取A点向左射线与边的交点的x坐标:
dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - point.y)) / (dLat1 - dLat2);
//如果交点在A点左侧,则射线与边的全部交点数加一:
if (dLon < point.x)
{
iSum++;
}
//如果相等,则说明A点在边上
if (dLon == point.x)
return true;
}
}
}
if ((iSum % 2) != 0)
{
return true;
}
return false;
}
#endregion
}
本文来自博客园,作者:码农阿亮,转载请注明原文链接:https://www.cnblogs.com/wml-it/p/17774520.html
技术的发展日新月异,随着时间推移,无法保证本博客所有内容的正确性。如有误导,请大家见谅,欢迎评论区指正!
开源库地址,欢迎点亮:
GitHub:https://github.com/ITMingliang
Gitee: https://gitee.com/mingliang_it
GitLab: https://gitlab.com/ITMingliang
建群声明: 本着技术在于分享,方便大家交流学习的初心,特此建立【编程内功修炼交流群】,为大家答疑解惑。热烈欢迎各位爱交流学习的程序员进群,也希望进群的大佬能不吝分享自己遇到的技术问题和学习心得!进群方式:扫码关注公众号,后台回复【进群】。
![](https://images.cnblogs.com/cnblogs_com/wml-it/2196906/o_230823011905_wxgzhss.png)