【问题标题】:find the nearest location in ms-sql在 ms-sql 中找到最近的位置
【发布时间】:2015-08-27 18:01:17
【问题描述】:

我将这些参数发送给我的脚本:纬度:41.0186 经度:28.964701(它是示例)。我想找到最近位置的名称。这个怎么做? (查询必须更改代码的地方)

Sql 查询:

   SELECT  Name FROM Location 
   WHERE Latitude = 41.0186 AND longitude= 28.964701

位置表是这样的:(实际上,这是一个巨大的表)

Latitude         longitude          Name
41.0200500000   40.5234490000        a
41.0185714000   37.0975924000        b
41.0184913000   34.0373739000        c
41.0166667000   39.5833333000        d
41.0166667000   28.9333333000        e

【问题讨论】:

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


    【解决方案1】:

    使用此功能

    CREATE FUNCTION dbo.DictanceKM(@lat1 FLOAT, @lat2 FLOAT, @lon1 FLOAT, @lon2 FLOAT)
    RETURNS FLOAT 
    AS
    BEGIN
    
        RETURN ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+COS(PI()*@lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0))*6371
    END
    

    你可以通过这个函数排序,但是在大数据集上它会很慢,所以尝试对记录集进行预过滤

    UPD:

    使用@chopikadze 的测试数据:

    declare @lat float, @lng float
    select @lat = 41.0186, @lng = 28.964701
    
    declare @Location table(Latitude float, Longtitude float, Name nvarchar(50))
    insert into @Location(Latitude, Longtitude, Name) values (41.0200500000, 40.5234490000, 'a')
    insert into @Location(Latitude, Longtitude, Name) values (41.0185714000, 37.0975924000, 'b')
    insert into @Location(Latitude, Longtitude, Name) values (41.0184913000, 34.0373739000, 'c')
    insert into @Location(Latitude, Longtitude, Name) values (41.0166667000, 39.5833333000, 'd')
    insert into @Location(Latitude, Longtitude, Name) values (41.0166667000, 28.9333333000, 'e')
    
    SELECT ABS(dbo.DictanceKM(@lat, Latitude, @lng, Longtitude)) DistanceKm, * FROM @Location
    ORDER BY ABS(dbo.DictanceKM(@lat, Latitude, @lng, Longtitude))
    

    假设地球不是大地水准面,而是圆球,如果你需要1m以下的精确公式——我能找到,不要随身携带

    【讨论】:

      【解决方案2】:
      declare @latitude float, @longitude float
      select @latitude = 41.0186, @longitude = 28.964701
      
       SELECT [Name]   --, other columns
            ,Distance
            from
            (
            select 
            [Name]       --, other columns 
             ,( 3959 * acos( cos( radians(@latitude) ) * cos( radians( [Lattitude] ) ) * cos( radians( [Longitude] )
             - radians(@longitude) ) + sin( radians(@latitude) ) * sin( radians( [Lattitude] ) ) ) ) 
             AS Distance  FROM [dbo].[Location]
         ) as x   
          where Distance < 5   
        order by distance
      

      【讨论】:

        【解决方案3】:

        我认为这并不像感觉那么容易。您必须进行一些三角函数计算才能获得离您所在位置最近的位置。

        找到不错的 Javascript 示例:

        var R = 6371; // km Radius of earth
        var dLat = (lat2-lat1).toRad();
        var dLon = (lon2-lon1).toRad(); 
        var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
                Math.sin(dLon/2) * Math.sin(dLon/2); 
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
        var d = R * c;
        

        它为您提供点之间的距离。

        或者您可以尝试传递 long 和 lats 的平方 delta 值的排序顺序:

        ((<lat> - LAT_COLUMN) * (<lat> - LAT_COLUMN) +
         (<lng> - LNG_COLUMN) * (<lng> - LNG_COLUMN))
        

        【讨论】:

        • 请注意,此类球体计算在数千公里范围内精确到大约 10 米。如果需要更高的准确度,请使用 Vincenty 或 Karney 的算法。
        猜你喜欢
        • 2014-01-17
        • 2015-12-05
        • 1970-01-01
        • 2022-11-28
        • 1970-01-01
        • 2011-09-09
        • 1970-01-01
        • 2011-04-24
        • 1970-01-01
        相关资源
        最近更新 更多