मैं एक निश्चित मील का पत्थर की एक सीमा के भीतर सभी स्थलों को कुशलता से कैसे खोज सकता हूं?


14

मैं एक जियो सर्च प्रोजेक्ट के साथ शुरुआत करने की कोशिश कर रहा हूं, जो किसी विशेष लैंडमार्क के 10 किमी / मील (इस कहानी के लिए महत्वपूर्ण नहीं) में सभी स्थलों को ढूंढेगा।

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

क्या ऐसा करने का एक बेहतर तरीका है?

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

क्या Google मैप्स API मदद कर सकता है?


5
आप संभवत: एक त्वरित मैनहट्टन दूरी की गणना करके और फिर 10 किमी वर्ग के भीतर लेकिन 10 किमी के दायरे के बाहर के स्थलों को बाहर करने के लिए एक दूसरे फिल्टर का प्रदर्शन करके एक अच्छा कई को समाप्त कर सकते हैं।
नील

3
आप किस डेटाबेस तकनीक का उपयोग कर रहे हैं? इसका उत्तर डेटाबेस अज्ञेय नहीं है।
jpmc26

1
@Neil एक दूसरे पास के रूप में आप किसी भी मील के पत्थर को शामिल कर सकते हैं जहां वास्तविक दूरी की गणना के बिना x और y दोनों मूल के 7 किमी में आते हैं।
जिम्मीजम्स

जवाबों:


10

SQL Server 2008 के बाद से, एक भूगोल डेटा प्रकार है जो स्थानों (lat / lon जोड़े) को संग्रहीत करता है और आपके लिए स्थान-संबंधित क्वेरी लिखना आसान बनाता है।

एक मौजूदा StackOverflow उत्तर है जो इस बारे में गहराई से चर्चा करता है।

निकटतम 7 वस्तुओं को खोजने के लिए एक मूल प्रश्न :

USE AdventureWorks2012  
GO  
DECLARE @g geography = 'POINT(-121.626 47.8315)';  
SELECT TOP(7) SpatialLocation.ToString(), City FROM Person.Address  
WHERE SpatialLocation.STDistance(@g) IS NOT NULL  
ORDER BY SpatialLocation.STDistance(@g);  

100 मीटर के भीतर सब कुछ खोजने के लिए एक मूल प्रश्न (प्रश्न का दूसरा उत्तर)

-- Get the center point
DECLARE @g geography
SELECT @g = geo FROM yourTable WHERE PointId = something

-- Get the results, radius 100m
SELECT * FROM yourTable WHERE @g.STDistance(geo) <= 100

11
@KonradRudolph: जैसा कि किसी भी SQL कॉलम के लिए होता है, जिसका उपयोग बड़े पैमाने पर एक पंक्ति में क्वेरी के लिए किया जाता है। आप सही हैं, लेकिन यह टिप्पणी लगभग किसी भी SQL क्वेरी पर लागू होगी जो उत्तर के रूप में पोस्ट की गई है।
14

2
आपने प्रश्न में "MS SQL Server" कहाँ पढ़ा है?
डॉक्टर ब्राउन

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

2
@ jpmc26: आपको यह याद है कि मैंने एक वैध विकल्प सूचीबद्ध किया है और कुछ अन्य विकल्प शामिल नहीं किए हैं? क्या? यदि आपको लगता है कि PostGIS को जोड़ना प्रासंगिक है, तो अपने आप को उत्तर दें (जो आपने किया था) और आप के समान विचार न रखने के लिए दूसरों की आलोचना का सहारा न लें।
फ्लाटर

3
आपका जवाब मुझे मूल रूप से सिर्फ एक MS SQL बिक्री पिच के रूप में दिखाई देता है। आपकी टिप्पणियों का सुझाव है कि वे डेटाबेस को किसी ऐसी चीज़ पर स्विच करते हैं जिसकी लागत 10 हज़ार डॉलर होगी, वास्तव में इस बात की जानकारी के बिना कि उनकी स्थिति केवल इसे करोड़ों दिखाई देती है। यह भी वर्णन नहीं करता है कि ओपी वास्तव में अपनी क्वेरी को कैसे लागू कर सकता है या इस तथ्य पर चर्चा कर सकता है कि ऐसा करने और स्थानिक सूचकांक का उपयोग करने पर एमएस एसक्यूएल में अन्य DBs की तरह सीधा नहीं है। न ही यह किसी भी अंतर्निहित अवधारणाओं पर चर्चा करता है। यह एक बुरा जवाब है, चाहे वह "वैध" हो। इसलिए यह मुझे परेशान करता है।
jpmc26

29

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

यदि आपको अपने एप्लिकेशन के भीतर इस तरह के प्रश्नों को लागू करने की आवश्यकता है, तो आप एक डेटा संरचना को लागू कर सकते हैं जो स्थानिक प्रश्नों की अनुमति देता है, जैसे कि kd ट्री । यह एक द्विआधारी खोज पेड़ की तरह है, सिवाय इसके कि एक अलग समन्वय आयाम पर पेड़ विभाजन के प्रत्येक स्तर। यह आपको खोज को संभव उम्मीदवारों के एक छोटे समूह तक सीमित करने की अनुमति देता है। प्रभावी रूप से, आप अपनी खोज "10 किमी त्रिज्या" को प्रत्येक समन्वय आयाम के लिए सीमा में तब्दील कर देते हैं, और जब आप पेड़ पर चढ़ते हैं तो सीमा को कस देते हैं।



8
PostGIS प्रमुख मुफ्त विकल्प है। यह एसक्यूएल सर्वर के बहुत ही बुनियादी जीआईएस प्रकारों और कार्यों की तुलना में बहुत अधिक समर्थन करता है। लेकिन यह बुनियादी कार्यक्षमता है।
jpmc26

@amon मुझे jpmc26 की टिप्पणी एक अच्छे जोड़ के रूप में मिलती है, न कि आपके उदाहरण की आलोचना करने के लिए। "यदि आप स्क्रैच से शुरू करना चाहते हैं, तो आपको लाइसेंस प्राप्त डीबी के लिए भुगतान करने की आवश्यकता नहीं है - यह मुफ़्त, ओपन-सोर्स एक भी चाल को अच्छी तरह से करेगा"।
मर्गिसारिसिया 11

11

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

आप "दूरी के भीतर" प्रश्न (कुछ अन्य ज्यामिति की एक निश्चित दूरी के भीतर ज्यामिति के लिए प्रश्न) में देखना चाहते हैं। ये बहुत मानक और बहुत हल की गई समस्याएँ हैं और उपरोक्त सभी डेटाबेस में संभव हैं (और कई में निर्मित):

  • PostGIS: ST_DWithin
  • SQL सर्वर: STDistance(स्पष्ट नहीं है कि इस फ़ंक्शन के 3D भूगोल संस्करण पर सूचकांक का उपयोग समर्थित है)
  • ओरेकल: SDO_WITHIN_DISTANCE(यह स्पष्ट रूप से यह नहीं कहता है कि यह सूचकांक उपयोग को ट्रिगर करेगा। मैं क्वेरी योजना की दोहरी जांच करूंगा। आपको सूचकांक का उपयोग SDO_FILTERकरने के लिए इसे प्राप्त करने के लिए आवेदन करने की आवश्यकता हो सकती है ।)
  • MySQL: फिर भी यह पता लगाना।

सूचकांक उपयोग को ट्रिगर करने के लिए समाधान

में सबसे खराब मामला है जहाँ आप मुसीबत प्रणाली इन प्रश्नों के साथ स्थानिक सूचकांक का उपयोग करने के लिए हो रही है, तो आप एक अतिरिक्त फ़िल्टर जोड़ सकते हैं। आप लंबाई 2 * (खोज दूरी) के पक्षों के साथ एक वर्ग सीमांकन बॉक्स बना सकते हैं अपनी खोज बिंदु पर केंद्रित और तालिका geometries 'के खिलाफ बॉक्स बाउंडिंग तुलना कि वास्तविक दूरी की जाँच से पहले। यही ST_DWithinऊपर PostGIS ' आंतरिक रूप से वैसे भी करता है।


जीआईएस में दूरी

जबकि स्थानिक सूचकांक शानदार हैं और आपकी समस्या का बिल्कुल सही समाधान है, दूरी की गणना तार्किक रूप से जटिल हो सकती है। विशेष रूप से, आपको यह चिंता करने की आवश्यकता है कि आपके डेटा में कौन से प्रक्षेपण (मूल रूप से समन्वय प्रणाली के लिए सभी पैरामीटर) संग्रहीत हैं। अधिकांश 2D अनुमान (विभिन्न अक्षांश / लंबे अनुमानों की तरह कोणीय समन्वय प्रणालियों के अलावा अन्य चीजें) लंबाई को काफी विकृत करती हैं। उदाहरण के लिए, वेब मर्केटर प्रोजेक्शन (Google, बिंग और प्रत्येक अन्य प्रमुख आधार मानचित्र प्रदाता द्वारा उपयोग किया जाने वाला) क्षेत्रों और दूरियों का विस्तार करता है, क्योंकि स्थान भूमध्य रेखा से और आगे बढ़ जाता है । मैं गलत हो सकता हूं क्योंकि मैं जीआईएस में औपचारिक रूप से शिक्षित नहीं हूं, लेकिन 2 डी अनुमानों के लिए मैंने जो सबसे अच्छा देखा है वह कुछ विशिष्ट हैं जो एक से दूरी का वादा करते हैंपूरी दुनिया में एकल, निरंतर बिंदु । (नहीं, यह हर क्वेरी के लिए एक अलग प्रक्षेपण का उपयोग करने के लिए व्यावहारिक नहीं है; जो आपके अनुक्रमित बेकार को प्रस्तुत करेगा।)

लब्बोलुआब यह है कि आपको यह सुनिश्चित करने की आवश्यकता है कि आपका गणित सटीक है। विकास के दृष्टिकोण से ऐसा करने का सबसे सरल तरीका कोणीय अनुमानों का उपयोग करना है (इन्हें अक्सर "भौगोलिक" के रूप में संदर्भित किया जाता है) और ऐसे कार्य जो एक गोलाकार मॉडल का उपयोग करके गणित का समर्थन करते हैं, लेकिन ये गणना 2 डी समकक्षों की तुलना में थोड़ी अधिक महंगी हैं। और कुछ DBs उन्हें अनुक्रमण का समर्थन नहीं कर सकते हैं। यदि आप उनका उपयोग करके स्वीकार्य प्रदर्शन प्राप्त कर सकते हैं, हालांकि, शायद यही रास्ता तय करना है। एक अन्य आम विकल्प क्षेत्रीय अनुमानों (जैसे कि UTM ज़ोन) हैं जो दोनों दूरी और क्षेत्रों को सही होने के लिए प्राप्त करते हैं यदि आपका डेटा दुनिया के किसी विशेष हिस्से तक सीमित है। आपके ऐप के लिए जो सबसे अच्छा है वह आपकी विशिष्ट आवश्यकताओं पर निर्भर करेगा,

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


3

मैं सहमत हूँ कि यदि संभव हो तो डेटाबेस में विशिष्ट समर्थन का उपयोग करना ऐसा करने का सबसे समझदार तरीका होगा।

हालाँकि, अगर मुझे विशिष्ट समर्थन के बिना एक डेटाबेस पर ऐसा करना पड़ता है, तो मैं एक वर्ग के लिए क्वेरी करके शुरू करूँगा जो कि घेरे को घेरता है जैसे (y> (y1 - rad)) AND (y <(y1 + rad)) AND (x> ( एक्स 1 - रेड)) और (एक्स <(एक्स + रेड))। मान लें कि आपके बिंदुओं में लगभग एक वर्ग के लिए वितरण क्वेरी है, तो आपको अपने असली मैचों के साथ-साथ लगभग 30% अतिरिक्त झूठे मैच मिलेंगे। फिर आप झूठे मैचों को हटा सकते हैं।


लेकिन एक उपयुक्त स्थानिक सूचकांक के बिना, इस तरह के एक प्रश्न पूरे डेटाबेस में सबसे खराब सभी बिंदुओं पर स्कैन करेगा, जो आपके सूचकांक के आधार पर दिए गए अक्षांश या देशांतर सीमा के भीतर सबसे अच्छा सभी वस्तुओं पर होगा, अर्थात एक वर्ग के बजाय "बैंड"। यदि आप प्रदर्शन को मारना नहीं चाहते हैं, तो एक डेटाबेस का उपयोग करें जो स्थानिक सूचकांक का समर्थन करता है!
जैकर्न

@jcaron मेरा मानना ​​है कि इस क्वेरी को एक साधारण बी-ट्री इंडेक्स के साथ अनुकूलित किया जा सकता है xऔर y। (शायद संयुक्त, शायद अलग। मैं यह जानने के लिए थोड़ा सा प्रोफ़ाइल करूंगा कि क्या अभ्यास में बेहतर काम करता है।)
jpmc26

@ jpmc26 नहीं, यह नहीं हो सकता। इसके माध्यम से सोचो, आप देखेंगे।
20

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

2
@ जकारोन वास्तव में आप किसी चीज के लिए सूचकांक का उपयोग कर सकते हैं, y between -68 and -69 and x between 10 and 11लेकिन निश्चित रूप से स्थानिक सूचकांक उस कार्य के लिए एक बेहतर काम करते हैं
जुआन कार्लोस ओरोपेजा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.