从具有纬度和经度的餐馆列表中,如何获得所有这些点之间至少 X km的点?
我的意思是,每家餐厅都没有 X km半径内的任何其他餐厅。
我尝试了下一个查询:
SELECT
id,
lat as x,
lng as y,
concat(ceil((lat+90)/5),',',ceil((lng+180)/5)) as groupParam
FROM
restaurants
GROUP BY groupParam
结果如下:
在那个查询中,我按照经纬度和经度进行分组(例如:“12,23”)。所以我只从(lat> = 12&& lat< 13)和(lng> = 23&& lng< 24)得到一个节点。
这很快但不太准确。
谢谢, 威廉·
答案 0 :(得分:0)
我为一个我写成webapp的hamradio数据库做了一些lon / lat计算: http://dk7sl.de/iRelais
这是select语句,其中$ x和$ y是我的lon / lat坐标。 最大距离设置为15公里。如果您只是删除查询中的“* 1.609344”,则可以切换到里程。此查询选择地理数据表中最近的条目。 Geodata取自http://www.geodatasource.com/world-cities-database/free,在我的mysqldb中包含大约240万条记录。数据库索引是纬度,经度,要素类和要素代码(但这只是因为我按要素类和代码过滤条目)
$ query =“SELECT name,(((ACOS(SIN('。”。$ x。“'* PI()/ 180)* SIN(纬度* PI()/ 180)+ COS(”。$ x 。“* PI()/ 180)* COS(纬度* PI()/ 180)* COS(('”。$ y。“ - 经度)* PI()/ 180))* 180 / PI()) * 60 * 1.1515))* 1.609344 AS distance
FROM geodata
WHERE feature class
='P'和(feature code
='PPLX'或feature code
='PPL ')HAVING distance
< ='15'Order by distance
ASC LIMIT 1;“;
也许您可以使用我的select语句并对其进行修改,以便从数据库中获得正确的一组点。
答案 1 :(得分:0)
回答原始问题:
我认为这将为您提供所需的信息:
SELECT DISTINCT
a.id AS a,
b.id AS b,
ACOS(
SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
) * 6371.01 AS km
FROM
restaurants a,
restaurants b
WHERE
b.id > a.id AND
ACOS(
SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
) * 6371.01 >= X
ORDER BY
ACOS(
SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
);
其中X是你想要的最小公里数。
不幸的是,这种类型的查询是CROSS JOIN返回Cartesian Product,所以有10家餐馆,你将有36个比较,100个你将有4,851,1,000你将有498,501,等
回答您修改过的问题:
要找到距离任何其他餐厅至少X公里的所有餐厅,请使用:
SELECT
a.id AS a,
MIN(ACOS(
SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
) * 6371.01) AS km
FROM
restaurants a,
restaurants b
WHERE
b.id > a.id
GROUP BY
a.id
HAVING
MIN(ACOS(
SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
) * 6371.01) >= X
ORDER BY
MIN(ACOS(
SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
) * 6371.01)
其中X是你想要的最小公里数。