QGIS विशेषता तालिका फ़ील्ड को स्वचालित बनाना?


9

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

जानकारी है कि मुझे निकालने की जरूरत है:

  • आईडी नंबर
  • लंबाई
  • X, Y प्रारंभ और अंत निर्देशांक

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

क्या कोई रास्ता है जब मैं एक रेखा खींचता हूं ये क्षेत्र अपने आप भर जाते हैं? यही है, मैं एक रेखा खींचता हूं / संपादित करता हूं (नोड को संपादित करना या नोड शुरू करना) और जब मैं विशेषता तालिका खोलता हूं तो लंबाई फ़ील्ड और निर्देशांक X, Y भरे और अद्यतन किए जाते हैं।


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

जवाबों:


7

यदि आपको केवल QGIS के अंदर इन फ़ील्ड की आवश्यकता है , तो आप वर्चुअल फ़ील्ड का उपयोग कर सकते हैं। ये एक अभिव्यक्ति (जैसे $length) का उपयोग करने की अनुमति देते हैं जो अन्य मूल्यों या ज्यामिति पर निर्भर करता है।

फ़ील्ड कैलकुलेटर खोलें, नाम लंबाई के साथ एक नया फ़ील्ड जोड़ें, "वर्चुअल फ़ील्ड" चेकबॉक्स की जांच करें और $lengthअभिव्यक्ति (या अन्य क्षेत्रों के लिए कुछ और) के रूप में दर्ज करें।

हालांकि ये एक्सेल फाइल में सेव नहीं होंगे।

यदि आप ज्यामिति के लिए एक shp फ़ाइल के साथ एक excel फ़ाइल रखना चाहते हैं और excel फ़ाइल में व्युत्पन्न फ़ील्ड शामिल हैं, तो ShpSync नामक एक प्लगइन है जो इस अवधारणा के बारे में जानता है और सुविधाओं को बदलने, जोड़ने या हटाने पर स्वचालित रूप से फ़ील्ड अपडेट करता है।


वास्तव में, नीचे दिया गया जवाब ठीक उसी तरह से काम करता है जैसा कि मैं करना चाहता हूं, लेकिन यह प्लगइन आपने कहा कि मेरे प्रोजेक्ट के अगले चरण के लिए काम करेगा। आपकी मदद के लिए धन्यवाद
लियोनाज़रेथ

15

दिलचस्प सवाल! आप जो चाहते हैं, उसे प्राप्त करने के किसी भी अन्य तरीके से मैं अवगत नहीं हूं, लेकिन PyQGIS का उपयोग कर रहा हूं।

नीचे दिए गए कोड को पढ़ें। यह उस में कुछ ग्रंथों है: 'lines', 'length', 'startX', 'startY', 'endX', 'endY'। आप अपने डेटा पर काम करने के लिए स्क्रिप्ट में उन नामों को समायोजित कर सकते हैं। पहला आप परत नाम है, जबकि बाकी फ़ील्ड नामों से मेल खाता है। मुझे लगता है कि आपकी लाइन की परत में वे क्षेत्र हैं (आखिरकार, आप चाहते हैं कि मान वहां लिखे जाएं)।

एक बार जब आप अपना परत नाम और उन क्षेत्रों के नाम समायोजित कर लेते हैं जिन्हें आप स्वचालित रूप से अपडेट करना चाहते हैं, तो QGIS पायथन कंसोल में स्क्रिप्ट को कॉपी और पेस्ट करें।

यदि सब कुछ ठीक हो जाता है, तो आपको यह देखने में सक्षम होना चाहिए कि फ़ील्ड मान स्वचालित रूप से दो परिदृश्यों में अपडेट किए जाते हैं: 1) जब नई सुविधाएँ जोड़ी जाती हैं, और 2) जब ज्यामिति संशोधित होती हैं।

# Initialize required variables
myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
lengthField = myLayer.fieldNameIndex( 'length' )
startXField = myLayer.fieldNameIndex( 'startX' )
startYField = myLayer.fieldNameIndex( 'startY' )
endXField = myLayer.fieldNameIndex( 'endX' )
endYField = myLayer.fieldNameIndex( 'endY' )

# Slot, updates field values
def updateFeatureAttrs( fId, geom=None ):
    f = myLayer.getFeatures( QgsFeatureRequest( fId ) ).next()    
    if not geom:
        geom = f.geometry() 
    myLayer.changeAttributeValue( fId, lengthField, geom.length() )
    myLayer.changeAttributeValue( fId, startXField, geom.vertexAt( 0 )[0] )
    myLayer.changeAttributeValue( fId, startYField, geom.vertexAt( 0 )[1] )
    myLayer.changeAttributeValue( fId, endXField, geom.asPolyline()[-1][0] )
    myLayer.changeAttributeValue( fId, endYField, geom.asPolyline()[-1][1] )

# Update feature attributes when new features are added or geometry changes
myLayer.featureAdded.connect( updateFeatureAttrs )
myLayer.geometryChanged.connect( updateFeatureAttrs )

यह इस तरह काम करता है:

QGIS में खेतों का स्वचालित अद्यतन

यदि आपको स्क्रिप्ट चलाते समय कोई समस्या है, तो इस उत्तर के नीचे एक टिप्पणी जोड़ें।

जब आप अपना QGIS प्रोजेक्ट खोलते हैं, तो आपके लिए यह कार्यक्षमता पहले से उपलब्ध हो सकती है। अगर ऐसा है, तो मुझे बताएं, मैं ऐसा करने के लिए निर्देश दे सकता हूं।


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

इस कार्यक्षमता के उपलब्ध होने के लिए हर बार जब आप अपना QGIS प्रोजेक्ट खोलते हैं (जैसे, एक .qgsफ़ाइल, जिसमें अन्य, आपकी लाइन की परत) आपको इन चरणों का पालन करने की आवश्यकता है:

  1. पर जाएं QGIS->Project->Project Properties->Macros, जाँच Python macrosविकल्प, और यह एक (अपने परत और फ़ील्ड नाम का संकेत मान समायोजित) के साथ पूरे कोड की जगह:

    from qgis.core import QgsMapLayerRegistry, QgsFeatureRequest
    def openProject():    
        # Initialize required variables
        myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
    
        # Update feature attributes when new features are added or geometry changes
        myLayer.featureAdded.connect( updateFeatureAttrs )
        myLayer.geometryChanged.connect( updateFeatureAttrs )
    
    # Slot, updates field values
    def updateFeatureAttrs( fId, geom=None ):
        myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
        lengthField = myLayer.fieldNameIndex( 'length' )
        startXField = myLayer.fieldNameIndex( 'startX' )
        startYField = myLayer.fieldNameIndex( 'startY' )
        endXField = myLayer.fieldNameIndex( 'endX' )
        endYField = myLayer.fieldNameIndex( 'endY' )
        f = myLayer.getFeatures( QgsFeatureRequest( fId ) ).next()    
        if not geom:
            geom = f.geometry() 
        myLayer.changeAttributeValue( fId, lengthField, geom.length() )
        myLayer.changeAttributeValue( fId, startXField, geom.vertexAt( 0 )[0] )
        myLayer.changeAttributeValue( fId, startYField, geom.vertexAt( 0 )[1] )
        myLayer.changeAttributeValue( fId, endXField, geom.asPolyline()[-1][0] )
        myLayer.changeAttributeValue( fId, endYField, geom.asPolyline()[-1][1] )
    
    def saveProject():
        pass
    
    def closeProject():
        pass
    
  2. सुनिश्चित करें कि आप अपने प्रोजेक्ट पर मैक्रोज़ को इस तरह से सक्षम करते हैं Settings->Options->General->Enable macros: Always:।

  3. अपने QGIS प्रोजेक्ट को सहेजें।

अब, हर बार जब आप .qgsअपने द्वारा सेव की गई फ़ाइल को खोलते हैं , तो जब आप एक नई सुविधा जोड़ते हैं या एक ज्यामिति को संशोधित करते हैं, तो आपकी लाइन लेयर की विशेषताओं को स्वचालित रूप से अपडेट किया जाएगा (यानी, अब क्यूजीआईएस पायथन कंसोल में कुछ भी कॉपी करने की आवश्यकता नहीं है)।


दूसरा संस्करण:

मैंने इस तरह की समस्याओं को हल करने में लोगों की मदद करने के लिए AutoFields नामक एक प्लगइन प्रकाशित किया है। मैंने एक वीडियो भी बनाया है जिसमें दिखाया गया है कि कैसे आप अपने हल को हल कर सकते हैं, आप इसे देख सकते हैं:

https://vimeo.com/germap/autofields-geometric-properties

AutoFields प्रलेखन: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis


2
यही वह है जिसकी तलाश में मैं हूं। वास्तव में मैं X, Y निर्देशांक को पकड़ने के लिए आपके कोड का उपयोग कर रहा था, जो कि मैंने इस पोस्ट लिंक में आपके पुराने उत्तर में पाया है , वही जो आप अभी पोस्ट करते हैं। मैंने पहले ही स्वचालन का परीक्षण कर लिया है और यह पूरी तरह से काम करता है। मैंने पायथन कोड को ".pycl" के रूप में सहेजा है। यदि आप मुझे समझा सकते हैं कि जब मैं अपना QGIS प्रोजेक्ट खोलूंगा तो यह कैसे उपलब्ध हो सकता है। मदद के लिए धन्यवाद।
लियोनाज़ारेथ

1
जर्मन, यह एक भयानक जवाब था! धन्यवाद! मैंने जो कुछ पोस्ट किया है, उससे मैंने आपसे बहुत कुछ सीखा!
jbgramm

1
मैं वास्तव में एक प्लगइन पर काम कर रहा हूं जो आपको बिल्कुल ऐसा करने की अनुमति देगा। जैसा कि मैं केवल अपने खाली समय में इसके विकास के लिए समर्पित कर सकता हूं, मैं आपको एक रिलीज की तारीख नहीं बता सकता। इस बीच, आप Tramo.shp जोड़ने के बाद मेरा पहला कोड स्निपेट चला सकते हैं, समायोजित करना: myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'Tramo' )[0]यदि आप वास्तव में मेरे भविष्य के प्लगइन में रुचि रखते हैं, तो कृपया मुझे कोई सुझाव भेजें, जो आपके पास है, मैं उसकी सराहना करता हूं। आप मुझसे जियोक्स पर संपर्क कर सकते हैं ।
जर्मेन कैरिलो

1
यह मेरे लिए बहुत अच्छा होगा (और बहुत सारे लोगों के लिए), मैं पहले से ही आपके द्वारा सुझाए गए इस अन्याय के साथ कोड का उपयोग कर रहा हूं। मैं उत्सुकता से आपके नए प्लगइन की प्रतीक्षा करता हूं, और अगर मुझे लगता है कि कुछ उपयोगी है तो मैं आपसे संपर्क करता हूं। हरचीज के लिए धन्यवाद।
लियोनाज़रेथ

1
@LeoNazareth, क्या आप प्लगइन का परीक्षण करना चाहेंगे? यह तैयार हो रहा है, लेकिन मैं इसे जारी करने से पहले कुछ परीक्षण करना चाहूंगा। यदि आप इसका परीक्षण करने के इच्छुक हैं, तो कृपया मुझे एक ई-मेल भेजें
जर्मेन कैरिलो

2

QGIS 3 के लिए Layers Properties=>> Attributes Form= ज्यामिति मानों के साथ अपना क्षेत्र चुनें (उदाहरण के लिए area) => बॉक्स $areaमें टाइप Defaults valueकरें और जांचें Apply default value on update। यह भी उपयोगी हो सकता है: $perimeter, $y, $x,$id


1

मैं डेटा को एक डेटाबेस (पोस्टजीआईएस) में डालूंगा और डेटा को क्यूजीआईएस में (शायद भौतिक रूप से) देखने के लिए निकालूंगा।

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