मैं GPS पोजीशन वाले पॉइंट्स के पास कैसे ग्रुप करूँ


10

मैं एक आईटी व्यक्ति हूं, इसलिए मुझे अनुमानों आदि के बारे में बहुत अधिक जानकारी नहीं है, मुझे आशा है कि आप मेरी मदद कर सकते हैं।

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

मेरा पहला विचार (समस्या को थोड़ा और समझाने के लिए) अक्षांश और समूह के लिए देशांतर के दशमलव का उपयोग करना था; उदाहरण के लिए, एक समूह 35.123 और 35.124 के बीच अक्षांश के साथ और 60.101 और 60.102 के बीच देशांतर होगा। इसलिए अगर मुझे lat = 35.1235647 और lon = 60.1012254598 जैसी स्थिति मिलती है, तो यह बिंदु उस समूह में जाएगा।

यह समाधान एक कार्टेशियन 2 डी प्रतिनिधित्व के लिए ठीक होगा, क्योंकि मेरे पास 0.001 इकाइयों के क्षेत्र होंगे जो व्यापक और उच्च होंगे; हालांकि, देशांतर के 1 डिग्री के आकार के रूप में अलग-अलग अक्षांशों पर अलग-अलग हैं, मैं इस दृष्टिकोण का उपयोग नहीं कर सकता।

कोई उपाय?


आप स्थिति को स्टोर क्यों नहीं कर सकते, और फिर बाद में प्रोसेसिंग कर सकते हैं? भूमध्य रेखा पर भी, 1 डिग्री देशांतर लगभग 111 किमी है, इसलिए 0.001 डिग्री 1 किलोमीटर से थोड़ा अधिक होगा। क्या तुम सच में अपने डिब्बे इतना बड़ा चाहते हो?
देवदत्त तेंग्शे

0.001 डिग्री मेरे विचार का एक उदाहरण मात्र था। बेशक मुझे इसे आवश्यकताओं के अनुकूल बनाना होगा। मैं पोस्ट प्रोसेसिंग नहीं कर सकता क्योंकि यह एक वास्तविक समय अनुप्रयोग होने के लिए प्लान है, और मैं अपने उपयोगकर्ताओं को कल तक पकड़ नहीं सकता , क्योंकि मुझे अंक " विचारों के लिए धन्यवाद वैसे भी समूहित करना है; "
कुऊ

जवाबों:


6

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

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

(क्या मैंने "विमान" को विभाजित करते हुए कहा? हां - यदि पृथ्वी की सतह को एक गोले के रूप में मॉडल करें और भू-भाग (x, y, z) का समन्वय करें, तो हमारी अधिकांश गणना तीन आयामों में होती है, जहाँ त्रिभुजों के किनारे टुकड़े होते हैं) अपने मूल के माध्यम से विमानों के साथ गोले के चौराहों । यह गणना तेज और आसान बनाता है।


मैं एक क्षेत्र के एक अष्टक पर प्रक्रिया दिखा कर वर्णन करूंगा; अन्य सात अष्टक समान तरीके से संसाधित किए जाते हैं। ऐसा अष्टक 90-90-90 त्रिभुज है। अपने ग्राफिक्स में मैं यूक्लिडियन त्रिकोणों को एक ही कोनों में फैलाऊंगा: वे बहुत अच्छे नहीं लगते जब तक कि वे छोटे न हो जाएं, लेकिन वे आसानी से और जल्दी से तैयार हो सकते हैं। यहां अष्टक के अनुरूप यूक्लिडियन त्रिभुज है: यह प्रक्रिया की शुरुआत है।

आकृति 1

सभी पक्षों की लंबाई समान होने पर, किसी को "सबसे लंबा" और उप-विभाजित के रूप में यादृच्छिक रूप से चुना जाता है:

चित्र 2

प्रत्येक नए त्रिकोण के लिए इसे दोहराएं:

चित्र तीन

N चरणों के बाद हमारे पास 2 ^ n त्रिकोण होंगे। 10 चरणों के बाद यहां स्थिति है, ओकटेंट में 1024 त्रिकोण दिखाते हैं (और कुल मिलाकर 8192 क्षेत्र):

चित्र 4

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

चित्र 5

संयोग से, किसी बिंदु के स्थान को अक्षांश (लगभग) के एक डिग्री तक सीमित करने के लिए, आप ध्यान देंगे कि यह लगभग 1/60 रेडियन है और इसलिए लगभग (1/60) ^ 2 / (Pi / 2) = 1/6000 कुल सतह। चूंकि प्रत्येक उपखंड लगभग त्रिकोण आकार को आधा कर देता है, अष्टकूट के लगभग 13 से 14 उपखंड चाल करेंगे। यह अधिक संगणना नहीं है - जैसा कि हम नीचे देखेंगे - यह कुशल बनाता है कि पेड़ को बिल्कुल भी न रखें, लेकिन मक्खी पर उपखंड का प्रदर्शन करें। शुरुआत में आप ध्यान देंगे कि बिंदु किसमें निहित है - यह उसके तीन निर्देशांक के संकेतों से निर्धारित होता है, जिसे तीन अंकों के बाइनरी नंबर के रूप में दर्ज किया जा सकता है - और प्रत्येक चरण में आप यह याद रखना चाहते हैं कि बिंदु झूठ है या नहीं त्रिभुज के बाएँ (0) या दाएँ (1)। यह एक और 14-अंकीय बाइनरी नंबर देता है। आप इन कोड का उपयोग मनमाने ढंग से करने के लिए कर सकते हैं।

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


मैंने इसे लागू करने के लिए Mathematica 8 का उपयोग किया है : आप इसे अपने प्रोग्रामिंग प्रोग्राम के वातावरण में क्रियान्वयन के लिए या-स्यूडोकोड के रूप में ले सकते हैं।

निर्धारित करें कि 0-ab बिंदु p के समतल किस तरफ है :

side[p_, {a_, b_}] := If[Det[{p, a, b}] >=  0, left, right];

बिंदु p पर आधारित त्रिभुज abc को परिष्कृत करें।

refine[p_, {a_, b_, c_}] := Block[{sides, x, y, z, m},
  sides = Norm /@ {b - c, c - a, a - b} // N;
  {x, y, z} = RotateLeft[{a, b, c}, First[Position[sides, Max[sides]]] - 1];
  m = Normalize[Mean[{y, z}]];
  If[side[p, {x, m}] === right, {y, m, x}, {x, m, z}] 
  ]

अंतिम आंकड़ा ओक्टेंट को प्रदर्शित करके और उसके ऊपर, निम्न सूची को बहुभुज के एक सेट के रूप में प्रस्तुत करके तैयार किया गया था:

p = Normalize@RandomReal[NormalDistribution[0, 1], 3]        (* Random point *)
{a, b, c} = IdentityMatrix[3] . DiagonalMatrix[Sign[p]] // N (* First octant *)
NestWhileList[refine[p, #] &, {a, b, c}, Norm[#[[1]] - #[[2]]] >= 0.05 &, 1, 16]

NestWhileListबार-बार एक ऑपरेशन ( refine) लागू होता है, जबकि एक स्थिति से संबंधित है (त्रिकोण बड़ा है) या जब तक एक अधिकतम ऑपरेशन गिनती (16) तक नहीं पहुंच गया है।

अष्टक के पूर्ण त्रिकोण को प्रदर्शित करने के लिए, मैंने पहले अष्टक के साथ शुरुआत की और दस बार शोधन किया। यह एक मामूली संशोधन के साथ शुरू होता है refine:

split[{a_, b_, c_}] := Module[{sides, x, y, z, m},
  sides = Norm /@ {b - c, c - a, a - b} // N;
  {x, y, z} = RotateLeft[{a, b, c}, First[Position[sides, Max[sides]]] - 1];
  m = Normalize[Mean[{y, z}]];
  {{y, m, x}, {x, m, z}}
  ]

अंतर यह है कि अपने इनपुट त्रिकोण के दोनों हिस्सों को एक के बजाय splitलौटाता है जिसमें एक दिया बिंदु निहित है। इसे पूरा करने के द्वारा पूर्ण त्रिभुज प्राप्त होता है:

triangles = NestList[Flatten[split /@ #, 1] &, {IdentityMatrix[3] // N}, 10];

जांच करने के लिए, मैंने हर त्रिकोण के आकार का एक माप लिया और सीमा को देखा। (यह "आकार" प्रत्येक त्रिभुज और गोलाकार केंद्र द्वारा संयोजित पिरामिड के आकार की आकृति के लिए आनुपातिक है, इन जैसे छोटे त्रिकोणों के लिए, यह आकार अनिवार्य रूप से इसके गोलाकार क्षेत्र के लिए आनुपातिक है।)

Through[{Min, Max}[Map[Round[Det[#], 0.00001] &, triangles[[10]] // N, {1}]]]

{0.00523, 0.00739}

इस प्रकार आकार उनके औसत से लगभग 25% भिन्न या कम होता है: जो कि समूह बिंदुओं के लिए लगभग समान तरीके से प्राप्त करने के लिए उचित लगता है।

इस कोड को स्कैन करने पर, आप बिना किसी त्रिकोणमिति को नोटिस करेंगे : केवल उसी स्थान की आवश्यकता होगी, यदि बिल्कुल भी, गोलाकार और कार्टेशियन निर्देशांक के बीच आगे और पीछे परिवर्तित करने में होगा। कोड किसी भी नक्शे पर पृथ्वी की सतह को प्रोजेक्ट नहीं करता है, जिससे परिचर विकृतियों से बचा जा सकता है। अन्यथा, यह केवल औसत ( Mean), पाइथोगोरियन प्रमेय ( Norm) और एक 3 बाय 3 निर्धारक ( Det) सभी काम करने के लिए उपयोग करता है। ( प्रत्येक त्रिकोण की सबसे लंबी ओर की खोज के साथ, कुछ सरल सूची-जोड़-तोड़ आदेश भी हैं RotateLeftऔर Flatten, भी।)


1

यह एक कठिन है, क्योंकि 3 डी WGS84 भौगोलिक समन्वय प्रणाली से फ्लैट 2 डी प्रोजेक्शन में जाने पर अनुमानों में विकृति आती है। वैश्विक स्तर पर, आपको सिस्टम में कहीं न कहीं विकृतियाँ आ सकती हैं।

मुझे लगता है कि आपका सबसे अच्छा दांव यूनिवर्सल ट्रांसवर्स मर्केटर प्रोजेक्शन को प्रोजेक्ट करना है । जहां तक ​​मुझे पता है कि यह निकटतम है आप कम से कम विरूपण के साथ एक वैश्विक प्रक्षेपण के लिए प्राप्त कर सकते हैं।

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


1
UTM एक "वैश्विक प्रक्षेपण" नहीं है: प्रदर्शन यह है कि लगभग किसी भी प्रकार के मान्य निर्देशांक, जैसे कि (500000, 5000000), UTM प्रणाली में कम से कम 120 अलग-अलग व्यापक रूप से अलग-अलग बिंदुओं से मेल खाते हैं। और, दुर्भाग्य से, क्लस्टरिंग एल्गोरिदम वास्तविक समय में समूह बिंदुओं में सक्षम होने के लिए ओपी की जरूरतों को पूरी तरह से उनके स्थान पर आधारित नहीं है (और अन्य बिंदुओं के लिए उनकी निकटता पर नहीं)।
whuber

@whuber re: "वैश्विक प्रक्षेपण" - सही है। इसलिए मैंने कहा "वैश्विक प्रक्षेपण के लिए आप निकटतम हो सकते हैं"। यदि आप एक बेहतर प्रक्षेपण प्रणाली के बारे में जानते हैं जो अधिक उपयुक्त है तो कृपया इसे टिप्पणियों में छोड़ दें और मैं अपना उत्तर संपादित करूँगा। इसके अलावा, प्रारंभिक पोस्ट में ओपी को वास्तविक समय की आवश्यकता नहीं थी। मैं इस पर ध्यान देने के लिए अपने उत्तर को संपादित करूँगा।
सीन बारब्यू

शॉन, (1) वैश्विक प्रक्षेपण समस्या का मेरा समाधान एक का उपयोग नहीं करना है। एकवचन के बिना कोई वैश्विक प्रक्षेपण मौजूद नहीं है । (२) सच है, वास्तविक समय स्पष्टीकरण एक टिप्पणी में दिखाई दिया। "मेरा पहला विचार" के बाद का पाठ एक अच्छा काम करता है, हालांकि, इस बात पर जोर देने में कि यह समस्या स्थानों के एक समूह को जोड़ने के बजाय पृथ्वी की सतह को विभाजित करने में से एक है। यही वह बिंदु है जो मैं (बहुत प्रभावी ढंग से नहीं) आपके पहले की टिप्पणी के पार पाने की कोशिश कर रहा था।
whuber
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.