PHP และ SQL: คำนวณหรือค้นหาระยะห่างของวงกลมใหญ่ระหว่างจุดละติจูดและลองจิจูดด้วยสูตร Haversine

สูตร Haversine - คำนวณระยะทาง Great Circle ด้วย PHP หรือ MySQL

เดือนนี้ฉันได้เขียนโปรแกรมใน PHP และ MySQL เกี่ยวกับ GIS ค่อนข้างน้อย การสอดแนมรอบ ๆ เน็ตฉันมีช่วงเวลาที่ยากลำบากในการค้นหาไฟล์ การคำนวณทางภูมิศาสตร์ เพื่อหาระยะห่างระหว่างสถานที่สองแห่งดังนั้นฉันจึงต้องการแบ่งปันที่นี่

แผนที่เที่ยวบินยุโรปด้วยระยะทางวงกลมที่ดี

วิธีง่ายๆในการคำนวณระยะห่างระหว่างจุดสองจุดคือการใช้สูตรพีทาโกรัสเพื่อคำนวณด้านตรงข้ามมุมฉากของรูปสามเหลี่ยม (A² + B² = C²) นี้เรียกว่า ระยะทางแบบยุคลิด.

นั่นเป็นการเริ่มต้นที่น่าสนใจ แต่ใช้ไม่ได้กับภูมิศาสตร์เนื่องจากระยะห่างระหว่างเส้นละติจูดและลองจิจูดคือ ไม่ใช่ระยะทางที่เท่ากัน ห่างกัน เมื่อคุณเข้าใกล้เส้นศูนย์สูตรมากขึ้นเส้นละติจูดจะห่างกันมากขึ้น หากคุณใช้สมการสามเหลี่ยมอย่างง่ายบางอย่างมันอาจวัดระยะทางได้อย่างแม่นยำในตำแหน่งหนึ่งและอีกตำแหน่งหนึ่งผิดอย่างมากเนื่องจากความโค้งของโลก

ระยะทาง Great Circle

เส้นทางที่เดินทางเป็นระยะทางไกลทั่วโลกเรียกว่า ระยะทาง Great Circle. นั่นคือ…ระยะทางที่สั้นที่สุดระหว่างสองจุดบนทรงกลมนั้นแตกต่างจากจุดในแผนที่แบน รวมเข้ากับข้อเท็จจริงที่ว่าเส้นละติจูดและลองจิจูดไม่เท่ากัน ... และคุณมีการคำนวณที่ยากลำบาก

นี่คือคำอธิบายวิดีโอที่ยอดเยี่ยมเกี่ยวกับวิธีการทำงานของ Great Circles

สูตร Haversine

ระยะทางโดยใช้ความโค้งของโลกรวมอยู่ใน สูตร Haversineซึ่งใช้ตรีโกณมิติเพื่อให้เกิดความโค้งของโลก เมื่อคุณหาระยะห่างระหว่างสถานที่ 2 แห่งบนโลก (ขณะที่อีกาบิน) เส้นตรงคือส่วนโค้งจริงๆ

สิ่งนี้ใช้ได้ในเที่ยวบิน - คุณเคยดูแผนที่จริงของเที่ยวบินและสังเกตว่ามีโค้งหรือไม่? นั่นเป็นเพราะมันสั้นกว่าที่จะบินในซุ้มระหว่างสองจุดมากกว่าตรงไปยังที่ตั้ง

PHP: คำนวณระยะทางระหว่าง 2 จุดละติจูดและลองจิจูด

อย่างไรก็ตามนี่คือสูตร PHP สำหรับการคำนวณระยะห่างระหว่างจุดสองจุด (พร้อมกับการแปลงไมล์เทียบกับกิโลเมตร) ปัดเศษเป็นทศนิยมสองตำแหน่ง

function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'miles') {
  $theta = $longitude1 - $longitude2; 
  $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta))); 
  $distance = acos($distance); 
  $distance = rad2deg($distance); 
  $distance = $distance * 60 * 1.1515; 
  switch($unit) { 
    case 'miles': 
      break; 
    case 'kilometers' : 
      $distance = $distance * 1.609344; 
  } 
  return (round($distance,2)); 
}

SQL: การดึงข้อมูลทั้งหมดภายในช่วงโดยการคำนวณระยะทางเป็นไมล์โดยใช้ละติจูดและลองจิจูด

นอกจากนี้ยังสามารถใช้ SQL เพื่อทำการคำนวณเพื่อค้นหาระเบียนทั้งหมดภายในระยะทางที่กำหนด ในตัวอย่างนี้ฉันจะค้นหา MyTable ใน MySQL เพื่อค้นหาระเบียนทั้งหมดที่น้อยกว่าหรือเท่ากับตัวแปร $ distance (เป็นไมล์) ไปยังตำแหน่งของฉันที่ $ latitude และ $ longitude:

แบบสอบถามสำหรับการดึงระเบียนทั้งหมดภายในไฟล์ ระยะทาง โดยการคำนวณระยะทางเป็นไมล์ระหว่างละติจูดและลองจิจูดสองจุดคือ:

$query = "SELECT *, (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180)) + cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180)))) * 180/pi()) * 60 * 1.1515) as distance FROM `table` WHERE distance <= ".$distance."

คุณจะต้องปรับแต่งสิ่งนี้:

  • ลองจิจูด $ - นี่คือตัวแปร PHP ที่ฉันส่งผ่านลองจิจูดของจุด
  • ละติจูด $ - นี่คือตัวแปร PHP ที่ฉันส่งผ่านลองจิจูดของจุด
  • ระยะทาง $ - นี่คือระยะทางที่คุณต้องการค้นหาระเบียนทั้งหมดน้อยกว่าหรือเท่ากับ
  • ตาราง - นี่คือตาราง ... คุณจะต้องแทนที่ด้วยชื่อตารางของคุณ
  • ละติจูด - นี่คือเขตข้อมูลของละติจูดของคุณ
  • ลองจิจูด - นี่คือช่องลองจิจูดของคุณ

SQL: การดึงข้อมูลทั้งหมดภายในช่วงโดยการคำนวณระยะทางเป็นกิโลเมตรโดยใช้ละติจูดและลองจิจูด

และนี่คือแบบสอบถาม SQL โดยใช้กิโลเมตรใน MySQL:

$query = "SELECT *, (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180)) + cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`) * pi()/180)))) * 180/pi()) * 60 * 1.1515 * 1.609344) as distance FROM `table` WHERE distance <= ".$distance."

คุณจะต้องปรับแต่งสิ่งนี้:

  • ลองจิจูด $ - นี่คือตัวแปร PHP ที่ฉันส่งผ่านลองจิจูดของจุด
  • ละติจูด $ - นี่คือตัวแปร PHP ที่ฉันส่งผ่านลองจิจูดของจุด
  • ระยะทาง $ - นี่คือระยะทางที่คุณต้องการค้นหาระเบียนทั้งหมดน้อยกว่าหรือเท่ากับ
  • ตาราง - นี่คือตาราง ... คุณจะต้องแทนที่ด้วยชื่อตารางของคุณ
  • ละติจูด - นี่คือเขตข้อมูลของละติจูดของคุณ
  • ลองจิจูด - นี่คือช่องลองจิจูดของคุณ

ฉันใช้รหัสนี้ในแพลตฟอร์มการทำแผนที่ระดับองค์กรที่เราใช้กับร้านค้าปลีกที่มีสาขามากกว่า 1,000 แห่งทั่วอเมริกาเหนือและทำงานได้ดี

77 คอมเมนต์

  1. 1

    ขอบคุณมากสำหรับการแบ่งปัน นี่เป็นงานคัดลอกและวางที่ง่ายและใช้งานได้ดี คุณช่วยฉันได้มากเวลา
    FYI สำหรับทุกคนที่ย้ายไปที่ C:
    double deg2rad (ดับเบิ้ล deg) {return deg * (3.14159265358979323846 / 180.0); }

  2. 2

    การโพสต์ที่ดีมาก - ทำได้ดีมาก - ฉันต้องเปลี่ยนชื่อของตารางที่ถือ lat-long เท่านั้น มันทำงานได้ค่อนข้างเร็วสำหรับ .. ฉันมี lat-long จำนวนน้อยพอสมควร (<400) แต่ฉันคิดว่ามันจะปรับขนาดได้ดี เว็บไซต์ที่ดีเช่นกัน - ฉันเพิ่งเพิ่มลงในบัญชี del.icio.us ของฉันและจะกลับมาตรวจสอบเป็นประจำ

  3. 4
  4. 5
  5. 8

    ฉันคิดว่า SQL ของคุณต้องการคำสั่งที่มี
    แทนที่จะเป็น WHERE ระยะทาง <= $ ระยะทางที่คุณอาจต้องการ
    ใช้ HAVING distance <= $ distance

    ไม่งั้นก็ขอบคุณที่ช่วยฉันประหยัดเวลาและพลังงาน

    • 9

      สวัสดีเดวิด

      หากคุณกำลังทำคำสั่ง GROUP BY ประเภทใด ๆ คุณจะต้องมี HAVING ฉันไม่ได้ทำอย่างนั้นในตัวอย่างด้านบน

      ดั๊ก

  6. 10
  7. 11
  8. 12

    ขอบคุณมากสำหรับการแบ่งปันรหัสนี้ ช่วยให้ฉันประหยัดเวลาในการพัฒนาได้มาก นอกจากนี้ขอขอบคุณผู้อ่านของคุณที่ชี้ให้เห็นว่าคำสั่ง HAVING นั้นจำเป็นสำหรับ MySQL 5.x เป็นประโยชน์มาก

  9. 14

    สูตรข้างต้นช่วยให้ฉันประหยัดเวลาได้มาก ขอบคุณมาก.
    ฉันต้องสลับระหว่างรูปแบบ NMEA กับองศาด้วย ฉันพบสูตรที่ URL นี้ที่ด้านล่างของหน้า http://www.errorforum.com/knowledge-base/16273-converting-nmea-sentence-latitude-longitude-decimal-degrees.html

    ไม่มีใครรู้วิธีตรวจสอบสิ่งนี้?

    ขอขอบคุณ!
    Harry

  10. 15
  11. 16

    ฉันยังพบว่า WHERE ไม่ได้ผลสำหรับฉัน เปลี่ยนเป็น HAVING และทุกอย่างทำงานได้อย่างสมบูรณ์แบบ ตอนแรกฉันไม่ได้อ่านความคิดเห็นและเขียนใหม่โดยใช้การเลือกที่ซ้อนกัน ทั้งสองอย่างจะทำงานได้ดี

  12. 17
  13. 18

    เป็นประโยชน์อย่างไม่น่าเชื่อขอบคุณมาก! ฉันมีปัญหาบางอย่างกับ "HAVING" ใหม่แทนที่จะเป็น "WHERE" แต่เมื่ออ่านความคิดเห็นที่นี่ (หลังจากบดฟันด้วยความหงุดหงิดประมาณครึ่งชั่วโมง = P) ฉันก็ทำงานได้ดี ขอบคุณครับ ^ _ ^

  14. 19
  15. 20

    โปรดทราบว่าคำสั่งที่เลือกเช่นนั้นจะมีความเข้มข้นในการคำนวณมากและช้า หากคุณมีข้อความค้นหาเหล่านี้จำนวนมากอาจทำให้สิ่งต่าง ๆ ล้มเหลวได้อย่างรวดเร็ว

    วิธีการที่เข้มข้นน้อยกว่ามากคือการเรียกใช้การเลือก (หยาบ) ครั้งแรกโดยใช้พื้นที่ SQUARE ที่กำหนดโดยระยะทางที่คำนวณได้เช่น“ เลือก * จากชื่อตารางที่ละติจูดระหว่างละติจูด 1 และละติจูด 2 และลองจิจูดระหว่าง lon1 และ lon2” lat1 = targetlatitude - latdiff, lat2 = targetlatitude + latdiff คล้ายกับ lon latdiff ~ = ระยะทาง / 111 (สำหรับกม.) หรือระยะทาง / 69 สำหรับไมล์เนื่องจากละติจูด 1 องศาคือ ~ 111 กม. (การเปลี่ยนแปลงเล็กน้อยเนื่องจากโลกเป็นวงรีเล็กน้อย แต่เพียงพอสำหรับจุดประสงค์นี้) londiff = ระยะทาง / (abs (cos (deg2rad (ละติจูด)) * 111)) - หรือ 69 สำหรับไมล์ (คุณสามารถใช้สี่เหลี่ยมที่ใหญ่กว่าเล็กน้อยเพื่อพิจารณารูปแบบต่างๆได้) จากนั้นนำผลลัพธ์ของสิ่งนั้นและป้อนเข้าไปในรัศมีเลือก อย่าลืมคำนึงถึงพิกัดนอกขอบเขตนั่นคือช่วงของลองจิจูดที่ยอมรับได้คือ -180 ถึง +180 และช่วงละติจูดที่ยอมรับได้คือ -90 ถึง +90 ในกรณีที่ latdiff หรือ londiff ของคุณทำงานนอกช่วงนี้ . โปรดทราบว่าในกรณีส่วนใหญ่สิ่งนี้อาจใช้ไม่ได้เนื่องจากมีผลต่อการคำนวณในแนวข้ามมหาสมุทรแปซิฟิกจากขั้วโลกถึงขั้วโลกเท่านั้นแม้ว่ามันจะตัดกันบางส่วนของ chukotka และบางส่วนของอลาสก้า

    สิ่งที่เราทำได้คือการลดจำนวนคะแนนลงอย่างมากจากการคำนวณนี้ หากคุณมีจุดทั่วโลกหนึ่งล้านจุดในฐานข้อมูลที่กระจายอย่างเท่าเทียมกันและคุณต้องการค้นหาในระยะ 100 กม. การค้นหา (อย่างรวดเร็ว) ครั้งแรกของคุณจะมีพื้นที่ 10000 ตารางกิโลเมตรและอาจให้ผลลัพธ์ประมาณ 20 รายการ (ขึ้นอยู่กับการกระจายแบบสม่ำเสมอในช่วง พื้นที่ผิวประมาณ 500M ตร.กม. ) ซึ่งหมายความว่าคุณรันการคำนวณระยะทางที่ซับซ้อน 20 ครั้งสำหรับแบบสอบถามนี้แทนที่จะเป็นล้านครั้ง

    • 21

      ความผิดพลาดเล็กน้อยในตัวอย่าง…ซึ่งจะอยู่ในระยะ 50 กม. (ไม่ใช่ 100) เนื่องจากเรากำลังดู“ รัศมี” ของ…กำลังสองของเรา

      • 22

        คำแนะนำที่ยอดเยี่ยม! ฉันทำงานร่วมกับนักพัฒนาที่เขียนฟังก์ชันที่ดึงสี่เหลี่ยมด้านในจากนั้นฟังก์ชันวนซ้ำที่สร้าง 'สี่เหลี่ยม' รอบปริมณฑลเพื่อรวมและไม่รวมจุดที่เหลือ ผลลัพธ์ที่ได้คือผลลัพธ์ที่รวดเร็วอย่างไม่น่าเชื่อเขาสามารถประเมินหลายล้านจุดในหน่วยไมโครวินาที

        แนวทางของฉันข้างต้นคือ 'หยาบ' แต่มีความสามารถ ขอบคุณอีกครั้ง!

        • 23

          ดั๊ก

          ฉันพยายามใช้ mysql และ php เพื่อประเมินว่า lat long point อยู่ในรูปหลายเหลี่ยมหรือไม่ คุณทราบหรือไม่ว่าเพื่อนนักพัฒนาของคุณได้เผยแพร่ตัวอย่างวิธีการทำงานนี้ให้สำเร็จ หรือคุณรู้จักตัวอย่างที่ดี ขอบคุณล่วงหน้า.

  16. 24

    สวัสดีทุกคนนี่คือคำสั่ง SQL ทดสอบของฉัน:

    SELECT DISTINCT area_id, (
    (
    (
    acos( sin( ( 13.65 * pi( ) /180 ) ) * sin( (
    `lat_dec` * pi( ) /180 ) ) + cos( ( 13.65 * pi( ) /180 ) ) * cos( (
    `lat_dec` * pi( ) /180 )
    ) * cos( (
    ( 51.02 - `lon_dec` ) * pi( ) /180 )
    )
    )
    ) *180 / pi( )
    ) *60 * 1.1515 * 1.609344
    ) AS distance
    FROM `post_codes` WHERE distance <= 50

    และ Mysql กำลังบอกฉันว่าระยะทางไม่มีอยู่เป็นคอลัมน์ฉันสามารถใช้คำสั่งโดยฉันสามารถทำได้โดยไม่ต้อง WHERE และใช้งานได้ แต่ไม่ใช่กับมัน ...

  17. 26

    มันเยี่ยมมาก แต่มันก็เหมือนกับนกบิน จะเป็นการดีที่จะลองรวม Google Maps API เข้ากับสิ่งนี้ (อาจใช้ถนนเป็นต้น) เพียงเพื่อให้แนวคิดโดยใช้รูปแบบการขนส่งอื่น ฉันยังไม่ได้สร้างฟังก์ชันการหลอมจำลองใน PHP ซึ่งจะสามารถนำเสนอวิธีแก้ปัญหาพนักงานขายที่เดินทางได้อย่างมีประสิทธิภาพ แต่ฉันคิดว่าฉันอาจสามารถนำรหัสบางส่วนของคุณกลับมาใช้ใหม่ได้

  18. 27
  19. 28

    บทความดี! ฉันพบบทความมากมายที่อธิบายวิธีคำนวณระยะห่างระหว่างจุดสองจุด แต่ฉันกำลังมองหาข้อมูลโค้ด SQL จริงๆ

  20. 29
  21. 30
  22. 31
  23. 32
  24. 36

    2 วันของการวิจัยในที่สุดก็พบหน้านี้ที่แก้ปัญหาของฉัน ดูเหมือนว่าฉันจะดีกว่ากำจัด WolframAlpha ของฉันและแปรงคณิตศาสตร์ของฉัน การเปลี่ยนแปลงจาก WHERE เป็น HAVING มีสคริปต์ของฉันอยู่ในลำดับการทำงาน ขอบคุณ

  25. 37
    • 38

      ขอบคุณ Georgi ฉันยังคงไม่พบคอลัมน์ 'ระยะทาง' เมื่อฉันเปลี่ยน WHERE เป็น HAVING มันได้ผลอย่างมีเสน่ห์!

  26. 39

    ฉันหวังว่านี่จะเป็นหน้าแรกที่ฉันพบในสิ่งนี้ หลังจากลองใช้คำสั่งต่างๆมากมายนี่เป็นคำสั่งเดียวที่ทำงานได้อย่างถูกต้องและมีการเปลี่ยนแปลงเพียงเล็กน้อยเพื่อให้พอดีกับฐานข้อมูลของฉันเอง
    ขอบคุณมาก!

  27. 40

    ฉันหวังว่านี่จะเป็นหน้าแรกที่ฉันพบในสิ่งนี้ หลังจากลองใช้คำสั่งต่างๆมากมายนี่เป็นคำสั่งเดียวที่ทำงานได้อย่างถูกต้องและมีการเปลี่ยนแปลงเพียงเล็กน้อยเพื่อให้พอดีกับฐานข้อมูลของฉันเอง
    ขอบคุณมาก!

  28. 41
  29. 42
  30. 43
  31. 45
  32. 46
  33. 47

    ฉันรู้ว่าสูตรนี้ใช้ได้ผล แต่ฉันไม่เห็นว่ารัศมีของโลกถูกนำมาพิจารณาที่ใด ใครช่วยชี้แนะหน่อยได้ไหมคะ?

  34. 49
  35. 50
  36. 52

    ขอบคุณดักลาสแบบสอบถาม SQL เป็นสิ่งที่ฉันต้องการและฉันคิดว่าฉันต้องเขียนด้วยตัวเอง คุณช่วยฉันจากเส้นโค้งการเรียนรู้ละติจูดลองจิจูดเป็นชั่วโมง ๆ

  37. 53
  38. 55

    ขอบคุณสำหรับบทความดีๆนี้! เพิ่งทดสอบโค้ดบนฐานข้อมูลของฉันและใช้งานได้ดี! 

  39. 56

    ดักลาสขอบคุณสำหรับรหัสที่น่าทึ่งนี้ ฉันหัวแตกเกี่ยวกับวิธีการทำในพอร์ทัลชุมชน GPS ของฉัน คุณช่วยฉันได้หลายชั่วโมง

  40. 58

    ขอบคุณสำหรับการโพสต์บทความที่เป็นประโยชน์นี้  
    แต่ฉันอยากถามด้วยเหตุผลบางอย่าง
    วิธีการรับระยะห่างระหว่าง coords ภายใน mysql db และ coords ที่แทรกไปยัง php โดยผู้ใช้?
    เพื่ออธิบายให้ชัดเจนยิ่งขึ้น:
    1. ผู้ใช้ต้องใส่ [id] เพื่อเลือกข้อมูลที่ระบุจาก db และ coords ของผู้ใช้เอง
    2. ไฟล์ php รับข้อมูลเป้าหมาย (coords) โดยใช้ [id] จากนั้นคำนวณระยะทางระหว่างผู้ใช้และจุดเป้าหมาย

    หรือแค่ได้ระยะห่างจากโค้ดด้านล่าง?

    $ qry =“ SELECT *, (((acos (sin (“. $ latitude.” * pi () / 180)) * sin ((`Latitude` * pi () / 180)) + cos ((“. $ latitude.” * pi () / 180)) * cos ((`Latitude` * pi () / 180)) * cos (((“. $ longitude.” -` Longitude`) * pi () / 180) ))) * 180 / pi ()) * 60 * 1.1515 * 1.609344) เป็นระยะทางจาก "MyTable" WHERE distance> = ". $ distance" >>>> ฉันสามารถ "ออก" จากที่นี่ได้หรือไม่?
    ขอบคุณอีกครั้ง,
    ทิมมี่เอส

    • 59

      ไม่เป็นไรฉันเข้าใจแล้วว่า "ฟังก์ชัน" ทำงานอย่างไรใน php
      $ dis = getDistanceBetweenPointsNew ($ userLati, $ userLongi, $ lati, $ longi, $ unit = 'Km')
      ขอบคุณมาก!! 

  41. 60

    โอเคทุกอย่างที่ลองใช้ไม่ได้ผล ฉันหมายความว่าสิ่งที่ฉันทำงานได้ แต่ระยะทางนั้นไกลออกไป

    มีใครเห็นรหัสนี้ผิดปกติหรือไม่

    ถ้า (isset ($ _ POST ['ส่งแล้ว'])) {$ z = $ _POST ['zipcode']; $ r = $ _POST ['รัศมี']; echo“ ผลลัพธ์สำหรับ“. $ z; $ sql = mysql_query (“ SELECT DISTINCT m.zipcode, m.MktName, m.LocAddSt, m.LocAddCity, m.LocAddState, m.x1, m.y1, m.verified, z1.lat, z2.lon, z1 เมือง, z1.state จาก mrk m, zip z1, zip z2 โดยที่ m.zipcode = z1.zipcode และ z2.zipcode = $ z AND (3963 * acos (ตัดทอน (sin (z2.lat / 57.2958) * sin (m. y1 / 57.2958) + cos (z2.lat / 57.2958) * cos (m.y1 / 57.2958) * cos (m.x1 / 57.2958 - z2.lon / 57.2958), 8))) <= $ r ") หรือตาย (mysql_error ()); while ($ row = mysql_fetch_array ($ sql)) {$ store1 = $ row ['MktName']. "”; $ store = $ row ['LocAddSt'].””; $ store. = $ row ['LocAddCity'].”,“. $ row ['LocAddState']” “. $ row ['รหัสไปรษณีย์']; $ latitude1 = $ row ['lat']; $ longitude1 = $ row ['lon']; $ latitude2 = $ row ['y1']; $ longitude2 = $ row ['x1']; $ city = $ row ['เมือง']; $ state = $ row ['รัฐ']; $ dis = getnew ($ latitude1, $ longitude1, $ latitude2, $ longitude2, $ unit = 'Mi'); // $ dis = ระยะทาง ($ lat1, $ lon1, $ lat2, $ lon2); $ ตรวจสอบแล้ว = $ row ['ตรวจสอบแล้ว']; ถ้า ($ ตรวจสอบแล้ว == '1') {echo“”; ก้อง“”. $ store.””; ก้อง $ dis. " ห่างออกไป"; ก้อง“”; } else {echo“”. $ store.””; ก้อง $ dis. " ห่างออกไป"; ก้อง“”; }}}

    รหัส functions.php ของฉัน
    ฟังก์ชัน getnew ($ latitude1, $ longitude1, $ latitude2, $ longitude2, $ unit = 'Mi') {$ theta = $ longitude1 - $ longitude2; $ ระยะทาง = (sin (deg2rad ($ latitude1)) * sin (deg2rad ($ latitude2))) + (cos (deg2rad ($ latitude1)) * cos (deg2rad ($ latitude2)) * cos (deg2rad ($ theta)) ); $ distance = acos (ระยะทาง $); $ distance = rad2deg (ระยะทาง $); $ ระยะทาง = $ ระยะทาง * 60 * 1.1515; สวิตช์ ($ unit) {case 'Mi': break; กรณี 'Km': $ distance = $ distance * 1.609344; } กลับ (รอบ (ระยะทาง $ 2)); }

    ขอขอบคุณล่วงหน้า

  42. 61
  43. 62

    เฮ้ดักลาสบทความที่ดี ฉันพบว่าคำอธิบายของคุณเกี่ยวกับแนวคิดทางภูมิศาสตร์และโค้ดนั้นน่าสนใจมาก คำแนะนำเดียวของฉันคือเว้นวรรคและเยื้องรหัสเพื่อแสดง (เช่น Stackoverflow เป็นต้น) ฉันเข้าใจว่าคุณต้องการประหยัดพื้นที่ แต่การเว้นระยะห่าง / การเยื้องรหัสแบบเดิมจะทำให้ฉันในฐานะโปรแกรมเมอร์อ่านและแยกส่วนได้ง่ายขึ้นมาก อย่างไรก็ตามนั่นเป็นเรื่องเล็กน้อย ติดตามการทำงานที่ดี.

  44. 64
  45. 65

    ที่นี่ในขณะที่ใช้กับฟังก์ชั่นเราได้ระยะทางหนึ่งประเภท. ในขณะที่ใช้การสืบค้นระยะทางประเภทอื่น

  46. 66
  47. 67
  48. 68
  49. 69
  50. 70

    ดูเหมือนว่าเร็วกว่า (mysql 5.9) ที่จะใช้สองเท่าของสูตรในการเลือกและที่:
    $ formula =“ (((acos (sin ((“. $ latitude.” * pi () / 180)) * sin ((`Latitude` * pi () / 180)) + cos ((“. $ latitude. ” * pi () / 180)) * cos ((`ละติจูด` * pi () / 180)) * cos (((“. $ ลองจิจูด” -` ลองจิจูด ') * pi () / 180)))) * 180 / ปี่ ()) * 60 * 1.1515 * 1.609344)”;
    $ sql = 'SELECT *,'. $ สูตร ' เป็นระยะทางจากตาราง WHERE '.. $ สูตร' <= '. $ ระยะทาง;

  51. 71
  52. 72

    ขอบคุณมากสำหรับการตัดบทความนี้เป็นประโยชน์มาก
    PHP ถูกสร้างขึ้นในตอนแรกเป็นแพลตฟอร์มการเขียนสคริปต์แบบธรรมดาที่เรียกว่า“ หน้าแรกส่วนบุคคล” ปัจจุบัน PHP (ย่อมาจาก Hypertext Preprocessor) เป็นอีกทางเลือกหนึ่งของเทคโนโลยี Active Server Pages (ASP) ของ Microsoft

    PHP เป็นภาษาฝั่งเซิร์ฟเวอร์แบบโอเพ่นซอร์สซึ่งใช้สำหรับการสร้างเว็บเพจแบบไดนามิก สามารถฝังลงใน HTML โดยทั่วไป PHP จะใช้ร่วมกับฐานข้อมูล MySQL บนเว็บเซิร์ฟเวอร์ Linux / UNIX อาจเป็นภาษาสคริปต์ที่ได้รับความนิยมมากที่สุด

  53. 73

    ฉันพบว่าโซลูชันข้างต้นทำงานไม่ถูกต้อง
    ฉันต้องการเปลี่ยนเป็น:

    $ qqq =“ SELECT *, ((acos (sin ((“. $ latitude.” * pi () / 180)) * sin ((`latt` * pi () / 180)) + cos ((”. $ ละติจูด“ * pi () / 180)) * cos ((`latt` * pi () / 180)) * cos (((”. $ ลองจิจูด.“ -` longt`) * pi () / 180) ))) * 180 / pi ()) * 60 * 1.1515) เป็นระยะทางจาก `register`“;

  54. 75

    ขอบคุณครับที่สมบูรณ์แบบ .. แต่ผมมีคำถามหนึ่งข้อหากต้องการแสดงผลโดยไม่มีจุดทศนิยมแล้วจะทำอย่างไร .. ?

    ขอบคุณล่วงหน้า

  55. 76

    สวัสดีฉันต้องการความช่วยเหลือจากคุณจริงๆ

    ฉันได้ส่งคำขอไปยังเว็บเซิร์ฟเวอร์ของฉัน http://localhost:8000/users/findusers/53.47792/-2.23389/20/
    53.47792 = ละติจูด $
    -2.23389 = ลองจิจูด $
    และ 20 = ระยะทางที่ฉันต้องการเรียกคืน

    อย่างไรก็ตามการใช้สูตรของคุณจะดึงข้อมูลแถวทั้งหมดในฐานข้อมูลของฉัน

    $ results = DB :: select (DB :: raw (“ SELECT *, (((acos (sin ((“. $ latitude.” * pi () / 180)) * sin ((lat * pi () / 180 )) + cos ((“. $ latitude.” * pi () / 180)) * cos ((lat * pi () / 180)) * cos (((“. $ ลองจิจูด.” - lng) * pi ( ) / 180)))) * 180 / pi ()) * 60 * 1.1515 * 1.609344) เป็นระยะทางจากเครื่องหมาย HAVING distance> =“. $ distance));

    [{“ id”: 1,” name”:” Frankie Johnnie & Luigo Too”,” address”:” 939 W El Camino Real, Mountain View, CA”,” lat”: 37.386337280273,” lng”: - 122.08582305908, "ระยะทาง": 16079.294719663}, {"id": 2, "name": "Amici's East Coast Pizzeria", "ที่อยู่": "790 Castro St, Mountain View, CA", "lat": 37.387138366699, "lng": -122.08323669434, "ระยะทาง": 16079.175940152}, {"id": 3, "name": "Kapp's Pizza Bar & Grill", "ที่อยู่": "191 Castro St, Mountain View, CA", "lat": 37.393886566162, ” lng”: - 122.07891845703,” ระยะทาง”: 16078.381373826}, {“ id”: 4,” name”:” Round Table Pizza: Mountain View”,” address”:” 570 N Shoreline Blvd, Mountain View, CA”, "lat": 37.402652740479, "lng": - 122.07935333252, "ระยะทาง": 16077.420540582}, {"id": 5, "name": "Tony & Alba's Pizza & Pasta", "address": "619 Escuela Ave, Mountain View, CA”,” lat”: 37.394012451172,” lng”: - 122.09552764893,” distance”: 16078.563225154}, {“ id”: 6,” name”:” Wood-Fired Pizza ของออริกาโน”,” ที่อยู่”:” 4546 El Camino Real, Los Altos, CA”,” lat”: 37.401725769043,” lng”: - 122.11464691162,” distance”: 16077.937560795}, {“ id”: 7,” name”:“ The Bars and Grills”,” address”:” 24 Whiteley Street, Manchester”,” lat”: 53.485118865967,” lng”: - 2.1828699111938,” distance”: 8038.7620112314}]

    ฉันต้องการดึงข้อมูลเฉพาะแถวที่มีระยะทาง 20 ไมล์ แต่นำทุกแถวมา ได้โปรดฉันทำอะไรผิด

  56. 77

    ฉันกำลังมองหาคำค้นหาที่คล้ายกัน แต่เพิ่มขึ้นเล็กน้อย - โดยสรุปคือการจัดกลุ่มพิกัดทั้งหมดภายใน 2 ไมล์ของแต่ละพิกัดแล้วนับจำนวนพิกัดในแต่ละกลุ่มและส่งออกเพียงกลุ่มเดียวที่มีพิกัดมากที่สุด - แม้ว่า คุณมีกลุ่มมากกว่าหนึ่งกลุ่มในกลุ่มที่มีจำนวนพิกัดมากที่สุด – เพียงแค่ส่งออกกลุ่มสุ่มจากกลุ่มที่มีจำนวนมากที่สุดเท่ากัน –

คุณคิดอย่างไร?

ไซต์นี้ใช้ Akismet เพื่อลดสแปม เรียนรู้วิธีการประมวลผลข้อมูลความคิดเห็นของคุณ.