ฉันจะสร้างและเพิ่มฟีเจอร์ให้กับเลเยอร์หน่วยความจำใน QGIS 1.9 ได้อย่างไร


13

ฉันมีปลั๊กอินที่ใช้งานได้ใน QGIS 1.8 ซึ่งอ่านข้อมูลจากฐานข้อมูล MSAccess และเพิ่มลงในชุดของเลเยอร์หน่วยความจำ มีการประมวลผลที่เกี่ยวข้องในระหว่างกาลดังนั้นฉันไม่คิดว่าการใช้ QGIS เพื่ออ่านโดยตรงจากฐานข้อมูลเป็นตัวเลือก

ฉันต้องการย้ายจาก QGIS 1.8 เป็น 1.9 (สาเหตุหลักมาจากการปรับปรุงคุณภาพของนักแต่งเพลงการพิมพ์) ปลั๊กอินไม่ทำงานกับ API ใหม่

ฉันลองใช้วิธีการหลายวิธีที่ปรากฏในการค้นหาของ Google หนึ่งแก้ไขรหัสด้านล่าง - จากhttp://www.qgis.org/pyqgis-cookbook/vector.html#memory-providerเช่นการเพิ่มรูปทรงเรขาคณิตและคุณลักษณะให้กับดาต้าเบสเดอร์จากนั้นอัปเดตเลเยอร์ - เพื่อให้เหมาะกับ API ใหม่ที่ทำงาน เล็กน้อย แต่ไม่สามารถมองเห็นแอตทริบิวต์ได้จนกว่าฉันจะเข้าสู่โหมดแก้ไข (คล้ายกับhttp://hub.qgis.org/issues/3713 ) วิธีอื่นที่มีรายละเอียดในการตอบกลับ # 1 ของลิงค์ด้านบนเพิ่มเลเยอร์และคุณลักษณะอย่างถูกต้อง แต่ฉันไม่สามารถเพิ่มคุณสมบัติให้กับเลเยอร์ได้

ระบุว่ามันควรจะเป็นงานที่ค่อนข้างง่ายฉันหวังว่าบางคนในที่นี้จะสามารถนำเสนอตัวอย่างการทำงานของวิธีการที่ควรทำ (PS ฉันไม่ใช่โปรแกรมเมอร์มืออาชีพและการเข้ารหัสส่วนใหญ่ของฉันค่อนข้างหยาบ - ฉันยินดีต้อนรับแนวทางใด ๆ แต่ขอให้คุณแก้ตัวไม่รู้ในส่วนของฉัน)

# Receivers = a list of lists returned from a database query

# create layer
vl = QgsVectorLayer("Point", item, "memory")
pr = vl.dataProvider()

# add fields
pr.addAttributes( [ QgsField("Rec_No", QVariant.Int), QgsField("Include",  QVariant.String), QgsField("Label",  QVariant.String), QgsField("X", QVariant.Double),
                    QgsField("Y", QVariant.Double), QgsField("Z", QVariant.Double), QgsField("Height", QVariant.Double),
                    QgsField("Project_Re", QVariant.String), QgsField("NCA", QVariant.String),
                    QgsField("DayCrit", QVariant.Int), QgsField("EveCrit", QVariant.Int), QgsField("NightCrit", QVariant.Int) ] )

for i in range(len(Receivers)):          
  # add a feature
  fet = QgsFeature()
  X = Receivers[i][3]
  Y = Receivers[i][4]
  fet.setGeometry( QgsGeometry.fromPoint(QgsPoint(X,Y)) )

  # Details = a list of results returned from a database query specific to each result in 'Receivers'

  if Receivers[i][3] != 0:
    Include = 'Yes'
  else:
    Include = 'No'

  fet.setAttributeMap( { 0 : QVariant(Receivers[i][0]), 1 : QVariant(Include), 2 : QVariant(Receivers[i][2]),
                         3 : QVariant(Receivers[i][3]), 4 : QVariant(Receivers[i][4]), 5 : QVariant(Receivers[i][5]), 6 : QVariant(Receivers[i][6]),
                         7 : QVariant(Details[0]), 8 : QVariant(Details[1]), 9 : QVariant(Details[2]), 10 : QVariant(Details[3]), 11 : QVariant(Details[4]) } )
  pr.addFeatures( [ fet ] )

# add a style
vl.loadNamedStyle('C:/OSGeo4W/apps/qgis/python/plugins/Gopher2QGIS/styles/Receiver_Style.qml')

# update layer's extent when new features have been added
# because change of extent in provider is not propagated to the layer
vl.commitChanges()
vl.updateExtents()
vl.updateFieldMap()

QgsMapLayerRegistry.instance().addMapLayer(vl)

ลองดูที่ปลั๊กอิน PinPoint มันเพิ่มคุณสมบัติที่มีคุณลักษณะให้กับเลเยอร์หน่วยความจำและทำงานกับ 2.0 API
gsherman

ดีมากทำงานเหมือนมีเสน่ห์ ฉันใช้ตัวอย่างนี้เพื่อเพิ่มเลเยอร์ที่มีคะแนนจากบริการ Restfull QGis ยอดเยี่ยม
Peter Venema

คำตอบ:


8

ขอบคุณ gsherman ด้านบนตัวอย่างปลั๊กอิน PinPoint นั้นสมบูรณ์แบบ

ตามที่ฉันเข้าใจกระบวนการนี

  1. สร้างเลเยอร์ด้วยแอตทริบิวต์ในสายอักขระการก่อสร้าง
  2. เพิ่มเลเยอร์ที่กล่าวไปยังการลงทะเบียนแผนที่
  3. เริ่มแก้ไขในเลเยอร์นั้น
  4. เพิ่มคุณสมบัติและส่งการเปลี่ยนแปลง

นี่คือสารสกัดจากรหัสของฉันที่ใช้งานได้ในขณะนี้

layer =  QgsVectorLayer(
          "Point?field=Rec_No:integer&field=Include:string(120)&field=Label:string(120)&field=X:double&field=Y:double&field=Z:double&field=Height:double&field=Project_Re:string(120)&field=NCA:string(120)&field=DayCrit:integer&field=EveCrit:integer&field=NightCrit:integer",
          item,
          "memory")
QgsMapLayerRegistry.instance().addMapLayer(layer)

# Receivers = as in the above example 'Receivers' is a list of results
for i in range(len(Receivers)):

  # add a feature
  feature = QgsFeature()

  X = Receivers[i][3]
  Y = Receivers[i][4]
  feature.setGeometry( QgsGeometry.fromPoint(QgsPoint(X,Y)) )

  # Details = as in the above example 'Details' is a list of results

  if Receivers[i][1] != 0:
    Include = 'Yes'
  else:
    Include = 'No'

  values = [ QVariant(Receivers[i][0]), QVariant(Include), QVariant(Receivers[i][2]),
                         QVariant(Receivers[i][3]), QVariant(Receivers[i][4]), QVariant(Receivers[i][5]), QVariant(Receivers[i][6]),
                         QVariant(Details[0]), QVariant(Details[1]), QVariant(Details[2]), QVariant(Details[3]), QVariant(Details[4]) ]

  feature.setAttributes(values)
  layer.startEditing()
  layer.addFeature(feature, True)
  layer.commitChanges()

6

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

นี่คือการอัปเดตรหัสของ Cookbook ที่ทำงานกับ 2.0 API:

# create layer
vl = QgsVectorLayer("Point", "temporary_points", "memory")
pr = vl.dataProvider()

# changes are only possible when editing the layer
vl.startEditing()
# add fields
pr.addAttributes([QgsField("name", QVariant.String),QgsField("age", QVariant.Int),QgsField("size", QVariant.Double)])

# add a feature
fet = QgsFeature()
fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10,10)))
fet.setAttributes(["Johny", 2, 0.3])
pr.addFeatures([fet])

# commit to stop editing the layer
vl.commitChanges()

# update layer's extent when new features have been added
# because change of extent in provider is not propagated to the layer
vl.updateExtents()

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