T-SQL按经度和纬度优化地理搜索

时间:2012-11-08 09:50:21

标签: algorithm tsql optimization geolocation geocoding

我在其中一张表中存储的是以下格式的地理点:

  

经度Latitude PostalCode

我们的想法是使用表格中的信息,通过给定的经度和纬度获得最接近的邮政编码。

我的算法工作如下:

  1. Init UserLongitude和UserLatitude
  2. Init StepVariable as 1.0
  3. 从我的表格中获取所有记录

    longitude>UserLongitude-StepVariable 
    and
    longitude<UserLongitude+StepVariable 
    and
    latitude>Userlatitude-StepVariable   
    and
    latitude<Userlatitude+StepVariable
    
  4. 如果未找到任何记录,请使用1.0增加StepVariable并执行第3步
  5. 正如我read所示,当我们移动到两极时,1.0的经度值会更小。因此,当经度和纬度的1.0值不相同时,我的算法将以不正确的方式扩展搜索区域。

    是否有一种将我的可搜索区域扩展为Square的棘手方法,因为就目前而言,在某些地方我会使用矩形而我相信这会使我的搜索速度变慢。

2 个答案:

答案 0 :(得分:0)

我建议使用GeographyGeometry数据类型及其相关函数(例如:STDistance

请参阅http://msdn.microsoft.com/en-us/library/bb933917(v=sql.100).aspx

如果你不能这样做,那么Haversine formula对计算距离很有用

答案 1 :(得分:0)

为了计算特定地理点的经度和纬度长度,我使用以下算法:

-- Geograpic Point Cordinates
DECLARE @LATTIDUDE REAL=45
DECLARE @LONGITUDE REAL=45
DECLARE @Distance REAL=10

-- Constants
DECLARE @ConvertionConstant AS FLOAT=2*PI()/360
DECLARE @MetersPerDegree AS FLOAT

DECLARE @LattidueInRadians AS FLOAT=@ConvertionConstant*@LATTIDUDE

DECLARE @LongitudeParameter1 AS FLOAT=111412.84
DECLARE @LongitudeParameter2 AS FLOAT=-93.5 
DECLARE @LongitudeParameter3 AS FLOAT=0.118

SET @MetersPerDegree=(@LongitudeParameter1*COS(@LattidueInRadians))+(@LongitudeParameter2*(COS(3*@LattidueInRadians)))+(@LongitudeParameter3*COS(5*@LattidueInRadians))
DECLARE @LongitudeRangeTemp AS FLOAT=@Distance/(@MetersPerDegree/1000)

-- Results for longitude
SELECT @LongitudeRangeTemp AS DegreesForGivenKM
SELECT @MetersPerDegree    AS MetersPerDegreeOfLongitude

-- Constants
DECLARE @LatitudeParameter1 AS FLOAT=111132.92
DECLARE @LatitudeParameter2 AS FLOAT=-559.82
DECLARE @LatitudeParameter3 AS FLOAT=1.175
DECLARE @LatitudeParameter4 AS FLOAT=-0.0023

-- Results for longitude
SET @MetersPerDegree=(@LatitudeParameter1+(@LatitudeParameter2*COS(2*@LattidueInRadians))+(@LatitudeParameter3*COS(4*@LattidueInRadians))+(@LatitudeParameter4*COS(6*@LattidueInRadians)))
DECLARE @LatitudeRangeTemp AS FLOAT=@Distance/(@MetersPerDegree/1000)
SELECT @LatitudeRangeTemp AS  DegreesForGivenKM
SELECT @MetersPerDegree   AS  MetersPerDegreeOfLatitude

为公里添加了一个额外的参数 - 代码将计算等于给定公里数的度数。

您可以自由地在函数中实现代码。