确定点之间的基数(指南针)方向(Determining cardinal (compass) dir

2019-08-16 19:24发布

有没有办法在SQL Server 2008R2知道,如果一个点在华南,华东等......另外一点的?

例如,我有一个起源point(lat1,lng1)我想知道在哪里point(lat2,lng2)是从原点位于:北部,西部等..

我试图构建一个风玫瑰图,这可能是对我有用。

Answer 1:

为了同时使用SQL Server 2008 R2的地理类型来计算两个坐标之间的轴承,您可以使用此功能:

CREATE FUNCTION [dbo].[CalculateBearing] 
(
    @pointA as geography
    ,@pointB as geography
)

RETURNS decimal(18,12)

AS

    BEGIN

    -- Declare the return variable
    DECLARE @bearing decimal(18,12)

    -- Declare the local variables
    DECLARE @x decimal(18,12)
    DECLARE @y decimal(18,12)
    DECLARE @dLat decimal(18,12)
    DECLARE @dLong decimal(18,12)
    DECLARE @rLat1 decimal(18,12)
    DECLARE @rLat2 decimal(18,12)

    IF(@pointA.STIsEmpty() = 1 OR @pointB.STIsEmpty() = 1)
        set @bearing = null
    ELSE
        BEGIN

        -- Calculate delta between coordinates
        SET @dLat = RADIANS(@pointB.Lat - @pointA.Lat)
        SET @dLong = RADIANS(@pointB.Long - @pointA.Long)

        -- Calculate latitude as radians
        SET @rLat1 = RADIANS(@pointA.Lat)
        SET @rLat2 = RADIANS(@pointB.Lat)

        SET @y = SIN(@dLong)*COS(@rLat2)
        SET @x = COS(@rLat1)*SIN(@rLat2)-SIN(@rLat1)*COS(@rlat2)*COS(@dLong)

        IF (@x = 0 and @y = 0)
            SET @bearing = null
        ELSE
            BEGIN
                SET @bearing = CAST((DEGREES(ATN2(@y,@x)) + 360) as decimal(18,12)) % 360
            END
    END

    -- Return the result of the function
    RETURN @bearing

END

GO

而在此之后,你可以使用这样这个功能:

DECLARE @pointA as geography
DECLARE @pointB as geography

SET @pointA = geography::STGeomFromText('POINT(3 45)', 4326)
SET @pointB = geography::STGeomFromText('POINT(4 47)', 4326)

SELECT [dbo].[CalculateBearing](@pointA, @pointB)

更新 :将架构



Answer 2:

我想出了利用计算一个相当简单的使用标准的SQL功能轴承的一种方式。 该ATAN函数做了大部分工作的; 两个CASE语句只是特殊情况下的修正。 图1是源极和2为目的地。

atan(([Longitude2]-[Longitude1])/(10e-10+[Latitude2]-[Latitude1]))*360/pi()/2
+case when [Latitude2]<[Latitude1] then 180 else 0 end
+case when [Longitude2]<[Longitude1] and [Latitude2]>[Latitude1] then 360 else 0 end


Answer 3:

今天上午,我有需要此功能,在我们的系统订单附近搜索时提供的范围和基本方向给用户。 我来到尼古拉斯的答案在这里,它大部分的方式让我在那里。 我创建了一个使用萨科的让自己的缩写主方向(N,NE,E等),为我的UI第二功能。

使用这里提供的结合值尼古拉斯的方位计算从https://en.wikipedia.org/wiki/Points_of_the_compass以确定每个基本方向范围内,

CREATE FUNCTION [dbo].[CalculateCardinalDirection] 
(
    @pointA as geography
    ,@pointB as geography
)

RETURNS varchar(2)

AS
BEGIN
    DECLARE @bearing decimal(18,12)
    -- Bearing calculation provided by http://stackoverflow.com/a/14781032/4142441
    SELECT @bearing = dbo.CalculateBearing(@pointA, @pointB)

    RETURN CASE WHEN @bearing BETWEEN 0 AND 22.5 THEN 'N'
                WHEN @bearing BETWEEN 22.5 AND 67.5 THEN 'NE'
                WHEN @bearing BETWEEN 67.5 AND 112.5 THEN 'E'
                WHEN @bearing BETWEEN 112.5 AND 157.5 THEN 'SE'
                WHEN @bearing BETWEEN 157.5 AND 202.5 THEN 'S'
                WHEN @bearing BETWEEN 202.5 AND 247.5 THEN 'SW'
                WHEN @bearing BETWEEN 247.5 AND 292.5 THEN 'W'
                WHEN @bearing BETWEEN 292.5 AND 337.5 THEN 'NW'
                ELSE 'N' -- Catches NULL bearings and the 337.5 to 360.0 range
           END
END
GO


Answer 4:

如果点的数据类型是“几何”(像UTM坐标系),你可以用下面的公式:

DEGREES(ATAN((X2-X1)/(Y2-Y1)))
+case when Y2<Y1 then 180 else 0 end
+case when Y2>Y1 and X2<X1 then 360 else 0 end

下面是更多的澄清架构:



Answer 5:

X=X2-X1Y=Y2-Y1. 的公式,其从0轴承顺时针(正Y轴)到360度给出。

  f(X,Y)=180-90*(1+SIGN(Y))*(1-SIGN(X^2))-45*(2+SIGN(Y))*SIGN(X)-180/PI()*SIGN(Y*X)*ATAN((ABS(Y)-ABS(X))/(ABS(Y)+ABS(X)))


文章来源: Determining cardinal (compass) direction between points