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

PinPoint 플러그인 예제 위의 gsherman 덕분에 완벽합니다.

내가 이해하는 바와 같이 프로세스는 다음과 같습니다.

  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의 답변을 바탕으로, 설명 된 프로세스에 대한 추가 테스트는 속성 및 기능 작성과 같은 변경을 수행 하기 전에 메모리 계층 편집을 시작한 다음 변경 사항을 커밋하는 것이 필수 요구 사항임을 보여줍니다 . 이 작업은 맵 레지스트리에 레이어를 추가하기 전에 수행 할 수 있습니다.

2.0 API와 함께 작동하는 Cookbook 코드 업데이트는 다음과 같습니다.

# 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.