Anda memiliki referensi yang cukup bagus untuk pencarian jarak jauh mySQL.
Lupakan hal-hal Oracle Spasial. Terlalu banyak kode, terlalu banyak kerumitan, tidak cukup nilai tambah.
Inilah kueri yang akan melakukan trik. Ini menggunakan jarak dalam mil undang-undang. EDIT Ini memperbaiki bug yang disebutkan oleh mdarwin, dengan biaya pemeriksaan terpisah jika Anda mencoba menggunakannya untuk lokasi di kutub utara atau selatan.
SELECT id, city, LATITUDE, LONGITUDE, distance
FROM
(
SELECT id,
city,
LATITUDE, LONGITUDE,
(3959 * ACOS(COS(RADIANS(LATITUDE))
* COS(RADIANS(mylat))
* COS(RADIANS(LONGITUDE) - RADIANS(mylng))
+ SIN(RADIANS(LATITUDE))
* SIN(RADIANS(mylat))
))
AS distance,
b.mydst
FROM Cities
JOIN (
SELECT :LAT AS mylat,
:LONG AS mylng,
:RADIUS_LIMIT AS mydst
FROM DUAL
)b ON (1 = 1)
WHERE LATITUDE >= mylat -(mydst/69)
AND LATITUDE <= mylat +(mydst/69)
AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
)a
WHERE distance <= mydst
ORDER BY distance
Jika Anda bekerja dalam kilometer, ubah mydst/69 menjadi mydst/111.045, dan ubah 3959 menjadi 6371,4. (1/69 mengubah mil ke derajat; 3959 adalah nilai jari-jari planet.)
Sekarang, Anda mungkin tergoda untuk menggunakan kueri besar ini sebagai "kotak hitam ajaib". Jangan lakukan itu! Ini tidak terlalu sulit untuk dipahami, dan jika Anda memahaminya, Anda akan dapat melakukan pekerjaan yang lebih baik. Inilah yang terjadi.
Klausa ini adalah inti dari apa yang membuat kueri menjadi cepat. Ini mencari tabel Kota Anda untuk kota-kota terdekat ke titik yang Anda tentukan.
WHERE LATITUDE >= mylat -(mydst/69)
AND LATITUDE <= mylat +(mydst/69)
AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
Agar berfungsi, Anda pasti membutuhkan indeks pada kolom LATITUDE Anda. Indeks pada kolom LONGITUDE Anda juga akan sedikit membantu. Itu melakukan pencarian perkiraan, mencari baris yang berada dalam patch kuasi-persegi panjang di permukaan bumi dekat titik Anda. Ini memilih terlalu banyak kota, tetapi tidak terlalu banyak.
Klausa ini di sini memungkinkan Anda menghilangkan kota tambahan dari kumpulan hasil Anda:
WHERE distance <= mydst
Klausa ini adalah rumus haversine yang menghitung jarak lingkaran besar antara setiap kota dan titik Anda.
(3959 * ACOS(COS(RADIANS(LATITUDE))
* COS(RADIANS(mylat))
* COS(RADIANS(LONGITUDE) - RADIANS(mylng))
+ SIN(RADIANS(LATITUDE))
* SIN(RADIANS(mylat))
Klausa ini memungkinkan Anda memasukkan titik Anda, dan batas radius Anda, sekali saja sebagai variabel terikat ke kueri Anda. Ini membantu karena berbagai rumus menggunakan variabel tersebut beberapa kali.
SELECT :LAT AS mylat,
:LONG AS mylng,
:RADIUS_LIMIT AS mydst
FROM DUAL
Sisa kueri hanya mengatur hal-hal sehingga Anda memilih dan memesan berdasarkan jarak.
Berikut penjelasan lebih lengkapnya:http://www.plumislandmedia.net /mysql/haversine-mysql-nearest-loc/