سؤال

لقد تمكنت من إنشاء وظيفة PHP لتحديد قائمة الرموز البريدية ضمن نطاق معين من رمز بريدي معين. ومع ذلك ، فإن مهمتي التالية أكثر تعقيدًا قليلاً.

دعنا نقول أن الجدول لديه الأعمدة التالية:

id,
username
info
latitude
longitude
range

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

عندما يقوم المستخدم بالبحث من خلال قاعدة البيانات ، يجب استرداد جميع السجلات لإحداثيات خط العرض وخط الطول ضمن قيمة النطاق من المستخدمين/الطويل.

لذلك ، مثال غير وظيفي للرمز باستخدام صيغة المسافة لتوضيح ذلك سيكون

$userLat = خط عرض المستخدم الذي يقوم بتشغيل البحث

$userLong = خط طول المستخدم الذي يقوم بتشغيل البحث

SELECT info FROM table 
WHERE sqrt(($userLat - lat)^2 - ($userLong - long)^2) <= range 
ORDER BY username ASC

سيكون ذلك مثاليًا ، لكنه غير صالح من وجهة نظر الترميز. هل هناك أي طريقة لتشغيل المقارنات أعلاه باستخدام PHP و MySQL في استعلام واحد؟ قد يتضمن ذلك القدرة على تشغيل العمليات باستخدام قيم أعمدة متعددة من صف معين.


تحديث + حل

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

وظيفة مستخدم MySQL المحددة لبناء خطوط الطول

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

المحلول

هذه وظيفة Lil mysql الأنيقة التي كتبتها يجب أن تقوم بالتأكيد بالخدعة لك.

BEGIN
   DECLARE x decimal(18,15);
   DECLARE EarthRadius decimal(7,3);
   DECLARE distInSelectedUnit decimal(18, 10);

   IF originLatitude = relativeLatitude AND originLongitude = relativeLongitude THEN
          RETURN 0; -- same lat/lon points, 0 distance
   END IF;

   -- default unit of measurement will be miles
   IF measure != 'Miles' AND measure != 'Kilometers' THEN
          SET measure = 'Miles';
   END IF;

   -- lat and lon values must be within -180 and 180.
   IF originLatitude < -180 OR relativeLatitude < -180 OR originLongitude < -180 OR relativeLongitude < -180 THEN
          RETURN 0;
   END IF;

   IF originLatitude > 180 OR relativeLatitude > 180 OR originLongitude > 180 OR relativeLongitude > 180 THEN
         RETURN 0;
   END IF;

   SET x = 0.0;

   -- convert from degrees to radians
   SET originLatitude = originLatitude * PI() / 180.0,
       originLongitude = originLongitude * PI() / 180.0,
       relativeLatitude = relativeLatitude * PI() / 180.0,
       relativeLongitude = relativeLongitude * PI() / 180.0;

   -- distance formula, accurate to within 30 feet
   SET x = Sin(originLatitude) * Sin(relativeLatitude) + Cos(originLatitude) * Cos(relativeLatitude) * Cos(relativeLongitude - originLongitude);

   IF 1 = x THEN
          SET distInSelectedUnit = 0; -- same lat/long points
          -- not enough precision in MySQL to detect this earlier in the function
   END IF;

   SET EarthRadius = 3963.189;
   SET distInSelectedUnit = EarthRadius * (-1 * Atan(x / Sqrt(1 - x * x)) + PI() / 2);

   -- convert the result to kilometers if desired
   IF measure = 'Kilometers' THEN
          SET distInSelectedUnit = MilesToKilometers(distInSelectedUnit);
   END IF;

   RETURN distInSelectedUnit;
END

يتطلب الأمر OriginLatitude و Originlongitude و Relativelatitude و Relativelongitude وقياس المعلمات. يمكن أن يكون المقياس ببساطة Miles أو Kilometers

امل ان يساعد!

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