计算距离核心代码:
//private const double EARTH_RADIUS = 6378.137; //赤道半径 -地球半径 //private const double EARTH_RADIUS = 6356.755; //极半径 -地球半径 private const double EARTH_RADIUS = 6371.004; //平均半径 -地球半径 /// <summary> /// 度数转弧度 /// </summary> /// <param name="d">度数</param> /// <returns></returns> private static double rad(double d) { return d * Math.PI / 180.0; } /// <summary> /// 计算坐标距离:默认北半球(N)纬度为正,南半球(S)为负;东半球(E)经度为正,西半球(W)为负 /// </summary> /// <param name="lat1">坐标A纬度</param> /// <param name="lng1">坐标A经度度</param> /// <param name="lat2">坐标B纬度</param> /// <param name="lng2">坐标B经度</param> /// <returns></returns> public double GetDistance(double lat1, double lng1, double lat2, double lng2) { double radLat1 = rad(lat1); double radLat2 = rad(lat2); double a = radLat1 - radLat2; double b = rad(lng1) - rad(lng2); double s = 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))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000) / 10000; return s; }
业务场景:
/// <summary> /// 计算两坐标之间的距离(米)【默认北半球,东半球】 /// </summary> /// <param name="input"></param> /// <returns></returns>public double CalculateDistance(CalculateDistanceRequestDto input) { double distance = 0; /*基本思路: * 设第一点A的经 纬度为(LonA, LatA),第二点B的经纬度为(LonB, LatB), * 按照0度经线的基准,东经取经度的正值(Longitude),西经取经度负值(-Longitude), * 北纬取90-纬度值(90- Latitude),南纬取90+纬度值(90+Latitude), * 则经过上述处理过后的两点被计为(MLonA, MLatA)和(MLonB, MLatB)。 * 那么根据三角推导,可以得到计算两点距离的如下公式: * C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB) * Distance = R*Arccos(C)*Pi/180 * **/ //根据输入坐标,调整 var simpleCoords1 = GetSimpleCoords(input.Coords1); var simpleCoords2 = GetSimpleCoords(input.Coords2); var distance = GetDistance(simpleCoords1.lat, simpleCoords1.lon, simpleCoords2.lat, simpleCoords2.lon) * 1000;//单位:米 return distance; } //坐标归化 private BuoyDataCoordsSimpleDto GetSimpleCoords(BuoyDataCoordsDto coords) { BuoyDataCoordsSimpleDto retData = new BuoyDataCoordsSimpleDto(); //默认北纬,东经 //纬度 if (coords.NS.ToUpper() == "S") { retData.lat = -coords.lat; } else { retData.lat = coords.lat; } //经度 if (coords.EW.ToUpper() == "W") { retData.lon = -coords.lon; } else { retData.lon = coords.lon; } return retData; }
其中的参数实体
/// <summary> /// 计算距离坐标实体 /// </summary> public class CalculateDistanceRequestDto { /// <summary> /// 坐标1 /// </summary> public CoordsDto Coords1 { get; set; } /// <summary> /// 坐标2 /// </summary> public CoordsDto Coords2 { get; set; } } /// <summary> /// 坐标信息实体 /// </summary> public class CoordsDto { /// <summary> /// 纬度 /// </summary> public double lat { get; set; } /// <summary> /// 南纬北纬 /// </summary> public string NS { get; set; } /// <summary> /// 经度 /// </summary> public double lon { get; set; } /// <summary> /// 东经西经 /// </summary> public string EW { get; set; } }