MySQL में अक्षांश / देशांतर दूरी गणना का समर्थन करने वाला कोई भू-स्थानिक विस्तार कार्य नहीं है। MySQL जैसा है 5.7
।
आप पृथ्वी की सतह पर निकटता मंडल मांग रहे हैं। आपने अपने प्रश्न में उल्लेख किया है कि आपके flags
. में प्रत्येक पंक्ति के लिए आपके पास अक्षांश/लंबे मान हैं तालिका, और यूनिवर्सल ट्रांसवर्स मर्केटर
भी (UTM) कई अलग-अलग UTM क्षेत्रों
में से एक में अनुमानित मान . अगर मुझे अपने यूके आयुध सर्वेक्षण के नक्शे ठीक से याद हैं, तो UTM उन मानचित्रों पर वस्तुओं का पता लगाने के लिए उपयोगी है।
एक ही क्षेत्र में two दो बिंदुओं के बीच की दूरी की गणना करना एक साधारण बात है UTM में:कार्टेशियन दूरी चाल है। लेकिन, जब बिंदु अलग-अलग क्षेत्रों में होते हैं, तो वह गणना काम नहीं करती है।
तदनुसार, आपके प्रश्न में वर्णित एप्लिकेशन के लिए, ग्रेट सर्कल डिस्टेंस , जिसकी गणना हावर्सिन या किसी अन्य उपयुक्त सूत्र का उपयोग करके की जाती है।
MySQL, भू-स्थानिक एक्सटेंशन के साथ संवर्धित, ज्यामितीय आदिम के रूप में विभिन्न प्लानर आकृतियों (अंक, पॉलीलाइन, बहुभुज, और आगे) का प्रतिनिधित्व करने के तरीके का समर्थन करता है। MySQL 5.6 एक अनियंत्रित दूरी फ़ंक्शन को लागू करता है st_distance(p1, p2)
. हालांकि, यह फ़ंक्शन कार्टेशियन दूरियां लौटाता है। तो यह पूरी तरह से अनुपयुक्त है अक्षांश और देशांतर आधारित गणना के लिए। समशीतोष्ण अक्षांशों पर अक्षांश की एक डिग्री देशांतर (पूर्व-पश्चिम) की डिग्री के रूप में सतह की दूरी (उत्तर-दक्षिण) से लगभग दोगुनी हो जाती है, क्योंकि अक्षांश रेखाएं ध्रुवों के निकट एक साथ बढ़ती हैं।
इसलिए, एक गोलाकार निकटता सूत्र को वास्तविक अक्षांश और देशांतर का उपयोग करने की आवश्यकता होती है।
अपने आवेदन में, आप सभी flags
. पा सकते हैं किसी दिए गए latpoint,longpoint
. के दस क़ानून मील के भीतर अंक इस तरह की एक क्वेरी के साथ:
SELECT id, coordinates, name, r,
units * DEGREES(ACOS(LEAST(1.0, COS(RADIANS(latpoint))
* COS(RADIANS(latitude))
* COS(RADIANS(longpoint) - RADIANS(longitude))
+ SIN(RADIANS(latpoint))
* SIN(RADIANS(latitude))))) AS distance
FROM flags
JOIN (
SELECT 42.81 AS latpoint, -70.81 AS longpoint,
10.0 AS r, 69.0 AS units
) AS p ON (1=1)
WHERE MbrContains(GeomFromText (
CONCAT('LINESTRING(',
latpoint-(r/units),' ',
longpoint-(r /(units* COS(RADIANS(latpoint)))),
',',
latpoint+(r/units) ,' ',
longpoint+(r /(units * COS(RADIANS(latpoint)))),
')')), coordinates)
अगर आप 20 किमी के भीतर बिंदु खोजना चाहते हैं, तो क्वेरी की इस पंक्ति को बदलें
20.0 AS r, 69.0 AS units
इसके लिए, उदाहरण के लिए
20.0 AS r, 111.045 AS units
r
वह त्रिज्या है जिसमें आप खोजना चाहते हैं। units
पृथ्वी की सतह पर प्रति डिग्री अक्षांश की दूरी इकाइयाँ (मील, किमी, फ़र्लांग, जो भी आप चाहते हैं) हैं।
यह क्वेरी MbrContains
. के साथ एक बाउंडिंग lat/long का उपयोग करती है उन बिंदुओं को बाहर करने के लिए जो निश्चित रूप से आपके शुरुआती बिंदु से बहुत दूर हैं, फिर शेष बिंदुओं के लिए दूरी उत्पन्न करने के लिए महान सर्कल दूरी सूत्र का उपयोग करता है। एक इस सबका स्पष्टीकरण यहां पाया जा सकता है
. यदि आपकी तालिका MyISAM पहुंच पद्धति का उपयोग करती है और इसमें स्थानिक अनुक्रमणिका है, MbrContains
आपको तेज़ी से खोजने के लिए उस अनुक्रमणिका का उपयोग करेगा।
अंत में, उपरोक्त क्वेरी आयत के भीतर सभी बिंदुओं का चयन करती है। इसे सर्कल में केवल बिंदुओं तक सीमित करने के लिए, और उन्हें निकटता से क्रमबद्ध करने के लिए, क्वेरी को इस तरह लपेटें:
SELECT id, coordinates, name
FROM (
/* the query above, paste it in here */
) AS d
WHERE d.distance <= d.r
ORDER BY d.distance ASC