अधिक

अतिव्यापी सुविधाओं को हटाने के लिए ST_Difference का उपयोग करना?

अतिव्यापी सुविधाओं को हटाने के लिए ST_Difference का उपयोग करना?


मैं बहुभुज का एक सेट बनाने के लिए ST_Difference का उपयोग करने का प्रयास कर रहा हूं (processing.trimmedparcelsnew) जिसमें PostGis 2.1 (और Postgres SQL 9.3) का उपयोग करके पॉलीगॉन के दूसरे सेट (test.single_geometry_1) द्वारा कवर किया गया कोई भी क्षेत्र शामिल नहीं है। यहाँ मेरी क्वेरी है:

क्रिएट टेबल प्रोसेसिंग.trimmedparcelsnew AS SELECT orig.id, ST_Difference(orig.geom, cont.geom) AS डिफरेंस फ्रॉम टेस्ट.single_geometry_1 cont, test.multi_geometry_1 orig;

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

मैंने परिणाम की एक तस्वीर संलग्न की है


टिप्पणियों के बाद, मैंने WHERE क्लॉज जोड़ने का प्रयास किया है। मैं उन पार्सल को चाहता हूं जिनमें कोई चौराहा नहीं है, और अन्य पार्सल के प्रतिच्छेदन क्षेत्रों को हटा दिया गया है (परत test.single_geometry उस संदूषण का प्रतिनिधित्व करता है जिसे मैं अपने पार्सल से हटाना चाहता हूं)। मैंने एक चौराहे की कोशिश की, लेकिन निश्चित रूप से मैं वास्तव में गैर चौराहों को चाहता हूं इसलिए अब मैं एक असंबद्ध प्रयास कर रहा हूं। मैंने अपनी तालिका में मूल को जोड़ने का भी प्रयास किया है, लेकिन ST_Difference (http://postgis.net/docs/ST_Difference.html) के लिए प्रलेखन कहता है कि यह मुझे आवश्यक सटीक ज्यामिति देता है (एक ज्यामिति जो ज्यामिति A के उस भाग का प्रतिनिधित्व करती है) ज्यामिति बी के साथ प्रतिच्छेद नहीं करता है), इसलिए मैं उलझन में हूं कि मैं इसके बजाय अपनी तालिका में मूल बहुभुज क्यों चाहूंगा। वैसे भी, यहाँ मेरा संशोधित कोड है:

क्रिएट टेबल प्रोसेसिंग.trimmedparcelsnew as SELECT orig.id, ST_Difference(orig.geom, cont.geom) AS डिफरेंस, orig.geom AS geom FROM test.single_geometry_1 cont, test.multi_geometry_1 मूल जहां ST_Disjoint(orig.geom), cont.geom ;

डबस्टन के उत्तर के बाद मैंने अब कोशिश की है:

चयन आईडी, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom) से test.single_geometry_1 b जहां ST_Intersects(a.geom, b.geom) AND a.id != b.id) के रूप में तालिका संसाधन बनाएं.parcels_trimmed)) , a.geom) परीक्षण से।multi_geometry_1 a;

इसका परिणाम केवल test.multi_geometry_1 की एक प्रति है। हालांकि अब बंटवारा नहीं हो रहा है।

मैंने पहले के संस्करण की कोशिश की, लेकिन फिर से बस test.multi_geometry_1 की एक प्रति प्राप्त करें:

चयन आईडी के रूप में तालिका संसाधन बनाएँ। , a.geom) परीक्षण से।multi_geometry_1 a;

मुझे आश्चर्य होने लगा है कि क्या कुछ और है जो मैं गलत कर रहा हूँ? कार्यवाही कथन है:

ड्रॉप टेबल यदि मौजूद है तो प्रोसेसिंग।parcels_trimmed_no_coalesce;

और मैं PostgreSQL SQL क्वेरी विंडो और Openjump से क्वेरी चला रहा हूं।

तालिका देखने के लिए मैं जिस कथन का उपयोग करता हूं वह है:

चयन करें * प्रसंस्करण से।parcels_trimmed_no_coalesce;

सरलीकरण के हित में मैंने अब इस प्रश्न को कम कर दिया है:

सेलेक्ट आईडी, COALESCE(ST_Difference(geom, (सिलेक्ट ST_Union(b.geom) से test.geometriestocut खिलाफ b जहां ST_Intersects(a.geom, b.geom) AND a.id != b.id)), a.geom) से test.geometriestocut a;

यह अभी भी केवल मूल बहुभुजों (test.geometriestocut) में परिणत होता है जब वांछित परिणाम test.geometriestocut खिलाफ मूल छंटनी की जाती है।


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

चयन आईडी, ST_Difference (जियोम, (चयन ST_Union (b.geom) से पार्सल b जहां ST_Intersects (a.geom, b.geom) और a.id! = b.id) के रूप में तालिका पार्सल बनाएं) पार्सल से a;

हालाँकि, आपको परिणामों में कुछ अजीब दिखाई दे सकता है। जिन पार्सल में कोई ओवरलैप नहीं है उन्हें पूरी तरह से गिराया जा रहा है! ऐसा इसलिए है क्योंकिST_संघएक खाली रिकॉर्डसेट पर कुल होने जा रहा हैशून्य, तथाST_Difference (जियोम, NULL)हैशून्य. इसे चिकना करने के लिए, आपको अपने को लपेटना होगाST_अंतरमें कॉल करेंसम्मिलित:

चयन आईडी, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom) पार्सल से b जहां ST_Intersects(a.geom, b.geom) और a.id!= b.id)) के रूप में तालिका पार्सल बनाएं, a.geom ) पार्सल से a;

इसका अर्थ यह है कि यदि परिणामST_अंतरहैशून्य, समेकित व्यंजक मूल ज्यामिति का मूल्यांकन करेगा।

उपरोक्त क्वेरी आपके डोमेन से अतिव्यापी क्षेत्रों को पूरी तरह से हटा देगी। यदि आप इसके बजाय एक विजेता चुनना चाहते हैं, तो आप कर सकते हैंa.id , या कुछ अन्य मानदंड, के बजायa.id != b.id.


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

चयन आईडी, COALESCE(ST_Difference(geom, (SELECT ST_Collect(b.geom) से पार्सल b जहां ST_Intersects(a.geom, b.geom))) के रूप में तालिका पार्सल बनाएं, a.geom) पार्सल से a;

मैं PostGIS Addons से ST_DifferenceAgg() का उपयोग करता हूं। आपको दो तालिकाओं को एक साथ मिलाना होगा, एक विशिष्ट पहचानकर्ता और ज्यामिति स्तंभ पर एक अनुक्रमणिका होनी चाहिए। यहाँ एक संक्षिप्त उदाहरण है:

ओवरलैपिंगटेबल एएस के साथ (चुनें 1 आईडी, ST_GeomFromText ('पॉलीगॉन ((0 1, 3 2, 3 0, 0 1), (1.5 1.333, 2 1.333, 2 0.666, 1.5 0.666, 1.5 1.333)') जियोम यूनियन सभी का चयन करें 2 आईडी, ST_GeomFromText('POLYGON((1 1, 3.8 2, 4 0, 1 1))') UNION ALL SELECT 3 id, ST_GeomFromText('POLYGON((2 1, 4.6 2, 5 0, 2 1))' ) यूनियन सभी चयन 4 आईडी, ST_GeomFromText ('पॉलीगॉन ((3 1, 5.4 2, 6 0, 3 1))') यूनियन सभी चयन 5 आईडी, ST_GeomFromText ('POLYGON ((3 1, 5.4 2, 6 0, 3) 1))')) सेलेक्ट a.id, ST_DifferenceAgg(a.geom, b.geom) geom FROM ओवरलैपिंगटेबल a, ओवरलैपिंगटेबल b जहां a.id = b.id OR - पॉलीगॉन को अपने साथ कम से कम एक बार पास करना सुनिश्चित करें ((ST_Contains(a.geom, b.geom) OR -- सभी युक्त, समाहित और अतिव्यापी बहुभुजों का चयन करें ST_Contains(b.geom, a.geom) OR ST_Overlaps(a.geom, b.geom)) और (ST_Area( a.geom)  0 और ST_IsEmpty नहीं (ST_DifferenceAgg(a.geom, b.geom));

यह अतिव्यापी भागों को सबसे बड़े अतिव्यापी बहुभुज के साथ मिला देगा। यदि आप अतिव्यापी भाग को अलग रखना चाहते हैं तो ST_splitAgg() उदाहरण देखें।