QGISのSVG塗りつぶしパターンを属性から作ってみる
FOSS4G 2013 Tokyoお疲れ様でした
10/31-11/2行われていたFOSS4G 2013 Tokyoに参加していました。運営のみなさま疲れさまでした。引き続き11/6-7のFOSS4G 2013 Osaka頑張ってください。Ust中継見てようと思います。
今回参加しての収穫の1つが、下記の本を紹介してもらったことでした。
- 作者: Sandra Rendgen,Paolo Ciuccarelli,Richard Saul Wurman,Simon Rogers,Julius Wiedemann
- 出版社/メーカー: Taschen America Llc
- 発売日: 2012/05/27
- メディア: ハードカバー
- クリック: 2回
- この商品を含むブログ (1件) を見る
面を属性で埋める
"Information Graphics"の中で紹介されていた、文字列で作った地図が気になっています。例えば行政区域のポリゴンがあったとしてその名称で、"あさひかわあさひかわあさひかわ"のようなパターンで埋めます。うまく伝えられなくてごめんなさい。
QGISで旨いこと出来ないかなと思い、少しだけやってみました。
制約が多いので、あくまで実験的のものです。他にいい方法あるよという方、ご指摘お待ちしております。
使用するデータ
natural earthのデータを使用します。
1:50m Cultural Vectorsの"Admin 0 – Countries"になります。
結果
先に結果。ポリゴンの属性に入っている国名からSVGファイルを作成して、スタイルに指定しています。本当はもう少し1文字ずつサイズとか変えながらやれると格好いいと思うのですが、そこまでやれないので単純なパターンで。当然"Information Graphics"で紹介されている地図はもっともっと格好いいです。
書いたソース
QGIS2.0の、pythonコンソールから実行します。"エディタの表示"をしておいて、ソースを貼り付けて実行しています。
前提条件として、
- "sovereignt"カラムの値を描画することにしています。他のカラムの場合utf8以外のコードが入っているとエラーが出たため、そうしています。
- レイヤーは選択済み
としています。
処理としては、
- 属性値のリストを作っておく
- 属性値毎のSVGファイルを作成(temporaryファイルですが消さず)
- symbolにSVG塗りつぶしを入れる
- "ルールに基づいた"スタイルにフィルターと合わせてsymbolをセット
- 全ての属性値に対するルールの設定が終わったら、スタイルをrendererに入れてlayerに設定
- 再描画
といった流れです。
# -*- coding: utf-8 -*- from PyQt4 import QtGui, QtCore import tempfile #レイヤーが選択されていることが前提 layer = iface.activeLayer() #描画する属性フィールド key = "sovereignt" #空の"ルールに基づいた"スタイル作成 rule = QgsRuleBasedRendererV2.Rule(None) #指定の属性フィールドの値リストを作成 attrList = [] features = layer.getFeatures() for feature in features: if feature[key] not in attrList: attrList.append(feature[key]) for attr in attrList: #指定の属性を入れたSVGファイルを作成 fillPattern = """<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">""" fillPattern += '<svg width="%.1fpx" height="1px" ' % (len(attr)*0.5) fillPattern += 'xmlns="http://www.w3.org/2000/svg" version="1.1">' fillPattern += '<text x="0" y="1" font-family="serif" font-size="1" fill="blue" >' fillPattern += '%s' % attr fillPattern += '</text></svg>' tempSvg = tempfile.NamedTemporaryFile(mode="w+t", delete=False) tempSvg.write(fillPattern) tempSvg.close() #空のシンボルを作成 symbol = QgsSymbolV2.defaultSymbol(QGis.Polygon) symbol.deleteSymbolLayer(0) #属性を入れたSVGを指定して、SVG塗りつぶしを作成 fillLayer = QgsSVGFillSymbolLayer(tempSvg.name, len(attr)*2) #シンボルに塗りつぶしを追加 symbol.appendSymbolLayer(fillLayer) #指定の属性カラムによるフィルタを設定して、ルールを作成、追加 ruleAdd = QgsRuleBasedRendererV2.Rule(symbol, label=attr, filterExp="\"%s\" = '%s'" % (key, attr), description=attr) rule.appendChild(ruleAdd) renderer = QgsRuleBasedRendererV2(rule) layer.setRendererV2(renderer) iface.mapCanvas().refresh() iface.legendInterface().refreshLayerSymbology(layer)