我正在写一个应用程序,需要允许用户选择在其位置半径内的元素。没有办法知道最终会有多少个地点,但可能会有成千上万个。进行搜索的用户是位置节点之一(而不仅仅是他们的手机或诸如此类的东西提交的任意位置)
我看到的答案是这样的:mysql lat lon calulation显示半径内的位置,但我担心这是一项非常严肃的任务,因为涉及的数学将需要为每个“其他”位置计算。
我考虑的另一种方法是使用一个关系表来标识每个位置之间的距离(每次添加一个位置时我都会填充该表),尽管它将有大量行来定义每个可能的关系,但如果选择*该表,速度会非常快,尤其是在距离被索引的情况下。
我很想从mySQL中做过这件事的人那里得到一些建议,他们可以警告我支持或反对最好的方法。
以下SQL查询使用余弦球形定律计算表中坐标和坐标之间的距离。它将结果限制为10,并按距离排序。这是用来代替Haversine公式,这是太复杂的MySQL执行
余弦球面定律
其中R=3959英里或6371公里
d = acos( sin(lat1).sin(lat2) + cos(lat1).cos(lat2).cos(lng2-lng1) ).R
SQL
SELECT name, lat, lng, ( 3959 * acos( cos( radians($center_lat) )
* cos( radians( lat ) ) * cos( radians( lng )
- radians($center_lng) ) + sin( radians($center_lat) )
* sin( radians( lat ) ) ) ) AS distance FROM table
ORDER BY distance LIMIT 0 , 10
center_lat代码
查询使用SQLMath函数
对包含50068行的数据库的查询耗时0.2506秒
MySQL中可用的空间函数不适合您的应用程序,请参阅此博客
地理信息系统是半径距离的良好起点,但最终(比例)您将不得不解析为lat/long栅格。半径是昂贵的计算网格是非常简单的存储和查找。根据我的经验,MySQL中的FWIW GIS功能在5.6之前的许多内核(10)上无法很好地扩展,可能要到5.7才能修复。
如果您预先计算了一些实际需要的数据并将其存储在数据库中,那么基于这些数据进行计算应该会非常快。
根据我对这个问题的回答:
在SO上排序邮政编码邻近问题
您可以使用如下计算方法:
$iRadius * 2 * ASIN(SQRT(POWER(SIN(( $fLat - abs(pos.lat)) * pi() / 180 / 2),2) +
COS( $fLat * pi()/180) * COS(abs(pos.lat) * pi() / 180) * POWER(SIN(( $fLon - pos.lon) *
pi() / 180 / 2), 2) )) AS distance
实际数学函数的负载可以预先计算,也可以存储在数据库中。这将帮助您加快查询速度。
如果您知道您只对特定半径感兴趣,您甚至可以忽略差异较大的lat/lon值(因为这已经意味着它们具有特定的距离),因此您只能计算距离您所在位置特定范围内的lat/lon值。
我使用这种方法计算到邮政编码的距离(
问题总是:你需要计算多少个值?