Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

मैं MySQL बहुभुज ओवरलैप प्रश्नों को कैसे संभाल सकता हूं?

SQL fiddle

बहुभुज स्तंभ के साथ तालिका बनाएं

कृपया ध्यान दें, कि स्थानिक अनुक्रमणिका का उपयोग करने के लिए, आप InnoDB का उपयोग नहीं कर सकते। आप स्थानिक अनुक्रमणिका के बिना ज्यामिति का उपयोग कर सकते हैं, लेकिन प्रदर्शन हमेशा की तरह कम हो जाता है।

CREATE TABLE IF NOT EXISTS `spatial` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `poly` geometry NOT NULL,
  UNIQUE KEY `id` (`id`),
  SPATIAL INDEX `poly` (`poly`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

3 वर्ग और एक त्रिभुज सम्मिलित करें

INSERT INTO `spatial` (`poly`) VALUES (GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))',0));
INSERT INTO `spatial` (`poly`) VALUES (GeomFromText('POLYGON((10 50,50 50,50 10,10 10,10 50))',0));
INSERT INTO `spatial` (`poly`) VALUES (GeomFromText('POLYGON((1 15,5 15,5 11,1 11,1 15))',0));
INSERT INTO `spatial` (`poly`) VALUES (GeomFromText('POLYGON((11 5,15 5,15 1,11 5))',0));

वह सब चुनें जो निचले बाएं कोने में छोटे वर्ग को प्रतिच्छेद करता हो (बैंगनी वर्ग #1)

SELECT id,AsText(poly) FROM  `spatial` 
    WHERE 
        ST_Intersects(`poly`,
            GEOMFROMTEXT('POLYGON((0 0,2 0,2 2,0 2,0 0))', 0 )
        )
;

वह सब चुनें जो त्रिभुज को निचले बाएँ से निचले दाएँ कोने से लेकर ऊपरी दाएँ कोने तक काटता हो) (वर्ग #1 और #2 और त्रिभुज #4.)

SELECT id,AsText(poly) FROM  `spatial` 
    WHERE 
        ST_Intersects(`poly`,
            GEOMFROMTEXT('POLYGON((0 0,50 50,50 0,0 0))', 0 )
        )
;

वर्ग में सब कुछ चुनता है जो हमारी छवि के बाहर है (कुछ नहीं)

SELECT id,AsText(poly) FROM  `spatial` 
    WHERE 
        ST_Intersects(`poly`,
            GEOMFROMTEXT('POLYGON((100 100,200 100,200 200,100 200,100 100))', 0 )
        )
;

#1 संपादित करें:

मैंने प्रश्न को फिर से पढ़ा और मुझे लगता है कि आपके स्थानिक संबंध थोड़े भ्रमित हैं। यदि आप जो चाहते हैं वह सब कुछ एक वर्ग (बहुभुज) के अंदर फिट बैठता है, तो आपको इसमें शामिल/ST_Contains का उपयोग करने की आवश्यकता है। कृपया MySQL के दस्तावेज़ों में स्थानिक फ़ंक्शन देखें यह पता लगाने के लिए कि कौन सा फ़ंक्शन आपके लिए काम करता है। कृपया एसटी / एमबीआर कार्यों के बीच निम्नलिखित अंतर पर ध्यान दें:

वह सब कुछ चुनता है जो पूरी तरह से एक वर्ग के अंदर है (#0 नीचे से) (वर्ग #1, #2, त्रिभुज #4)

SELECT id,AsText(poly) FROM  `spatial` 
    WHERE 
        Contains(
          GEOMFROMTEXT('POLYGON((0 0,20 0,20 20,0 20,0 0))', 0 ),
          `poly`
        )
;

वह सब कुछ चुनता है जो पूरी तरह से एक वर्ग के अंदर है (नीचे से #0) और किनारों को साझा नहीं करता है (वर्ग #2, त्रिभुज #4)

SELECT id,AsText(poly) FROM  `spatial` 
    WHERE 
        ST_Contains(
          GEOMFROMTEXT('POLYGON((0 0,20 0,20 20,0 20,0 0))', 0 ),
          `poly`
        )
;

#2 संपादित करें:

@StephanB से बहुत अच्छा जोड़ (SQL fiddle )

कोई भी अतिव्यापी ऑब्जेक्ट चुनें

SELECT s1.id,AsText(s1.poly), s2.id, AsText(s2.poly)
FROM  `spatial` s1, `spatial` s2
    WHERE 
        ST_Intersects(s1.poly, s2.poly)
    AND s1.id < s2.id
;

(बस ध्यान दें, कि आपको AND s1.id < s2.id . को हटा देना चाहिए अगर आप CONTAINS . के साथ काम कर रहे हैं , जैसा कि CONTAINS(a,b) <> CONTAINS(b,a) जबकि Intersects(a,b) = Intersects(b,a) )

निम्न चित्र में (गैर-विस्तृत सूची):

  • 2 प्रतिच्छेद #6.

  • 6 प्रतिच्छेद #2

  • 0 प्रतिच्छेद करता है #1, #2, #3, #4, #5

  • 1 प्रतिच्छेद करता है #0, #5

  • 0 में #1, #3, #4 और #5 शामिल हैं (#1, #3, #4 और #5 #0 के भीतर हैं)

  • 1 में #5 शामिल है (#5 #1 के अंदर है)

  • 0 st_ में #3, #4 और #5 शामिल हैं

  • 1 st_contains #5

संपादित करें #3:दूरी के आधार पर खोजना/मंडलियों में (साथ) कार्य करना

MySQL सीधे एक ज्यामिति के रूप में सर्कल का समर्थन नहीं करता है, लेकिन आप स्थानिक फ़ंक्शन का उपयोग कर सकते हैं Buffer(geometry,distance) इसके आसपास काम करने के लिए। क्या Buffer() करता है, ज्यामिति के चारों ओर उक्त दूरी का एक बफर बना रहा है। यदि आप ज्यामिति बिंदु से शुरू करते हैं, तो बफ़र वास्तव में एक वृत्त है।

आप केवल कॉल करके देख सकते हैं कि बफ़र वास्तव में क्या करता है:

SELECT ASTEXT(BUFFER(GEOMFROMTEXT('POINT(5 5)'),3))

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

इसलिए यदि आप एक वृत्त में आने वाले सभी बहुभुजों का चयन करना चाहते हैं आप पिछले उदाहरण को धो सकते हैं और दोहरा सकते हैं (यह सिर्फ वर्ग #3 मिलेगा)

SELECT id,AsText(poly) FROM  `spatial` 
    WHERE 
        ST_Contains(
          Buffer(GEOMFROMTEXT('POINT(6 15)'), 10),
          `poly`
        )
;

सभी बहुभुजों का चयन करें जो एक वृत्त के साथ प्रतिच्छेद करते हैं

SELECT id,AsText(poly) FROM  `spatial` 
    WHERE 
        ST_Intersects(
          Buffer(GEOMFROMTEXT('POINT(6 15)'), 10),
          `poly`
        )
;

आयतों से भिन्न आकृतियों के साथ काम करते समय, आपको ST_* . का उपयोग करना चाहिए कार्य। ST_ के बिना कार्य एक बाउंडिंग आयत का उपयोग करें। तो पिछला उदाहरण त्रिभुज #4 का चयन करता है, भले ही वह वृत्त में न हो।

Buffer() के रूप में काफी बड़े बहुभुज बनाता है, निश्चित रूप से ST_Distance() का उपयोग करने पर कुछ प्रदर्शन दंड होगा तरीका। दुर्भाग्य से मैं इसकी मात्रा निर्धारित नहीं कर सकता। आपको कुछ बेंचमार्किंग करनी होगी।

दूरी के आधार पर वस्तुओं को खोजने का दूसरा तरीका ST_Distance() . का उपयोग करना है समारोह।

तालिका से सभी तत्वों का चयन करें और बिंदु POINT(6 15) से उनकी दूरी की गणना करें

SELECT id, AsText(`poly`), 
    ST_Distance(poly, GeomFromText('POINT(6 15)')) 
    FROM `spatial`
;

आप ST_Distance . का उपयोग कर सकते हैं WHERE . में खंड भी।

उन सभी तत्वों का चयन करें जिनकी POINT(0 0) से दूरी 10 से कम या बराबर है (#1, #2 और #3 का चयन करता है)

SELECT id, AsText(`poly`), 
    ST_Distance(poly, GeomFromText('POINT(6 15)')) 
    FROM `spatial`
    WHERE ST_Distance(poly, GeomFromText('POINT(6 15)')) <= 10
;

हालांकि दूरी की गणना निकटतम बिंदु से निकटतम बिंदु तक की जाती है। इसे ST_Intersect . के समान बनाना . तो उपरोक्त उदाहरण #2 का चयन करेगा, भले ही वह पूरी तरह से सर्कल के अंदर फिट न हो।

और हाँ, GeomFromText(text,srid) . के लिए दूसरा तर्क (0) , कोई भूमिका नहीं निभाता है, आप इसे सुरक्षित रूप से अनदेखा कर सकते हैं। मैंने इसे कुछ नमूने से उठाया है और यह मेरे जवाब में फंस गया है। मैंने इसे अपने बाद के संपादनों में छोड़ दिया है।

बीटीडब्ल्यू। phpMyAdmin स्थानिक विस्तार के लिए समर्थन निर्दोष नहीं है, लेकिन यह देखने में काफी मदद करता है कि आपके डेटाबेस में क्या है। मेरे द्वारा संलग्न इन छवियों के साथ मेरी मदद की।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डिफ़ॉल्ट MySQL डेटाबेस नाम

  2. Django में GROUP_CONCAT समकक्ष

  3. MySQL (InnoDB) में सबसे अच्छी मिलान पंक्ति खोजें

  4. MySQL से एक्सएमएल आउटपुट

  5. MySQL में स्ट्रीम त्रुटि के पिछले छोर को पढ़ने का प्रयास किया गया