SQL Server根据地图坐标经纬度计算距离
实战1-亲测,返回结果是米(m)
如果嫌麻烦直接跳转至:“参考方案一”
注意:该方法仅支持 SQL Server 2008 和该版本以上的数据库
1、准备-工具
百度坐标拾取器:
http://api.map.baidu.com/lbsapi/getpoint/index.html
百度地图:https://map.baidu.com/
2、准备-SQL语句,新增一张表
USE [DBTase]
GO
/****** Object: Table [dbo].[distance_lat_lng] Script Date: 2021/11/4 16:16:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[distance_lat_lng]([id] [int] IDENTITY(1,1) NOT NULL,[Name] [nchar](50) NOT NULL,[lng] [real] NOT NULL,[lat] [real] NOT NULL,CONSTRAINT [PK_distance_lat_lng] PRIMARY KEY CLUSTERED
([id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]GO
SET IDENTITY_INSERT [dbo].[distance_lat_lng] ON GO
INSERT [dbo].[distance_lat_lng] ([id], [Name], [lng], [lat]) VALUES (1, N'河南青少年中心', 113.694893, 34.78782)
GO
INSERT [dbo].[distance_lat_lng] ([id], [Name], [lng], [lat]) VALUES (2, N'财源大厦', 113.693436, 34.78596)
GO
INSERT [dbo].[distance_lat_lng] ([id], [Name], [lng], [lat]) VALUES (5, N'我的位置【中原油气】公司宿舍', 113.695381, 34.7867737)
GO
SET IDENTITY_INSERT [dbo].[distance_lat_lng] OFF
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'经度' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'distance_lat_lng', @level2type=N'COLUMN',@level2name=N'lng'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'纬度' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'distance_lat_lng', @level2type=N'COLUMN',@level2name=N'lat'
GO
3、基础测试:
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('POINT(113.694893 34.78782)', 4326);
SET @h = geography::STGeomFromText('POINT(113.693436 34.78596)', 4326);
SELECT @g.STDistance(@h);
结果
245.681793435016
根据下面“图一”和“图二”的测距结果,和sql结果对比,得出的距离是米,距离范围相差不多
图一
图二
4、创建一个“标量函数”
CREATE FUNCTION fun_Get_distance_lat_lng_1
(@destination_lng varchar(30),@destination_lat varchar(30),@myLocation_lng varchar(30),@myLocation_lat varchar(30)
)
RETURNS varchar(30) AS -- @destination_lng 目标经度
-- @destination_lat 目标纬度
-- @myLocation_lng 我的经度
-- @myLocation_lat 我的纬度BEGINdeclare @distance varchar(30);--返回值declare @destination geography,@myLocation geography;--@destination 目标位置--@myLocation 我的位置--@distance 距离SET @destination = geography::STGeomFromText('POINT(' +@destination_lng+ ' ' + @destination_lat +')', 4326);SET @myLocation = geography::STGeomFromText('POINT(' + @myLocation_lng+ ' ' + @myLocation_lat+')', 4326);SET @distance=cast(@destination.STDistance(@myLocation) as varchar(30));return @distance
END
不知道标量函数的可以看下面的文章
sql server 中的表值函数和标量函数 - cplvfx - 博客园sql server 中的表值函数和标量函数https://www.cnblogs.com/cplvfx/articles/15508241.html#4963500
这个就是刚才新建的“标量函数”
5、调用“标量函数”
select dbo.fun_Get_distance_lat_lng_1('113.694893','34.78782','113.693436','34.78596')
结果
245.682
根据“图一”和“图二”的测距结果,和sql结果对比,得出的距离是米,距离范围相差不多
6、根据刚才创建的表 批量算距离
select * from [dbo].[distance_lat_lng]
--根据刚才创建的表 批量算距离
declare @myLocation_lng varchar(30), @myLocation_lat varchar(30);
set @myLocation_lng='113.695381';
set @myLocation_lat='34.7867737';
-- @myLocation_lng 我的经度
-- @myLocation_lat 我的纬度selectdis.id,dis.lng,dis.lat,dis.Name,dbo.fun_Get_distance_lat_lng_1(cast(dis.lng as varchar(30)),cast(dis.lat as varchar(30)),@myLocation_lng,@myLocation_lat) as distancefrom [dbo].[distance_lat_lng] as dis
数据存储的数据
id | Name | lng | lat |
1 | 河南青少年中心 | 113.694893 | 34.78782 |
2 | 财源大厦 | 113.693436 | 34.78596 |
5 | 我的位置【中原油气】公司宿舍 | 113.695381 | 34.7867737 |
执行结果
id | lng | lat | Name | distance(距离) |
1 | 113.694893 | 34.78782 | 河南青少年中心 | 124.37 |
2 | 113.693436 | 34.78596 | 财源大厦 | 199.595 |
5 | 113.695381 | 34.7867737 | 我的位置【中原油气】公司宿舍 | 0 |
根据“图三”和“图四”的测距结果,和sql结果对比,得出的距离是米,距离范围相差不多
图三
图四
7、跟坐标距离小于5公里的数据
selectdis.id,dis.lng,dis.lat,dis.Name,dbo.fun_Get_distance_lat_lng_1(cast(dis.lng as varchar(30)),cast(dis.lat as varchar(30)),@myLocation_lng,@myLocation_lat) as distancefrom [dbo].[distance_lat_lng] as dis WHERE dbo.fnGetDistance(cast(dis.lat as REAL),cast(dis.lng as REAL),@myLocation_lat,@myLocation_lng) < 5000
结果
id | lng | lat | Name | distance |
1 | 113.694893 | 34.78782 | 河南青少年中心 | 0.124602102 |
2 | 113.693436 | 34.78596 | 财源大厦 | 0.199557602 |
5 | 113.695381 | 34.7867737 | 我的位置【中原油气】公司宿舍 | 0 |
实战2-亲测-返回结果是公里(km)
参考:https://www.cnblogs.com/smartsmile/p/6234120.html
1、创建一个“标量函数”
CREATE FUNCTION [dbo].[fnGetDistance](@LatBegin REAL, @LngBegin REAL, @LatEnd REAL, @LngEnd REAL) RETURNS FLOATAS
BEGIN--距离(千米)DECLARE @Distance REALDECLARE @EARTH_RADIUS REALSET @EARTH_RADIUS = 6378.137 DECLARE @RadLatBegin REAL,@RadLatEnd REAL,@RadLatDiff REAL,@RadLngDiff REALSET @RadLatBegin = @LatBegin *PI()/180.0 SET @RadLatEnd = @LatEnd *PI()/180.0 SET @RadLatDiff = @RadLatBegin - @RadLatEnd SET @RadLngDiff = @LngBegin *PI()/180.0 - @LngEnd *PI()/180.0 SET @Distance = 2 *ASIN(SQRT(POWER(SIN(@RadLatDiff/2), 2)+COS(@RadLatBegin)*COS(@RadLatEnd)*POWER(SIN(@RadLngDiff/2), 2)))SET @Distance = @Distance * @EARTH_RADIUS --SET @Distance = Round(@Distance * 10000) / 10000 RETURN @Distance
END
不知道标量函数的可以看下面的文章
sql server 中的表值函数和标量函数 - cplvfx - 博客园sql server 中的表值函数和标量函数https://www.cnblogs.com/cplvfx/articles/15508241.html#4963500
2、根据“实战1”创建的表 批量算距离 -返回结果是公里(km)
--根据刚才创建的表 批量算距离
declare @myLocation_lng REAL, @myLocation_lat REAL;
set @myLocation_lng=113.695381;
set @myLocation_lat=34.7867737;
-- @myLocation_lng 我的经度
-- @myLocation_lat 我的纬度selectdis.id,dis.lng,dis.lat,dis.Name,dbo.fnGetDistance(cast(dis.lat as REAL),cast(dis.lng as REAL),@myLocation_lat,@myLocation_lng) as distancefrom [dbo].[distance_lat_lng] as dis
结果
id | lng | lat | Name | distance |
1 | 113.694893 | 34.78782 | 河南青少年中心 | 0.124602102 |
2 | 113.693436 | 34.78596 | 财源大厦 | 0.199557602 |
5 | 113.695381 | 34.7867737 | 我的位置【中原油气】公司宿舍 | 0 |
这个结果和“实战1”的结果一模一样,唯一不一样的返回是公里(km)
3、跟坐标距离小于5公里的数据
--跟坐标距离小于5公里的数据
SELECT * FROM [distance_lat_lng] as dis WHERE dbo.fnGetDistance(cast(dis.lat as REAL),cast(dis.lng as REAL),@myLocation_lat,@myLocation_lng) < 5
结果
id | Name | lng | lat |
1 | 河南青少年中心 | 113.694893 | 34.78782 |
2 | 财源大厦 | 113.693436 | 34.78596 |
5 | 我的位置【中原油气】公司宿舍 | 113.695381 | 34.7867737 |
参考方案一
参考链接1:https://blog.csdn.net/winnyrain/article/details/51605924
参考链接2:https://my.oschina.net/u/200350/blog/1794111
注意:该方法仅支持 SQL Server 2008 和该版本以上的数据库
计算两点距离,4326是空间引用标识符,4326代表GCS-WGS-1984坐标系,是系统默认的坐标系。
地理坐标系空间需要用geography ,平面坐标系空间用geometry,计算距离使用STDistance
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('POINT(104.12765 31.61)', 4326);
SET @h = geography::STGeomFromText('POINT(114.132179 22.547010)', 4326);
SELECT @g.STDistance(@h);
查询某点经纬度距离1000米范围内的记录
SELECT * FROM [GpsData] WHERE
geography::STGeomFromText('POINT(' + cast([Longitude] as varchar(20)) + ' '
+ cast([Latitude] as varchar(20)) +')', 4326).STDistance(
geography::STGeomFromText('POINT(114.132179 22.547010)', 4326))<1000
STDistance也可以计算点到面的最短距离。
利用的是 geography::STPointFromText()。
第一个参数 POINT() 里面再跟经度、纬度。
第二个参数 4326 代表 GCS-WGS-1984 坐标系。具体本文后面会列出相关链接。
参考:
空间引用标识符
https://technet.microsoft.com/zh-cn/library/bb964707(v=sql.105)
STDistance(geometry 数据类型)
https://msdn.microsoft.com/zh-cn/library/bb933952(v=sql.100).aspx
STDistance的使用及geometry和geography的区别
http://blog.csdn.net/jcx5083761/article/details/46010215
相关阅读
- STDistance的使用及geometry和geography的区别
- MSDN 空间索引概述
- LBS系统的大地坐标系、84坐标系、百度/腾讯/高德坐标系
参考方案二
SQL SERVER 根据地图经纬度计算距离函数 - 深南大道 - 博客园前些天客户提出一个这样的要求:一个手机订餐网,查询当前所在位置的5公里范围的酒店,然后客户好去吃饭。 拿到这个请求后,不知道如何下手,静静地想了一下,在酒店的表中增加两个字段,用来存储酒店所在的经度和https://www.cnblogs.com/smartsmile/p/6234120.html
前些天客户提出一个这样的要求:一个手机订餐网,查询当前所在位置的5公里范围的酒店,然后客户好去吃饭。
拿到这个请求后,不知道如何下手,静静地想了一下,在酒店的表中增加两个字段,用来存储酒店所在的经度和纬度,当订餐的时候,要求手机得到当前客户所在的经度和纬度传过来,再与数据库中酒店的经度和纬度计算一下,就查出来。
为了在数据库中查询两点之间的距离,所以这个函数需要在数据库中定义。
我网上找了很久,却没有找到这个函数。最后在CSDN上,一个朋友的帮助下解决了这个问题,非常感谢lordbaby给我提供这个函数,我把这个函数放到这里来,以便帮助更多许要的朋友。
--计算地球上两个坐标点(经度,纬度)之间距离sql函数 --作者:lordbaby --整理:www.aspbc.com CREATE FUNCTION [dbo].[fnGetDistance](@LatBegin REAL, @LngBegin REAL, @LatEnd REAL, @LngEnd REAL) RETURNS FLOATAS BEGIN--距离(千米)DECLARE @Distance REALDECLARE @EARTH_RADIUS REALSET @EARTH_RADIUS = 6378.137 DECLARE @RadLatBegin REAL,@RadLatEnd REAL,@RadLatDiff REAL,@RadLngDiff REALSET @RadLatBegin = @LatBegin *PI()/180.0 SET @RadLatEnd = @LatEnd *PI()/180.0 SET @RadLatDiff = @RadLatBegin - @RadLatEnd SET @RadLngDiff = @LngBegin *PI()/180.0 - @LngEnd *PI()/180.0 SET @Distance = 2 *ASIN(SQRT(POWER(SIN(@RadLatDiff/2), 2)+COS(@RadLatBegin)*COS(@RadLatEnd)*POWER(SIN(@RadLngDiff/2), 2)))SET @Distance = @Distance * @EARTH_RADIUS --SET @Distance = Round(@Distance * 10000) / 10000 RETURN @Distance END
--经度 Longitude 简写Lng, 纬度 Latitude 简写Lat --跟坐标距离小于5公里的数据 SELECT * FROM 商家表名 WHERE dbo.fnGetDistance(121.4625,31.220937,longitude,latitude) < 5
这里的longitude,latitude分别是酒店的经度和纬度字段,而121.4625,31.220937是手机得到的当前客户所在的经度,后面的5表示5公里范围之内。
JS版本
function toRadians(degree) {return degree * Math.PI / 180; } function distance(latitude1, longitude1, latitude2, longitude2) {// R is the radius of the earth in kilometersvar R = 6371;var deltaLatitude = toRadians(latitude2-latitude1);var deltaLongitude = toRadians(longitude2-longitude1);latitude1 =toRadians(latitude1);latitude2 =toRadians(latitude2);var a = Math.sin(deltaLatitude/2) *Math.sin(deltaLatitude/2) +Math.cos(latitude1) *Math.cos(latitude2) *Math.sin(deltaLongitude/2) *Math.sin(deltaLongitude/2);var c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a));var d = R * c;return d; }
SQL Server根据地图坐标经纬度计算距离相关推荐
- 百度地图根据经纬度计算距离php,详解js根据百度地图提供经纬度计算两点距离...
正常在使用百度地图时,我们可以通过BMap的实例对象提供的方法计算距离: var map = new BMap.Map('map_canvas'); map.getDistance(point1 ,p ...
- 百度地图经纬度计算距离(Java)
百度地图Java经纬度计算距离 阅读百度地图Web服务api文档 Maven依赖 百度地图经纬度工具类 阅读百度地图Web服务api文档 Maven依赖 <!--baidu--><d ...
- vue中引用高德地图根据经纬度计算两地距离
vue中引用高德地图根据经纬度计算两地距离 一.示例图: npm安装 npm install vue-amap --save 在min.js文件中引入vue-amap import VueAMap f ...
- Java-高德地图根据经纬度计算两坐标之间的直线距离
Java-高德地图根据经纬度计算两坐标之间的直线距离 最近在做毕设项目,项目打卡需要用到高德地图,看了下高德地图计算两坐标距离的方法,官网上提供的开发包中也有相关的方法. /**** @author ...
- mysql数据库根据经纬度计算距离,获取离我最近的地点列表,并排序。附近的人,附近商店等功能,一个sql就搞定
mysql数据库根据经纬度计算距离,获取离我最近的地点列表,并排序 附近的人,附近商家等功能,顺序显示顺序是由近到远的,便利用户查看和判断,sql实现如下. StringBuilder sb=new ...
- mysql,php和js根据经纬度计算距离
根据经纬度计算距离公式 图片来自互联网 对上面的公式解释如下: Lung1 Lat1表示A点经纬度, Lung2 Lat2表示B点经纬度: a=Lat1 – Lat2 为两点纬度之差 b=Lung1 ...
- php mysql 经纬度_mysql,php和js根据经纬度计算距离
根据经纬度计算距离公式 图片来自互联网 对上面的公式解释如下: Lung1 Lat1表示A点经纬度, Lung2 Lat2表示B点经纬度: a=Lat1 – Lat2 为两点纬度之差 b=Lung1 ...
- php 经纬度 距离排序,php mysql 根据经纬度计算距离和排序
#1.两点距离(1.4142135623730951) select st_distance(point(0,0),point(1,1)); select st_distance(point (120 ...
- 根据两点经纬度计算距离
根据两点经纬度计算距离 这些经纬线是怎样定出来的呢?地球是在不停地绕地轴旋转(地轴是一根通过地球南北两极和地球中心的 假想线),在地球中腰画一个与地轴垂直的大圆圈,使圈上的每一点都和南北两极的距离相等 ...
- django 按经纬度计算距离排序
django 按经纬度计算距离排序 需求: 实现离用户距离最近的店铺排序 公式: 公式解释如下: Lung1 Lat1表示A点经纬度, Lung2 Lat2表示B点经纬度: a=Lat1–Lat2 为 ...
最新文章
- springcloud 子项目怎么导入_使用eclipse一步一步创建SpringCloud项目(二)—— 使用feign和ribbon调用微服务...
- python空字典添加元素_python遍历删除字典里值为空的元素报错
- JDK8特性--Stream(list转map)
- 鸿蒙系统cpu,鸿蒙系统,再加上自研电脑CPU,华为在下一盘很大的棋? - 区块网...
- springboot动态数据源切换(多数据源配置)
- (王道408考研数据结构)第六章图-第四节6:拓扑排序(AOV网、代码、排序规则)
- 为什么派生的子类报错不能实例化抽象类_一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别...
- java,java基础面试笔试题
- sqlplus可以连接plsql连接不上_Gee引擎配置微端不更新,连接不上,尝试重新连接的解决方法...
- gpt2 代码自动补全_如果您认为GPT-3使编码器过时,则您可能不编写代码
- uploadify php使用,如何在ThinkPHP中使用Uploadify对图片进行上传
- 机器学习防止模型过拟合方法总结
- ubuntu11.04(unix 就可以了) 共享文件以及支持上传文件
- OpenCV中的图片截取和颜色通道提取
- js将数字金额用符号间隔 vue中使用逗号间隔数字金额-共享博客
- windows系统oracle11.2.0.4打补丁
- 利用akshare读取50EFF期权1
- SEON - 1 怒怼Dp(1)
- 数据结构课程设计——迷宫问题课程设计报告
- 基于Dragonboard410c的智能音箱(四)