MySQLを使用して距離内のポイントを見つける


20

ユーザーの名前、緯度、経度を含むmySQLテーブルがあります。特定の距離で特定の緯度と経度の円または正方形の内側にいるユーザーのリストを取得したいと思います。たとえば、入力Lat = 78.3232およびLong = 65.3234およびdistance = 30マイルです。ポイント78.3232および65.3234から30マイルの距離内にいるユーザーのリストを取得したいと思います。単一のクエリでこれを解決することは可能ですか?または、このクエリを解決するためのヒントを教えてください。地理ベースの情報は初めてです。


なぜPostGISではないのですか?ジオプロジェクトを開始している場合でも、スタックを変更できます
-simplexio

stackoverflow.com/a/40272394/1281385 このクエリを高速化するのに役立ちます(必要な場合)
exussum

回答:


32

78.3232、65.3234座標から半径30マイル以内にある最も近い20の場所を検索するSQLステートメント。その行の緯度/経度とターゲットの緯度/経度に基づいて距離を計算し、距離値が30マイル未満の行のみを要求し、距離でクエリ全体を順序付け、20の結果に制限します。マイルではなくキロメートルで検索するには、3959を6371に置き換えます。

SELECT
  id, (
    3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
  ) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;

これは、既にお持ちのMySQLバックエンドでGoogle Maps API v3を使用しています。

https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql


「#
1582-

見つかりました:lng変数が空でした!ごめんなさい!
bluantinoo 14年

まさに私が望んでいたものですが、何千ものレコードのクエリパフォーマンスの過負荷はどうですか?精度はどうですか?
アミットシャー

1
より良いメートルで検索するため6371392.896にそれを交換する
Vasilii Suricov

34

マッパーズの答えは無効です。洞は緯度ではなく経度から計算する必要があります。したがって、corect SQLステートメントは次のとおりです。

SELECT
    id, (
      3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;

あなたの答えは最初に注文する必要があります。
アミットシャー

@AmitShah質問者(このサイトで6年近くアクティブになっていない@shihabK)にpingを送信し
PolyGeo

これは受け入れられた答えであるはずです。
catbadger

2

関数を作成するためのベースになる可能性があります..他の領域で再利用できます。また、クエリが少しきれいになります...少なくともそれは私の2セントです。

DELIMITER $$

create function calcDistance(lat float, lng float, pnt_lat float, pnt_lng float)

Returns float
BEGIN

Declare dist float;
SET dist =
  3959 * acos (
  cos ( radians(pnt_lat) )
  * cos( radians( lat ) )
  * cos( radians( lng ) - radians(pnt_lng) )
  + sin ( radians(pnt_lat) )
  * sin( radians( lat ) )
);

RETURN dist;

END

コードスタイルを修正すると、答えは支持されます。それの右の方法
Vasilii Suricov

0

ここに私のクエリのバリアントがありますが、少し簡単です(http://dexxtr.com/post/83498801191/how-to-determine-point-inside-circle-using-mysql

SELECT 
    *
FROM 
    `locator`
WHERE
    SQRT(POW(X(`center`) - 49.843317 , 2) + POW(Y(`center`) - 24.026642, 2)) * 100 < `radius`

4
簡単ですが、地球が曲がっているという事実を無視します。
ティムリャベック

正確な式が必要です。たぶん、これは短距離でのみ良いでしょう:D
Jethro

屋はミサイルを発射するか、それとも何か?
デニス・ブラガ

1
@DennisBraga-もしそうなら、おそらくこの質問はトピック外であり、http://globalthermonuclearwar.stackexchange.comにより適しています ...?
ashleedawg
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.