克里斯提出的解决方案:
SELECT * AS distance FROM items ORDER BY ((location_lat-lat)*(location_lat-lat)) + ((location_lng - lng)*(location_lng - lng)) ASC
当我们靠近赤道时是正确的。为了让它在其他纬度正常工作,我建议:
SELECT * AS distance FROM items ORDER BY ((location_lat-lat)*(location_lat-lat)) + ((location_lng - lng)*(location_lng - lng)* cos_lat_2 ) ASC
我们必须预先计算:
cos_lat_2 = cos(location_lat * PI / 180) ^ 2
问题:
如果我们在赤道并且我们在经度上移动 1 度(东或西),我们在 40,000 公里的圆周上移动,代表距离为 40.000 / 360。如果我们在纬度上移动 1 度(北或南),我们在一个穿过两极的圆上这样做,这也涉及 40.000 / 360 的距离(考虑到地球是一个球体)。
但是,如果我们在英格兰南部,纬度为 50°,并且我们在经度上移动 1 度(东或西),我们会在 50 度纬线上进行,它的周长小于赤道。距离是 perimeter_parallel_50 / 360。计算这个周长很简单:perimeter_parallel_50 = cos (50) * 2 * PI * EARHT_RADIUS = 0.64 * 40,000 km。如果我们向南或向北移动 1 度,则看不到这种距离的减少。我们移动的圆周仍有 40,000 公里的周长。
解决方案:
由于 location_lat 是一个预先知道的值,我们可以预先计算 cos(location_lat) 的值,以便将其用作比例因子,使经度和纬度的位移相等。此外,我们预先平方它以避免必须将其乘以两次。
笔记:
这仍然是一个近似值,在大距离移动时会给出错误的结果,尤其是在两极附近和穿过 180 度子午线时。