निकटता की खोज के लिए जियोशॉट का उपयोग करना?


30

मैं बिंदु निकटता भू खोज समय का अनुकूलन करने के लिए देख रहा हूँ।

मेरा इनपुट अव्यक्त है, lng बिंदु है और मैं स्थानों के एक पूर्व निर्धारित स्थान पर n निकटतम बिंदुओं पर खोज कर रहा हूं।

मुझे परवाह नहीं है कि स्थानों के पूर्व-अनुक्रमित सूचकांक के निर्माण में कितना समय / स्थान लगेगा लेकिन मुझे लगता है कि प्रश्न सुपर फास्ट होंगे।

मैं खोज कुंजी के रूप में जियोहॉश का उपयोग करने के बारे में सोच रहा हूं, जहां मैं पहले जांच करूंगा कि क्या मुझे कुंजी के एक्स चार्ट के लिए परिणाम मिलते हैं और फिर कुंजी के अंत से नीचे के छंटनी जारी रखना चाहिए जब तक कि मैं परिणाम देखना शुरू नहीं कर देता।

भू सूचकांक तकनीकों की मेरी (अभी के लिए बहुत विरल) समझ यह दृष्टिकोण अन्य सभी ज्ञात कार्यान्वयनों (जैसे आर ट्री और सह) की तुलना में सबसे तेज़ परिणाम (क्वेरी समय के संदर्भ में) का उत्पादन करने में सक्षम होना चाहिए।


क्या एक भू-राशि का उपयोग करने और पूर्व / उत्तर-पूर्व (उदाहरण के लिए) में अपने लैट / लंबे भंडारण के बीच एक महत्वपूर्ण अंतर है? संभवतः दोनों के साथ आप चार्ट / अंकों को ट्रिम करके अपनी खोज सटीकता को बदल सकते हैं। (यह विशुद्ध रूप से जिज्ञासा से बाहर का प्रश्न है - मैं इस विषय से अपरिचित हूँ)।
djq

क्या ये बिंदु डेटाबेस में या मेमोरी में संग्रहीत हैं या?
मार्क फफिस्टर

@MarcPfister यह मुद्दा 2 साल पुराना है (मेरे उपयोग-मामले के लिए) लेकिन यह हमेशा समुदाय के लिए प्रासंगिक है इसलिए मैं सक्रिय चर्चा जारी रखूंगा। चर्चा किए गए डेटा को वास्तव में एक nosql डेटाबेस में संग्रहीत किया गया था।
मैक्सिम वीक्स्लर

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

आह अच्छा। CouchDB में अब स्थानिक अनुक्रमण भी था, शायद भूभाष का उपयोग भी।
मार्क फिस्टर

जवाबों:


25

बिल्कुल आप कर सकते हैं। और यह काफी तेज हो सकता है। (गहन संगणना बिट्स को भी वितरित किया जा सकता है)

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

विधि यहाँ उल्लिखित है: https://github.com/yinqiwen/ardb/wiki/Spatial-Index

लेकिन इसका सार यह है (लिंक को गलत ठहराने के लिए):

  1. आप अपने सभी जियोहैश्ड पॉइंट को सबसे अच्छे रिज़ॉल्यूशन में स्टोर करते हैं जो आप चाहते हैं (अधिकतम आमतौर पर 64 बिट पूर्णांक है अगर यह सुलभ है, या जावास्क्रिप्ट के मामले में, 52बिट्स) एक ऑर्डर किए गए सेट में (यानी। रेडिस में zset)। इन दिनों अधिकांश जियोश लाइब्रेरियों में जियोहैश पूर्णांक कार्य निर्मित होते हैं, और आपको अधिक सामान्य बेस 32 जियोशेस के बजाय इनका उपयोग करने की आवश्यकता होगी।
  2. उस त्रिज्या के आधार पर जिसे आप खोजना चाहते हैं, आपको तब थोड़ी गहराई / रिज़ॉल्यूशन खोजने की आवश्यकता होती है जो आपके खोज क्षेत्र से मेल खाए और यह आपके संग्रहीत भू-बिट बिट की गहराई से कम या बराबर होना चाहिए। लिंक की गई साइट में एक टेबल है जो एक जियोश की बिट गहराई को मीटर में उसके बाउंडिंग बॉक्स क्षेत्र से संबद्ध करता है।
  3. तब आप इस निचले संकल्प पर अपने मूल समन्वय को पुनः व्यवस्थित करते हैं।
  4. उस निचले रिज़ॉल्यूशन में 8 पड़ोसी (n, ne, e, se, s, sw, w, nw) जियोहैश क्षेत्र भी मिलते हैं। पड़ोसी विधि को करने का कारण यह है, क्योंकि दो निर्देशांक एक दूसरे के बगल में लगभग पूरी तरह से अलग-अलग भू-खंड हो सकते हैं, इसलिए आपको खोज द्वारा कवर किए गए क्षेत्र के कुछ औसत करने की आवश्यकता है।
  5. एक बार जब आप इस निचले रिज़ॉल्यूशन पर सभी पड़ोसी भूशाश प्राप्त कर लेते हैं, तो चरण 3 से अपने समन्वय के जियोश को सूची में जोड़ें।
  6. तो फिर तुम एक का निर्माण करने की आवश्यकता रेंज खोज करने के लिए हैं जिसके तहत इन्हें 9 क्षेत्रों को कवर geohash मूल्यों की। चरण 5 से मान आपकी निचली सीमा सीमा है, और यदि आप उनमें से प्रत्येक में 1 जोड़ते हैं, तो आप अपनी ऊपरी सीमा सीमा प्राप्त करेंगे। तो आपके पास 9 श्रेणियों की एक सरणी होनी चाहिए, जिनमें से प्रत्येक में एक निचली सीमा और ऊपरी भूओश सीमा (कुल में 18 भू-आकार) हैं। ये geohashes अभी भी चरण 2 से उस कम रिज़ॉल्यूशन में हैं।
  7. फिर आप इन सभी जियोशेस को 18 बिट में जो भी बिट गहराई / रिज़ॉल्यूशन में जमा करते हैं, उसे अपने डेटाबेस में कन्वर्ट कर लेते हैं। आम तौर पर आप इसे बिट बिट्स को वांछित बिट डेप्थ में बदलकर करते हैं।
  8. अब आप इन 9 सीमाओं के भीतर बिंदुओं के लिए एक श्रेणी क्वेरी कर सकते हैं और आपको अपने मूल बिंदु की दूरी के भीतर लगभग सभी बिंदु मिल जाएंगे। कोई ओवरलैप नहीं होगा, इसलिए आपको किसी भी चौराहे की ज़रूरत नहीं है, बस शुद्ध श्रेणी के प्रश्न, बहुत तेज़ हैं। (यानी; रेडिस में: ZRANGEBYSCORE zsetname लोअरलिमिट अपरलीमिट, इस चरण में उत्पादित 9 से अधिक रेंज)

आप इसे आगे (स्पीड वार) ऑप्टिमाइज़ कर सकते हैं:

  1. चरण 6 से उन 9 रेंजों को लेना और यह पता लगाना कि वे एक दूसरे में कहाँ जाते हैं। आमतौर पर आप अपने समन्वय के आधार पर 9 अलग-अलग श्रेणियों को लगभग 4 या 5 तक कम कर सकते हैं। इससे आपकी क्वेरी का समय आधा हो सकता है।
  2. एक बार जब आपकी अंतिम सीमा हो जाती है, तो आपको उन्हें पुन: उपयोग के लिए पकड़ना चाहिए। इन श्रेणियों की गणना में अधिकांश प्रसंस्करण समय लग सकता है, इसलिए यदि आपका मूल समन्वय बहुत अधिक नहीं बदलता है, लेकिन आपको फिर से समान दूरी क्वेरी बनाने की आवश्यकता है, तो आपको इसे हर बार गणना करने के बजाय तैयार रखना चाहिए।
  3. यदि आप रेडिस का उपयोग कर रहे हैं, तो MULTI / EXEC में प्रश्नों को संयोजित करने का प्रयास करें, ताकि यह उन्हें थोड़ा बेहतर प्रदर्शन के लिए पाइपलाइन कर सके।
  4. सबसे अच्छा हिस्सा: आप एक ही स्थान पर सभी गणना करने के बजाय क्लाइंट पर 2-7 कदम वितरित कर सकते हैं। यह उन स्थितियों में CPU लोड को बहुत कम करता है जहां लाखों अनुरोध आ रहे हैं।

यदि आप परिशुद्धता के बारे में बहुत अधिक ध्यान रखते हैं, तो आप लौटे परिणामों पर एक सर्कल की दूरी / हैवरसिन प्रकार्य फ़ंक्शन का उपयोग करके सटीकता में सुधार कर सकते हैं।

यहां सामान्य बेस 32 जियोहेस और रेडिस के बजाय SQL क्वेरी का उपयोग करने वाली एक समान तकनीक है: https://github.com/davetroy/geohash-js

मुझे अपनी चीज़ को प्लग करने का मतलब नहीं है, लेकिन मैंने नोडज और रेडिस के लिए एक मॉड्यूल लिखा है जो इसे लागू करने के लिए वास्तव में आसान बनाता है। यदि आप चाहें तो इस कोड को देखें : https://github.com/arjunmehta/node-georedis


अनुगमन के कुछ जोड़े - आप पड़ोसियों की गणना कैसे करते हैं? पूर्णांक हैशिंग ट्रिमिंग की अनुमति देता है (base32 z-वक्र आधारित पूर्व के लिए, नहीं करता है। (7 base32 geohash में 8 से बहुत दूर है)। कैसे विधि में उल्लिखित है geohash-js github.com/davetroy/geohash-js/blob/ मास्टर / matrix.txt समान हालांकि इस एल्गोरिथ्म की अपेक्षा की निकटता भू-अंक geohash-js का उत्पादन करता है हे (1) पड़ोसी कोशिकाओं की गणना केवल?।
मैक्सिम Veksler

वाह, यह बहुत उपयोगी था। इस प्रतिक्रिया में इतनी विशेषज्ञता। काफी चुनौती भरा काम
साइमन

9

प्रश्न को कई तरीकों से पढ़ा जा सकता है। मेरा मतलब है कि आपके पास बड़ी संख्या में अंक हैं और आप उन्हें मनमाने ढंग से बिंदुओं के साथ बार-बार जांच करने का इरादा रखते हैं, समन्वित जोड़े के रूप में दिए गए हैं, और जांच के लिए निकटतम निकटतम बिंदुओं को प्राप्त करने की इच्छा रखते हैं, एन निश्चित पूर्व से। (सिद्धांत रूप में, यदि n अलग-अलग होगा, तो आप हर संभव n के लिए एक डेटा संरचना सेट कर सकते हैं और इसे प्रत्येक जांच के साथ O (1) समय में चुन सकते हैं: यह बहुत लंबा सेटअप समय ले सकता है और बहुत अधिक RAM की आवश्यकता होती है, लेकिन हम ऐसी चिंताओं को नजरअंदाज करने के लिए कहा जाता है।)

सभी बिंदुओं के क्रम-एन वोरोनोई आरेख का निर्माण करें । यह विमान को जुड़े क्षेत्रों में विभाजित करता है, जिनमें से प्रत्येक में समान पड़ोसी होते हैं। यह स्थिति को बिंदु-इन-बहुभुज समस्या को कम करता है, जिसमें कई कुशल समाधान हैं।

वोरोनोई आरेख के लिए एक वेक्टर डेटा संरचना का उपयोग करते हुए, बिंदु-इन-बहुभुज खोजों में ओ (लॉग (एन)) समय लगेगा। व्यावहारिक उद्देश्यों के लिए आप इस O (1) को आरेख के रेखापुंज संस्करण बनाकर एक अत्यंत छोटे निहित गुणांक के साथ बना सकते हैं। रेखापुंज में कोशिकाओं के मान या तो हैं (i) n निकटतम बिंदुओं की सूची के लिए एक सूचक या (ii) एक संकेत है कि यह कोशिका आरेख में दो या अधिक क्षेत्रों को स्थिर करती है। एक मनमाना बिंदु के लिए परीक्षण (x, y) हो जाता है:

Fetch the cell value for (x,y).
If the value is a list of points, return it.
Else apply a vector point-in-polygon algorithm to (x,y).

O (1) प्रदर्शन को प्राप्त करने के लिए, रास्टर जाल को पर्याप्त रूप से ठीक होना चाहिए कि अपेक्षाकृत कुछ जांच बिंदु कोशिकाओं में गिरेंगे जो कई वोरोनोई क्षेत्रों को फैलाते हैं। यह हमेशा पूरा किया जा सकता है, ग्रिड के लिए भंडारण में संभावित रूप से महान व्यय के साथ।


3

मैं बिल्कुल इसके लिए जियोशेस का उपयोग करता हूं। इसका कारण मैं हूं क्योंकि मुझे पिरामिड शैली की सूचना प्रणाली का उपयोग करके निकटता की खोजों को लागू करने की आवश्यकता थी .. जहां 8 वीं स्तर की सटीकता के साथ जियोशेस का आधार 'आधार' था और 7 वीं परिशुद्धता के जियोहाईश के लिए नए योग का गठन किया .. और इसी तरह आगे । ये योग क्षेत्र थे, ग्राउंड कवर के प्रकार, आदि .. यह कुछ बहुत फैंसी सामान करने के लिए एक बहुत ही फैंसी तरीका था।

तो 8 वें स्तर के जियोशेस में जानकारी शामिल होगी:

प्रकार: घास एकड़: 1.23

और 7 वें, 6 वें .. आदि में ऐसी जानकारी शामिल होगी:

घास_टाइप्स: 123 एकड़: 6502

यह हमेशा सबसे कम सटीकता से बनाया गया था। इससे मुझे हर तरह के मज़ेदार आँकड़े बहुत जल्दी मिल गए। मैं GeoJSON का उपयोग करके प्रत्येक जियोहैश संदर्भ के लिए एक ज्यामिति संदर्भ निर्दिष्ट करने में सक्षम था।

मैं अपने वर्तमान व्यूपोर्ट को बनाने वाले सबसे बड़े जियोशॉट्स को खोजने के लिए कई फ़ंक्शन लिखने में सक्षम था और फिर व्यूपोर्ट के भीतर दूसरी सबसे बड़ी परिशुद्धता के जियोशॉट खोजने के लिए उन का उपयोग करता था। इसे आसानी से अनुक्रमित श्रेणी के प्रश्नों तक बढ़ाया जा सकता है जहां मैं न्यूनतम aa 86ssaaaa ’और अधिकतम for 86sszzzz’ के लिए जो भी सटीक चाहता था, उसके लिए क्वेरी करूंगा।

मैं MongoDB का उपयोग कर रहा हूं।


3

2018 के लिए अद्यतन करना, और कुछ गणितीय फंड या जियोश की ऐतिहासिक-सिद्धता:

  • जिनेश के लिए प्रेरणा बाइनरी अंकों का सरल इंटरलेव था , शायद भोले एल्गोरिदम का एक अनुकूलन जो सी-वर्गों की तरह, दशमलव अंकों को इंटरलेयड किया ।

  • बाइनरी इंटरलेसिंग स्वाभाविक रूप से एक जेड-ऑर्डर-वक्र इंडेक्स रणनीति के परिणामस्वरूप हुई , जियोश आविष्कारक ने "सबसे अच्छा फ्रैक्टल वक्र की तलाश" शुरू नहीं की ... लेकिन उत्सुकता से, यह डिजाइन अनुकूलन, एक बेहतर फ्रैक्टल वक्र, (!) संभव है।

S2 ज्यामिति लाइब्रेरी का उपयोग करें

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

... हम बेहतर कर सकते हैं ... असंगतता जैसा कि हम ऊपर दाईं ओर से नीचे बाएँ बाएँ चतुर्थ परिणाम में जाते हैं, जिससे हमें कुछ सीमाएँ विभाजित करनी पड़ती हैं जिन्हें हम अन्यथा सन्निहित बना सकते हैं। (...) हम क्वाडट्रीस और हिल्बर्ट कर्व्स के साथ स्थानिक अनुक्रमण पर किसी भी असंतोष (...) blog.notdot.net/2009 को पूरी तरह से समाप्त कर सकते हैं

अब यह एक स्वतंत्र और कुशल पुस्तकालय है, https://s2geometry.io देखें

पुनश्च: N2JS केs2-geometry रूप में (अच्छे) गैर-आधिकारिक सरलीकृत संस्करण भी हैं , और कई "खेल के मैदान", ऐड-इन्स और डेमो, जैसे s2.sidewalklabs.com


2

मैं रेडिस में GEORADIUS क्वेरी का उपयोग करने की सलाह दूंगा।

GEOADD कॉल का उपयोग करके डेटा को सर्वोत्तम अनुकूल जियोहैश स्तर से जोड़ा गया।

इसके अलावा, इस पर एक नज़र -> निकटता है

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.