Temukan poin dalam jarak tertentu menggunakan MySQL

20

Saya memiliki tabel mySQL dengan nama pengguna, lintang dan bujur dari pengguna. Saya ingin mendapatkan daftar pengguna yang berada di dalam lingkaran atau kuadrat dari garis lintang dan bujur tertentu dengan jarak tertentu. Misalnya input saya Lat = 78,3232 dan Panjang = 65,3234 dan jarak = 30 mil. Saya ingin mendapatkan daftar pengguna yang berada dalam jarak 30 mil dari titik 78.3232 dan 65.3234. Apakah mungkin untuk menyelesaikan ini dengan satu permintaan? Atau bisakah Anda memberi saya petunjuk untuk mulai menyelesaikan pertanyaan ini? Saya baru mengenal informasi berbasis geo.

shihab K
sumber
Kenapa tidak PostGIS? Jika Anda memulai proyek geo, Anda masih dapat mengubah tumpukan Anda
simplexio
stackoverflow.com/a/40272394/1281385 Harus berguna dalam mempercepat permintaan ini (jika perlu)
exussum

Jawaban:

32

Pernyataan SQL yang akan menemukan 20 lokasi terdekat yang berada dalam radius 30 mil ke 78,3232, 65,3234 koordinat. Ini menghitung jarak berdasarkan garis lintang / garis bujur dari baris itu dan garis lintang / garis bujur target, dan kemudian meminta hanya baris di mana nilai jaraknya kurang dari 30 mil, memesan seluruh kueri berdasarkan jarak, dan membatasinya hingga 20 hasil. Untuk mencari menurut kilometer bukannya mil, ganti 3959 dengan 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;

Ini menggunakan Google Maps API v3 dengan backend MySQL yang sudah Anda miliki.

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

Mapperz
sumber
Saya mendapatkan kesalahan sintaksis dalam pilih saya menggunakan ini, "# 1582 - Parameter salah menghitung dalam panggilan ke fungsi asli 'radian' apa yang bisa terjadi?
bluantinoo
Ditemukan: Saya punya variabel lng kosong! Maaf!
bluantinoo
Apa yang saya inginkan, tapi apa kinerja permintaan yang berlebihan untuk ribuan catatan? dan bagaimana dengan akurasinya?
Amit Shah
1
jauh lebih baik untuk menggantinya ke 6371392.896 untuk pencarian dengan meter
Vasilii Suricov
34

Jawaban Mapperz tidak valid. Sinus harus dihitung dari garis lintang dan BUKAN dari garis bujur. Jadi pernyataan SQL yang benar adalah:

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;
Marek Čačko
sumber
Jawaban Anda harus dipesan terlebih dahulu.
Amit Shah
@AmitShah Jika Anda berpikir bahwa Anda dapat melakukan ping penanya (@shihabK yang belum aktif di situs selama hampir 6 tahun) dan / atau memilih meta.stackexchange.com/questions/268666/…
PolyGeo
Ini harus menjadi jawaban yang diterima.
catbadger
2

Mungkin basis untuk membuat fungsi .. sehingga Anda dapat menggunakannya kembali daerah lain. Juga akan membuat kueri Anda sedikit lebih bersih ... Setidaknya itu adalah 2 sen saya.

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
eDriven_Levar
sumber
Jawabannya akan dibatalkan jika Anda memperbaiki codestyle. itu jalan yang benar
Vasilii Suricov
0

Inilah varian kueri saya, sepertinya sedikit lebih mudah ( 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`
dexxtr
sumber
4
Lebih mudah tetapi mengabaikan fakta bahwa bumi melengkung.
Tim Rijavec
Perlu formula agar akurat. Mungkin ini akan bagus untuk jarak pendek saja: D
Jethro
Ya akan meluncurkan rudal, atau sesuatu?
Dennis Braga
1
@DennisBraga - jika demikian, maka mungkin pertanyaan ini di luar topik, lebih cocok untuk http://globalthermonuclearwar.stackexchange.com ...?
ashleedawg