مقدمة
مع التطوير الواسع النطاق للإنترنت عبر الهاتف المحمول اليوم ، أصبح تطوير التطبيق الخيار الأول للعديد من الشركات لدخول الإنترنت عبر الهاتف المحمول. قام المؤلف بتطوير العديد من التطبيقات ووجد أن العديد من التطبيقات لديها مثل هذه الوظيفة ، أي الحصول على أشخاص قريبين. كيف تحصل على أشخاص قريبين؟ في الواقع ، الأمر بسيط للغاية. إنه دائمًا ما يتم تسجيل معلومات إحداثيات المستخدم (خط العرض وخط الطول) في قاعدة البيانات ، ثم البحث عن جميع المستخدمين في قاعدة البيانات وموضع التنسيق الحالي ضمن نطاق معين بناءً على إحداثيات المستخدم الحالية.
في الواقع ، بالنسبة للمسافة بين موضوعين لا يتغير موقعهما الجغرافي ، فمن الأفضل أن تنقص النتيجة مباشرة. وهذا هو ، اكتبها مباشرة في التكوين.
على سبيل المثال ، ابحث عن محطة مترو الأنفاق بالقرب من منزلك.
في هذه الحالة ، بشكل عام ، لن يكون موضوع "الصفحة الرئيسية" "يركض" بسهولة. ليس من المنطقي حساب المسافة بمجرد كل استعلام. من الأفضل أن تستمر المسافة والاستعلام عنها مباشرة.
حالة أخرى:
احصل على محطة مترو الأنفاق بالقرب من موقع مستخدم التطبيق
في هذه الحالة ، يتغير الموقع الجغرافي للمستخدم. لذلك يجب حساب المسافة الفعلية في الوقت الحقيقي في كل مرة.
أفكار التنفيذ
عالج الأرض على أنها كرة قياسية واستخدم صيغة المسافة الكروية لحساب طول القوس للدائرة الكبيرة بين نقطتين على السطح الكروي.
مسافة كروية
GetDistance2 الثابتة العامة (Double Long1 ، Double Lat1 ، double Long2 ، double Lat2) {lat1 = rad (lat1) ؛ LAT2 = RAD (LAT2) ؛ مضاعفة A = LAT1 - LAT2 ؛ Double B = RAD (Long1 - Long2) ؛ Double SA2 = Math.sin (A / 2.0) ؛ Double SB2 = Math.sin (B / 2.0) ؛ إرجاع 2 * earth_mean_radius_km * math.asin (math.sqrt (sa2 * sa2 + math.cos (lat1) * math.cos (lat2) * sb2 * sb2)) ؛}فقط تعرف على خط العرض وخط الطول بين نقطتين.
بالطبع ، يجب وضع هذا الحساب في قاعدة البيانات ثم يتم فرزه مرة أخرى وفقًا للمسافة. فقط أحضر الصيغة أعلاه إلى SQL.
أمثلة على محطات المترو القريبة
مثال على الجدول لبناء محطة مترو الأنفاق
إنشاء محطة جدول (ID int auto_increment المفتاح الأساسي ، الاسم varchar (20) التعليق الفارغ "اسم محطة MRT" ، LNG Double Null Comment "longitude" ، LAT Double Null Comment 'Dimension') ؛
مثال SQL
setRetGgetLat = 31.175702 ؛ setRgetLng = 121.519095 ؛ Select S.ID ، S.Name ، S.Lng ، S.Lat ، Round (6378.138 * 2 * Asin (Sqrt (pow (sin ((targetlat * pi () / 180 - S.Lat *. targetlat * pi () / 180) * cos (s.lat * pi () / 180) * pow (sin ((targetlng * pi () / 180 - s.lng * pi () / 180) / 2) ، 2))) * 1000) كمحطة من المسافة من قبل المسافة ، s.idlimit 20 ؛
من بينها ، TargetLat و TargetLng هي المواقع الجغرافية للمستخدمين.
هذا يمكن أن يحقق بالفعل الهدف. ومع ذلك ، هذا هو حساب المسافة بين جميع البيانات والمستخدم أولاً ثم فرزها.
عندما يكون عدد محطات مترو الأنفاق أكبر من اللازم ، ستكون هذه العملية أقل أناقة. ليس فقط أنه ليس أنيقًا بما فيه الكفاية ، ولكنه أيضًا فعال للغاية.
تحسين
في الواقع ، يمكن تصفية الكثير من البيانات قبل حساب المسافة.
ليست هناك حاجة لحساب المسافة بين محطة مترو الأنفاق الأمريكية عند حساب المسافة بين محطات مترو الأنفاق شنغهاي.
يمكن ترشيح ذلك بعض البيانات غير المرغوب فيها أولاً في معظم التطبيقات.
على سبيل المثال ، عندما تميز البيانات المدن ، يمكنك تغيير SQL إلى ما يلي:
set RARGETLAT = 31.175702 ؛ SETARGETLNG = 121.519095 ؛ SET @CITYID = 605 ؛ SELECT S.ID ، S.NAME ، S.LNG ، S.LAT ، Round (6378.138 * 2 * ASIN (SQRT (SIN ((targetlat * 2) + cos (targetlat * pi () / 180) * cos (s.lat * pi () / 180) * pow (sin ((targetlng * pi () / 180 - s.lng * pi () / 180) / 2) ، 2)) 20 ؛
التحسن أعلاه هو إزالة معظم البيانات المراد حسابها قبل الحساب. عند البحث عن محطة مترو أنفاق Changsha ، ليست هناك حاجة للبحث في شنغهاي أولاً.
بالطبع ، هذا الموقف مميز بعض الشيء لأنه يمكنك معرفة المدينة التي يوجد بها المستخدم مسبقًا.
تحسن آخر هو:
مع موقع المستخدم كمركز ، ارسم دائرة بنصف قطر R ، ثم قم بإخراج مدى خطوط الطول والطول من الربع الخارجي للدائرة. قبل حساب المسافة ، قم بتصفية البيانات خارج خط الطول وخط الطول في الرباعي الخارجي.
حدد دائرة نصف قطرها مثالية وتصفية البيانات التي لا يمكنها تلبية المعايير أولاً.
النطاق الرباعي الخارجي الخارجي العكسي
/*** احصل على خط العرض وخط الطول من الرؤوس الأربع للنقطة عند خط العرض والطول المحدد {Code Radius} km Quadrilateral Office (chick intain ، يجب أن يكون مكعبًا خارجيًا) tuple4 <borted> calcboxbydistfrompt (double lng ، double lat ، double radius) {spatialContext context = spatialContext.geo ؛ مستطيل المستطيل = context.getDistcalc () // .calcboxbydistfrompt (// context.makepoint (lng ، lat) ، // radius * com.spatial4j.core.distance.distanceutils.km_to_deg ، السياق ، null //) ؛ إرجاع tuple4 <> (rectangle.getminx () ، rectangle.getmaxx () ، rectangle.getminy () ، rectangle.getmaxy ()) ؛}إحداثيات Maven المستخدمة هنا هي على النحو التالي:
<Rependency> <roupeD> com.spatial4j </rougeid> <StifactId> spatial4j </stifactid> <الإصدار> 0.5 </version> </prement>
في هذا الوقت ، يمكن تغيير SQL إلى هذا:
setRetGgetLat = 31.175702 ؛ setRgetLng = 121.519095 ؛ Select S.ID ، S.Name ، S.Lng ، S.Lat ، Round (6378.138 * 2 * Asin (Sqrt (pow (sin ((targetlat * pi () / 180 - S.Lat *. @targetlat * pi () / 180) * cos (s.lat * pi () / 180) * pow (sin ((targetlng * pi () / 180 - s.lng * pi () / 180) / 2) ، 2)) * 1000) كقوانين مسافة (s.lng بين $ {lng1} $ {lat1} و $ {lat2}) من خلال المسافة ASC ، s.idlimit 20 ؛إن LNG1 أعلاه ، LNG2 ، LAT1 ، LAT2 هو نطاق الرباعي الخارجي.
المعلومات المذكورة: http://blog.csdn.net/a364572/article/details/50483568
عينة رمز المصدر
الخدمة: https: //github.com/hylexus/bl ...
تهيئة البيانات: https: //github.com/hylexus/bl ...
لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون لمحتوى هذه المقالة قيمة مرجعية معينة لدراسة أو عمل الجميع. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل. شكرا لك على دعمك إلى wulin.com.