سؤال

لقد وجدت وظيفة في صفحة PHP تحسب عدد الأميال بين نقطتين، ولكنها معيبة.من المفترض أن تعمل مع خرائط جوجل، لكن الفرق في المسافات يتراوح من 1.3 إلى 1.65 مرة في خرائط جوجل (وهي أكثر دقة).

ها هي الوظيفة:

$M =  69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2))));

أجد الأمر معقدًا بعض الشيء ولا أعرف الكثير عن الهندسة لمعرفة ما إذا كان هذا صحيحًا أم لا.

هل يمكن لشخص لديه المزيد من المعرفة إلقاء نظرة على هذا ومعرفة ما هو الخطأ فيه؟

هل كانت مفيدة؟

المحلول

وربما كنت مقارنة "المسافة كما الغراب يطير" (خط مباشر بين نقطتين) مع مسافة قصيرة بالسيارة؟

وأيضا، انظر في هذا المنصب للحصول على حساب المسافة بين نقطتين في PHP.

نصائح أخرى

أنت تبحث عن Haversine صيغة لحساب المسافة بين نقطتين من أن لديك خطوط الطول والعرض ل.

ووتنفيذ واضحة منه في جافا سكريبت يمكن العثور عليها هنا ، والتي ينبغي أن يكون من السهل تحويلها إلى PHP.

هناك على الأقل ثلاث طرق مختلفة لحساب المسافة على سطح الأرض، والتي تختلف في الدقة والحساب المطلوب.

  1. القانون الكروي لجيب التمام ليست دقيقة للغاية ، بسيطة للغاية لحساب
  2. صيغة هافيرسين [دقيق باستثناء المسافات الأصغر، ولا يزال حسابه سهلًا نسبيًا]
  3. صيغة فنسنتي [دقيق للغاية ويمكن استخدام عدة نماذج إهليلجية مختلفة لسطح الأرض، وأكثر تعقيدًا في الحساب]

يبدو أن المثال الذي قدمته هو قانون حساب جيب التمام، في حين أن خرائط Google أكثر دقة لأنها تستخدم صيغة فينسنتي.(أجد أن رابط Vincenty يشرح الصيغة بتفاصيل أفضل من صفحة Wikipedia الخاصة به)

يحرر:لقد رأيت تعليقًا أعلاه مفاده أن الخطأ الناتج عن الانحراف في سطح الأرض هو خطأ تافه ولا يمكن أن يشكل الخطأ الذي تراه.وأخشى أن هذا ينطبق فقط على مسافات كبيرة جدًا.وعلى مسافات تصل إلى بضع مئات من الكيلومترات أو أقل، يمكن أن تكون الأخطاء غير تافهة بالتأكيد.

وهنا هو نسخة أكثر بساطة، ولكن لم تكن دقيقة لأماكن بعيدة جدا:

    const ONE_DEGREE = 111120;

public function distance( $point ) {
    $coef = cos( $this->getLatitude() / 180 * M_PI );
    $x = $this->getLatitude() - $point->getLatitude();
    $y = ( $this->getLongitude() - $point->getLongitude() ) * $coef;
    $result = sqrt( $x * $x + $y * $y ) * self::ONE_DEGREE;
    return $result;
}

ونقطة $ و $ هذه هي الحالات من الدرجة الموقع مع getLatitude () وgetLongitude () الأساليب.

لا أعرف أي شيء عن الهندسة أيضًا، لكن جوجل اقترحت ذلك هذه الصفحة.ربما ستجده مفيدًا

ويبدو أن صيغة دقيقة - انظر، على سبيل المثال، ويكيبيديا على "مسافة الدائرة الكبرى ". عامل 69.09 في الجبهة هو، في اعتقادي، عدد الأميال في درجة واحدة تقاس على طول الدائرة الكبرى (مثل ميل في 1 درجة من خط الطول عند خط الاستواء)، لذلك إجابتك ستكون في ميل.

وفكرة jonstjohn والتي قد تكون غير صحيح مقارنة المسافة في خط مستقيم مع مسافة قصيرة بالسيارة يبدو مثل التفسير الأكثر ترجيحا بالنسبة لي.

تحرير : أو يمكن أن يكون الخطأ التقريب ويكيبيديا يذكر، إذا كنت تعمل مع فصل الصغيرة. ولكن أود أن أشير إصبعي في قيادة الفرق المباشر / المسافة أولا.

ويبدو أن حساب كنت الرجوع يستخدم نظام الإحداثيات الكروي. الصيغة صحيحة تقريبا. جزء من ما يمكن رمي الحساب الخاص بك قبالة هو دائرة نصف قطرها الذي تستخدمه. على 69.09 هو نصف قطر الكرة (الأرض في هذه الحالة). كما تعلمون، والأرض ليست في الحقيقة المجال، أكثر من الإهليلجي. كنت تشير الى محاولة صياغة أدناه:

3963 * acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2)));

لنتائج أكثر دقة، فأنت تريد أن تستخدم Vincenty أو Haversine الحسابات.

وتحرير: لتوضيح، أنا لا أسعى ليعني أن الجزء الأكبر من الخطأ الذي تبلغ عنه ويرجع ذلك إلى استخدام كروية تنسيق حساب. هذا الخطأ هو أصغر بكثير من ما ترونه. وكان الهدف من تعديل صيغة I زودت أن يكون نسخة أوضح من الصيغة، كما كان 69.09 وقيمة نصف قطر الأرض تعديلها لنظام درجة، وهو أقل سهولة من استخدام ببساطة راديان. بالإضافة إلى ذلك، فإنه من الجدير بالذكر أن لحساب مسافات صغيرة جدا، وذلك باستخدام الصيغة أعلاه غير دقيقة للغاية (إلى حوالي 1M المسافات) طالما ان النظام يعمل به حساب مع المنازل العشرية بما فيه الكفاية. استخدام تطفو في الحوسبة الحديثة تمنحك هذه الدقة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top