我没有那么多的SQL经验,老实说也没有线索从哪里开始,大多数提出这样的问题的人都在使用MS Server之类的东西,并且可以使用一堆参数/我不能的价值观。我正在使用MySQL。
这是Java中用于在X英里内创建随机位置的代码。
public static GeoPosition randomLocation(GeoPosition location, double radius) {
Random random = new Random();
// Convert radius from miles to meters
double meters = radius * 1609.34;
// Convert radius from meters to degrees
double radiusInDegrees = meters / 111300f;
double u = random.nextDouble();
double v = random.nextDouble();
double w = radiusInDegrees * Math.sqrt(u);
double t = 2 * Math.PI * v;
double x = w * Math.cos(t);
double y = w * Math.sin(t);
// Adjust the x-coordinate for the shrinking of the east-west distances
double new_x = x / Math.cos(location.latitude());
double foundLongitude = new_x + location.longitude();
double foundLatitude = y + location.latitude();
return new GeoPosition(foundLongitude, foundLatitude);
}
这些GeoPositions(经度/纬度组)存储在数据库中。但是现在我需要弄清楚如何在半径X英里内获得数据库中的所有行。
在Java中编写时,distanceBetween方法如下所示:
public static double distanceBetween(GeoPosition a, GeoPosition b) {
double longDif = a.longitude() - b.longitude();
double distance =
Math.sin(deg2rad(a.latitude()))
*
Math.sin(deg2rad(b.latitude()))
+
Math.cos(deg2rad(a.latitude()))
*
Math.cos(deg2rad(b.latitude()))
*
Math.cos(deg2rad(longDif));
distance = Math.acos(distance);
distance = rad2deg(distance);
distance = distance * 60 * 1.1515; // Convert to meters
distance = distance * 0.8684; // Convert to miles.
return distance;
}
private static double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}
private static double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
我只需要遍历一个集合来查找所有位置,其中distanceBetween
是true
。然而,这似乎需要在客户端做更多的工作。
是否有正确的方法来处理从数据库中的纬度/经度X英里内返回所有结果?因为从服务器返回每个结果将成为一个非常快的带宽杀手。
问题也标记为PHP,因为这是我将用于轮询数据库的内容。
答案 0 :(得分:1)
在你的位置,我只是将距离计算移动到mysql端。虽然您的代码很复杂,但是Haversine formula可以计算它,但不是。在这里你还可以看到用于计算的mysql代码示例,它甚至不需要存储函数。
不幸的是,这个简单的公式已经太复杂了,无法从mysql索引。这个解决方案将解决你的带宽查杀问题,但也许它会重载你的mysql。这取决于您的查询率和您的职位数量。
如果mysql超载,我建议在一个新问题中提出这个问题。
地理信息系统here有一个stackexchange站点。