13 votos

¿Cómo puedo crear mediante programación y agregar características a una capa de memoria en QGIS 1.9?

Yo tenía un trabajo plugin de QGIS 1.8 que leer datos de una base de datos MSAccess y se añadió a una serie de capas de la memoria. Hay algún tipo de procesamiento implicados en el ínterin así que no creo que simplemente el uso de QGIS para leer directamente desde la base de datos es una opción.

Me gustaría pasar de QGIS 1.8 a 1.9 (debido, principalmente, a la mejora de la calidad de la impresión compositor). El plugin no funciona con la nueva API.

He probado una gran variedad de métodos que se vino arriba en las búsquedas de google. Uno, modificando el código de abajo - de http://www.qgis.org/pyqgis-cookbook/vector.html#memory-provider, es decir, la adición de la geometría y atributos para el objeto dataprovider y, a continuación, la actualización de la capa - para adaptarse a la nueva API trabajado un poco, pero sus atributos no eran visibles hasta que me manully entrado en el modo de edición (similar a http://hub.qgis.org/issues/3713). Un enfoque alternativo que se detalla en la respuesta #1 de el enlace de arriba, añadió la capa y atributos correctamente, pero no pude agregar características a la capa.

Dado que debe ser una tarea bastante simple tengo la esperanza de que alguien de aquí puede ofrecer un ejemplo de cómo debe hacerse. (P. S. yo no soy un programador profesional y la mayoría de mis codificación es bastante crudo - doy la bienvenida a cualquier orientación, pero pedimos que excusa alguna ignorancia de mi parte)

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

8voto

user18047 Puntos 21

Gracias a gsherman por encima de la PinPoint plugin de ejemplo es perfecto.

Como entiendo que el proceso es el siguiente:

  1. Crear la capa con los atributos en la cadena de construcción
  2. Agregar dijo capa al mapa de registro
  3. Iniciar la edición de la capa
  4. Agregar características y confirmar los cambios

Aquí es un extracto de mi código que ahora trabaja.

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()

6voto

dreeves Puntos 166

Basado en la respuesta de Adam Bioletti, más pruebas para el proceso que se describe muestran que el único requisito indispensable es para iniciar la edición de la capa de memoria antes de realizar cualquier cambio, como la creación de los atributos y características y, a continuación, confirme los cambios. Esto se puede hacer antes de añadir la capa de mapa de registro.

Aquí está una actualización del libro de cocina del código que trabaja con la API 2.0:

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

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X