我在尝试通过SQL语句将最近的位置返回给用户时遇到问题.为了测试我使用完全相同的坐标,这里是我所拥有的:
SQL:
SELECT `companies`.`customerName` ,
(3959 *
ACOS(
COS(
RADIANS(37.367485) * COS(RADIANS(`locations`.`gps_lat`)) *
COS(
RADIANS(`locations`.`gps_lng`) - RADIANS(-77.399994) +
SIN(RADIANS(37.367485)) * SIN(RADIANS(`locations`.`gps_lat`))
)
)
)
)
AS `distance`
FROM `locations`
JOIN `companies` ON `locations`.`co_id`
HAVING `distance` > 25
ORDER BY distance
LIMIT 0 , 10
Run Code Online (Sandbox Code Playgroud)
结果:
| customerName | distance |
| SOME COMPANY | 1914.41747964854 |
Run Code Online (Sandbox Code Playgroud)
locations 表值:
gps_lat | gps_lng
37.367485 | -77.399994
Run Code Online (Sandbox Code Playgroud)
我使用了谷歌的例子,我检查了几次公式,我似乎无法想出我出错的地方.任何帮助表示赞赏.
编辑:
因为我知道自己在做什么似乎有些困惑:
的>被取代的,得到的结果,1914很明显大于25.
这个应用程序是将用户坐标从Android应用程序传递到我们的Web服务器.纬度和经度将从$_GET值中提取,并从我们的Web服务器MYSQL数据库中的公司进行交叉引用.
上面的语法只是我在Mysql Workbench中检查我的SQL语句.显然我正在寻找零值结果.
我想我已经解决了这个问题,从Googles的例子改为"一个被采用的yooper的冒险"提供的公式.使用他/她的Haversine Formula版本.
注意:上面的Google示例也使用了Haversine.
SQL:
SELECT `companies`.`customerName` ,
(2 * (3959 * ATAN2(
SQRT(
POWER(SIN((RADIANS(37.367485 - `locations`.`gps_lat` ) ) / 2 ), 2 ) +
COS(RADIANS(`locations`.`gps_lat`)) *
COS(RADIANS(37.367485 )) *
POWER(SIN((RADIANS(-77.399994 - `locations`.`gps_lng` ) ) / 2 ), 2 )
),
SQRT(1-(
POWER(SIN((RADIANS(37.367485 - `locations`.`gps_lat` ) ) / 2 ), 2 ) +
COS(RADIANS(`locations`.`gps_lat`)) *
COS(RADIANS(37.367485)) *
POWER(SIN((RADIANS(-77.399994 - `locations`.`gps_lng` ) ) / 2 ), 2 )
))
)
))
AS 'distance'
FROM `locations`
JOIN `companies` ON `locations`.`co_id`
HAVING distance < 25
ORDER BY distance
LIMIT 0 , 10
Run Code Online (Sandbox Code Playgroud)
对于那些对我的应用程序感兴趣的人,最终PHP:
获取价值: ?lat=37.367485&lng=-77.399994
$earth_radius_miles = 3959; // Earth radius in miles
$earth_radius_kilometers = 6371; // Earth radius in kilometers
$result_radius = 10000; // Maximum distance in either miles or kilometers
$get_lat = $_GET["lat"];
$get_lng = $_GET["lng"];
$dbSelect = mysql_query("SELECT `companies`.`customerName`,
(2 * (".$earth_radius_miles." * ATAN2(
SQRT(
POWER(SIN((RADIANS(".$get_lat." - `locations`.`gps_lat` ) ) / 2 ), 2 ) +
COS(RADIANS(`locations`.`gps_lat`)) *
COS(RADIANS(".$get_lat.")) *
POWER(SIN((RADIANS(".$get_lng." - `locations`.`gps_lng` ) ) / 2 ), 2 )
),
SQRT(1-(
POWER(SIN((RADIANS(".$get_lat." - `locations`.`gps_lat` ) ) / 2 ), 2 ) +
COS(RADIANS(`locations`.`gps_lat`)) *
COS(RADIANS(".$get_lat.")) *
POWER(SIN((RADIANS(".$get_lng." - `locations`.`gps_lng` ) ) / 2 ), 2 )
))
)
))
AS 'distance'
FROM `locations`
JOIN `companies` ON `locations`.`co_id`
HAVING distance < ".$result_radius."
ORDER BY distance
LIMIT 0 , 10")
or die(mysql_error());
Run Code Online (Sandbox Code Playgroud)
结果:
[{"customerName":"SOME COMPANY","distance":"0"}]
Run Code Online (Sandbox Code Playgroud)
我用其他坐标测试了这些结果,看起来效果很好.没有测试两点之间距离很远的东西,但我的申请并没有要求我这样做.