SQL Server - 从纬度和计算中计算初始方位角使用GEOGRAPHY的经度

时间:2016-04-13 08:27:35

标签: sql sql-server database sql-server-2008

最近,在Stackoverflow成员的帮助下,我得到了以下解决方案来计算两个纬度和经度点之间的距离:

GEOGRAPHY::Point(DepartureAirportLatitude, DepartureAirportLongitude, 4326)
        .STDistance(GEOGRAPHY::Point(ArrivalAirportLatitude, ArrivalAirportLongitude, 4326)) AS [Default],

        GEOGRAPHY::Point(DepartureAirportLatitude, DepartureAirportLongitude, 4326)
        .STDistance(GEOGRAPHY::Point(ArrivalAirportLatitude, ArrivalAirportLongitude, 4326)) / 1609.344 AS [Mi],

        GEOGRAPHY::Point(DepartureAirportLatitude, DepartureAirportLongitude, 4326)
        .STDistance(GEOGRAPHY::Point(ArrivalAirportLatitude, ArrivalAirportLongitude, 4326)) / 1000 AS [Km]

是否有办法使用GEOGRAPHY功能计算相同数据点之间的初始方位,并将其显示为标题?

由于

马修

2 个答案:

答案 0 :(得分:0)

感谢您的回复和信息。

经过几个小时的游戏和大量的Google搜索,我使用下面的解决方案,它给了我正确的结果:

DECLARE @Pi AS FLOAT
DECLARE @D2R AS FLOAT

SET @Pi = '3.14159265358979'
SET @D2R = @Pi / 180.0;


PICalculation AS
(
    SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,

        @D2R * DepartureAirportLatitude AS [DepartureAirportLatitude], @D2R * DepartureAirportLongitude AS [DepartureAirportLongitude],
        @D2R * ArrivalAirportLatitude AS [ArrivalAirportLatitude], @D2R * ArrivalAirportLongitude AS [ArrivalAirportLongitude]

    FROM RawData    
),

RadiansCalculation AS
(
    SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,

            Radians(ArrivalAirportLatitude - DepartureAirportLatitude) AS [DLat],
            Radians(ArrivalAirportLongitude - DepartureAirportLongitude) AS [DLon],
            Radians(DepartureAirportLatitude) AS [RLat1],
            Radians(ArrivalAirportLatitude) AS [RLat2]

    FROM PICalculation  
),

XYCalculation AS
(
    SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,

        SIN(DLon)*COS(RLat2) AS [Y],
        COS(RLat1)*SIN(RLat2)-SIN(RLat1)*COS(RLat2)*COS(DLon) AS [X]

    FROM RadiansCalculation
),

HeadingCalculation AS
(
    SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,

        CASE WHEN X = 0 AND Y = 0 THEN 0
            ELSE CAST((DEGREES(ATN2(Y,X)) + 360) AS DECIMAL(5,1)) % 360 
        END AS [InitialBearing]

    FROM XYCalculation
)

SELECT *
FROM DataJoin

希望这个解决方案对于偶然发现这篇文章的其他人也很有用:)

马修

答案 1 :(得分:0)

这是一个标量函数和运行它的测试点。注意:我找到了来源here

CREATE FUNCTION dbo.Bearing (
  @point1 geography,
  @point2 geography  )
RETURNS float
AS
BEGIN
  DECLARE @Bearing decimal(18,15)
  DECLARE @Lat1 float = Radians(@point1.Lat)
  DECLARE @Lat2 float = Radians(@point2.Lat)
  DECLARE @dLon float = Radians(@point2.Long - @point1.Long)
  IF (@point1.STEquals(@point2) = 1)
    SET @Bearing = NULL
  ELSE
    SET @Bearing = ATN2(
      sin(@dLon)*cos(@Lat2),
     (cos(@Lat1)*sin(@Lat2)) - (sin(@Lat1)*cos(@Lat2)*cos(@dLon))
    )
    SET @Bearing = (Degrees(@Bearing) + 360) % 360
  RETURN @Bearing
END
GO

DECLARE @g  GEOGRAPHY = GEOGRAPHY::Point(43, 43, 4326);
DECLARE @g1 GEOGRAPHY = GEOGRAPHY::Point(42, 43, 4326);
DECLARE @g2 GEOGRAPHY = GEOGRAPHY::Point(44, 43, 4326);
DECLARE @g3 GEOGRAPHY = GEOGRAPHY::Point(43, 42, 4326);
DECLARE @g4 GEOGRAPHY = GEOGRAPHY::Point(43, 44, 4326);

SELECT dbo.[Bearing](@g, @g1),
    [dbo].[Bearing](@g, @g2),
    [dbo].[Bearing](@g, @g3),
    [dbo].[Bearing](@g, @g4);

如果在T-SQL中执行此操作最终速度太慢,那么该链接上也会有一些CLR实现。