一个纬度/经度坐标与使用 SQL 的固定坐标之间的近似距离

Posted

技术标签:

【中文标题】一个纬度/经度坐标与使用 SQL 的固定坐标之间的近似距离【英文标题】:Approximate distance between one lat/long coordinate and a fixed one using SQL 【发布时间】:2016-01-25 16:02:39 【问题描述】:

这里

Distance between two lat,lon points

我发现了一个很简单很好的公式:

d = sqrt(pow(lat2-lat1, 2) + cos(lat1)*pow(lon2-lon1, 2))

我是这样使用的:

SELECT name, SQRT(POW(lat-45, 2) + COS(45)*POW(lon-8, 2)) AS distance
FROM shop
ORDER BY distance

一切正常,因为我只需要得到一个近似的相对距离。

但后来我需要一个绝对距离,即使是近似的......我开始意识到也许“d”不能转换为米/英里,因为例如纬度有 180 度,但经度有 360 度,所以这个几乎是勾股定理正在“拉伸”对角线,从而弄乱了可能的绝对计算……过了一会儿,我放弃了……在这里我上午。

如何将“d”转换为以米/英里为单位的绝对距离?

PS:是的,我会在最终版本中预先计算SQL查询中的所有常量...

【问题讨论】:

您使用的是哪个 DBMS?后格雷斯?甲骨文? 操作,抱歉,不,不...只是 mysql 对于 Postgres,您可以使用 earthdistance 模块:postgresql.org/docs/current/static/earthdistance.html MySQL Great Circle Distance (Haversine formula)的可能重复 【参考方案1】:

这对我有用:

$sql = "SELECT *,(((acos(sin((".$latitude."*pi()/180)) * sin((Latitude*pi()/180))+cos( (".$latitude."*pi()/180)) * cos((Latitude*pi()/180)) * cos(((".$longitude."-Longitude)*pi() /180))))*180/pi())*60*1.1515*1.609344) 作为距离 FROM shop WHERE distance >= ".$distance; //距离以公里为单位

也看看谷歌地图的功能: https://developers.google.com/maps/articles/phpsqlsearch_v3?csw=1#findnearsql

【讨论】:

【参考方案2】:

在 SQL 中获取米的距离检查这个查询,你也可以将它转换为一个函数

declare @lat1 FLOAT
declare @lat2 FLOAT
declare @lon1 FLOAT
declare @lon2 FLOAT

SET @lat1 = 18.4768047
SET @lon1 = -69.9516518
SET @lat2 = 18.4624464
SET @lon2 = -69.9652686


select (ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+COS(PI()*@lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0))*6371)*1000

这是一个例子

更新!!!

我为 MySQL 创建此程序以获取 KM、Miles、Metters 和码

DELIMITER //
CREATE PROCEDURE sp_Distance(lat1 FLOAT,lon1 FLOAT,lat2 FLOAT,lon2 FLOAT,unit INT) 
BEGIN  

declare KM INT;
declare MILE INT;
declare METTER INT;
declare YARD INT;

SET KM = 6371;
SET MILE = 3959;
SET METTER = KM*1000;
SET YARD = MILE*1760;


SELECT ((ACOS(SIN(PI()*lat1/180.0)*SIN(PI()*lat2/180.0)+
COS(PI()*lat1/180.0)*COS(PI()*lat2/180.0)*COS(PI()*lon2/180.0-PI()*lon1/180.0)))*
(SELECT CASE
WHEN unit = 1 THEN KM
WHEN unit = 2 THEN MILE
WHEN unit = 3 THEN METTER
WHEN unit = 4 THEN YARD END as unit_value)
) as Distance;
END;//

DELIMITER ;

致电:

call sp_Distance(18.4768047,-69.9516518,18.4624464,-69.9652686,1)

对于 SQL

CREATE PROCEDURE sp_Distance(@lat1 FLOAT,@lon1 FLOAT,@lat2 FLOAT,@lon2 FLOAT,@unit INT) 
AS
BEGIN 

declare @KM INT
declare @MILE INT
declare @METTER INT
declare @YARD INT

SET @KM = 6371
SET @MILE = 3959
SET @METTER = @KM*1000
SET @YARD = @MILE*1760

SELECT ((ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+
COS(PI()*@lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0)))*
(SELECT CASE
WHEN @unit = 1 THEN @KM
WHEN @unit = 2 THEN @MILE
WHEN @unit = 3 THEN @METTER
WHEN @unit = 4 THEN @YARD END as unit_value)
) as Distance
END

致电:

exec sp_Distance 18.4768047,-69.9516518,18.4624464,-69.9652686,1

【讨论】:

谢谢,我会尝试,但我不会将其标记为已接受,因为我在询问是否可以从“d”获取仪表,而不是进行其他查询;)但我会测试一下! 更新:@RickJames 使用它来获取里程选择 ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+COS(PI()* @lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0))*3959

以上是关于一个纬度/经度坐标与使用 SQL 的固定坐标之间的近似距离的主要内容,如果未能解决你的问题,请参考以下文章

如何计算两对坐标(纬度/经度)之间的距离

利用SQL计算两个地理坐标(经纬度)之间的地表距离

检查纬度经度是不是位于两个坐标之间的线上

sql怎么将一系列点经纬度坐标匹配到某市

sql 使用最近的纬度和经度坐标(MySQL和SQLite)进行SQL排序

2个纬度/经度点(坐标)列表之间的地理/地理空间距离