Kotchasan PHP Framework

การค้นหาพื้นที่ใกล้เคียง จาก ลองติจูด และ ละติจูด ด้วย MySql

เราสามารถ Query ข้อมูลสถานที่ ที่อยู่รอบๆจากตำแหน่ง ลองติจูด และ ละติจูดที่บันทึกไว้ในฐานข้อมูลได้ โดยอาศัยการคำนวณแบบพื้นฐาน (ในกรณีที่ไม่ได้เก็บข้อมูลในรูป Geolocation) ตัวอย่างนี้เป็นการ Query ข้อมูลจากสถานที่นะครับ โดยผมต้องการข้อมูลตำบลที่อยู่ใกล้เคียง ตำบลลาดหญ้า จังหวัดกาญจนบุรี ในระยะทางไม่เกิน 10 กม.
SELECT T.`TAMBON_T`,T.`AMPHOE_T`,T.`CHANGWAT_T`, 
(6371 * acos(cos(radians(Q.`lat`)) * cos(radians(T.`lat`)) * cos(radians(T.`long`) - radians(Q.`long`)) + sin(radians(Q.`lat`)) * sin(radians(T.`lat`)))) AS `distance` 
FROM `tambon` AS T
INNER JOIN `tambon` AS Q ON Q.`TAMBON_T`='ลาดหญ้า' AND Q.`CHANGWAT_T`='กาญจนบุรี'
HAVING `distance` < 10
ORDER BY `distance`

ได้ผลลัพท์ ตามนี้ ระยะทาง (distance) 0 คือจุดศูนย์กลางของตำแหน่งที่เราค้นหา ซึ่งก็คือตำบลลาดหญ้า และภายในรัศมีรอบๆ ไม่เกิน 10 กม. ก็จะมีตำบลต่างๆดังรูป
อธิบาย Query
  • คำสั่ง INNER JOIN ใช้สำหรับการ Query จุดศูนย์กลางที่ต้องการ (ตำบลลาดหญ้า จังหวัดกาญจนบุรี)
  • ซึ่งจะได้ผลลัพท์เป็นพิกัด Q.lat และ Q.long ใช้สำหรับส่งให้กับฟังก์ชั่นเพื่อคำนวณระยะห่างจากจุดศูนย์กลางเป็นวงกลมโดยรอบ (distance) หน่วยเป็น กิโลเมตร
  • HAVING ใช้สำหรับระบุขอบเขตที่ต้องการ (ซึ่งก็คือ 10 กม.)
  • ในกรณีที่ต้องการคำนวณพิกัดโดยการระบุตำแหน่ง เช่น การอ่านจาก GPS สามารถแทนค่าลงใน Q.lat และ Q.long ได้โดยตรง โดยไม่จำเป็นต้องใช้คำสั่ง INNER JOIN

หรือ หากต้องการหาระยะทางเป็นไมล์เราจะใช่ค่าคงที่ 3959 แทน 6371 ได้คำสั่ง SQL ตามด้านล่างนี้
SELECT T.`TAMBON_T`,T.`AMPHOE_T`,T.`CHANGWAT_T`, 
(3959 * acos(cos(radians(Q.`lat`)) * cos(radians(T.`lat`)) * cos(radians(T.`long`) - radians(Q.`long`)) + sin(radians(Q.`lat`)) * sin(radians(T.`lat`)))) AS `distance` 
FROM `tambon` AS T
INNER JOIN `tambon` AS Q ON Q.`TAMBON_T`='ลาดหญ้า' AND Q.`CHANGWAT_T`='กาญจนบุรี'
HAVING `distance` < 10
ORDER BY `distance`