1. 程式人生 > 其它 >C# 計算兩座標之間的距離(米)【預設北半球,東半球】 經緯度

C# 計算兩座標之間的距離(米)【預設北半球,東半球】 經緯度

計算距離核心程式碼:

//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; }
}
斬後知