QGISで属性の値に応じてポリゴン分割?
うまくタイトル考えられません。
Typography Mapはおいておいて、相変わらずInformation Graphicsを眺めております。
- 作者: Sandra Rendgen,Paolo Ciuccarelli,Richard Saul Wurman,Simon Rogers,Julius Wiedemann
- 出版社/メーカー: Taschen America Llc
- 発売日: 2012/05/27
- メディア: ハードカバー
- クリック: 2回
- この商品を含むブログ (1件) を見る
使用するデータ
ちょうど手元にあった北海道の図形を使います。
これに北海道の住民基本台帳人口・世帯数のページから年齢5歳階級別人口を持ってきて、属性として付けました。
結果
ポリゴン内に一定間隔のポイントを発生させます。
このポイントを、5歳区切りの人口の割合に応じて、属性分けしてあげました。
0-4歳の人口が、総人口の3%なら、発生したポイントのうち3%に"0-5歳"と属性を入れてあげます。
そして属性で色分け。
もう少し階層を少なく、そして色分けをくっきりしないと、なんだかわからないですね。何かいいデータを見つけたら、あらためて絵を作ってみよう。
書いたソース
QGIS2.0の、pythonコンソールから実行します。"エディタの表示"をしておいて、ソースを貼り付けて実行しています。
前提条件として、
- レイヤーは選択済み
- 図形は1つしかないこと
- 入っている属性がすべてintegerであること
- すべての属性を使います、使わない属性が入っていないこと
としています。
処理としては、
- 選択済みのレイヤーの属性定義を取っておく、作成したレイヤの属性にカラム名を入れるため
- 図形を1つ持ってくる、各属性値を属性値の総和で割って、割合を求めておく
- ポイントを一定間隔で発生
- 発生したポイントレイヤにカラムを1つ追加
- 位置でソートされていることを期待してポイントに順次アクセス、同じ属性を、求めておいた割合*総ポイント数分の図形に入れていく
といった流れです。
色付けは手動でやっています。
# -*- coding: utf-8 -*- from PyQt4 import QtGui, QtCore import processing #作成六角形サイズ size = 0.1 #属性を入れるカラム名 sort = u'sort' #レイヤーが選択されていることが前提 layer = iface.activeLayer() if layer.featureCount() != 1: print "Warnnig:this program allow to run on condition layer has one feature" #1つだけ図形を持ってくる layer.selectAll() inputFeature = layer.selectedFeatures () #属性定義をとっておく fields = inputFeature[0].fields() #各属性の割合を調べておく attrList = inputFeature[0].attributes() all = sum(attrList) attrListFloat = map(lambda x:float(x)/all, attrList) #processingを使って、六角形作成、中心点作成、必要範囲のみ切り取り #processingの必要はなし、使ってみたかっただけ hexResult = processing.runalg('script:hexgridfromlayerbounds', layer, size, None) centroidsResult = processing.runalg('qgis:polygoncentroids', hexResult['grid'], None) intersectionResult = processing.runalg('qgis:intersection', centroidsResult['OUTPUT_LAYER'], layer, None) pointLayer = processing.load(intersectionResult['OUTPUT']) pointLayer.startEditing () #属性を入れるカラムを追加 pointLayer.addAttribute(QgsField(sort, QtCore.QVariant.String, u'string', 10)) #図形はソートされていることを期待して、id順にアクセス featureCount = pointLayer.featureCount() fieldIndex = 0 fieldCnt = 0 for i in range(featureCount): #調べておいた割合にしたがって、図形に属性を入れていく #大体の数ということで pointLayer.changeAttributeValue(i, pointLayer.fieldNameIndex(sort), fields.field(fieldIndex).name()) fieldCnt += 1 if fieldCnt >= featureCount * attrListFloat[fieldIndex]: fieldIndex += 1 if fieldIndex >= len(attrListFloat): break fieldCnt = 0 pointLayer.commitChanges ()
ToDo
面白い絵が出来そうなデータを見つけて、絵を作ってみる。
以上