8 votos

De la representación y el Etiquetado de Shapefile con PyQGIS

He estado corriendo en un par de problemas al trabajar con el QGIS API para python. Me he metido más cómodo trabajando en la consola de python en QGIS, pero tengo problemas cuando intento ejecutar el código fuera de QGIS.

Básicamente quiero tomar un shapefile, la etiqueta se basa en el atributo especificado de nombre y representación de una imagen. El código funciona en QGIS, pero no funciona fuera de QGIS. Entonces, ¿dónde está mi problema viene?

import sys
import qgis
import PyQt4

from qgis.core import *
from qgis.utils import *
from qgis.gui import *


from PyQt4.QtCore import *
from PyQt4.QtGui import *

#initialize QGIS
QgsApplication.setPrefixPath( r"C:\OSGeo4W64\apps\qgis", True )

QgsApplication.initQgis()

#Add layer to instance
file = QgsVectorLayer("Good Shape File", "BMAS", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(file)


#Adjust layer Settings
#Code sample from http://gis.stackexchange.com/questions/77870/how-to-label-vector-features-programmatically
palyr = QgsPalLayerSettings() 
palyr.enabled = True 
palyr.fieldName = 'Attribute' 
palyr.placement= QgsPalLayerSettings.OverPoint 
palyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'8','') 
palyr.writeToLayer(file)

if file.isValid():
  print "File is valid."


mapRenderer = iface.mapCanvas().mapRenderer()

lst = [file.id()]
mapRenderer.setLayerSet(lst)

mapRenderer.setLayerSet( lst )
c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
composerMap = QgsComposerMap(c, x,y,w,h)
c.addItem(composerMap)
composerLabel = QgsComposerLabel(c)

composerLabel.adjustSizeToText()
c.addItem(composerLabel)
composerLabel.setItemPosition(20,10)
composerLabel.setItemPosition(20,10, 100, 30)

legend = QgsComposerLegend(c)
legend.model().setLayerSet(mapRenderer.layerSet())
c.addItem(legend)

#set image sizing
dpi = c.printResolution()
dpmm = dpi / 25.4
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())
img = QImage(QSize(width, height), QImage.Format_ARGB32)
img.setDotsPerMeterX(dpmm * 1000)
img.setDotsPerMeterY(dpmm * 1000)
img.fill(0)
imagePainter = QPainter(img)
sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
targetArea = QRectF(0, 0, width, height)

#renders image
c.render(imagePainter, targetArea, sourceArea)
imagePainter.end()
img.save("E:/QGisTestImages/out.png", "png")

Yo soy capaz de hacer la simple representación de ejemplo en python libro de cocina, por lo que creo que mis caminos están configurados correctamente.

"Una buena Forma de Archivo" debe ser reemplazado con una buena ubicación de ruta de acceso si desea ejecutar este. Y palyr.fieldName = "Atributo" debe estar configurado con un nombre de campo válido para que shapefile.

Editar: He tenido que deshacerse de iface y se inserta el código para que la medida entre el mapRenderer de inicialización y el lst declaración.

mapRenderer = QgsMapRenderer()

rect = file.extent()
mapRenderer.setExtent(rect)
mapRenderer.setLabelingEngine(QgsPalLabeling())
lst = [file.id()]

Edit: he añadido

app = QgsApplication([], True)

después de

QgsApplication.initQgis()

y el código funcionó.

7voto

faker Puntos 11270

Oye moderador que eliminó a mi último post sobre el mismo tema, por favor, deje este. Esto es completamente relevante porque yo no creo que las respuestas sobre el trabajo y yo no soy el único que está luchando aquí.

O yo estoy loco, o los dos bits de código ya no funciona. He copiado estos y ajustado para mi uso y para la vida de mí no puedo sacar una tif de la shapefile con otra cosa que un lienzo en blanco que dice "Leyenda: Contornos" en la esquina superior izquierda.

Mi objetivo es tomar un shapefile (shp) y convertirla a un formato tif con el contorno de las líneas marcadas en la elevación. Soy capaz de abrir el archivo de forma en qgis, y la superposición en el archivo dem del que he hecho los contornos. Soy incluso capaz de superposición de los dos en una ventana (lienzo), el uso de otros códigos, pero no puedo por la vida de mí llegar a salvar a una .archivo tif con los contornos y las etiquetas.

Aquí está mi código como está ahora:

import sys
import os
import qgis
import PyQt4

from qgis.core import *
from qgis.utils import *
from qgis.gui import *


from PyQt4.QtCore import *
from PyQt4.QtGui import *

#initialize QGIS
QgsApplication.setPrefixPath( '/usr', True )
userPath = os.path.expanduser('~')
dataFilesDir = os.path.join(userPath, 'Data', 'Claremont')
vectorLayerPath = os.path.join(dataFilesDir, 'contours.shp')

QgsApplication.initQgis()
app = QgsApplication([], True)

#Add layer to instance
vlayer = QgsVectorLayer(vectorLayerPath, "Contours", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)

if vlayer.isValid():
  print "vlayer is valid."
  print 'feature count: %d' %(vlayer.featureCount())

#Adjust layer Settings
#Code sample from http://gis.stackexchange.com/questions/77870/how-to-label-vector-features-programmatically

palyr = QgsPalLayerSettings() 
palyr.readFromLayer(vlayer)
palyr.enabled = True 
palyr.fieldName = 'elev'
# palyr.fontMinPixelSize = 20
palyr.size = 20
palyr.textColor = Qt.blue
palyr.drawLabels = True
palyr.placement= QgsPalLayerSettings.OverPoint 
palyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'8','') 
palyr.writeToLayer(vlayer)

mapRenderer = QgsMapRenderer()

rect = vlayer.extent()
mapRenderer.setExtent(rect)
mapRenderer.setLabelingEngine(QgsPalLabeling())
lst = [vlayer.id()]

mapRenderer.setLayerSet(lst)

c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)
# c.setPlotStyle(QgsComposition.Preview)
x, y = 300, 300
w, h = c.paperWidth(), c.paperHeight()
print 'width: %f' %(w)
print 'height: %f' %(h)
composerMap = QgsComposerMap(c,x,y,w,h)
# composerMap.drawCanvasItems()


print 'current extent width: %f,  height %f' \
    %(composerMap.currentMapExtent().width(), composerMap.currentMapExtent().height())

c.addItem(composerMap)
# c.addComposerMap(composerMap)
composerLabel = QgsComposerLabel(c)


composerLabel.adjustSizeToText()
c.addItem(composerLabel)
# c.addComposerLabel(composerLabel)
composerLabel.setItemPosition(20,10)
composerLabel.setItemPosition(20,10, 100, 30)

legend = QgsComposerLegend(c)
legend.model().setLayerSet(mapRenderer.layerSet())
c.addItem(legend)

#set image sizing
dpi = c.printResolution()
dpmm = dpi / 25.4
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())
img = QImage(QSize(width, height), QImage.Format_ARGB32)
img.setDotsPerMeterX(dpmm * 1000)
img.setDotsPerMeterY(dpmm * 1000)
img.fill(Qt.transparent)
imagePainter = QPainter(img)
sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
targetArea = QRectF(1000, 1000, width, height)

#renders image
print 'Rendering Image'
# c.refreshItems()
# c.updateBounds()

# composerMap.draw(imagePainter, sourceArea, QSize(300, 300), 96)

c.render(imagePainter, targetArea, sourceArea)
# c.renderPage(imagePainter, 0)
imagePainter.end()
img.save(os.path.join(dataFilesDir, 'contourmap.tif'), 'tif')

Aquí está la salida a la consola: vlayer es válido. función de conteo: 13645 ancho: 297.000000 altura: 210.000000 extensión actual ancho: 0.000000, altura 0.000000 La Representación De La Imagen [Terminado en 0,3 s]

Cualquier ayuda sería inmensamente apreciado.

2voto

Brayn Puntos 671

La combinación de la eliminación de iface y la declaración de la aplicación de la variable que parece haber funcionado. Yo ahora obtener una imagen representa a partir de los shapefile con cada característica de la etiqueta con el atributo basado en el "Atributo".

1voto

Etna Puntos 26

Estoy teniendo problemas a la hora de crear los archivos png con dicho método. Mi shapefile es leer correctamente, una imagen se crea, pero siempre se queda completamente en blanco.

Como se puede ver en las impresiones, el mapRenderer.medida() los valores son siempre cero. Es esto normal, o tengo que cavar más profundo en esto?

Los controles posteriores con el dpi, ancho y altura de la QgsComposition entregar algunos valores, aunque no tengo ni idea de si son correctos o no.

También he probado un número de diferentes de impresión/opciones de representación, como c.render(), o a dar las cosas como archivos pdf. Nunca me lo errores, pero mi página siempre se queda en blanco.

Ha alguien más experimentado el problema de la recepción de fotografías en blanco?

Cualquier ayuda se agradece! Gracias!

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from qgis.core import *
from qgis.utils import *
from qgis.gui import *
import os

QgsApplication.initQgis()
app = QgsApplication([], True)

#Add layer to instance
TransmissionLayer = QgsVectorLayer(os.path.join(homepath,"shapefile.shp"),"T_Layer","ogr")
print TransmissionLayer.featureCount(), TransmissionLayer.isValid()
QgsMapLayerRegistry.instance().addMapLayer(TransmissionLayer)
mapRenderer = QgsMapRenderer()

mapRenderer.setLayerSet(QStringList(TransmissionLayer.id()))
print mapRenderer.extent().width(), mapRenderer.extent().height()
print mapRenderer.extent().center()

c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()

composerMap = QgsComposerMap(c,x,y,w,h)
c.addItem(composerMap)

#set image sizing
dpi = c.printResolution()
dpmm = dpi / 25.4 / 3
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())
img = QImage(QSize(width, height), QImage.Format_ARGB32)
img.setDotsPerMeterX(dpmm * 1000)
img.setDotsPerMeterY(dpmm * 1000)
img.fill(0)
imagePainter = QPainter(img)
sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
targetArea = QRectF(0, 0, width, height)

print dpi, width, height
print sourceArea, targetArea

#renders image
#c.render(imagePainter, targetArea, sourceArea)
print c.numPages(), c.paperWidth(), c.paperHeight()
c.renderPage(imagePainter,0)
imagePainter.end()
outpic = "output/Pic_Case" + str(z+1) + ".png"
img.save(os.path.join(homepath,outpic), "png")

app.exitQgis()

La salida de este segmento de código:

1 True

0.0 0.0

(0,0)

300 1169 826

PyQt4.QtCore.QRectF(0.0, 0.0, 297.0, 210.0) PyQt4.QtCore.QRectF(0.0, 0.0, 1169.0, 826.0)

1 297.0 210.0

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