QGIS में वोरोनोई बहुभुज निर्माण में छेद / बाधाओं को ध्यान में रखते हुए?


12

मैं QGIS में वोरोनोई पॉलीगॉन बनाने की कोशिश कर रहा हूं जो सामान्य डोमेन में "छेद" पर विचार करेगा। एक उदाहरण होगा:

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

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

यहां दो समस्याएं उत्पन्न होती हैं:

  1. "अंतर" फ़ंक्शन 100% ठीक से काम नहीं करता है, कुछ बहुभुज सीमाएं "छेद" में फैली हुई हैं। यह विशेषता तालिका में पंक्ति ढूंढकर तय की जा सकती है, जिसमें बहुभुज आईडी संख्या (या "0" की आईडी) नहीं है।

  2. इस प्रकार के बाद के "छेद-छिद्रण" के परिणामस्वरूप असंतुलित बहुभुज हो सकते हैं, जैसा कि छवि में लाल तीर द्वारा दिखाया गया है।

मेरा सवाल यह है: क्या एक वोरोनोई टूल या प्लगइन है जो डोमेन के केंद्र में "छेद" की उपस्थिति पर विचार कर सकता है, एक-कदम प्रक्रिया के रूप में, और बंद पॉलीगोन की पीढ़ी को भी खत्म कर सकता है? मैं कल्पना करता हूं कि ऐसा उपकरण एक अन्य सीमा के साथ निकटतम चौराहे तक बहुभुज सीमा का विस्तार करेगा, जब तक कि एक "छेद" सीमा के खिलाफ अन्य सीमा स्लैम न हो।


यह आर्कजीआईएस में एक पर्यावरण मास्क का उपयोग करने के विपरीत (लेकिन मुझे लगता है) के समान होगा । यह आपको एक विशेष सीमा के भीतर बनाए गए बहुभुज को बाधित करने देगा। हालाँकि मुझे ऐसे किसी भी उपकरण के बारे में पता नहीं है जो जटिल सीमाओं / छिद्रों का उपयोग करेगा (हालाँकि शायद आर्कगिस में मास्क उस जटिल हो सकता है - मैंने इसका परीक्षण नहीं किया है और हो सकता है कि बाद में समय हो तो मैं इसे आजमा सकता हूँ)।
क्रिस डब्ल्यू

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

2
आप संभावित रूप से रेखापुंज में जाकर इसे हल कर सकते हैं। एक रास्टर मास्क के साथ, यूक्लिडियन दूरी आपके बिंदुओं से तब तक बाहर निकलेगी जब तक कि यह किसी अन्य बिंदु से निकलने वाली कोशिकाओं या आपके मुखौटा रेखापुंज (आपकी सीमा स्लैम विवरण) को हिट न कर दे। फिर आप कुछ जोनल क्लीनअप करते हैं और पॉलीगॉन प्राप्त करने के लिए परिणाम को वेक्टर करते हैं।
क्रिस डब्ल्यू

1
मुझे यकीन है कि voronoi जियोमेट्री v.clean चलाकर मान्य है तो ज्यामिति की जांच करें। अंत में, छेद बनाने के लिए अंतर को निष्पादित करें।
क्लेविस

इन छिद्रों के बारे में वोरोनोई क्या है? क्या आप छिद्रों को सफाई से पंच करना नहीं चाहते हैं? कोई बहुभुज परत क्यों नहीं करेगा?
23

जवाबों:


3

यह संभव है कि चूहों का उपयोग करना। पहले अपने बिंदुओं और सीमा बहुभुजों को एक उच्च रिज़ॉल्यूशन रेखापुंज में परिवर्तित करें। का उपयोग कर अपनी सीमाओं के लिए एक मुखौटा सेट करें r.mask। फिर, r.grow.distanceGRASS में चलाएं और उपयोग करें Value= output। यह आपको प्रत्येक पिक्सेल के लिए देगा, जो निकटतम बिंदु है। इसे वापस वेक्टर बहुभुज में बदलें। स्लिवर पॉलीगोन से छुटकारा पाने के लिए आवश्यक अतिरिक्त कदम हो सकते हैं।


2

यह निश्चित रूप से मुर्गों के साथ संभव है।

यह स्क्रीनशॉट उम्मीद करता है कि मुद्दा अधिक स्पष्ट रूप से दिखाई देगा। वोरोनोई का भाग B, मूल वोरोनोई केंद्र के समीप 'कौवा मक्खियों के रूप में' है, लेकिन यह इस तथ्य को ध्यान में नहीं रखता है कि भवन के चारों ओर चलने में अधिक समय लगेगा। ओपी के सवाल के बारे में मेरी समझ यह है कि भवन के चारों ओर चलने के लिए वोरोनोई को इस अतिरिक्त दूरी को ध्यान में रखना होगा।

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

मुझे @ गिलूयूम का सुझाव पसंद है। हालाँकि, जब मैंने इसकी कोशिश की तो मुझे r.grow.distanceमास्क का सम्मान करने में समस्या हो रही थी (नीचे देखें। रिपल्स को इमारतों से नहीं गुजरना चाहिए)।

मेरा ग्रास ज्ञान उतना मजबूत नहीं है जितना कि यह हो सकता है, इसलिए शायद मैं कुछ बेवकूफी कर रहा हूं। निश्चित रूप से, पहले उस सुझाव की जाँच करें क्योंकि यह मेरी तुलना में बहुत कम काम होगा ;-)

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

चरण 1 - एक लागत सतह बनाएं

लागत की सतह बनाने के लिए पहला कदम है। यह केवल एक बार किया जाना चाहिए।

  • एक संपादन योग्य परत, छेद और सभी बनाएं।
  • 'यूनिट' नामक फ़ील्ड जोड़ें, इसे 1 पर सेट करें।
  • बहुभुज-से-रेखापुंज का उपयोग आपके "छिद्रित" वेक्टर परत (जिस पर छेद होता है) पर फ़ील्ड 'यूनिट' का उपयोग करके किया जाता है। अब आपके पास एक लेयर "मास्क" है, जहाँ 1 खाली जगह है और 0 बिल्डिंग है।
  • इसे एक लागत सतह में बदलने के लिए रेखापुंज कैलकुलेटर का उपयोग करें। मैं 'आउटडोर' को 1 और 'घर के अंदर' को 9999 पर सेट करूँगा। यह इमारतों के बीच से गुजरना बेहद मुश्किल होगा।

    (( "मुखौटा @ 1" = 1) * 1) + (( "मुखौटा @ 1" = 0) * 9999)

आप लागत सतह पर थोड़ा सा शोर जोड़कर अधिक 'कार्बनिक' परिणाम प्राप्त कर सकते हैं (जैसे कि 1 से 3 तक यादृच्छिक संख्या का उपयोग करें, बजाय बाहरी pxiels के लिए 1)।

चरण 2. प्रत्येक वोरोनोई केंद्र के लिए संचयी लागत आपदाएं बनाएं

अब हम r.cost.coordinatesअपनी लागत सतह की परत के खिलाफ GRASS एल्गोरिथम (एक समय में एक वोरोनोई सेल के लिए) चला सकते हैं ।

प्रारंभ समन्वय के लिए, वोरनोई केंद्र का उपयोग करें। अंत समन्वय के लिए, अपने क्षेत्र के कोनों में से एक चुनें। मेरा सुझाव है कि 'नाइट्स टूर' का उपयोग करें क्योंकि इससे चिकनी परिणाम मिलते हैं।

परिणाम एक वोरोनोई केंद्र से समान यात्रा समय की रेखाओं को दर्शाता है। ध्यान दें कि इमारतों के चारों ओर बैंड कैसे लपेटते हैं।

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

यकीन नहीं है कि यह कैसे स्वचालित करने के लिए सबसे अच्छा है। शायद बैच मोड प्रसंस्करण, या pyqgis में किया।

चरण 3. चूहों को मर्ज करें

इसके लिए शायद कोड की जरूरत होगी। एल्गोरिथ्म होगा

create a raster 'A' to match the size of your cumulative cost images
fill raster 'A' with a suitably high number e.g. 9999
create an array of the same size as the raster.
for each cumulative cost raster number 1..N
    for each cell in image
        if cell < value in raster 'A'
            set value in raster 'A' to cell value
            set corresponding cell in array to cum. cost image number
write out array as a raster

उस दृष्टिकोण को एक रेखापुंज प्राप्त करना चाहिए जहां प्रत्येक कोशिका को वोरोनोई केंद्र द्वारा वर्गीकृत किया जाता है जो इसे निकटतम है, खाते की बाधाओं को ध्यान में रखते हुए।

तब आप रैस्टर-टू-बहुभुज का उपयोग कर सकते हैं। फिर आप रैस्टर से "स्टेप" इफेक्ट कलाकृतियों को हटाने के लिए जनरलाइज प्लगइन का उपयोग कर सकते हैं ।

चरण 2 और 3 पर अस्पष्टता के लिए क्षमा याचना ... मैं एक और सुरुचिपूर्ण समाधान के साथ किसी में झंकार की उम्मीद कर रहा हूँ :)


1
धन्यवाद स्टीवन, मेरे पास एक कामकाजी GRASS रेखापुंज काम-के आसपास है, लेकिन मैं अधिक सुरुचिपूर्ण समाधान की उम्मीद कर रहा था जैसा कि बाउंटी विवरण में वर्णित है।
UnderDark

0

नोट # 1 : मैं प्रस्तावित मुद्दे को पुन: पेश करने में सक्षम नहीं था क्योंकि अंतर उपकरण ने मेरे लिए कई परीक्षणों में अच्छा काम किया था जो मैंने किया था (शायद यह मुद्दे की सरल ज्यामिति के कारण था या क्योंकि प्रश्न के बाद से उपकरण में सुधार हुआ है 1 साल पहले पूछा)।

हालाँकि, मैं अंतर उपकरण के उपयोग से बचने के लिए PyQGIS में वर्कअराउंड प्रस्तावित करता हूं । सब कुछ दो इनपुट परतों के बीच स्थानीय चौराहे पर आधारित है (नीचे आंकड़ा देखें):

  1. एक बहुभुज वेक्टर परत वोरोनोई बहुभुज का प्रतिनिधित्व करती है;
  2. बहुभुज वेक्टर परत छेद / बाधाओं का प्रतिनिधित्व करती है जिसे विश्लेषण से बाहर करने की आवश्यकता होती है।

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

नोट # 2 : चूंकि मैं अंतर उपकरण का उपयोग नहीं करना चाहता , इसलिए मैं "स्लवर्स" (तब देखें) के निर्माण से बचने में सक्षम नहीं हूं, इसलिए मुझे v.cleanउन्हें खत्म करने के लिए उपकरण चलाने की आवश्यकता थी । इसके अलावा, @ क्रिस डब्ल्यू ने कहा,

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

इन आवश्यक परिसरों के बाद, मैं अपना कोड पोस्ट करता हूं:

##Voronoi_Polygons=vector polygon
##Constraints=vector polygon
##Voronoi_Cleaned=output vector

from qgis.core import *

voronoi = processing.getObject(Voronoi_Polygons)
crs = voronoi.crs().toWkt()
ex = voronoi.extent()
extent = '%f,%f,%f,%f' % (ex.xMinimum(), ex.xMaximum(), ex.yMinimum(), ex.yMaximum())

constraints = processing.getObject(Constraints)

# Create the output layer
voronoi_mod = QgsVectorLayer('Polygon?crs='+ crs, 'voronoi' , 'memory')
prov = voronoi_mod.dataProvider()
fields = voronoi.pendingFields() # Fields from the input layer
prov.addAttributes(fields) # Add input layer fields to the outLayer
voronoi_mod.updateFields()

# Spatial index containing all the 'constraints'
index_builds = QgsSpatialIndex()
for feat in constraints.getFeatures():
    index_builds.insertFeature(feat)

final_geoms = {}
final_attrs = {}

for feat in voronoi.getFeatures():
    input_geom = feat.geometry()
    input_attrs = feat.attributes()
    final_geom = []
    multi_geom = input_geom.asPolygon()
    input_geoms = [] # edges of the input geometry
    for k in multi_geom:
        input_geoms.extend(k)
    final_geom.append(input_geoms)
    idsList = index_builds.intersects(input_geom.boundingBox())
    mid_geom = [] # edges of the holes/constraints
    if len(idsList) > 0:
        req = QgsFeatureRequest().setFilterFids(idsList)
        for ft in constraints.getFeatures(req):
            geom = ft.geometry()
            hole = []
            res = geom.intersection(input_geom)
            res_geom = res.asPolygon()
            for i in res_geom:
                hole.extend(i)
                mid_geom.append(hole)
        final_geom.extend(mid_geom)
    final_geoms[feat.id()] = final_geom
    final_attrs[feat.id()] = input_attrs

# Add the features to the output layer
outGeom = QgsFeature()
for key, value in final_geoms.iteritems():
    outGeom.setGeometry(QgsGeometry.fromPolygon(value))
    outGeom.setAttributes(final_attrs[key])
    prov.addFeatures([outGeom])

# Add 'voronoi_mod' to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(voronoi_mod)

# Run 'v.clean'
processing.runalg("grass7:v.clean",voronoi_mod, 2, 0.1, extent, -1, 0.0001, Voronoi_Cleaned, None)

# Remove 'voronoi_mod' to the Layers panel
QgsMapLayerRegistry.instance().removeMapLayer(voronoi_mod)

जो इस परिणाम की ओर जाता है:

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

केवल स्पष्टता के लिए, यह v.cleanउपकरण के उपयोग के बिना परिणाम होगा :

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

@LeaningCactus द्वारा परिणाम के साथ अंतर यह है कि, अब तक, ज्यामिति टूटी नहीं हैं और उन्हें त्रुटियों के बिना "साफ" किया जा सकता है


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

क्षमा करें, मुझे समझ नहीं आया: क्या आपको परिणामों में कोई त्रुटि मिली? मैंने केवल उन मामलों के लिए कोड का परीक्षण किया, जिनमें बहुभुज प्रश्न में प्रस्तावित लोगों के समान थे।
15

अभी दुर्भाग्य से कोड का परीक्षण नहीं किया जा सकता है, लेकिन क्या आप i.stack.imgur.com/Jpfra.png में कटे हुए छेदों में परिवर्तन के साथ प्राप्त परिणाम दिखा सकते हैं ?
UnderDark

यदि मैं दाईं ओर सुविधा के लिए बाधा बढ़ाता हूं, तो मुझे यह प्राप्त होता है । इसके बजाय, यदि मैं सीधे बाधा को स्थानांतरित करता हूं, तो मैं इसे प्राप्त करता हूं ।
mgri

मेरे ड्राइंग पॉइंट में लाल तीर जो छोटा त्रिकोण है वह मुद्दा है। यह वहाँ नहीं होना चाहिए, लेकिन यह आपके परिणामों में भी है। इस दृष्टिकोण की तरह लगता है कि समस्या का # 1 हल करता है लेकिन # 2 को छोड़ देता है।
UnderDark
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.