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' GO3、基礎測試:
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))<1000STDistance也可以計算點到面的最短距離。 ? ? ? ?
利用的是?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根据地图坐标经纬度计算距离的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的世界服务器发消息有符号,我的世界彩色
- 下一篇: 关于高德地图转换经纬度为屏幕点,方便自定