स्पैटियालाइट में बिंदु स्थानों के साथ दो तालिकाओं के बीच निकटतम पड़ोसियों का पता लगाना?


10

मैंने आज स्पैटलाइट के साथ खेलना शुरू कर दिया है और पहले से ही एक समस्या पर ठोकर खाई है।

TableOne में संग्रहीत प्रत्येक बिंदु स्थान के लिए मैं tableTwo से एक, निकटतम (रैखिक दूरी) बिंदु का चयन करना चाहूंगा।

अब तक मैं एक अनाड़ी समाधान के साथ आया था जो दृश्य का उपयोग करता है:

CREATE VIEW testview AS 
SELECT 
A.id , 
B.myValue, 
Distance(A.Geometry, B.Geometry) AS distance
FROM tableOne AS A, tableTwo AS B
WHERE distance < 10000
ORDER BY A.Id, distance;

और तब:

SELECT * FROM testview
WHERE distance = (SELECT MIN(distance) FROM testview AS t WHERE t.id = testview.id)

काम करने लगता है।

दो सवाल:

क्या VIEW बनाए बिना ऐसी क्वेरी करने का कोई तरीका है?

क्या बेहतर प्रदर्शन के लिए इस क्वेरी को अनुकूलित करने का कोई अन्य तरीका है? एक वास्तविक विश्व परिदृश्य में टेबलऑन में सैकड़ों-युगल हजारों रिकॉर्ड होंगे, और टेबलटू - 1.3 मिलियन।


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

वास्तव में GRASS, ArcGIS, QGIS, SQLServer और किसी भी अन्य स्थानिक db / डेस्कटॉप GIS की तुलना में बहुत तेज है (हालांकि Oracle निकटतम पड़ोसी कार्यक्षमता की कोशिश नहीं की है)। बस मुझे बताएं कि क्या यह एक विकल्प है।
रागी यासर बुरहुम

@ रागी: मुझे पता है कि इस तरह की समस्या से निपटने के लिए PostGIS ज्यादा कारगर तरीका होगा। हालाँकि इस अभ्यास का अंतिम लक्ष्य छोटे पोर्टेबल ऐप बनाना होगा और इस मामले में स्पैटियालाइट विजेता है।
राडेक

आपके पोर्टेबल ऐप के लिए आपका विकास मंच क्या है?
एलन अडेयर

@ एलन: दोनों पर काम करना: विंडोज सर्वर 2008 और उबंटू फिलहाल।
राडेक

जवाबों:


5

मैंने इस एसक्यूएल का परीक्षण किया है और यह काम करता है:

SELECT g1.OGC_FID As id1, g2.OGC_FID As id2, MIN(ST_Distance(g1.GEOMETRY,g2.GEOMETRY)) AS DIST
FROM table_01 As g1, table_02 As g2   
WHERE g1.OGC_FID <> g2.OGC_FID
AND ST_Contains(ST_Expand(g1.geometry,50),g2.geometry)
GROUP BY id1
ORDER BY id1

जैसा कि आप यहाँ पढ़ सकते हैं "निकटतम पड़ोसी क्वेरी को करने का भोला तरीका क्वेरी ज्यामिति से दूरी द्वारा उम्मीदवार तालिका को क्रमबद्ध करना है, और फिर सबसे छोटी दूरी के साथ रिकॉर्ड लेना है"।

सादर,

एंड्रिया


मैं इस क्वेरी का उपयोग करने की कोशिश कर रहा हूं, लेकिन मुझे अप्रत्याशित परिणाम मिल रहे हैं - मुझे एक परिणामी तालिका मिल रही है, लेकिन लाइनों के लिए आईडी के साथ मैं देख सकता हूं कि निकटतम पड़ोसी नहीं हैं। मैं एक बहु परत स्ट्रिंग परत में निकटतम बिंदु को एक और परत में खोजने की कोशिश कर रहा हूं। मैं स्पैटलाइट के साथ नया हूं। कोई सुझाव? इसके अलावा, मैं अंततः इसे 1 मिलियन + अंक
kflaw

मुझे यकीन नहीं है कि मैं इस कथन के उद्देश्य को समझता हूं: WHERE g1.OGC_FID <> g2.OGC_FID
kflaw

इसके अलावा, मेरे परिणाम में मुझे अशक्त दूरी मिल रही है। मैंने इस लाइन के साथ खेला है: और ST_Contains (ST_Expand (g1.geometry, 50), g2.geometry) साथ ही इसे हटा दिया और अभी भी कोई दूरी मान नहीं मिलता है, भले ही मुझे एक आईडी मिल रही हो
kflaw

6

यदि आप सभी बिंदु संयोजनों के बीच की दूरी की गणना नहीं करना चाहते हैं, तो आप तालिका में से किसी एक पर एक स्थानिक सूचकांक का उपयोग कर सकते हैं:

SELECT 
  A.id , 
  B.myValue, 
  MIN(Distance(A.Geometry, B.Geometry)) AS distance
FROM tableOne AS A, tableTwo AS B
WHERE A.ROWID IN (
  SELECT ROWID
  FROM SpatialIndex WHERE
    f_table_name = 'A' 
    AND search_frame = BuildCircleMbr(ST_X(B.Geometry), ST_Y(B.Geometry), 10000))
GROUP BY A.id, B.myValue

मैंने आपके द्वारा पोस्ट किए गए समाधान का उपयोग करने की कोशिश की है क्योंकि मुझे एक स्थानिक सूचकांक का उपयोग करने की आवश्यकता है, लेकिन यह कोई मूल्य नहीं देता है? लाइन के लिए f_table_name = 'A', क्या मुझे वास्तविक तालिका नाम (तालिका एक) के साथ 'ए' को बदलने की आवश्यकता है? मैं किसी भी तरह की कोशिश की है और यह अभी भी कुछ भी वापस नहीं करता है, यह क्यों हो सकता है
kflaw

तुम सही f_table_name = 'A'हो f_table_name = 'tableOne'। ध्यान दें कि यह अनुरोध स्थानिकता मानता है> 4.x ( SpatialIndexवर्चुअल टेबल का उपयोग किया जाता है)। क्या आपने search_frameअपने उपयोग के मामले को समायोजित करने की कोशिश की ? ऊपर के उदाहरण में, अंक 10000 मीटर की अधिकतम दूरी पर माना जाता है।
शमूएल

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

यह संस्करण 4.1.1 के साथ sqlite संस्करण 3.7.17 है, इसलिए इसे तब काम करना चाहिए? मुझे आश्चर्य है कि क्या गलत है मैं इसे कुछ और परीक्षण
करूंगा

3

चूंकि संस्करण 4.4.0 स्पैटलाइट निकटतम पड़ोसी समस्याओं के लिए KNN वर्चुअल टेबल इंडेक्स का समर्थन करता है। यहाँ एक क्वेरी है जो एक पॉइंट टेबल में प्रत्येक बिंदु के लिए एक लिनेस्ट्रिंग तालिका में निकटतम रेखा पाता है।

SELECT k.* FROM knn k, points p
WHERE f_table_name = 'linestrings' 
AND ref_geometry = p.geometry
AND max_items = 1;

2

आप अपनी क्वेरी को इस तरह सरल बना सकते हैं।

SELECT 
   A.id , 
   B.myValue, 
   MIN(Distance(A.Geometry, B.Geometry)) AS distance
FROM tableOne AS A, tableTwo AS B
GROUP BY A.id, B.myValue

अधिक सामान्य समाधान के लिए, यह इस PostGIS निकटतम पड़ोसी फ़ंक्शन को परिवर्तित करने के लिए लायक हो सकता है: http://blog.mackerron.com/2011/03/postgis-nearest-neighbour/


दुर्भाग्य से कोड में परिणाम:SQL error: "misuse of aggregate: MIN()"
radek

PostGIS के रूप में BostonGIS वेबसाइट पर कुछ उदाहरण भी हैं , लेकिन अभी तक मैं उन्हें SpatiaLite में अनुवाद करने में सफल नहीं रहा: /
radek
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.