C# 計算兩座標之間的距離(米)【預設北半球,東半球】 經緯度
阿新 • • 發佈:2021-11-06
計算距離核心程式碼:
//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> privatestatic 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; } }斬後知