查找用户经纬度20英里内的经纬度
我正在开发一个应用,用户可以搜索他们附近的物品。
当用户注册我的服务时,会记录他们的经纬度坐标(其实是通过邮政编码获取的,然后通过谷歌查找对应的经纬度)。当用户添加物品时,也会询问他们物品的邮政编码,然后将其转换为经纬度。
我想知道,如何使用MySQL来查询用户位置周围,比如20英里内的所有物品,获取这些物品的信息?
6 个回答
1
根据你使用的平台,有几种选择:
暴力破解法 - 就是把数据库里的项目拿出来,然后用一个简单的计算方法,算出你的位置(经纬度)和这些项目的坐标之间的距离,像这样:
public decimal GeoDistance(decimal lat1, decimal lng1, decimal lat2, decimal lng2)
{
double r = 6378.7; //km
decimal p = (decimal)(Math.PI / 180.0);
lat1 *= p; lat2 *= p; lng1 *= p; lng2 *= p;
return (decimal)(r * (Math.Acos(Math.Sin((double)lat1) * Math.Sin((double)lat2) + Math.Cos((double)lat1) * Math.Cos((double)lat2) * Math.Cos((double)lng2 - (double)lng1))));
}
如果你使用的是MS SQL Server 2008(其他数据库也可能支持),你可以使用地理方法
2
当你存储经纬度数据时,可以同时存储一个叫做“地理空间索引”的东西,简单来说就是一个字符串,它把这两个数据一起编码了。一个这样的索引方法是Geohash算法,它用一串二进制位把地球划分成越来越小的方块。
然后,当你想按距离搜索时,首先根据geohash缩小搜索范围,再通过测试欧几里得距离或者使用哈弗辛公式来过滤结果。
另一个选择是使用一个专门的数据库来执行这种查询。例如,MongoDB原生支持地理空间索引,而CouchDB则可以通过geocouch稍微帮助一下来实现。
如果回到MySQL,这个介绍可能会对你有帮助:使用MySQL进行地理距离搜索
2
假设精确度不是特别重要(比如用正方形代替圆形,并且不考虑地形),你可以这样做:
SELECT ... FROM ...
WHERE (ABS(firstLong - secondLong) < 20) AND (ABS(firstLat - secondLat) < 20);
如果你想把它变成圆形的话,只需要写一个稍微复杂一点的数学公式来计算距离:SQRT(longDelta*longDelta + latDelta*latDelta) < 20