in How To

การคำนวณระยะห่างระหว่างจุดสองจุด (Latitude/Longitude points) ใน MySQL

วันนี้เขียนบันทึกสั้น ๆ หล่ะกัน  ^_^

สำหรับเราที่อยู่ในโลกยุคนี้ ปฏิเสธไม่ได้ว่าเราหนีบริการจากกูเกิลไปไม่ได้เลย และหนึ่งในบริการที่ใช้บ่อย ๆ ก็คือแผนที่ทั้งหาจุดสำคัญที่จะไป เส้นทางการเดินทาง และอื่น ๆ อีก

ในด้านสาธารณสุขเองก็เหมือนกันแผนที่ก็ยิ่งมีความสำคัญ อย่างเช่น การควบคุมแหล่งแพร่โรค (หมู่บ้านหรือชุมชน) ตัวนี้ก็ใช้เรื่องของแผนที่มาเกี่ยวข้องแต่ถึงอย่างงั้นก็ตามข้อมูลส่วนใหญ่ที่เราเก็บก็มักเป็นพิกัดละติจูด ลองจิจูด (Latitude/Longitude) และมีโปรแกรม/ทูลสักตัวมาทำงานคู่ด้วย

อย่ากระนั้นเลยบางทีสิ่งที่เราต้องการก็รอโปรแกรมหรือทูลมาทำงานได้ไม่ทันการณ์ ตัวอย่างเช่น “ขอรายชื่อ/บ้านของชาวบ้านที่อยู่ห่างจากบ้านที่พบผู้ป่วยไข้เลือดออกรัศมี 100 เมตร” แล้วสิ่งที่เรามี (พื้นฐาน) หล่ะมีอะไรบ้าง
– ข้อมูลพิกัดจาก HIS (Latitude/Longitude) มีเก็บ
– ทางเลือก โปรแกรม/ทูลก็ดีไปคลิก ๆ ค้นหา (มีเว็บ gisjhcis ให้ใช้นะครับ ตัวนี้ก็ใช้บริการ/API แผนที่จาก Google อีกต่อนึง) หรือคำนวณจากพิกัดที่เรามี
เรามันสายฮาร์ดคอร์อยู่แล้ว ทำเรื่องง่ายให้เป็นเรื่องยากสิ 5555 งั้นก็เริ่มกันเลย

  1. สร้างฟังก์ชั่นสำหรับการคำนวณระยะห่างจุดสองจุด (Latitude/Longitude points) ใน MySQL โดยใช้ Haversine formula รายละเอียดก็ไปอ่านต่อได้เลย
    DELIMITER $$
    DROP FUNCTION IF EXISTS haversine $$
    CREATE FUNCTION haversine (
            lat1 FLOAT, lon1 FLOAT,
            lat2 FLOAT, lon2 FLOAT
    ) RETURNS FLOAT
    NO SQL DETERMINISTIC
    BEGIN
        DECLARE r FLOAT unsigned DEFAULT 6372.8;
        DECLARE dLat FLOAT unsigned;
        DECLARE dLon FLOAT unsigned;
        DECLARE a FLOAT unsigned;
        DECLARE c FLOAT unsigned;
     
        SET dLat = RADIANS(lat2 - lat1);
        SET dLon = RADIANS(lon2 - lon1);
        SET lat1 = RADIANS(lat1);
        SET lat2 = RADIANS(lat2);
     
        SET a = POW(SIN(dLat / 2), 2) + COS(lat1) * COS(lat2) * POW(SIN(dLon / 2), 2);
        SET c = 2 * ASIN(SQRT(a));
        
        SET r = IF(htype = 'km', r, 3959);
        
        RETURN (r * c);
    END$$
     
    DELIMITER ;
  2. ลองทดสอบเรียกใช้งานฟังก์ชั่นดูจากพิกัดที่เรามี
    -- Ex
    SET @origin_lat0=15.829187;
    SET @origin_long0=105.262752;
    SET @origin_lat=15.828063;
    SET @origin_long=105.380678;
    
    SELECT ROUND(haversine(@origin_lat0, @origin_long0, @origin_lat, @origin_long), 2) AS distance_km;
    +-------------+
    | distance_km |
    +-------------+
    |       12.62 |
    +-------------+
    1 row in set (0.00 sec)
    
  3. ตรวจสอบว่าคลาดเคลื่อนมากน้อยแค่ไหน
  4. ทีนี้เราก็สามารถใช้ข้อมูลพิกัดจากตาราง house (ในที่นี้ใช้ HIS เป็น JHCIS ของกระทรวงฯ นะครับ) ได้เลย
  5. จบปิ๊งงงง ^_^

เพิ่มเติม
Fastest Way to Find Distance Between Two Lat/Long Points
Haversine formula
GISFORJHCIS

ป.ล.
เอาไปคำนวณระยะห่างระหว่างเราน่าจะไม่ได้