2012-07-20 4 views
20

अपडेट 16 वीं नवंबर 2012

मैं इस सवाल फिर से बढ़ाने के लिए, एक ठोस, अच्छा समाधान के लिए एक नया इनाम के साथ की पेशकश करना चाहते हैं। ऐसा लगता है कि केवल समाधान (shubhansh's answer) प्रभावी ढंग से काम नहीं करता है। मैं समझाऊंगा क्यों।परिणाम है कि डेटाबेस से मार्कर दायरों के भीतर गिर जाओ

सबसे पहले, इस लाइव नक्शा मैं दायरों और लोगों के साथ है, दायरों के red में हैं और लोगों blue में हैं।

enter image description here

जैसा कि आप देख सकते हैं, वहाँ eight दायरों के साथ इस नक्शे में two लोग, मूल रूप से मैं केवल एक ही व्यक्ति है जो Person A है हो रही है कर रहे हैं, लेकिन मैं नहीं मिल रहा है Person B , मुझे लगता है कि एसक्यूएल सही ढंग से इसे उठा नहीं रहा है जिसे मुझे व्यक्ति के त्रिज्या और मार्कर त्रिज्या से सटीक और सटीक होने की आवश्यकता है।

ऐसा लगता है कि त्रिज्या के अंदर क्या उठाया जाता है, न कि जो त्रिज्या को ओवरलैप करते हैं, मुझे किसी भी त्रिज्या के लिए किसी भी परिणाम को लेने में सक्षम होने की आवश्यकता होती है जो एक-दूसरे को ओवरलैप करता है।

मैं शुभांशु के उत्तर की तुलना में एक सटीक और सटीक एसक्यूएल की तलाश में हूं। आप नीचे पढ़ने के लिए पढ़ सकते हैं कि सटीक लोगों को कार्य करने और चुनने के लिए मुझे वास्तव में क्वेरी की आवश्यकता है।

डेटा, लोगों:

+-----------+-----------+--------+ 
| latitude | longitude | radius | 
+-----------+-----------+--------+ 
| 51.517395 | -0.053129 | 5.6 | 
| 51.506607 | -0.116129 | 0.7 | 
+-----------+-----------+--------+ 

कृपया ध्यान दें कि radius किलोमीटर की दूरी पर है।

+-----------+-----------+-----+ 
| latitude | longitude | km | 
+-----------+-----------+-----+ 
| 51.502117 | -0.103340 | 0.3 | 
| 51.498913 | -0.120850 | 0.7 | 
| 51.496078 | -0.108919 | 0.7 | 
| 51.496506 | -0.095873 | 0.7 | 
| 51.503399 | -0.090723 | 0.7 | 
| 51.508049 | -0.100336 | 0.7 | 
| 51.508797 | -0.112610 | 0.7 | 
| 51.505535 | -0.125227 | 0.7 | 
| 51.502331 | -0.108061 | 0.7 | 
+-----------+-----------+-----+ 

वर्तमान एसक्यूएल मैं का उपयोग करें: MySQL जो आप अपने प्रश्न का परीक्षण करने के लिए उपयोग कर सकते हैं

SELECT ppl.latitude, 
     ppl.longitude, 
     ppl.radius 
FROM 
(
    people ppl 
), 
(
    SELECT latitude, longitude 
    FROM radiuses 
) AS radius 
WHERE (POW((ppl.longitude - radius.longitude) * 111.12 * COS(ppl.latitude), 2) + POW((ppl.longitude - radius.longitude) * 111.12, 2)) <= 4 
GROUP BY ppl.id 

डेटा,

INSERT INTO radiuses (id, latitude, longitude, km) VALUES ('1', '51.502117', '-0.103340', '0.3'), ('2', '51.498913', '-0.120850', '0.7'), ('3', '51.496078', '-0.108919', '0.7'), ('4', '51.496506', '-0.095873', '0.7'), ('5', '51.503399', '-0.090723', '0.7'), ('6', '51.508049', '-0.100336', '0.7'), ('7', '51.508797', '-0.112610', '0.7'), ('8', '51.505535', '-0.125227', '0.7'), ('9', '51.502331', '-0.108061', '0.7'); 

INSERT INTO people (id, latitude, longitude, radius) VALUES ('1', '51.517395', '-0.053129', '5.6'), ('2', '51.506607', '-0.116129', '0.7'); 

पुरानी सारांश

नोट: सभी अक्षांश और रेखांश बस यादृच्छिक रूप से बनाए गए हैं।

मेरे पास एक नक्शा ऐपलेट है जो उपयोगकर्ता 1km त्रिज्या के साथ एक lat/lng स्थान के त्रिज्या रख सकता है।

अब, एक और उपयोगकर्ता है जो त्रिज्या मानचित्र पर किसी भी स्थान पर, प्रत्येक को 1 किमी त्रिज्या (ऊपर उपयोगकर्ता के समान) के साथ रख सकता है।

इस तरह की उपयोगकर्ता ए लाल है और उपयोगकर्ता बी नीला है।

enter image description here

मूल रूप से उपयोगकर्ता A भंडार एक मेज है कि इस तरह दिखता है में अपने दायरों:

+-----------+---------+-----------+-----------+ 
| radius_id | user_id | latitude | longitude | 
+-----------+---------+-----------+-----------+ 
|   1 |  1 | 81.802117 | -1.110035 | 
|   2 |  1 | 81.798272 | -1.144196 | 
|   3 |  1 | 81.726782 | -1.135919 | 
+-----------+---------+-----------+-----------+ 

और उपयोगकर्ता B भंडार एक और टेबल कि इस तरह दिखता है में अपने त्रिज्या - (ध्यान दें : वे केवल प्रति खाता 1 निर्देशांक स्टोर कर सकते हैं):

+---------+-----------+-----------+ 
| user_id | latitude | longitude | 
+---------+-----------+-----------+ 
|  6 | 81.444126 | -1.244910 | 
+---------+-----------+-----------+ 

मैप तस्वीर में त्रिज्या सर्किल छू रहे हैं, भले ही परिभाषित त्रिज्या के भीतर आने वाले उन उपयोगकर्ताओं को चुनने में सक्षम होना चाहते हैं। केवल केवल त्रिज्या लेने में सक्षम होगा, जब A और B नहीं।

मुझे यकीन है कि यह संभव है, लेकिन मुझे नहीं पता कि MySQL में इस तरह के सिस्टम के साथ कैसे आना है।

मुझे यह Google डेवलपर साइट पर मिल गया है, लेकिन यह सिर्फ इतना नहीं है कि मुझे क्या करना चाहिए।

संपादित: मैं, क्योंकि यह का उपयोग करता है 1 अक्षांश के लिए बाध्य एक अच्छा वाला पाया है, यह बहुत करीब है, लेकिन अभी भी नहीं है कि मैं क्या देख रहा हूँ और देशांतर निर्देशांक जब मैं एक टेबल में एकाधिक है।

+0

यह एक ऐसा उत्तर हो सकता है जो आपको एक संकेत देता है http://stackoverflow.com/questions/11502469/find-records-with-lattitude-and-logintude/11502530#11502530 आप बस 'WHERE दूरी <1234' जोड़ते हैं पूछताछ के लिए। – fdomig

उत्तर

6

आपकी ज्यामिति का आवश्यक बिंदु यह है कि यदि उनके केंद्रों के बीच की दूरी उनके त्रिज्या के योग से कम है तो दो मंडल ओवरलैप होती हैं। चूंकि हम तुलना कर रहे हैं, हम दूरी के वर्ग का उपयोग कर सकते हैं, क्योंकि इससे स्क्वायर रूट ऑपरेशन से बचा जाता है। मूल में, प्रत्येक त्रिज्या 1 पर तय किया जाता है, दो त्रिज्या का योग 2 होता है, और योग का वर्ग 4 होता है।

मूल प्रश्न और नए प्रश्न के बीच एक बड़ा अंतर है। पहले आपको फिक्स्ड त्रिज्या की सर्कल मिल गई है और दूसरी तरफ आपको अलग-अलग त्रिज्या की मंडल मिल गई है। तुलनात्मक अभिव्यक्ति [...distance^2...] <= 4 में स्थिर 4 को प्रतिस्थापित करने की आवश्यकता है, क्योंकि यह मूल के निश्चित त्रिज्या का एक आर्टिफैक्ट है। इसे लागू करने के लिए, क्वेरी में km फ़ील्ड जोड़ें। और जैसा कि आपको जांचना चाहिए, आप WHERE फ़िल्टर में ppl.radius का उपयोग नहीं कर रहे थे, इसलिए यह शायद ही आश्चर्य की बात है कि उस मूल्य के भिन्नता ने आपके क्वेरी परिणामों को नहीं बदला है।

SELECT ppl.latitude, ppl.longitude, ppl.radius 
FROM 
    (people ppl), 
    (SELECT latitude, longitude, km FROM radiuses) AS B 
WHERE [...distance^2...] <= POW(ppl.radius + B.km, 2) 

मैं कहना चाहिए कि इस सवाल का अब तक समय लगा समझने के लिए की तुलना में यह होना चाहिए, क्योंकि आप, संस्था-यही नहीं एक व्यक्ति को एक "त्रिज्या" कहते हैं जब वास्तव में आप एक मिल गया है संपत्ति जिसे दो अलग-अलग इकाइयों पर 'त्रिज्या' कहा जाना चाहिए। तो उस अन्य इकाई को कुछ वर्णनात्मक नाम दें।

14

इस सुलझाने के लिए आप चक्र के समीकरण को समझने के लिए है, जो केंद्र (x1, y1) के साथ चक्र में आते थे इस किसी भी बिंदु के लिए (एक्स, वाई) की तरह कुछ है की जरूरत है और (एक्स, वाई) और त्रिज्या = 2kms r त्रिज्या इकाइयों

(x-x1)^2 + (y - y1)^2 <= r^2 

where a^b = a to the power b 
अपने मामले उपयोगकर्ता B के (अक्षांश, देशांतर) में

यहाँ चक्र के केंद्र है कर रहे हैं, उपयोगकर्ता A का (अक्षांश, देशांतर) अंक हैं।

लेकिन मूल समस्या अक्षांश के अक्षांश की डिग्री बदलने की है, इसलिए यहां समाधान है, 1 डिग्री = 111.12 किमी। तो इकाइयों समीकरण के दोनों तरफ एक ही रखने के लिए, हम इसे किलोमीटर में बदल जाएगा

तो हमारे अंतिम समीकरण हो जाता है:

उसी के लिए
((x-x1)*111.12)^2 + ((y-y1)*111.12)^2 = 4  (=2^2) 

SQL विवरण इस

SELECT A.user_id, A.radius_id, A.latitude, A.logitude 
FROM UserA AS A, 
    (SELECT user_id, latitude, longitude 
     FROM UserB 
     WHERE user_id = 8) AS B 
WHERE (POW((A.latitude-B.latitude)*111.12, 2) + POW((A.longitude - B.longitude)*111.12, 2)) <= 4 
/* **Edit** Here I have used (A.longitude - B.longitude)*111.12, for more accurate results one can replace it with (A.longitude - B.longitude)*111.12*cos(A.latitude)) or (A.longitude - B.longitude)*111.12*cos(B.latitude)) 

And, as i have suggested in the comments that first filter some records based on approximation, so whether one uses A.latitude or B.latitude it will not make much difference */ 
कुछ ऐसा दिखाई देगा

उम्मीद है कि इससे मदद मिलेगी ...

+0

आप 111.12^2 को कारक बना सकते हैं। फिर उस राशि से दोनों तरफ विभाजित करें। कहां (पावर ((अक्षांश-बी। अक्षांश), 2) + पाउ ((एलोन्गिट्यूड - बी लोंग्यूड्यूड), 2)) <= 4/(111.12^2)। – walrii

+0

@walrii हाँ यह किया जा सकता है ... – Shubhansh

+2

एक डिग्री = 111.12 किमी केवल भूमध्य रेखा पर; जैसे ही आप ध्रुवों की तरफ बढ़ते हैं, अक्षांश अपेक्षाकृत स्थिर रहता है लेकिन देशांतर शून्य तक पहुंचता है, इसलिए यह समाधान आपके भूमध्य रेखा से दूर से अधिक गलत हो जाएगा। –

7

आपकी समस्या के केंद्र में सवाल है "मुझे कैसे पता चलेगा कि दो मंडल ओवरलैप हैं"। इसका उत्तर यह है कि "यदि उनके केंद्रों के बीच की दूरी उनके त्रिज्या के योग से कम है"। तो आप जो खोज रहे हैं वह है कि दो बिंदुओं के बीच की दूरी का निर्धारण कैसे करें।

दूसरा उत्तर अक्षांश और देशांतर का इलाज कर रहा है जैसे कि उनमें कार्टेसियन विमान शामिल है। जो वे नहीं करते हैं (जब आप भूमध्य रेखा से ध्रुवों तक पहुंचते हैं तो रेखांश शून्य की तरफ जाता है)।अब, एक अनुमान के रूप में, यह आपके समाधान के लिए आवश्यक सटीकता के आधार पर आपके समाधान के लिए ठीक काम कर सकता है। दूसरी ओर, यदि आपको यह बहुत सटीक होने की आवश्यकता है, तो आपको हावर्सिन फॉर्मूला की आवश्यकता है। वहाँ कैसे यहाँ MySQL में इसे लागू करने का एक बड़ा विवरण दिया गया है:

http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL

कि प्रस्तुति के स्लाइड 7 से

, तो आपको निम्न सूत्र है:

3956*2*ASIN(SQRT(POWER(SIN((orig.lat-dest.lat)*pi()/180/2),2)+ 
    COS(orig.lat*pi()/180)*COS(dest.lat*pi()/180)* 
    POWER(SIN((orig.lon-dest.lon)*pi()/180/2),2))) 

ध्यान दें कि पहले नंबर मतलब है मील में पृथ्वी का त्रिज्या; किलोमीटर के लिए 6371 में बदलें।

आप इस गणना की दूरी का उपयोग कैसे करते हैं, यह आपके पोस्ट में शामिल विवरणों पर निर्भर नहीं है, जैसे आप जिन बिंदुओं से निपट रहे हैं, भौगोलिक फैलाव, किसी प्रदर्शन की आवश्यकताएं, और डेटा स्थिर है या नहीं या लगातार अद्यतन किया जा रहा है।

मैं इन चीजों का जिक्र करता हूं क्योंकि प्रदर्शन एक मुद्दा होने जा रहा है, खासकर यदि आपके पास कोई महत्वपूर्ण मात्रा में डेटा है और/या इसे लगातार अद्यतन किया जा रहा है (जैसे उपयोगकर्ता के स्थान उनके फोन के जीपीएस डेटा के आधार पर)।

एक तरह से आप प्रदर्शन समस्या के साथ मदद कर सकते हैं सर्कल के बजाय वर्गों का उपयोग करते हैं, और एक डिग्री = 111.12 किमी के अनुमान का उपयोग करते हैं। इस तरह आप किसी भी बिंदु से स्पष्ट रूप से दूर किसी भी बिंदु को स्वचालित रूप से दूर कर सकते हैं। फिर आप ब्याज के क्षेत्र में आने वाले कुछ हद तक अंक के लिए केवल हावरसिन फॉर्मूला की गणना कर रहे हैं।

मुझे आशा है कि यह आपको सही दिशा में इंगित करने में सहायक होगा।

संबंधित मुद्दे