असंतुष्ट बहुभुज से वोरोनोई आरेख की तरह मोज़ेक बनाएं


12

नीचे दिया गया चित्रण समस्या दिखाता है :

यहाँ छवि विवरण दर्ज करें

के रूप में (ए) मैं PostGIS में ज्यामितीय के रूप में , बहुभुज का एक सेट है । मुझे कुछ ऐसा चाहिए (b) , बहुभुजों के इस सेट का "मोज़ेक" , इसे "प्रभाव क्षेत्र" मानदंड द्वारा निर्मित करना ... एक वोरोनोई निर्माण जैसा है (सचित्र (c) ): वास्तव में, यदि बहुभुज थे अंक, प्रभाव क्षेत्र वोरोनोई हैं।

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

पुनश्च: मुझे जरूरत है, वोरोनोई की तरह, उस स्थान परिसीमन ( (बी) में एक चौकोर फ्रेम ) को नजरअंदाज कर दिया जाता है।


यह समस्या लाइनों के बारे में इस अन्य के समान है ।

EDIT (@FelixIP टिप्पणी के बाद)

मैं वेक्टर ब्रह्माण्ड में रहने के लिए प्रीफ़ायर करता हूँ , खोई हुई शुद्धता नहीं (उदाहरण के लिए ST_DelaunayTriangles का उपयोग करना और मूल बहुभुजों द्वारा अंदरूनी जोड़ना और घटाना, उन्हें दोहरे ग्राफ़ समाधान को अपनाना ) ... कुछ साधारण और स्वचालित पैकेज जैसे pprepair ( QGIS टोपोलॉजिकल टूल की तरह सहायक) स्वचालित नहीं हैं)। लेकिन रेखापुंज शायद सरल और कम सीपीयू-खपत है।

यह "जीआरआईडी प्रक्रिया" चित्रण भी समाधान के रूप में मान्य है, यह मानते हुए कि यह एक ही परिशुद्धता और "यूक्लिडियन प्रभाव क्षेत्र को बढ़ने" की अनुमति दे सकता है।

यहाँ छवि विवरण दर्ज करें

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


धन्यवाद @Nir, अंकों के साथ भ्रम को क्षमा करें, मैं अंकों का उपयोग नहीं कर रहा हूं, केवल चित्र के (ए) और (बी) के रूप में बहुभुज ... क्या आपके पास समाधान के बारे में आपके सुराग का लिंक है?
पीटर क्रस

आर्कगिस में एक रस्टर सॉल्यूशन है जिसे यूकेलीन आवंटन या निकटता कहा जाता है
फेलिक्सिप

धन्यवाद @FelixIP, मैंने "वेलकम रास्टर सॉल्यूशंस" का संपादन किया; ;-)
पीटर क्रूस

यदि आप अपने पॉलीगनों को उनकी सीमा से मिटा देते हैं। तो, आप बहुभुज के साथ रह जाएंगे। इसका कंकाल gis.stackexchange.com/questions/177/… है जो आपको मेरे अनुमान की आवश्यकता है। कार्यान्वयन एक बड़ी बात है
फेलिक्सिप

1
@ साइरिल, मैं आपकी स्क्रिप्ट्स की समीक्षा कर सकता हूं ... अगले हफ्ते। आधुनिक PostGIS कार्यों के साथ एक समाधान लगता है कि कुछ पोस्ट करना, एक अच्छा पहला कदम होगा।
पीटर क्रस

जवाबों:


2

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

मैं अपने हास्य शैली में किसी के द्वारा नाराज नहीं होने और इसे एक खेल के रूप में समझने के लिए कहूंगा!

मूल फ़ाइल कटा हुआ फल और सरल आकार है (बाद में फल के रूप में संदर्भित), नीचे चित्र 1 देखें।

यहाँ छवि विवरण दर्ज करें

यहाँ मेरा नुस्खा है, और मुझे इसमें प्रिय प्रोग्रामर द्वारा मदद की जाएगी, जिन्हें आप बाद में जानेंगे। आइए शुरू करते हैं, और इसके लिए हम एक आटा बनाएँगे जिसमें हमारे फल रखे जाएँगे, जिसके लिए स्क्रिप्ट चलाएँ:

create table poly_extent as SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;

नीचे दिए गए चित्र 2 में परिणाम देखें

यहाँ छवि विवरण दर्ज करें

अब, अगर मेरे चित्र की तरह कुछ फल हैं, तो फलों पर बाहरी बफर की सीमा बनाएं, या यदि कई फल हैं, तो नकारात्मक बफर की सीमा बनाएं, जिसके लिए स्क्रिप्ट चलाएं:

create table poly_buff_dump as SELECT ((ST_Dump(ST_Boundary(ST_Union(ST_Buffer((geom),0.01, 'join=mitre mitre_limit=5.0'))))).geom) geom FROM poly;

और प्रत्येक फल के चारों ओर बफर लाइनों को स्लाइस करें

UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1) WHERE ST_IsClosed(geom)=true; नीचे दिए गए चित्र 3 में परिणाम देखें

यहाँ छवि विवरण दर्ज करें

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

फिर आपको प्राप्त लाइनों को आपके लिए एक सुविधाजनक तरीके से बराबर खंडों में विभाजित करने और उनसे अंक निकालने की आवश्यकता है

create table poly_buff_dump_pt as SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;

परिणाम, नीचे चित्र 4 देखें

यहाँ छवि विवरण दर्ज करें

अब वोरोनोई टूल चलाएं, इस स्थान पर मैंने लिंक मिकी द्वारा सुझाए गए टूल का उपयोग किया है: /gis//a/172246/120129 , जिसके परिणामस्वरूप आपने "वोरोनोई" नाम के साथ तालिकाओं का निर्माण किया होगा। "इस तथ्य के लिए कि" मेरा पहला सहायक "महाराज से धन्यवाद से अलग है! :-)।

इस चरण में दूसरा तरीका ST_VoronoiPolygons फ़ंक्शन को चलाना है।

परिणाम, नीचे चित्र 5 देखें

यहाँ छवि विवरण दर्ज करें

अब, स्क्रिप्ट चलाकर अतिरिक्त भागों को काट दें:

create table poly_voronoi_cut as SELECT ST_Intersection(a.geom, b.geom) geom FROM voronoi a INNER JOIN poly_extent b ON ST_Intersects(a.geom, b.geom); परिणाम, नीचे चित्र 6 देखें।

यहाँ छवि विवरण दर्ज करें

अब लाइनस्ट्रिंग में जियोडेटा प्रकार संरेखित करने के लिए स्क्रिप्ट चलाएँ:

create table poly_voronoi_dump as SELECT (ST_Dump(geom)).geom as geom FROM poly_voronoi_cut; और अब मैं अपने कर्तव्यों को पूरा करने के लिए "मेरे दूसरे साथी" से पूछूंगा और केक वेल (जेफ़ - /gis//a/785/120129 ) को मिला कर, इसे एक परत में समतल कर दूंगा , और उसके लिए इसके लिए मुझे धन्यवाद!

CREATE TABLE poly_overlay_cut AS SELECT geom FROM ST_Dump(( SELECT ST_Polygonize(geom) AS geom FROM ( SELECT ST_Union(geom) AS geom FROM ( SELECT ST_ExteriorRing(geom) AS geom FROM poly_voronoi_dump) AS lines ) AS noded_lines ) ); अब मेरे पास काम करने का समय है, जिसके लिए मैं स्क्रिप्ट चलाता हूं:

create table poly_voronoi_union as SELECT b.id, (ST_ConvexHull(ST_Union(a.geom, b.geom))) geom FROM poly_overlay_cut a INNER JOIN poly_buff_dump b ON ST_Intersects(a.geom, b.geom) GROUP BY b.id, a.geom, b.geom; और एक और स्क्रिप्ट:

create table poly_voronoi_union_area as SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union GROUP BY id; नीचे 7 आंकड़ा देखें

यहाँ छवि विवरण दर्ज करें

जैसा कि आप चित्र में देख सकते हैं, हमारी कटौती में छोटी परतें हैं, जिन्हें हटाया जा सकता है, एक विकल्प के रूप में ST_SnapToGrid (या किसी अन्य तरीके से) का उपयोग कर:

और अंत में, हम अपने पके हुए फल को हमारे पाई से काट लेंगे, मैं भी थोड़ा थक गया, ओवन से खड़ा हुआ, :-)

create table polygon_voronoi_result as SELECT (ST_Dump(ST_Difference(a.geom, b.geom))).geom as geom FROM poly_voronoi_union_area_snap as a JOIN poly b ON ST_Intersects(a.geom, b.geom); परिणाम आकृति 8 देखें यहाँ छवि विवरण दर्ज करें

इस दिन से सब कुछ, अब हर कोई स्वादिष्ट पिस - फलों की थाली को सेंकना सीख जाएगा। अपने आप को सभी की मदद करें, और उन टुकड़ों को चुनें, जिन्हें आप सभी के लिए पसंद करते हैं।

(यह एक दया है कि मैं वास्तव में सभी लोगों को नहीं खिला सकता हूं, इलेक्ट्रॉनिक केक के साथ नहीं, बल्कि असली केक के साथ, शायद भूख पृथ्वी पर समाप्त हो जाएगी ...)

संपादित करें: पाई पर चेरी इस तरह लग सकता है :-):

WITH
tbla AS (SELECT (ST_DumpPoints(geom)).geom geom FROM poly),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT ST_Intersection(a.geom, b.geom) geom FROM tblb a JOIN poly_extent b ON ST_Intersects(a.geom,b.geom)),
tbld AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM poly GROUP BY id, geom)
SELECT id, ST_Union(a.geom) as geom FROM tblc a JOIN tbld b ON ST_Intersects(a.geom, b.geom) GROUP BY id;

या

WITH
tbla AS (SELECT (ST_DumpPoints(geom)).geom geom FROM polygons),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM polygons GROUP BY id, geom)
SELECT id, ST_Union(a.geom) geom FROM tblb a JOIN tblc b ON ST_Intersects(a.geom, b.geom) GROUP BY id;

संशोधित स्क्रिप्ट 01.04.2020:

WITH tbla AS (
WITH atbl AS (SELECT id, (ST_ExteriorRing(((ST_Dump(geom)).geom))) geom FROM polygons),
intervals AS (SELECT generate_series (0, 501) as steps)
SELECT steps AS stp, ST_LineInterpolatePoint(geom, steps/(SELECT count(steps)::float-1 FROM intervals)) geom FROM atbl, intervals GROUP BY id, intervals.steps, geom),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM polygons GROUP BY id, geom)
SELECT id, ST_Union(a.geom) geom FROM tblb a JOIN tblc b ON ST_Intersects(a.geom, b.geom) GROUP BY id;

आपके साथ अच्छे और निष्पक्ष मिस्टर बेकर, आप सभी का धन्यवाद और शुभकामनाएँ: -) ...

मूल समाधान।

इस स्क्रिप्ट को कहा जाता है: ST_VoronoiDiagramsFromPolygons।


1
हाय, अच्छा चित्र, और अच्छा परिणाम लगता है (!)। एक संक्षिप्त चर्चा का सुझाव, @geogeek समाधान देखें, QGis के चरण यहाँ PostGIS के मुख्य चरण हैं ... ई की आवश्यकता क्यों है ST_Bufferऔर ST_ConvexHull? एक वैकल्पिक एल्गोरिदम हैं?
पीटर क्रूस

1) देखें, ST_Buffer और बहुभुजों पर वोरोनोई फ़ंक्शन के आवेदन के दौरान मूल आंकड़ों के बीच पृथक्करण लाइनों को कम करने के लिए बनाया जाता है, इसलिए, आप जितना बड़ा बफर आकार निर्दिष्ट कर सकते हैं, उतनी ही आसानी से पृथक्करण लाइनें बनाई जाएंगी। Voronoi फ़ंक्शन ... 2) ST_ConvexHull प्रत्येक बहुभुज पर आंकड़े की बहुतायत से, बहुभुज जो हमें चाहिए ... 3) आज, यह आपके प्रश्न को हल करने का मेरा दृष्टिकोण है, मुझे नहीं पता कि हम सभी का क्या होगा और भविष्य में हमारे फैसले ...
सिरिल मिखालचेंको

बफर लाइनों का एक और महत्वपूर्ण मूल्य यह है कि वे हमें वोरोनोई के कार्य के परिणाम से प्रत्येक आकृति के लिए संयुक्त बहुभुज बनाने के लिए टुकड़ों का चयन करने में मदद करेंगे ...
सिरिल मिखालचेंको

वैसे, मैं कोड और दृष्टिकोण में सुधार का स्वागत करता हूं, ताकि वे परिणाम को खराब न करें ...
सिरिल मिखालचेंको

1
हाय सिरिल, मैं सहमत हूँ कि ST_Buffer समोच्च लाइनों को सामान्य करने के लिए एक अच्छा विकल्प है, एकदम सही (!)। के बारे में ST_ConvexHull, केवल एक जिज्ञासा है, हम किस तरह के परिणाम प्राप्त कर सकते हैं चित्रा 6 के बाद, poly_voronoi_unionबिना ST_ConvexHull।
पीटर क्रूस

8

Postgis में voronoi के लिए एक समर्पित फ़ंक्शन नहीं है, लेकिन Qgis में vornoi फ़ंक्शन होता है जो बिंदुओं से voronoi बहुभुज बना सकता है, इसलिए qgis का उपयोग करते हुए मैंने इन परिणामों के लिए निम्न चरणों का पालन किया है:

extract nodesकार्यों का उपयोग कर बहुभुज से अंक बनाओ ।

Qgis में voroi कार्यों का उपयोग कर vornoi polygons ले लो।

-कगिस में एक स्थानिक जोड़ लें।

-विषयक परिणाम।

यहाँ छवि विवरण दर्ज करें


1
अच्छा समाधान (!), और चित्रण धन्यवाद। क्या आप इसे बढ़ा सकते हैं? नीचे दिए गए आयत को देखें, यह वोरोनोई में 4 अंक था, और आयत के केंद्र का कोई प्रतिनिधित्व नहीं है, अपने क्षेत्र को विकृत करना (त्रिकोण में खो जाना) ... शायद प्रत्येक बहुभुज का नियमित नमूनाकरण संभव है ... शायद कुछ आंतरिक बिंदु भी।
पीटर क्रस

मैं आर्कगिस में सघन उपकरण का उपयोग करता हूं। यह निकटता बहुभुज में काफी सुधार करता है। +1
फेलिक्सिप

3

ठीक है - इस बारे में थोड़ा सोचा और पाया कि यह कुछ ऐसा था जैसे मैं हाल ही में देख रहा हूँ।

अपना शुरुआती पोल लें:

यहाँ छवि विवरण दर्ज करें

एक नंबर के साथ एक नई विशेषता उत्पन्न करें (मेरे मामले में 100) वेक्टर का उपयोग करें-> अनुसंधान उपकरण -> बहुभुज उपकरण के अंदर यादृच्छिक अंक यह प्रत्येक बहुभुज के अंदर (100) अंक उत्पन्न करेगा: यहाँ छवि विवरण दर्ज करें

फिर वेक्टर-> ज्योमेट्री टूल्स -> वोरोनोई उस बिंदु परत के आधार पर पोल उत्पन्न करने के लिए।

यहाँ छवि विवरण दर्ज करें

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

अब आप अपने नए गुण के आधार पर वेक्टर-> जियोप्रोसेसिंग टूल-> को भंग कर सकते हैं।

यहाँ छवि विवरण दर्ज करें


धन्यवाद @AAmes (!), चित्र अच्छे हैं, और विधि एक अच्छा विकल्प है ... लेकिन सवाल "SQL एल्गोरिथ्म (या PostGIS के लिए कुछ विशिष्ट)" के बारे में है और अब, फ़ंक्शन के उपयोग के बारे में इनाम ST_VoronoiPolygons () , जो शायद एक क्लिक में सभी समस्या को हल कर सकते हैं ;-)
पीटर क्रस

@ एम्स एक त्वरित खोज से पता चलता है कि इस विधि का उपयोग वास्तव में PostGIS में भी किया जा सकता है। पोस्टगिस में एक बहुभुज में यादृच्छिक बिंदु कैसे बनाएं पॉलीगोन से बिंदु निर्माण की व्याख्या करता है और वहां से यह काफी सीधे आगे होना चाहिए।
फिल जी 12

मेरा इनाम आपके लिए था, प्रोत्साहन के रूप में (यहां आपका स्वागत है!), लेकिन यह सवाल और इनाम की आवश्यकताओं के लिए काम करता है।
पीटर क्रस

धन्यवाद पीटर, मैंने आपके नोट्स देखे लेकिन दुर्भाग्य से मुझे वापस आने और इसे संबोधित करने का अवसर नहीं मिला। मुझे अभी तक पोस्टजीआईएस में कोई अनुभव नहीं है और मुझे किसी भी तरह की अच्छी प्रतिक्रिया देने के लिए उपलब्ध होने में अधिक समय लगेगा। मुझे उम्मीद है कि भविष्य में इस स्थान की खोज लोगों के लिए उपयोगी है, हो सकता है कि अगर मुझे जल्द ही PostGIS में एक दरार मिल जाए, तो मैं वापस आऊंगा और अभ्यास के लिए एक और अजीब कदम उठाऊंगा!
AA

2

रैंडम पॉइंट पॉलीगॉन से एक वोरोनोई पॉलीगॉन उत्पन्न करने के लिए एक अच्छा विचार है, यह बहुत अच्छी तरह से काम करता है, लेकिन यह पॉलीगोन एक दूसरे के करीब के लिए बहुत बुरा है: यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

ST_ApproximateMedialAxis एक और अच्छा विकल्प है अगर PostGIS का उपयोग किया जाए: बहुभुज के लिए वोरोनोई आरेखों की गणना

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