11

PHPWebサービスに経度と緯度を含むMySQLテーブルがあります。たとえば、5つの最も近い座標のみをユーザーに送信したいと思います。座標からユーザーがPOSTリクエストで送信した座標までの距離を計算するメソッドを作成しましたが、それを並べ替える方法がわからず、数個しか返送されません。

距離法は次のとおりです。

function  distance($longToCompare,$latToCompare) {
    $dlong = $request_long - $longToCompare;
    $dlat = $request_lat - $latToCompare;
    $a = pow(sin($dlat/2)) + cos($latToCompare)*cos($request_lat)*pow(sin($dlong/2));
    $c = 2*atan2(sqrt($a),sqrt(1-$a));
    return 6373*$c; 
}

そして、ユーザーは現在DB全体を取得しています(今のところ、開発中は小さいですが、将来的にはかなり大きくなる可能性があります)

$q = mysql_query("SELECT * FROM Coordinates");
$coordinates = array ();
while ($e = mysql_fetch_assoc($q)) {
    $coordinates[] = $e;
}
print (json_encode($coordinates));

誰かが私を正しい方向に向けることができますか?私はPHPにかなり慣れていないので、uasortを使用してカスタムの並べ替えを作成できることは知っていますが、この距離関数を使用してそれを使用する方法がよくわかりません。

編集:@Norseのソリューションを使用すると、現在のクエリは次のようになります。

$request_long = $_POST['longitude'];
$request_lat = $_POST['latitude'];
    $km = 0.5;
        $query = "SELECT *, 
    ( 6373 * acos( cos( radians('$request_lat') ) * 
    cos( radians( latitude ) ) * 
    cos( radians( longitude ) - 
    radians('$request_long') ) + 
    sin( radians('$request_lat') ) * 
    sin( radians( latitude ) ) ) ) 
    AS distance FROM Coordinates HAVING distance < '$km' ORDER BY distance ASC LIMIT 0, 5";
        $coordinates = array ();
        while ($e = mysql_fetch_assoc($query)) {
            $coordinates[] = $e;
        }
        print (json_encode($coordinates));
4

3 に答える 3

27

Googleのアルゴリズムを使用する:

$lon = //your longitude
$lat = //your latitude
$miles = //your search radius

$query = "SELECT *, 
( 3959 * acos( cos( radians('$lat') ) * 
cos( radians( latitude ) ) * 
cos( radians( longitude ) - 
radians('$lon') ) + 
sin( radians('$lat') ) * 
sin( radians( latitude ) ) ) ) 
AS distance FROM yourtable HAVING distance < '$miles' ORDER BY distance ASC LIMIT 0, 5"

latitudeこのクエリでlongitudeは、緯度/経度の列名になります。

于 2012-05-27T01:28:35.420 に答える
3

最近同じ問題が発生しました。私が決めたのは、距離を計算するmysql関数を記述し、それをSQLクエリで使用することでした。Mysql関数:

CREATE FUNCTION distance(lat1 float, lon1 float, lat2 float, lon2 float) 
RETURNS float
RETURN ACOS(SIN(RADIANS(lat1))*SIN(RADIANS(lat2))+COS(RADIANS(lat1))*COS(RADIANS(lat2))*COS(RADIANS(lon2-lon1)))*6371

Coordinatesテーブルに列feがlatitudeある場合longitude、コードは次のようになります。

$q = mysql_query("SELECT * FROM Coordinates ORDER BY 
     distance(latitude, longitude, $lat, $lon) LIMIT 5";

提供された場所$lat$lon含みます。

于 2012-05-27T01:23:25.663 に答える
0

ソートをクエリに埋め込む方が効率的です。

この素晴らしいチュートリアルはあなたを助けます(そしてあなたのニーズを満たすクエリを提供します): https ://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql

于 2012-05-27T01:24:00.657 に答える