您的位置:首页 > 数据库

SQL 查询地理信息中指定距离范围内的记录

2016-03-30 17:30 567 查看
目标:选取在指定位置1公里范围的记录

测试数据:指定时间范围内,16万记录

跟据测试结果,如果不是需要很高精度,用第一种方法就可以了

方法1:按矩形算

优点:快,缺点:不是圆型的范围,平均执行150ms

DECLARE @GGP_LOCATE_POINT GEOGRAPHY = GEOGRAPHY::Point( 22.26663,113.821256666667, 4326);
DECLARE @FLT_LONGITUDE   FLOAT,  @FLT_LATITUDE   FLOAT  --纬度
SELECT @FLT_LONGITUDE =113.821256666667, @FLT_LATITUDE =22.26663
SELECT @GGP_LOCATE_POINT.STDistance(GEOGRAPHY::Point([LATITUDE],[LONGITUDE], 4326)) as [验证距离], *  FROM [目标表]
WHERE [ALERT_TIME] BETWEEN '2015-09-08' AND  '2015-09-28'
AND [LATITUDE]  BETWEEN @FLT_LATITUDE-0.010 AND @FLT_LATITUDE+0.010
AND [LONGITUDE] BETWEEN @FLT_LONGITUDE-0.010 AND @FLT_LONGITUDE+0.010


方法2:计算每个坐标的距离(圆),平均执行5500ms

DECLARE @GGP_LOCATE_POINT GEOGRAPHY = GEOGRAPHY::Point( 22.26663,113.821256666667, 4326);
SELECT *  FROM [dbo].[ALERT]
WHERE [ALERT_TIME] BETWEEN '2015-09-08' AND  '2015-09-28'
AND  @GGP_LOCATE_POINT.STDistance(GEOGRAPHY::Point([LATITUDE],[LONGITUDE], 4326))<=1000


方法3:计算目标是否在范围内,平均执行7500ms

DECLARE @GGP_LOCATE_POINT GEOGRAPHY = GEOGRAPHY::Point( 22.26663,113.821256666667, 4326);
DECLARE @buffer GEOGRAPHY;
set @buffer=@GGP_LOCATE_POINT.STBuffer(1000);
SELECT *  FROM [dbo].[ALERT]
WHERE [ALERT_TIME] BETWEEN '2015-09-08' AND  '2015-09-28'
AND @buffer.Filter(GEOGRAPHY::Point([LATITUDE],[LONGITUDE], 4326))>1000


补充:计算指定范围对应的经纬度大小

//地球子午线(南极到北极的连线)长度39940.67公里,纬度一度合110.94公里,一分合1.849公里,一秒合30.8米,不同纬度的间距是一样的。
//地球赤道圈长度40075.36公里,深圳在北纬22度左右,纬度圈长为111.32*cos(a),
//因此这里的经度一度合103.566436555110152670083196192

/// <summary>
/// 获取指定距离的经度
/// </summary>
/// <param name="org">对应的纬度</param>
/// <param name="range"></param>
/// <returns></returns>
public double GetLongitude(double org, float range)
{
// 1 经度的距离为 111.32*cos(a)
const double n = 1113200f;
double angle = Math.PI * org / 180.0;
return range / (n * Math.Cos(angle));
}

/// <summary>
/// 获取指定距离的纬度
/// </summary>
/// <param name="org"></param>
/// <param name="range"></param>
/// <returns></returns>
public double GetLatitude( float range)
{
// 1 纬度的距离为 110.94公里
const double n = 1109400f;
return range / n;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  sql 地理信息