Saya punya proyek di mana saya perlu membangun pencari lokasi toko untuk klien.
Saya menggunakan tipe posting khusus " restaurant-location
" dan saya telah menulis kode untuk melakukan geocode alamat yang disimpan dalam postmeta menggunakan Google Geocoding API (inilah tautan yang melakukan geocode Gedung Putih AS di JSON dan saya telah menyimpan lintang dan bujur kembali ke bidang khusus.
Saya telah menulis get_posts_by_geo_distance()
fungsi yang mengembalikan daftar posting sesuai urutan yang paling dekat secara geografis menggunakan rumus yang saya temukan dalam tayangan slide di posting ini . Anda dapat memanggil fungsi saya seperti itu (saya mulai dengan lat "panjang" sumber "):
include "wp-load.php";
$source_lat = 30.3935337;
$source_long = -86.4957833;
$results = get_posts_by_geo_distance(
'restaurant-location',
'geo_latitude',
'geo_longitude',
$source_lat,
$source_long);
echo '<ul>';
foreach($results as $post) {
$edit_url = get_edit_url($post->ID);
echo "<li>{$post->distance}: <a href=\"{$edit_url}\" target=\"_blank\">{$post->location}</a></li>";
}
echo '</ul>';
return;
Inilah fungsinya get_posts_by_geo_distance()
sendiri:
function get_posts_by_geo_distance($post_type,$lat_key,$lng_key,$source_lat,$source_lng) {
global $wpdb;
$sql =<<<SQL
SELECT
rl.ID,
rl.post_title AS location,
ROUND(3956*2*ASIN(SQRT(POWER(SIN(({$source_lat}-abs(lat.lat))*pi()/180/2),2)+
COS({$source_lat}*pi()/180)*COS(abs(lat.lat)*pi()/180)*
POWER(SIN(({$source_lng}-lng.lng)*pi()/180/2),2))),3) AS distance
FROM
wp_posts rl
INNER JOIN (SELECT post_id,CAST(meta_value AS DECIMAL(11,7)) AS lat FROM wp_postmeta lat WHERE lat.meta_key='{$lat_key}') lat ON lat.post_id = rl.ID
INNER JOIN (SELECT post_id,CAST(meta_value AS DECIMAL(11,7)) AS lng FROM wp_postmeta lng WHERE lng.meta_key='{$lng_key}') lng ON lng.post_id = rl.ID
WHERE
rl.post_type='{$post_type}' AND rl.post_name<>'auto-draft'
ORDER BY
distance
SQL;
$sql = $wpdb->prepare($sql,$source_lat,$source_lat,$source_lng);
return $wpdb->get_results($sql);
}
Kekhawatiran saya adalah bahwa SQL adalah tentang tidak dioptimalkan yang Anda dapatkan. MySQL tidak dapat memesan berdasarkan indeks apa pun yang tersedia karena geo sumber dapat diubah dan tidak ada set sumber geo terbatas untuk cache. Saat ini saya bingung bagaimana cara mengoptimalkannya.
Mempertimbangkan apa yang telah saya lakukan, pertanyaannya adalah: Bagaimana cara mengoptimalkan kasus penggunaan ini?
Tidak penting bahwa saya menyimpan semua yang telah saya lakukan jika solusi yang lebih baik membuat saya membuangnya. Saya terbuka untuk mempertimbangkan hampir semua solusi kecuali untuk yang membutuhkan melakukan sesuatu seperti menginstal server Sphinx atau apa pun yang memerlukan konfigurasi MySQL yang disesuaikan. Pada dasarnya solusinya harus dapat bekerja pada instalasi WordPress vanilla biasa. (Yang mengatakan, alangkah baiknya jika ada yang ingin mendaftar solusi alternatif untuk orang lain yang mungkin bisa menjadi lebih maju dan untuk anak cucu.)
Sumber Ditemukan
FYI, saya melakukan sedikit riset tentang hal ini daripada meminta Anda melakukan penelitian lagi atau daripada meminta Anda memposting tautan-tautan ini sebagai jawaban, saya akan melanjutkan dan memasukkannya.
- http://jebaird.com/blog/calculating-distance-miles-latitude-and-longitude
- http://wordpress.org/extend/plugins/geolocation/screenshots/
- http://code.google.com/apis/maps/articles/phpsqlsearch.html
- http://www.rooftopsolutions.nl/blog/229
- http://planet.mysql.com/entry/?id=18085
- http://blog.peoplesdns.com/archives/24
- http://www.petefreitag.com/item/622.cfm
- http://www.phpro.org/tutorials/Geo-Targetting-With-PHP-And-MySQL.html
- http://forum.geonames.org/gforum/posts/list/692.page
- http://forums.mysql.com/list.php?23
- http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
- http://developer.yahoo.com/maps/rest/V1/geocode.html
- http://geocoder.us/
Mengenai Pencarian Sphinx
- http://sphinxsearch.com/
- https://launchpad.net/wp-sphinx-plugin
- http://forums.site5.com/showthread.php?t=28981
- http://wordpress.org/extend/plugins/wordpress-sphinx-plugin/
- http://wordpress.org/extend/plugins/sphinx-search/
- http://www.mysqlperformanceblog.com/2008/02/15/mysql-performance-blog-now-uses-sphinx-for-site-search/
sumber
Ini mungkin sudah terlambat untuk Anda, tetapi saya tetap akan menjawab, dengan jawaban yang sama seperti yang saya berikan pada pertanyaan terkait ini , sehingga pengunjung di masa mendatang dapat merujuk kedua pertanyaan.
Saya tidak akan menyimpan nilai-nilai ini di tabel metadata posting, atau setidaknya tidak hanya di sana. Anda ingin meja dengan
post_id
,lat
,lon
kolom, sehingga Anda dapat menempatkan indekslat, lon
dan query pada itu. Ini seharusnya tidak terlalu sulit untuk tetap up to date dengan kait di pos simpan dan perbarui.Saat Anda query database, Anda mendefinisikan kotak pembatas di sekitar titik awal, sehingga Anda bisa melakukan kueri yang efisien untuk semua
lat, lon
pasangan antara perbatasan utara-selatan dan timur-barat kotak.Setelah Anda mendapatkan hasil yang dikurangi ini, Anda dapat melakukan perhitungan jarak yang lebih maju (arah mengemudi aktual atau sebenarnya) untuk menyaring lokasi yang berada di sudut kotak pembatas dan karenanya lebih jauh dari yang Anda inginkan.
Di sini Anda menemukan contoh kode sederhana yang berfungsi di area admin. Anda perlu membuat sendiri tabel database tambahan. Kode ini dipesan dari yang paling menarik hingga yang paling tidak menarik.
sumber
Saya terlambat ke pesta yang satu ini, tapi melihat kembali ke sini,
get_post_meta
ini benar-benar masalah di sini, daripada query SQL yang Anda gunakan.Saya baru-baru ini harus melakukan pencarian geo yang serupa di situs yang saya jalankan, dan daripada menggunakan tabel meta untuk menyimpan lat dan lon (yang membutuhkan dua gabungan terbaik untuk mencari dan, jika Anda menggunakan get_post_meta, dua database tambahan kueri per lokasi), saya membuat tabel baru dengan tipe data TITIK geometri terindeks spasial.
Permintaan saya sangat mirip dengan milik Anda, dengan MySQL melakukan banyak pengangkatan (saya mengabaikan fungsi trigonometri dan menyederhanakan semuanya menjadi ruang dua dimensi, karena cukup dekat untuk keperluan saya):
di mana $ client_location adalah nilai yang dikembalikan oleh layanan pencarian geo IP publik (saya menggunakan geoio.com, tetapi ada sejumlah yang serupa.)
Ini mungkin tampak sulit, tetapi dalam mengujinya, secara konsisten mengembalikan 5 lokasi terdekat dari tabel 80.000 baris dalam waktu 0,4 detik.
Sampai MySQL meluncurkan fungsi DISTANCE yang sedang diusulkan, ini sepertinya cara terbaik yang saya temukan untuk mengimplementasikan pencarian lokasi.
EDIT: Menambahkan struktur tabel untuk tabel khusus ini. Ini adalah set daftar properti, jadi mungkin atau mungkin tidak mirip dengan use case lainnya.
The
geolocation
kolom adalah satu-satunya hal yang relevan untuk tujuan di sini; itu terdiri dari koordinat x (lon), y (lat) yang baru saja saya cari dari alamat setelah mengimpor nilai baru ke dalam basis data.sumber
Cukup pra-hitung jarak antara semua entitas. Saya akan menyimpannya dalam tabel database sendiri, dengan kemampuan untuk mengindeks nilai.
sumber