การทำให้ฟิลด์ตารางแอตทริบิวต์ QGIS เป็นอัตโนมัติหรือไม่


9

ฉันกำลังทำงานเพื่อสร้างโครงการอุทกวิทยาโดยใช้ QGIS และแผ่นงาน Excel ที่ฉันมี เมื่อต้องการทำสิ่งนี้ฉันต้องการดึงข้อมูลบางอย่างของบรรทัดรวมอยู่ในเวกเตอร์เลเยอร์ซึ่งแสดงถึงส่วนของไพพ์

ข้อมูลที่ฉันต้องการแยกคือ:

  • หมายเลขประจำตัว
  • ความยาว
  • X, Y พิกัดเริ่มต้นและสิ้นสุด

ฉันพบวิธีจับฟิลด์นี้โดยใช้ "$ length" และอัลกอริธึมอื่นสำหรับพิกัด X และ Y แต่สำหรับฉันต้องเปิดตารางคุณสมบัติใส่นิพจน์ในคอลัมน์แอตทริบิวต์แต่ละรายการและคลิกเพื่ออัปเดตฟิลด์

มีวิธีการหรือไม่เมื่อฉันวาดเส้นฟิลด์เหล่านี้จะถูกเติมโดยอัตโนมัติ? นั่นคือฉันวาด / แก้ไขบรรทัด (เริ่มการแก้ไขหรือโหนดสิ้นสุด) และเมื่อฉันเปิดตารางคุณลักษณะฟิลด์ความยาวและพิกัด X, Y จะเต็มและปรับปรุง


1
ไม่แน่ใจอย่างมั่นใจว่าเป็นไปได้หรือไม่ในขณะที่อยู่ในโหมดแก้ไขเนื่องจากทำในตารางชั่วคราว แต่คุณอาจดูการกระทำ คุณสามารถใช้มันเพื่อรันโค้ดไพ ธ อนเพื่อเติมในการคำนวณของคุณ คุณต้องกดปุ่มพิเศษเพื่อเรียกใช้จากตารางที่เกี่ยวข้อง คุณสามารถดูความเป็นไปได้ที่มีอยู่และดูว่ามันเหมาะกับความคิดของคุณหรือไม่
เคลือบ

คำตอบ:


7

หากคุณต้องการฟิลด์เหล่านี้ภายใน QGISคุณสามารถใช้ฟิลด์เสมือนได้ อนุญาตให้ใช้นิพจน์ (เช่น$length) ที่ขึ้นอยู่กับค่าอื่นหรือรูปทรงเรขาคณิต

เปิดเครื่องคำนวณฟิลด์เพิ่มฟิลด์ใหม่ด้วยความยาวชื่อตรวจสอบช่องทำเครื่องหมาย "ฟิลด์เสมือน" และป้อน$lengthเป็นนิพจน์ (หรืออย่างอื่นสำหรับฟิลด์อื่น)

อย่างไรก็ตามสิ่งเหล่านี้จะไม่ถูกบันทึกลงในไฟล์ excel

หากคุณต้องการให้ไฟล์ excel ซิงค์กับไฟล์ shpสำหรับรูปทรงเรขาคณิตและรวมฟิลด์ที่ได้รับในไฟล์ excel จะมีปลั๊กอินชื่อShpSyncที่รับรู้ถึงแนวคิดและฟิลด์อัพเดตนี้โดยอัตโนมัติเมื่อมีการเปลี่ยนแปลงเพิ่มหรือลบคุณสมบัติ


อันที่จริงคำตอบด้านล่างนี้ทำงานได้อย่างถูกต้องตามที่ฉันต้องการ แต่ปลั๊กอินนี้ที่คุณพูดจะทำงานในขั้นตอนต่อไปของโครงการของฉัน ขอบคุณสำหรับความช่วยเหลือของคุณ
LeoNazareth

15

คำถามที่น่าสนใจ! ฉันไม่ได้ตระหนักถึงวิธีอื่นในการบรรลุสิ่งที่คุณต้องการ แต่ใช้ PyQGIS

อ่านรหัสด้านล่าง แต่ก็มีบางตำราในมัน'lines', 'length', 'startX', 'startY', ,'endX' 'endY'คุณสามารถปรับชื่อเหล่านั้นในสคริปต์เพื่อให้ทำงานกับข้อมูลของคุณ ชื่อแรกคือชื่อเลเยอร์ของคุณในขณะที่ส่วนที่เหลือสอดคล้องกับชื่อฟิลด์ ฉันสมมติว่าเลเยอร์บรรทัดของคุณมีฟิลด์เหล่านั้น (หลังจากนั้นทั้งหมดคุณต้องการให้มีการเขียนค่าไว้ที่นั่น)

เมื่อคุณปรับชื่อเลเยอร์และชื่อของฟิลด์ที่คุณต้องการอัปเดตโดยอัตโนมัติแล้วให้คัดลอกและวางสคริปต์ลงในคอนโซล QGIS Python

หากทุกอย่างเป็นไปด้วยดีคุณจะเห็นว่าค่าของฟิลด์นั้นได้รับการปรับปรุงโดยอัตโนมัติในสองสถานการณ์: 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ไฟล์ที่คุณเพิ่งบันทึกไว้คุณลักษณะของเลเยอร์บรรทัดของคุณจะได้รับการอัปเดตโดยอัตโนมัติเมื่อคุณเพิ่มคุณสมบัติใหม่หรือปรับเปลี่ยนรูปทรงเรขาคณิต (เช่นไม่จำเป็นต้องคัดลอกอะไรลงใน QGIS Python Console อีกต่อไป)


แก้ไขครั้งที่ 2:

ฉันเพิ่งเผยแพร่ปลั๊กอินที่เรียกว่า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 พิกัดที่ฉันได้พบในคำตอบเก่าของคุณในลิงค์โพสต์นี้เช่นเดียวกับที่คุณโพสต์ในขณะนี้ ฉันได้ทดสอบระบบอัตโนมัติแล้วและทำงานได้อย่างสมบูรณ์ ฉันบันทึกรหัส Python เป็นไฟล์ ".pycl" หากคุณสามารถอธิบายให้ฉันฟังว่ามันจะใช้ได้เมื่อฉันเปิดโครงการ QGIS ของฉันจะดีมาก ขอบคุณโดยความช่วยเหลือ
LeoNazareth

1
เยอรมันนั่นเป็นคำตอบที่ยอดเยี่ยม! ขอบคุณ! ฉันได้เรียนรู้มากมายจากสิ่งที่คุณโพสต์!
jbgramm

1
ฉันกำลังทำงานกับปลั๊กอินที่จะช่วยให้คุณทำอย่างนั้น เนื่องจากฉันสามารถอุทิศให้กับการพัฒนาได้เพียงเวลาว่างฉันไม่สามารถบอกวันที่คาดว่าจะวางจำหน่ายได้ ในระหว่างนี้คุณสามารถเรียกใช้ข้อมูลโค้ดที่ 1 ของฉันหลังจากที่คุณเพิ่ม Tramo.shp แล้วปรับ: myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'Tramo' )[0]หากคุณสนใจปลั๊กอินในอนาคตของฉันจริงๆโปรดส่งคำแนะนำที่คุณมีให้ฉัน คุณสามารถติดต่อเราได้ที่GeoTux
Germán Carrillo

1
นั่นจะเป็นสิ่งที่ยอดเยี่ยมสำหรับฉัน (และสำหรับผู้คนจำนวนมาก) ฉันใช้รหัสนี้กับความอยุติธรรมที่คุณแนะนำ ฉันจะรอปลั๊กอินใหม่ของคุณอย่างใจจดใจจ่อและถ้าฉันคิดว่ามีประโยชน์ฉันจะติดต่อคุณ ขอบคุณสำหรับทุกสิ่ง.
LeoNazareth

1
@LeoNazareth คุณต้องการทดสอบปลั๊กอินหรือไม่ มันเตรียมพร้อมแล้ว แต่ฉันต้องการที่จะทำการทดสอบก่อนที่จะปล่อยมัน ถ้าคุณยินดีที่จะทดสอบกรุณาส่งE-mail
Germán Carrillo

2

สำหรับ QGIS 3เดินทางไปLayers Properties=> Attributes Form=> เลือกสาขาของคุณมีค่าเรขาคณิต (ในตัวอย่างเช่นarea) => ประเภท$areaในกล่องและตรวจสอบDefaults value Apply default value on updateนอกจากนี้ยังอาจเป็นประโยชน์: $perimeter, $y, $x,$id


1

ฉันจะใส่ข้อมูลในฐานข้อมูล (PostGIS) และดึงข้อมูลไปยัง QGIS ด้วยมุมมอง (อาจปรากฏขึ้น)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.