SQL 查询地理信息中指定距离范围内的记录
2016-03-30 17:30
567 查看
目标:选取在指定位置1公里范围的记录
测试数据:指定时间范围内,16万记录
跟据测试结果,如果不是需要很高精度,用第一种方法就可以了
方法1:按矩形算
优点:快,缺点:不是圆型的范围,平均执行150ms
方法2:计算每个坐标的距离(圆),平均执行5500ms
方法3:计算目标是否在范围内,平均执行7500ms
补充:计算指定范围对应的经纬度大小
测试数据:指定时间范围内,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中的三值逻辑
- SQL Server 作业批量停止
- 结束SQL阻塞的进程
- 动态生成SQL Server视图作业
- SQL Server 语句操纵数据库
- SQL(结构化查询语句)
- oracle sql日期比较
- linux快速部署mysql服务器
- sql 存储过程分页
- 在WINXP系统上安装SQL Server企业版的方法
- 通过批处理调用SQL的方法(osql)
- SQL Server 存储过程的分页
- ASP程序与SQL存储过程结合使用详解
- SQL SERVER编写存储过程小工具
- 防御SQL注入攻击时需要注意的一个问题
- PostgreSQL教程(十九):SQL语言函数
- SQL Server复制需要有实际的服务器名称才能连接到服务器
- SQL Server 2000向SQL Server 2008 R2推送数据图文教程