PyQGISを使用したシェープファイルのレンダリングとラベル付け


8

QGIS API for pythonの操作でいくつかの問題が発生しています。QGISのpythonコンソールでの作業がより快適になりましたが、QGISの外部でコードを実行しようとすると問題が発生します。

基本的に、シェープファイルを取得し、指定された属性名に基づいてラベルを付け、画像をレンダリングしたいと思います。コードはQGISで機能しますが、QGISの外部では機能しません。だから私の問題はどこから来ているのですか?

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

Pythonクックブックで簡単なレンダリングの例を実行できるので、パスが正しく設定されていると思います。

これを実行する場合は、「Good Shape File」を適切なパスの場所に置き換える必要があります。また、palyr.fieldName = 'Attribute'は、そのシェープファイルの有効なフィールド名に設定する必要があります。

編集:ifRを取り除き、mapRendererの初期化とlst宣言の間の範囲のコードを挿入しました。

mapRenderer = QgsMapRenderer()

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

編集:追加しました

app = QgsApplication([], True)

QgsApplication.initQgis()

そしてコードは働いた。


1
まず、ifaceQGISの外では使用できません。それはする必要がありますmapRenderer = QgsMapRenderer()
ネイサンW

申し訳ありませんが、mapRendererを十分な情報で初期化していないようです。レイヤーの範囲とラベリングエンジンに関する情報を追加した後、コンソールがc = QgsComposition(mapRenderer)でフリーズします。コードはまだQGISで機能しますが、サイズを変更する必要があるだけです。
midfield99

1
QgsApplicationの初期化に問題があるようです。そして、この問題はgis.stackexchange.com/questions/69626/…でカバーされているようです。したがって、app変数を宣言し、app.exitQgis()を追加すると機能しました。
midfield99

上記の方法でpngを作成すると問題が発生します。私のシェープファイルは正しく読み取られ、画像が作成されますが、常に完全な白のままです。印刷結果を見るとわかるように、mapRenderer.extent()の値は常にゼロです。これは正常ですか、それとももっと深く掘り下げる必要がありますか?QgsCompositionのdpi、幅、高さを使用した後続のチェックでは、いくつかの値が提供されますが、それらが正しいかどうかはわかりません。また、c.render()などのさまざまな印刷/レンダリングオプションを試したり、pdfとして提供したりしました。エラーは発生しませんが、私のページ
Bob3k 2014年

同じトピックに関する私の最後の投稿を削除したモデレーターねえ、これは残しておいてください。上記の答えがまだ機能するとは思わないので、これは完全に関連があります。ここで苦労しているのは私だけではありません。私が狂っているか、2ビットのコードが機能しなくなっています。これらをコピーして微調整しましたが、私の生活の中で、左上隅に「凡例:輪郭」と書かれた白いキャンバス以外ではシェイプファイルからtifを取得できません。私の目標はシェープファイル(shp)を取得して、等高線が標高でラベル付けされたtifに変換します。sを開くことができます
Marc

回答:


2

ifaceの削除とapp変数の宣言の組み合わせが機能しているようです。シェープファイルからレンダリングされた画像を取得します。各機能には、「属性」に基づく属性でラベル付けされています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.