在MySQL数据库中搜索半径范围内的值(纬度/经度)

时间:2015-04-25 21:25:14

标签: java php mysql

我没有那么多的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);
}

我只需要遍历一个集合来查找所有位置,其中distanceBetweentrue。然而,这似乎需要在客户端做更多的工作。

是否有正确的方法来处理从数据库中的纬度/经度X英里内返回所有结果?因为从服务器返回每个结果将成为一个非常快的带宽杀手。

问题也标记为PHP,因为这是我将用于轮询数据库的内容。

1 个答案:

答案 0 :(得分:1)

在你的位置,我只是将距离计算移动到mysql端。虽然您的代码很复杂,但是Haversine formula可以计算它,但不是。在这里你还可以看到用于计算的mysql代码示例,它甚至不需要存储函数。

不幸的是,这个简单的公式已经太复杂了,无法从mysql索引。这个解决方案将解决你的带宽查杀问题,但也许它会重载你的mysql。这取决于您的查询率和您的职位数量。

如果mysql超载,我建议在一个新问题中提出这个问题。

地理信息系统here有一个stackexchange站点。