2009-05-21 12 views
8

から指定された場所の近くに選択した場所が、私は2つの位置の間の距離を計算するための次のコードを持っている:PHP/MySQLの:PHPでDB

<?php 
function distance($lat1, $long1, $lat2, $long2) { 
    // DEGREE TO RADIAN 
    $latitude1 = $lat1/180*pi(); 
    $longitude1 = $long1/180*pi(); 
    $latitude2 = $lat2/180*pi(); 
    $longitude2 = $long2/180*pi(); 
    // FORMULA: e = ARCCOS (SIN(Latitude1) * SIN(Latitude2) + COS(Latitude1) * COS(Latitude2) * COS(Longitude2-Longitude1)) * EARTH_RADIUS 
    $distance = acos(sin($latitude1)*sin($latitude2)+cos($latitude1)*cos($latitude2)*cos($longitude2-$longitude1))*6371; 
    return $distance; 
} 
echo distance(9.9921962, 53.5534074, 9.1807688, 48.7771056); // Hamburg, DE - Stuttgart, DE 
?> 

をしかし、今、私は近くの場所を選択します私のMySQLデータベースからPHP経由で場所を与えられた:ユーザーが彼の故郷

  • に入る

    • 私のスクリプトは、私には、GoogleのAPI
    • を経由して緯度/経度の値を取得しますデータベース、私は、ユーザーの故郷

    に最も近い10点の場所を選択するためにPHPとMySQLのコードを必要と経度値

  • ための緯度値とフィールドのフィールドで約200位置を有しますあなたが私を助けることを願っています。前もって感謝します!

  • 答えて

    7

    MySQL Great Circle Distance (Haversine formula)あなたが必要とするのは正確です。

    ただし、200個のレコードだけで、すべてをロードしてコードで確認することもできます。データセットは実際には小さすぎて、データベース対コードや他のそのような最適化についてあまり心配する必要はありません。

    Calculating distance between zip codes in PHPには、このアルゴリズムのいくつかのPHP実装があります。

    Geo Proximity Searchはまったく同じ問題です。

    +0

    ありがとう、nOw2が言ったように、Haversine式です。私はまだPHPの実装を持って、私の質問のコードを参照してください。 – caw

    0

    MySQLは地理空間インデックス行する能力を持っています。あなたは自分でこの数学を行う必要はないかもしれません(MySQLに2つのジオオブジェクト間の距離を計算し、それをソートすることができます)。

    参照:http://forums.mysql.com/read.php?23,159205,159205

    +0

    ありがとうございますが、MySQLの地理空間的な機能を使用することはできません。 – caw

    -1

    は、なぜあなたはMySQLの地理空間機能を使用していませんか...?いや、冗談よ。

    200レコードが町などの実際の場所である場合、代わりにGeoNamesのAPIを使用できますか?

    次のWebサービスを提供緯度とLNGへの10点の最も近い場所を提供します:

    http://ws.geonames.org/findNearby?lat=47.3&lng=9

    出典:http://www.geonames.org/export/web-services.html#findNearbyPlaceName

    全リスト:http://www.geonames.org/export/ws-overview.html

    +0

    ありがとう!自分のデータベースにデータがあるので、GeoNamesのAPIを使用する必要はありません。 – caw

    +0

    はい、私は理解しますが、あなたはGeonamesからの応答とそれらの200レコードを一致させることができます。これは、あなたの200レコードが何らかのランダムな位置ではなく、何らかの形で知られている場所であると仮定しています。 –

    1

    半正矢式です。 PHPをSQLに直接変換することで、データベースを空間的に照会することができます(データベースからすべてのレコードを取り出し、PHPを使用してデータを実行することもできます)。 MySQLには、必要なすべての数学関数が用意されています。

    これは、ポスト/郵便番号に基づく遠隔検索を提供する商用ウェブサイトでこれを行いました。そのため、特定のGIS機能がないと確かに可能です。

    +0

    ありがとう、それは正常に動作します! :)私は、MySQLにすべての数学関数があることを知らなかった。 – caw

    3

    多分

    SELECT field1, field2, ..., 
        ACOS(SIN(latitude/180 * PI()) * SIN(:1) + COS(latitude/180 * PI()) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance 
        ORDER BY distance ASC; 
    

    又は

    SELECT field1, field2, ..., 
        ACOS(SIN(RADIANS(latitude)) * SIN(:1) + COS(RADIANS(latitude)) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance 
        ORDER BY distance ASC; 
    

    (直接PHPコードから翻訳)

    :1:2ようなものは、それぞれ$lat2/180*pi()$long2/180*pi()です。

    +0

    ありがとう、それはnOw2の答えと同じですね。あなたは "$ lat2/180 * pi()"と書く。なぜ "RADIANS($ lat2)"だけではないのですか?あなたは残りのクエリでそれを使用しました、なぜここにもありませんか? – caw

    +0

    :1と:2は、RADIANSを持たないPHPに由来します。しかし、http://us2.php.net/deg2radでも使用できます。 – itsbth

    関連する問題