0

緯度と経度を持つレストランのリストから、それらすべての間に少なくともX km のポイントを取得するにはどうすればよいですか?

つまり、各レストランは半径X km内に他のレストランを持っていません。

次のクエリを試しました。

SELECT 
    id,
    lat as x, 
    lng as y,
    concat(ceil((lat+90)/5),',',ceil((lng+180)/5)) as groupParam
FROM 
    restaurants 
GROUP BY groupParam

結果は次のとおりです。

クエリの結果

そのクエリでは、丸められた緯度と経度 (例: "12,23") でグループ化しています。したがって、(lat >= 12 && lat <13) および (lng >= 23 && lng < 24) からのみノードを取得します。

それは高速ですが、あまり正確ではありません。

ありがとう、ウィリアム。

4

2 に答える 2

0

webapp として作成した hamradio データベースの経度/緯度の計算を行いました: http://dk7sl.de/iRelais

ここで、$x と $y は私の経度/緯度座標です。最大距離は 15 km に設定されています。クエリで「*1.609344」を削除するだけで、マイルに切り替えることができます。このクエリは、地理データ テーブル内の最も近いエントリを選択します。地理データはhttp://www.geodatasource.com/world-cities-database/freeから取得したもので、私の mysqldb には約 240 万のレコードが含まれています。DB インデックスは、緯度、経度、フィーチャ クラス、およびフィーチャ コードに基づいています (ただし、これは、エントリをフィーチャ クラスとコードでフィルタリングするためです)。

$query = "SELECT name, (((ACOS(SIN('".$x."' * PI() / 180) * SIN(緯度 * PI() / 180) + COS(".$x." * PI() / 180) * COS(緯度 * PI() / 180) * COS(('".$y."' - 経度) * PI() / 180)) * 180 / PI()) * 60 * 1.1515))*1.609344 AS distanceFROM geodataWHERE feature class= 'P' AND ( feature code= 'PPLX' OR feature code= 'PPL') HAVING distance<='15' ORDER BY distanceASC LIMIT 1;";

データベースから適切なポイントのグループを取得できるように、私の select ステートメントを使用して変更することができます。

于 2012-07-21T01:31:03.340 に答える
0

元の質問への回答:

これはあなたが探しているものを提供すると思います:

SELECT DISTINCT
    a.id AS a,
    b.id AS b,
    ACOS(
        SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
    ) * 6371.01 AS km
FROM 
    restaurants a,
    restaurants b
WHERE
    b.id > a.id AND
    ACOS(
        SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
    ) * 6371.01 >= X
ORDER BY
    ACOS(
        SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
    );

ここで、X はそれらの間に必要な最小のキロメートルです。

残念ながら、このタイプのクエリはCartesian Productを返すCROSS JOINであるため、レストランが 10 の場合は 36 の比較、100 の場合は 4,851、1,000 の場合は 498,501 などになります。

修正された質問への回答:

他のレストランから少なくとも X キロメートル離れたすべてのレストランを検索するには、次のようにします。

SELECT
    a.id AS a,
    MIN(ACOS(
        SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
    ) * 6371.01) AS km
FROM 
    restaurants a,
    restaurants b
WHERE
    b.id > a.id
GROUP BY
    a.id
HAVING
    MIN(ACOS(
        SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
    ) * 6371.01) >= X
ORDER BY
    MIN(ACOS(
        SIN(a.lat) * SIN(b.lat) + COS(a.lat) * COS(b.lat) * COS(a.lon - b.lon)
    ) * 6371.01)

ここで、X はそれらの間に必要な最小のキロメートルです。

于 2012-07-21T01:34:24.130 に答える