在ms-sql中找到最近的位置

时间:2022-10-12 01:58:39

I send these paramaters my script : Latitude : 41.0186 Longitude : 28.964701 (it is sample). i want to find nearest location's name. how to do this? (query's where code's must be changed)

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

Sql Query :

Sql查询:

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

Location table likes this: (in real, this is huge table)

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

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

3 个解决方案

#1


7  

Use this function

使用此功能

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

You may order by this function, BUT on large datasets it will be very slow, so try to prefilter the recordset

您可以通过此功能订购,但是对于大型数据集,它将非常慢,因此请尝试预先过滤记录集

UPD:

UPD:

Using @chopikadze's test data:

使用@ 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))

Assuming that the Earth is NOT a geoid, but the round ball, if you need under 1m exact formula - I can find it, don't have it with me

假设地球不是大地水准面,而是圆球,如果你需要1米以下的确切公式 - 我可以找到它,不要跟我一起

#2


1  

I think this is not so easy as it feels. You must do some trigonometry calculations to get the nearest positsion to your location.

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

Found nice Javascript example:

找到不错的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;

It gives you the distance between the points.

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

Or you can try to pass in a sort order of the squared delta values of the long and lats:

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

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

#3


1  

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

#1


7  

Use this function

使用此功能

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

You may order by this function, BUT on large datasets it will be very slow, so try to prefilter the recordset

您可以通过此功能订购,但是对于大型数据集,它将非常慢,因此请尝试预先过滤记录集

UPD:

UPD:

Using @chopikadze's test data:

使用@ 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))

Assuming that the Earth is NOT a geoid, but the round ball, if you need under 1m exact formula - I can find it, don't have it with me

假设地球不是大地水准面,而是圆球,如果你需要1米以下的确切公式 - 我可以找到它,不要跟我一起

#2


1  

I think this is not so easy as it feels. You must do some trigonometry calculations to get the nearest positsion to your location.

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

Found nice Javascript example:

找到不错的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;

It gives you the distance between the points.

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

Or you can try to pass in a sort order of the squared delta values of the long and lats:

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

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

#3


1  

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